
While trying to debug a problem and thinking that it may be an issue with circular imports, I come up with an interesting idea that might be of value. It wasn't a circular import problem in this case, but I may have found the actual bug sooner if I didn't need to be concerned about that possibility. I have had some difficulty splitting larger modules into smaller modules in the past where if I split the code by functionality, it doesn't correspond with how the code is organized by dependency. The result is an imported module needs to import the module it's imported into. Which just doesn't feel right to me. The solution I found was to call a function to explicitly set the shared items in the imported module. (The example is from a language I'm experimenting with written in python. So don't be concerned about the shared object names in this case.) In the main module... import parse parse.set_main(List=List, Keyword=Keyword, Name=Name, String=String, Express=Express, keywords=keywords, raise_with=raise_with, nil=nil) And in parse... # Sets shared objects from main module. from collections import namedtuple def set_main(**d): global main main = namedtuple(__name__, d.keys()) for k, v in d.items(): setattr(main, k, v) After this, the sub module access's the parent modules objects with... main.Keyword Just the same as if the parent module was imported as main, but it only shares what is intended to be shared within this specific imported module. I think that is better than using "import from" in the sub module. And an improvement over importing the whole module which can possibly expose too much. The benifits: * The shared items are explicitly set by the parent module. * If an item is missing, it results in a nice error message * Accessing objects works the same as if import was used. * It avoids (most) circular import problems. * It's easier to think about once you understand what it does. The problem is the submodule needs a function to make it work. I think it would be nice if it could be made a builtin but doing that may be tricky. Where I've used "main", it could set the name of the shared parent module(s) automatically. The name of the function probably should be "shared" or "sharing". (Or some other thing that makes sense.) I would like to hear what other here think, and of course if there are any obvious improvements that can be made. Would this be a good candidate for a new builtin? Cheers, Ron