Skip to content

Commit

Permalink
Adding support for renaming traits
Browse files Browse the repository at this point in the history
  • Loading branch information
Debith committed Apr 22, 2015
1 parent a3a39a9 commit bf376cc
Show file tree
Hide file tree
Showing 25 changed files with 286 additions and 165 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
Changelog
=========

0.12.0 (2015-04-22)
-------------------
- New feature: Rename of composed traits
- Cleaning up parts belonging to py2traits

0.11.0 (2015-04-18)
-------------------
- PEP8 fixes
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Installation
Documentation
=============

https://pytraits.readthedocs.org/
https://py3traits.readthedocs.org/

Development
===========
Expand Down Expand Up @@ -57,7 +57,7 @@ Features
- [X] Cherry-picking
- [ ] Symmertric Sum
- [ ] Override
- [ ] Alias
- [X] Alias (rename)
- [ ] Exclusion
- Supported Trait Targets
- [X] Classes
Expand Down
12 changes: 8 additions & 4 deletions examples/class_is_composed_from_cherrypicked_method_in_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ def instance_method(self):
# Here are the proofs that composed methods work as part of new class.
# Also we show that there is no inheritance done for ExampleClass.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass.static_method() == (1, 2, 3), "Class composition fails with classmethod in class!"
assert ExampleClass.class_method() == (24, 25, 26), "Class composition fails with class method in class!"
assert ExampleClass().class_method() == (24, 25, 26), "Class composition fails with class method in instance!"
assert ExampleClass().instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert ExampleClass.static_method() == (1, 2, 3),\
"Class composition fails with classmethod in class!"
assert ExampleClass.class_method() == (24, 25, 26),\
"Class composition fails with class method in class!"
assert ExampleClass().class_method() == (24, 25, 26),\
"Class composition fails with class method in instance!"
assert ExampleClass().instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ def instance_method(self):
# Here are the proofs that composed methods work as part of new class.
# Also we show that there is no inheritance done for ExampleClass.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass.static_method() == (1, 2, 3), "Class composition fails with classmethod in class!"
assert ExampleClass.class_method() == (24, 25, 26), "Class composition fails with classmethod in class!"
assert ExampleClass().class_method() == (24, 25, 26), "Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert ExampleClass.static_method() == (1, 2, 3),\
"Class composition fails with classmethod in class!"
assert ExampleClass.class_method() == (24, 25, 26),\
"Class composition fails with classmethod in class!"
assert ExampleClass().class_method() == (24, 25, 26),\
"Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
from pytraits import extendable


# Let's start by creating a simple class with some values. It contains
# class variables and instance variables. Composed methods will have
# access to all these variables.
@extendable
class ExampleClass(object):
PUBLIC = 24
_HIDDEN = 25
__PRIVATE = 26

def __init__(self):
self.public = 42
self._hidden = 43
self.__private = 44


# Then we create a class which contains different types of methods that will be
# transferred as a part of the class above. Note that ExampleTrait requires target
# object to contain class variables and instance variables, thus it won't work as a
# stand-alone object.
class ExampleTrait(object):
@staticmethod
def static_method():
return 1, 2, 3

@classmethod
def class_method(cls):
return cls.PUBLIC, cls._HIDDEN, cls.__PRIVATE

def instance_method(self):
return self.public, self._hidden, self.__private


# Then, here we do the actual composition, where we cherry-pick each method from
# ExampleTrait and compose them into ExampleClass. While we do that, we also
# specify function names as keyword parameters to change the name of the
# functions.
ExampleClass.add_traits(ExampleTrait.instance_method,
ExampleTrait.class_method,
ExampleTrait.static_method,
instance_method="renamed_instance_method",
class_method="renamed_class_method",
static_method="renamed_static_method")

# Here are the proofs that composed methods work as part of new class.
assert ExampleClass.renamed_static_method() == (1, 2, 3),\
"Class composition fails with classmethod in class!"
assert ExampleClass.renamed_class_method() == (24, 25, 26),\
"Class composition fails with class method in class!"
assert ExampleClass().renamed_class_method() == (24, 25, 26), \
"Class composition fails with class method in instance!"
assert ExampleClass().renamed_instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
20 changes: 9 additions & 11 deletions examples/class_is_composed_from_cherrypicked_property_in_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ def trait_property(self):
return self.public, self._hidden, self.__private


try:
# We don't support this yet. Property does not have name, thus we need to
# support renaming of trait before this can work.
raise NotImplementedError('')
except NotImplementedError:
ExampleClass.add_traits(ExampleTrait)

# Here are the proofs that composed property works as part of new class.
# Also we show that there is no inheritance done for ExampleClass instance.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass().trait_property == (42, 43, 44), "Cherry-picked property not working in new class!"
# Then add the property as a part of our new class simply by referring it.
ExampleClass.add_traits(ExampleTrait.trait_property)


# Here are the proofs that composed property works as part of new class.
# Also we show that there is no inheritance done for ExampleClass instance.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass().trait_property == (42, 43, 44),\
"Cherry-picked property not working in new class!"
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ def trait_property(self):
return self.public, self._hidden, self.__private


# Prepare instance for of trait for composition.
# Create instance out of the trait class. Now we need to notice that we need
# to refer to instance's class to get the property and transfer it to new
# location. Using directly my_trait_instance.trait_property would naturally
# invoke retrieval of the values (which in this case would not even exist and
# and would raise an error).
my_trait_instance = ExampleTrait()
ExampleClass.add_traits(my_trait_instance.__class__.trait_property)

try:
# We don't support this yet. Property does not have name, thus we need to
# support renaming of trait before this can work.
raise NotImplementedError('')
except NotImplementedError:
ExampleClass.add_traits(my_trait_instance)

# Here are the proofs that composed property works as part of new class.
# Also we show that there is no inheritance done for ExampleClass instance.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass().trait_property == (42, 43, 44), "Cherry-picked property not working in new class!"

# Here are the proofs that composed property works as part of new class.
# Also we show that there is no inheritance done for ExampleClass instance.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass().trait_property == (42, 43, 44),\
"Cherry-picked property not working in new class!"
15 changes: 10 additions & 5 deletions examples/class_is_composed_from_other_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ def value(self):
# Here are the proofs that composed methods work as part of new class. Also we show
# that there is no inheritance done for ExampleClass.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass.static_method() == (1, 2, 3), "Class composition fails with static method!"
assert ExampleClass.class_method() == (24, 25, 26), "Class composition fails with classmethod!"
assert ExampleClass().class_method() == (24, 25, 26), "Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert ExampleClass().value == (42, 43, 44), "Class composition fails with property!"
assert ExampleClass.static_method() == (1, 2, 3),\
"Class composition fails with static method!"
assert ExampleClass.class_method() == (24, 25, 26),\
"Class composition fails with classmethod!"
assert ExampleClass().class_method() == (24, 25, 26),\
"Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
assert ExampleClass().value == (42, 43, 44),\
"Class composition fails with property!"
15 changes: 10 additions & 5 deletions examples/class_is_composed_from_other_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ def value(self):
# Here are the proofs that composed methods work as part of new class. Also we show
# that there is no inheritance done for ExampleClass.
assert ExampleClass.__bases__ == (object, ), "Inheritance has occurred!"
assert ExampleClass.static_method() == (1, 2, 3), "Class composition fails with static method!"
assert ExampleClass.class_method() == (24, 25, 26), "Class composition fails with classmethod!"
assert ExampleClass().class_method() == (24, 25, 26), "Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert ExampleClass().value == (42, 43, 44), "Class composition fails with property!"
assert ExampleClass.static_method() == (1, 2, 3),\
"Class composition fails with static method!"
assert ExampleClass.class_method() == (24, 25, 26),\
"Class composition fails with classmethod!"
assert ExampleClass().class_method() == (24, 25, 26),\
"Class composition fails with classmethod in instance!"
assert ExampleClass().instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
assert ExampleClass().value == (42, 43, 44),\
"Class composition fails with property!"
12 changes: 8 additions & 4 deletions examples/function_is_composed_as_a_part_of_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ def new_static_function():


# Here are the proofs that composed functions work as part of new class.
assert ExampleClass.new_static_function() == (1, 2, 3), "Class composition fails with class method in class!"
assert ExampleClass.new_class_function() == (24, 25, 26), "Class composition fails with classmethod in class!"
assert ExampleClass().new_class_function() == (24, 25, 26), "Class composition fails with classmethod in instance!"
assert ExampleClass().new_method() == (42, 43, 44), "Class composition fails with instance method!"
assert ExampleClass.new_static_function() == (1, 2, 3),\
"Class composition fails with class method in class!"
assert ExampleClass.new_class_function() == (24, 25, 26),\
"Class composition fails with classmethod in class!"
assert ExampleClass().new_class_function() == (24, 25, 26),\
"Class composition fails with classmethod in instance!"
assert ExampleClass().new_method() == (42, 43, 44),\
"Class composition fails with instance method!"
18 changes: 12 additions & 6 deletions examples/function_is_composed_as_a_part_of_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,15 @@ def new_static_function():

# Here are the proofs that composed functions work as part of new instance. Also
# we demonstrate that original class is still untouched.
assert example_instance.new_static_function() == (1, 2, 3), "Instance composition fails with static method in instance!"
assert example_instance.new_class_function() == (24, 25, 26), "Instance composition fails with class method in instance!"
assert example_instance.new_method() == (42, 43, 44), "Instance composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"), "Instance composition fails due to class has changed!"
assert example_instance.new_static_function() == (1, 2, 3),\
"Instance composition fails with static method in instance!"
assert example_instance.new_class_function() == (24, 25, 26),\
"Instance composition fails with class method in instance!"
assert example_instance.new_method() == (42, 43, 44),\
"Instance composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"),\
"Instance composition fails due to class has changed!"
18 changes: 12 additions & 6 deletions examples/instance_is_composed_from_cherrypicked_method_in_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ def instance_method(self):


# Here are the proofs that composed methods work as part of new class.
assert example_instance.instance_method() == (42, 43, 44), "Instance composition fails with instance method!"
assert example_instance.class_method() == (24, 25, 26), "Instance composition fails with class method in instance!"
assert example_instance.static_method() == (1, 2, 3), "Instance composition fails with class method in instance!"
assert not hasattr(ExampleClass, "new_static_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"), "Instance composition fails due to class has changed!"
assert example_instance.instance_method() == (42, 43, 44),\
"Instance composition fails with instance method!"
assert example_instance.class_method() == (24, 25, 26),\
"Instance composition fails with class method in instance!"
assert example_instance.static_method() == (1, 2, 3),\
"Instance composition fails with class method in instance!"
assert not hasattr(ExampleClass, "new_static_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"),\
"Instance composition fails due to class has changed!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
from pytraits import extendable


# Let's start by creating a simple class with some values. It contains
# class variables and instance variables. Composed methods will have
# access to all these variables.
@extendable
class ExampleClass(object):
PUBLIC = 24
_HIDDEN = 25
__PRIVATE = 26

def __init__(self):
self.public = 42
self._hidden = 43
self.__private = 44


# Then we create a class which contains different types of methods that will be
# transferred as a part of the class above. Note that ExampleTrait requires target
# object to contain class variables and instance variables, thus it won't work as a
# stand-alone object.
class ExampleTrait(object):
@staticmethod
def static_method():
return 1, 2, 3

@classmethod
def class_method(cls):
return cls.PUBLIC, cls._HIDDEN, cls.__PRIVATE

def instance_method(self):
return self.public, self._hidden, self.__private


# Then, before composition, we create instance out of the class. After that
# we do the actual composition, where we cherry-pick each method from
# ExampleTrait and compose them into ExampleClass. While we do that, we also
# specify function names as keyword parameters to change the name of the
# functions.
example_instance = ExampleClass()
example_instance.add_traits(ExampleTrait.instance_method,
ExampleTrait.class_method,
ExampleTrait.static_method,
instance_method="renamed_instance_method",
class_method="renamed_class_method",
static_method="renamed_static_method")

# Here are the proofs that composed methods work as part of new instance.
assert example_instance.renamed_static_method() == (1, 2, 3),\
"Class composition fails with classmethod in class!"
assert example_instance.renamed_class_method() == (24, 25, 26),\
"Class composition fails with class method in class!"
assert example_instance.renamed_instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
18 changes: 12 additions & 6 deletions examples/instance_is_composed_from_other_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ def instance_method(self):

# Here are the proofs that composed methods work as part of new instance. Also
# we demonstrate that original class is still untouched.
assert example_instance.static_method() == (1, 2, 3), "Class composition fails with static method!"
assert example_instance.class_method() == (24, 25, 26), "Class composition fails with class method!"
assert example_instance.instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"), "Instance composition fails due to class has changed!"
assert example_instance.static_method() == (1, 2, 3),\
"Class composition fails with static method!"
assert example_instance.class_method() == (24, 25, 26),\
"Class composition fails with class method!"
assert example_instance.instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"),\
"Instance composition fails due to class has changed!"
18 changes: 12 additions & 6 deletions examples/instance_is_composed_from_other_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,15 @@ def instance_method(self):

# Here are the proofs that composed methods work as part of new instance. Also
# we demonstrate that original class is still untouched.
assert example_instance.static_method() == (1, 2, 3), "Class composition fails with static method!"
assert example_instance.class_method() == (24, 25, 26), "Class composition fails with class method!"
assert example_instance.instance_method() == (42, 43, 44), "Class composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"), "Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"), "Instance composition fails due to class has changed!"
assert example_instance.static_method() == (1, 2, 3),\
"Class composition fails with static method!"
assert example_instance.class_method() == (24, 25, 26),\
"Class composition fails with class method!"
assert example_instance.instance_method() == (42, 43, 44),\
"Class composition fails with instance method!"
assert not hasattr(ExampleClass, "new_static_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_class_function"),\
"Instance composition fails due to class has changed!"
assert not hasattr(ExampleClass, "new_method"),\
"Instance composition fails due to class has changed!"
5 changes: 3 additions & 2 deletions src/pytraits/sources/clazz.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ class ClassSource(object):
"""
"""
def __init__(self, clazz):
def __init__(self, clazz, resolutions):
self._class = clazz
self.__resolutions = resolutions

def __iter__(self):
for item in inspect.classify_class_attrs(self._class):
Expand All @@ -48,6 +49,6 @@ def __iter__(self):
elif item.kind == "method":
yield RoutineSource(item.object)
elif item.kind == "property":
yield PropertySource(item.object, item.name)
yield PropertySource(item.object, self.__resolutions)
else:
raise TypeError("We do not recognize this item: %s" % item)
Loading

0 comments on commit bf376cc

Please sign in to comment.