from x import y vs. import x
Hi @aranega
I try to create static code from complex ecore models like capella. I always run into the problem of circular includes.
But I think this could be avoided if other modules are loaded by using import x instead of from x import y.
So if you have a module like this
module examlple
__init__.py
from .one import Foo
from .one import helper
one.py
from example import two
class Foo(two.Bar):
def __init__(self):
super().__init__()
print('Init Foo')
def helper():
print('Help')
def main():
foo = Foo()
if __name__ == '__main__':
main()
two.py
from example import helper
class Bar:
def __init__(self):
print('Init Bar')
helper()
As far as I understood, by using from x import y y is loaded into the local namespace. Therefore example above will not work.
but changing two.py to
two.py
import example
class Bar:
def __init__(self):
print('Init Bar')
example.helper()
And it can be resolved. So instead loading single classifiers from different ecore files importing the whole package can maybe solve this issue. Maybe I find some time to dive deeper and can prepare a patch and some example. Hope you have a rough idea of the problem.
Maybe you can give me a hint how I easily get the containing package from the classifier in the code gen template.
Best regards, Andreas
Hi @AnNeub !
I see exactly what you mean for the imports. You're right, if you use the from x import y, y is loaded in the local namespace. However, I think that even if you just call import x, it will try to solve it as a module, so to load it and if x has a circular import toward your main module and use an element from it as a superclass, depending which module you call as "main" one, it will fail.
# A.py
import B
class AA(object):
...
# B.py
import A
class B(A.AA):
...
$ python A.py # works
$ python B.py # fails because of the circular import
Perhaps for submodule, the solution you propose can work juste fine :) I need to try on tricky metamodels to see if it fixes this issue. This is not an easy issue to solve, definitely.
For capella, helped with @cgava, we tried to pull a static version using pyecore and we reached a version with the various experiements @cgava made. You can find the efforts here https://github.com/cgava/pyEcoreCapella
We had to write a dedicated generator (a specific modification of pyecoregen) for this kind of metamodel with a lot of circular references, and you need to use the develop version of pyecore.
In any case, I'll try to work on that and to find a sexy solution that could either generate code in a different fashion for every metamodel, or a way of detecting circular imports and trigger a specific code generation in those cases (it would be the best I guess).