Skip to content

Wrong code generated for enums #34

Open

Description

@alessiostalla

See pyecore/pyecore#126 (comment)

Quoting from there, for enums,

pyecoregen generates the wrong code:

for classif in otherClassifiers:
    eClassifiers[classif.name] = classif
    classif.ePackage = eClass

for classif in eClassifiers.values():
    eClass.eClassifiers.append(classif.eClass)

What happens is that, initially, eClassifiers is empty. Then, first, enums are added to eClassifiers, and then the eClass of each object in eClassifiers is added to the EPackage (that for some reason is called eClass). So we have the EEnum class added to the package we're defining! And, of course, it gets removed from the Ecore package, because eClassifiers is a containment relationship. I don't know the purpose of the second for loop, maybe it was to handle custom metaclasses or stuff like that, but it should filter the classes that it puts into eClass, or be removed altogether if it's not necessary.

Activity

  1. aranega commented on Feb 21, 2023

    @aranega
    Member

    Hi @alessiostalla,

    Sorry again for the delay of my answer. As I stated in pyecore/pyecore#130 (comment) the new version should also fix this issue :). Regarding your observation with the two for loop, as you probably undersood, indeed the second for loop is redundant (in my opinion), I think it was here as a "fix" for a bug regarding the ePackage relation. At the end classif.ePackage = eClass and eClass.eClassifiers.append(classif.eClass) do the same thing as ePackage and eClassifiers are opposite relationship.

    Regarding the EPackage name in the code (eClass) it's because eClass is the name of the relationship that allows you to pass from a python instance to a pyecore-world instance (from static to dynamic). The idea was to make the python module polymorphic with other pyecore objects. However, the name eClass was badly chozen from the beginning. I chose this one and at the end, the semantic changes regarding the receiver of the attribute. If you are on a dynamic instance, eClass is actually the metaclass of your object in the pyecore-world (as in EMF), however, if you are on a static class (a python module that is an EPackage or a python class that is an EClass), then it means "get the dynamic instance that represent this module/class". This name is badly chosen from the beginning and I still keep it for retrocompatibility issues. Perhaps in the future I'll release a new version, but that will imply some breaking changes and an obligation to use the last version of pyecoregen (that will need som patch also). The last commit I added to 0.13.1 introduces a new relationship between the two worlds that will replace in the future the eClass reference to pass from python-world to pyecore-world: dyn_inst. The advantage is that if you call dyn_inst on a dynamic instance, it returns self. If you call it on a static element (class/module/package), it will return the dynamic instance.
    I didn't documented it yet as the name will perhaps change in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions