Skip to main content

pypi-version master-build coverage code-quality license

PyEcore is a Model Driven Engineering (MDE) framework written for Python. Precisely, it is an implementation of EMF/Ecore for 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’s see how we can create a very simple “dynamic” metamodel (as opposed to static ones, see the documentation for more details):

>>> from pyecore.ecore import EClass, 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: Graph and Node. Both have a name, and there exists a containment relationship between them. This relation is bi-directional, which means that each time a Node object is added to the nodes relationship of a Graph, the owned_by relation of the Node is also updated (it also works the other way around).

Let’s create some instances of our freshly created metamodel:

>>> # We create a Graph
>>> g1 = Graph(name='Graph 1')
>>> g1
<pyecore.ecore.Graph at 0x7f0055554dd8>
>>>
>>> # And two node instances
>>> n1 = Node(name='Node 1')
>>> n2 = Node(name='Node 2')
>>> n1, n2
(<pyecore.ecore.Node at 0x7f0055550588>,
 <pyecore.ecore.Node at 0x7f00555502b0>)
>>>
>>> # We add them to the Graph
>>> g1.nodes.extend([n1, n2])
>>> g1.nodes
EOrderedSet([<pyecore.ecore.Node object at 0x7f0055550588>,
             <pyecore.ecore.Node object at 0x7f00555502b0>])
>>>
>>> # bi-directional references are updated
>>> n1.owned_by
<pyecore.ecore.Graph at 0x7f0055554dd8>

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.

Installation

PyEcore is available on pypi, you can simply install it using pip:

$ pip install pyecore

The installation can also be performed manually (better in a virtualenv):

$ python setup.py install

Documentation

You can read the documentation at this address:

https://pyecore.readthedocs.io/en/latest/

Dependencies

The dependencies required by pyecore are:

  • ordered-set which is used for the ordered and unique collections expressed in the metamodel,

  • lxml which is used for the XMI parsing.

These dependencies are directly installed if you choose to use pip.

Run the Tests

The tests use py.test and ‘coverage’. Everything is driven by Tox, so in order to run the tests simply run:

$ tox

Liberty Regarding the Java EMF Implementation

  • There 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 act as transparent proxies and redirect all calls to the ‘proxied’ object.

  • PyEcore is able to automatically load some model/metamodel dependencies on its own.

State

In 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 resources,

  • xsi:schemaLocation support for XMI resources,

  • URI mapper like,

  • EGeneric support (first simple version),

  • URI converter like

The things that are in the roadmap:

  • new implementation of EOrderedSet, EList, ESet and EBag,

  • new implementation of EStringToStringMapEntry and EFeatureMapEntry,

  • improve documentation,

  • copy/paste (?).

Existing Projects

There aren’t too many projects proposing to handle models and metamodels in Python. The only projects I found are:

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 to have moved since a while.

Contributors

Thanks for making PyEcore better!

Additional Resources

  • This article on the blog of Professor Jordi Cabot gives more information and implementation details about PyEcore.

Metadata

Release files for pyecore 0.15.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyecore 0.15.2
File Size Uploaded
pyecore-0.15.2.tar.gz 58.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyecore 0.15.2
File Interpreter ABI Platform
pyecore-0.15.2-py3-none-any.whl Python 3 none any Details

Total release size: 102.4 kB

Release files / pyecore-0.15.2.tar.gz

Download URL pyecore-0.15.2.tar.gz
Size 58.7 kB
Tags Source
SHA-256 checksum
How to use checksums
bddab6e86d2c8b6e8b824d9dba8bfdbf198d6f12bd020e6a8c3ddb1bc73d6c02
BLAKE2b-256 checksum
How to use checksums
0c677701370654cc2d3a7388ea742a43c416c99b665ef82450083b2e7389bbfb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.11.10

Release files / pyecore-0.15.2-py3-none-any.whl

Download URL pyecore-0.15.2-py3-none-any.whl
Size 43.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
277250e1da2a888dff34a18aa3e8f16afb9bdd5b2484a6e917064c9702aeeb7d
BLAKE2b-256 checksum
How to use checksums
e00955d1cbda2460464c1979e83237da92eee67c2b1741515818e2fb12800b72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.11.10

Release history Release notifications | RSS feed

This release

0.15.2 This release

2 release files

0.15.1

2 release files

0.13.2

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.6

2 release files

0.11.5

2 release files

0.11.3

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.9.0

2 release files

0.8.8

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.13

2 release files

0.7.11

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page