-
Notifications
You must be signed in to change notification settings - Fork 35
Review the inheritance architechture #157
Comments
Please @cemsbr, @abaruchi, @beraldoleal and @raphaelmcobe help improve the above content so it is absolutely clear to everyone. |
Thanks for the clarification, I haven't noticed the However, if we find a module that has no changes, I would consider creating the module file in v0x02 that only imports the v0x01 version so the user can import anything from pyof.v0x02 (I haven't found such cases yet and they are expected to happen after all v0x02 changes are implemented). But I'll analyze it carefully before trying not to duplicate code. |
I've been thinking about this inheritance issue, and I still cannot see an easy and clean way of addressing it. It may be addressed by the We have some cases to think about:
One possible solution, to keep our GenericStruct/GenericMessage classes as they are, is to just (deep)copy the Another approach would be to forget about our "orderedDict" and create a new attribute that will be a list with the name of the class attributes in the expected order. These are just some ideas and insights I have had while trying to solve this problem. More ideas are welcome and I think that we need to have a deeper discussion on this matter, since it is a critical issue related to the evolution of the library. Cheers! |
On Wed, Dec 21, 2016 at 3:15 PM, Diego Rabatone Oliveira < ***@***.***> wrote:
I've been thinking about this inheritance issue, and I still cannot see an
easy and clean way of addressing it.
It may be addressed by the MetaStruct metaclass, with some logic
evaluating the *Parent class* (cls.*bases*), looking for the __ordered__
attribute.
We have some cases to think about:
1. Add a new attribute at the end of the new class;
2. Remove an existing attribute from the parent class;
3. Change an existing attribute from the parent class (but keeping it
on the same position);
4. Move an attribute from position A to position B;
5. Add a new attribute before/after another existing attribute;
6. Rename an existing attribute;
One possible solution, to keep our GenericStruct/GenericMessage classes as
they are, is to just (deep)copy the __ordered__ attribute from the parent
class (if it have that attribute) and modify the Child class attributes
using decorators ***@***.***(attr_name, attr_class), @addAttributeAt(attr_name,
attr_class, index), @removeAttribute(name), @moveAttributeAfter(name,
attr_ref_name), @renameAttribute(name, new_name), etc).
Another approach would be to forget about our "orderedDict" and create a
new attribute that will be a list with the name of the class attributes in
the expected order.
I prefer this KISS way. It will be easier to manipulate the attribute order
and for newcomers to understand the code.
… These are just some ideas and insights I have had while trying to solve
this problem. More ideas are welcome and I think that we need to have a
deeper discussion on this matter, since it is a critical issue related to
the evolution of the library.
Cheers!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#157 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADBSbAAE9MrK_K2W-Xb_e6dksXGl42bks5rKV7MgaJpZM4J2A2F>
.
|
Please, check https://github.com/kytos/python-openflow/wiki/Version-Inheritance. I've just added a solution to this problem among other ones. |
This commit alters the metaclass "MetaStruct". Now it will consider the existance of a `__ordered__` attribute of the base classes being used and also will evaluate three new `private` class attributes: - remove_attributes; - rename_attributes; - insert_before. With these three new attributes now we can have control of class attributes modifications while inheriting from another class (based on GenericStruct or GenericMessage). Usage: ```python class MyClassA(GenericStruct): attr_0 = UBInt8() attr_a = UBInt16() attr_z = UBInt8() attr_c = UBInt8() class MyClassB(MyClassA): attr_c = UBInt32() # This will update the attr_c from parent class attr_d = UBInt8() # This will add a new attribute positioned befor attr_a # according to the defined below attr_e = 8 # This will add a new attribute at the end of the list. _remove_attributes = ['attr_z'] _rename_attributes = [('attr_0', 'attr_new_name')] _insert_attributes_before = {'attr_d': 'attr_a'} ``` The resulting dictionary of 'MyClassB' will be: ```python OrderedDict([('attr_new_name', pyof.foundation.basic_types.UBInt8), ('attr_d', pyof.foundation.basic_types.UBInt8), ('attr_a', pyof.foundation.basic_types.UBInt16), ('attr_c', pyof.foundation.basic_types.UBInt32), ('attr_e', int)]) ``` Signed-off-by: Diego Rabatone Oliveira <[email protected]>
This commit alters the metaclass "MetaStruct". Now it will consider the existance of a `__ordered__` attribute of the base classes being used and also will evaluate three new `private` class attributes: - remove_attributes; - rename_attributes; - insert_before. With these three new attributes now we can have control of class attributes modifications while inheriting from another class (based on GenericStruct or GenericMessage). Usage: ```python class MyClassA(GenericStruct): attr_0 = UBInt8() attr_a = UBInt16() attr_z = UBInt8() attr_c = UBInt8() class MyClassB(MyClassA): attr_c = UBInt32() # This will update the attr_c from parent class attr_d = UBInt8() # This will add a new attribute positioned befor attr_a # according to the defined below attr_e = 8 # This will add a new attribute at the end of the list. _remove_attributes = ['attr_z'] _rename_attributes = [('attr_0', 'attr_new_name')] _insert_attributes_before = {'attr_d': 'attr_a'} ``` The resulting dictionary of 'MyClassB' will be: ```python OrderedDict([('attr_new_name', pyof.foundation.basic_types.UBInt8), ('attr_d', pyof.foundation.basic_types.UBInt8), ('attr_a', pyof.foundation.basic_types.UBInt16), ('attr_c', pyof.foundation.basic_types.UBInt32), ('attr_e', int)]) ``` Signed-off-by: Diego Rabatone Oliveira <[email protected]>
This commit alters the metaclass "MetaStruct". Now it will consider the existance of a `__ordered__` attribute of the base classes being used and also will evaluate three new `private` class attributes: - remove_attributes; - rename_attributes; - insert_before. With these three new attributes now we can have control of class attributes modifications while inheriting from another class (based on GenericStruct or GenericMessage). Usage: ```python class MyClassA(GenericStruct): attr_0 = UBInt8() attr_a = UBInt16() attr_z = UBInt8() attr_c = UBInt8() class MyClassB(MyClassA): attr_c = UBInt32() # This will update the attr_c from parent class attr_d = UBInt8() # This will add a new attribute positioned befor attr_a # according to the defined below attr_e = 8 # This will add a new attribute at the end of the list. _remove_attributes = ['attr_z'] _rename_attributes = [('attr_0', 'attr_new_name')] _insert_attributes_before = {'attr_d': 'attr_a'} ``` The resulting dictionary of 'MyClassB' will be: ```python OrderedDict([('attr_new_name', pyof.foundation.basic_types.UBInt8), ('attr_d', pyof.foundation.basic_types.UBInt8), ('attr_a', pyof.foundation.basic_types.UBInt16), ('attr_c', pyof.foundation.basic_types.UBInt32), ('attr_e', int)]) ``` Signed-off-by: Diego Rabatone Oliveira <[email protected]>
We have found a big problem regarding the inheritance between versions.
The first plan was to import the classes from a previous version if they haven't changed on the spec between both versions.
So, for example, on v0x01 we have:
v0x01/symmetric/echo_request.py
As the message EchoRequest has the same structure on the version v0x02, we expected to reuse the class from v0x01, so we would have:
v0x02/symmetric/echo_request.py
One of the problems is related to the value passed to the header. So, for example:
The same behavior would happen for any attribute that have changed between versions and also for any message that the Type has changed (because a new Type was inserted on the enum before its options).
Another problem is that if we try to create subclasses between versions, the subclass will loose the
__ordered__
dict from its superclass, and we need that attribute.All in all, we need to review how the inheritance for evolutive reuse can be done.
For now, we have decided to fully implement the versions without inheritance between versions.
The text was updated successfully, but these errors were encountered: