:EP: 5
:Title: Version inheritance problem
:Status: Accepted

***********************************
EP005 - Version inheritance problem
***********************************

Description
###########

A **library** that implements a **Protocol** have to deal with multiple versions of this protocol while it evolves.
In order to reduce code duplication, avoid the need of unnecessary code rewriting, and improve the development speed, we might want a development workflow that allows us to import prior versions of specific classes aiming their reuse.

Let's start with a simple example, in which the library contains only one version of the protocol (module **v1**), and it implements two submodules, **Foo** and **Bar**, according the following structure and contents:

*Package file tree*

.. code:: bash

  .
  ├── library
      ├── __init__.py
      ├── v1
          ├── __init__.py
          ├── foo_mod.py
          └── bar_mod.py

**library.v1.foo_mod** (*library/v1/foo_mod.py* file)

.. code:: python

  class Foo():
      foo_version = 1

**library.v1.bar_mod** (*library/v1/bar_mod.py* file)

.. code:: python

  from library.v1.foo_mod import Foo
  class Bar():
      bar_version = 1
      foo = Foo()


Now the *Protocol* has evolved and we are going to implement the new version, in which a new attribute has been added to the *Foo* class.
*Package file tree*

.. code:: bash

  .
  ├── library
  |   ├── __init__.py
  |   ├── v1
  |   |   ├── __init__.py
  |   |   ├── foo_mod.py
  |   |   └── bar_mod.py
  │   └── v2
  │       ├── __init__.py
  │       ├── foo_mod.py
  │       └── bar_mod.py

**library.v1.foo_mod** and **library.v1.bar_mod** remains the same.

This is the new implementation/definition of the **Foo** class:
**library.v2.foo_mod** (*library/v2/foo_mod.py* file)

.. code:: python

  class Foo():
      foo_version = 2
      foo_new_attribute = 'only on v2'

**library.v2.bar_mod** (*library/v2/bar_mod.py* file)

.. code:: python

  from library.v1.bar_mod import Bar

As the definition of the **Bar** on the **Protocol v2** is the same as the definition on **Protocol v1**, it would be nice if we do not need to redefine it. So, we just want to import the prior version to make it available to our library users.

But, doing so, we are using the **Bar** definition of **v1**, which uses the **Foo** definition of **v1**, instead of the new **Foo** definition of **v2**. So, we need to look for a way of making the class aware of the version in which it is being used so it can use the correct classes version of its attributes. All of these in a dynamic way.

Of course this can be achieved by reimplementing **Bar** on **v2**, but if we have dozens of classes, and  the changes between **v1** and **v2** just happened on one or two classes that are used in all other classes, then we would need to reimplement the full code base.

This problem can became more complex if we consider a more complex class structure, with more levels (such as **Bar** have an attribute that is a instance of **Foo** that have an attribute that is a instance of **Baz** and only **Baz** change between two specific versions).

All in all, what we are looking for is a way of make the classes look for its attributes classes (by name), first on the tree structure of its own version, then on the prior versions.
