Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

from x import y vs. import x #32

Open
AnNeub opened this issue Mar 7, 2022 · 1 comment
Open

from x import y vs. import x #32

AnNeub opened this issue Mar 7, 2022 · 1 comment

Comments

@AnNeub
Copy link

AnNeub commented Mar 7, 2022

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

@aranega
Copy link
Member

aranega commented Mar 8, 2022

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants