Package: pyecore
PyEcore is a Model Driven Engineering (MDE) framework written for Python.
Precisely, it is an implementation ofEMF/Ecorefor Python, and it tries to give an
API which is compatible with the original EMF Java implementation.PyEcore allows you to handle models and metamodels (structured data model), and
gives the key you need for building MDE-based tools and other applications based
on a structured data model. It supports out-of-the-box:Data inheritance,Two-ways relationship management (opposite references),XMI (de)serialization,JSON (de)serialization,Notification system,Reflexive API…Let see how to create on a very simple “dynamic” metamodel (in opposite to
static ones, see thedocumentationfor more details):>>>frompyecore.ecoreimportEClass,EAttribute,EString,EObject>>>Graph=EClass('Graph')# We create a 'Graph' concept>>>Node=EClass('Node')# We create a 'Node' concept>>>>>># We add a "name" attribute to the Graph concept>>>Graph.eStructuralFeatures.append(EAttribute('name',EString,default_value='new_name'))>>># And one on the 'Node' concept>>>Node.eStructuralFeatures.append(EAttribute('name',EString))>>>>>># We now introduce a containment relation between Graph and Node>>>contains_nodes=EReference('nodes',Node,upper=-1,containment=True)>>>Graph.eStructuralFeatures.append(contains_nodes)>>># We add an opposite relation between Graph and Node>>>Node.eStructuralFeatures.append(EReference('owned_by',Graph,eOpposite=contains_nodes))With this code, we have defined two concepts:GraphandNode. Both have
aname, and it exists a containment relationship between them. This relation
is bi-directionnal, which means that each time aNodeobject is added to thenodesrelationship of aGraph, theowned_byrelation of theNodeis updated also (it also work in the other way).Let’s create some instances of our freshly created metamodel:>>># We create a Graph>>>g1=Graph(name='Graph 1')>>>g1<pyecore.ecore.Graphat0x7f0055554dd8>>>>>>># And two node instances>>>n1=Node(name='Node 1')>>>n2=Node(name='Node 2')>>>n1,n2(<pyecore.ecore.Nodeat0x7f0055550588>,<pyecore.ecore.Nodeat0x7f00555502b0>)>>>>>># We add them to the Graph>>>g1.nodes.extend([n1,n2])>>>g1.nodesEOrderedSet([<pyecore.ecore.Nodeobjectat0x7f0055550588>,<pyecore.ecore.Nodeobjectat0x7f00555502b0>])>>>>>># bi-directional references are updated>>>n1.owned_by<pyecore.ecore.Graphat0x7f0055554dd8>This example gives a quick overview of some of the features you get for free
when using PyEcore.The project slowly grows and it still requires more love.InstallationPyEcore is available onpypi, you can simply install it usingpip:$pipinstallpyecoreThe installation can also be performed manually (better in a virtualenv):$pythonsetup.pyinstallDocumentationYou can read the documentation at this address:https://pyecore.readthedocs.io/en/latest/DependenciesThe dependencies required by pyecore are:ordered-set which is used for theorderedanduniquecollections expressed in the metamodel,lxml which is used for the XMI parsing.These dependencies are directly installed if you choose to usepip.Run the TestsTests usespy.testand ‘coverage’. Everything is driven byTox, so in order
to run the tests simply run:$toxLiberty Regarding the Java EMF ImplementationThere is some meta-property that could be missing inside PyEcore. If you see one missing, please open a new ticket!Proxies are not “removed” once resolved as in the the Java version, instead they acts as transparent proxies and redirect each calls to the ‘proxied’ object.PyEcore is able to automatically load some model/metamodel dependencies on its own.StateIn the current state, the project implements:the dynamic/static metamodel definitions,reflexive API,inheritance,enumerations,abstract metaclasses,runtime typechecking,attribute/reference creations,collections (attribute/references with upper bound set to-1),reference eopposite,containment reference,introspection,select/reject on collections,Eclipse XMI import (partially, only single root models),Eclipse XMI export (partially, only single root models),simple notification/Event system,EOperations support,code generator for the static part,EMF proxies (first version),object deletion (first version),EMF commands (first version),EMF basic command stack,EMF very basic Editing Domain,JSON import (simple JSON format),JSON export (simple JSON format),introduce behavior @runtime,resources auto-load for some cross-references,derived collections,multiple roots ressources,xsi:schemaLocationsupport for XMI resources,URI mapper like,EGenericsupport (first simple version),URI converter likeThe things that are in the roadmap:new implementation ofEOrderedSet,EList,ESetandEBag,new implementation ofEStringToStringMapEntryandEFeatureMapEntry,improve documentation,copy/paste (?).Existing ProjectsThere is not so much projects proposing to handle model and metamodel in Python.
The only projects I found are:PyEMOF (http://www.lifl.fr/~marvie/software/pyemof.html)EMF4CPP (https://github.com/catedrasaes-umu/emf4cpp)PyEMOFUC (http://www.istr.unican.es/pyemofuc/index_En.html)PyEMOF proposes an implementation of the OMG’s EMOF in Python. The project
targets Python2, only supports Class/Primitive Types (no Enumeration), XMI
import/export and does not provide a reflexion layer. The project didn’t move
since 2005.EMF4CPP proposes a C++ implementation of EMF. This implementation also
introduces Python scripts to call the generated C++ code from a Python
environment. It seems that the EMF4CPP does not provide a reflexive layer
either.PyEMOFUC proposes, like PyEMOF, a pure Python implementation of the OMG’s EMOF.
If we stick to a kind of EMF terminology, PyEMOFUC only supports dynamic
metamodels and seems to provide a reflexive layer. The project does not appear
seems to have moved since a while.ContributorsThanks for making PyEcore better!Mike Pagel (@moltob), which is also the author
ofpyecoregenandpymultigen(on which pyecoregen is based)Terry Kingston (@TerryKingston)Afonso Pinto (@afonsobspinto)Andy (@CFAndy)annighoefer (@annighoefer)Rodriguez Facundo (@rodriguez-facundo)Filippo Ledda (@filippometacell)Ewoud Werkman (@ewoudwerkman)Eugene (@4ekin)Alexandre Acebedo (@aacebedo)Jinhu (@jinhu)Pablo Campillo (@pablo-campillo)Jose Antonio Moral (@jamoralp)Marco Heinemann (@ubmarco)Christian Drabek (@cdrabek)Dan Yeaw (@danyeaw)Additional ResourcesThis articleon the blog of the Professor Jordi Cabot gives more information and
implementations details about PyEcore.