Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't hard-code class names in __repr__ implementations #1335

Merged
merged 8 commits into from
Nov 4, 2020
8 changes: 2 additions & 6 deletions traits/adaptation/adaptation_offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,8 @@ class AdaptationOffer(HasTraits):
def __repr__(self):
""" Return a string representation of the object. """

template = "<AdaptationOffer: '{from_}' -> '{to}'>"

from_ = self.from_protocol_name
to = self.to_protocol_name

return template.format(from_=from_, to=to)
return (f"<{self.__class__.__name__}: '{self.from_protocol_name}' "
f"-> '{self.to_protocol_name}'>")

#### 'AdaptationOffer' protocol ###########################################

Expand Down
17 changes: 17 additions & 0 deletions traits/adaptation/tests/test_adaptation_offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,20 @@ def test_lazy_loading(self):
from traits.adaptation.tests.lazy_examples import IFoo

self.assertIs(to_protocol, IFoo)

def test_adaptation_offer_str_representation(self):
""" test string representation of the AdaptationOffer class. """

class Foo:
pass

class Bar:
pass

adaptation_offer = AdaptationOffer(from_protocol=Foo, to_protocol=Bar)
desired_repr = "<AdaptationOffer: '{}' -> '{}'>".format(
adaptation_offer.from_protocol_name,
adaptation_offer.to_protocol_name
)
self.assertEqual(desired_repr, str(adaptation_offer))
self.assertEqual(desired_repr, repr(adaptation_offer))
9 changes: 4 additions & 5 deletions traits/observation/_dict_change_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ def __init__(self, *, object, removed, added):

def __repr__(self):
return (
"{event.__class__.__name__}("
"object={event.object!r}, "
"removed={event.removed!r}, "
"added={event.added!r}"
")".format(event=self)
f"{self.__class__.__name__}("
f"object={self.object!r}, "
f"removed={self.removed!r}, "
f"added={self.added!r})"
)


Expand Down
11 changes: 5 additions & 6 deletions traits/observation/_list_change_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ def __init__(self, *, object, index, removed, added):

def __repr__(self):
return (
"{event.__class__.__name__}("
"object={event.object!r}, "
"index={event.index!r}, "
"removed={event.removed!r}, "
"added={event.added!r}"
")".format(event=self)
f"{self.__class__.__name__}("
f"object={self.object!r}, "
f"index={self.index!r}, "
f"removed={self.removed!r}, "
f"added={self.added!r})"
)


Expand Down
9 changes: 4 additions & 5 deletions traits/observation/_set_change_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ def __init__(self, *, object, removed, added):

def __repr__(self):
return (
"{event.__class__.__name__}("
"object={event.object!r}, "
"removed={event.removed!r}, "
"added={event.added!r}"
")".format(event=self)
f"{self.__class__.__name__}("
f"object={self.object!r}, "
f"removed={self.removed!r}, "
f"added={self.added!r})"
)


Expand Down
24 changes: 23 additions & 1 deletion traits/tests/test_trait_dict_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from unittest import mock

from traits.api import HasTraits
from traits.trait_dict_object import TraitDict, TraitDictObject
from traits.trait_dict_object import TraitDict, TraitDictEvent, TraitDictObject
from traits.trait_errors import TraitError
from traits.trait_types import Dict, Int, Str

Expand Down Expand Up @@ -433,3 +433,25 @@ def test_trait_dict_object_pickle(self):
tdo_unpickled.value_validator("1")
tdo_unpickled.value_validator(1)
tdo_unpickled.value_validator(True)


class TestTraitDictEvent(unittest.TestCase):

def test_trait_dict_event_str_representation(self):
""" Test string representation of the TraitDictEvent class. """
desired_repr = "TraitDictEvent(removed={}, added={}, changed={})"
trait_dict_event = TraitDictEvent()
self.assertEqual(desired_repr, str(trait_dict_event))
self.assertEqual(desired_repr, repr(trait_dict_event))

def test_trait_dict_event_subclass_str_representation(self):
""" Test string representation of a subclass of the TraitDictEvent
class. """

class DifferentName(TraitDictEvent):
pass

desired_repr = "DifferentName(removed={}, added={}, changed={})"
differnt_name_subclass = DifferentName()
self.assertEqual(desired_repr, str(differnt_name_subclass))
self.assertEqual(desired_repr, repr(differnt_name_subclass))
19 changes: 19 additions & 0 deletions traits/tests/test_trait_list_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,25 @@ def test_defaults(self):
self.assertEqual(event.removed, [])
self.assertEqual(event.added, [])

def test_trait_list_event_str_representation(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding a test for a TraitListEvent subclass, to check that it's the subclass name that appears in the repr rather than TraitListEvent. (That's the original motivation for the change, after all.)

""" Test string representation of the TraitListEvent class. """
desired_repr = "TraitListEvent(index=0, removed=[], added=[])"
trait_list_event = TraitListEvent()
self.assertEqual(desired_repr, str(trait_list_event))
self.assertEqual(desired_repr, repr(trait_list_event))

def test_trait_list_event_subclass_str_representation(self):
""" Test string representation of a subclass of the TraitListEvent
class. """

class DifferentName(TraitListEvent):
pass

desired_repr = "DifferentName(index=0, removed=[], added=[])"
different_name_subclass = DifferentName()
self.assertEqual(desired_repr, str(different_name_subclass))
self.assertEqual(desired_repr, repr(different_name_subclass))


class TestTraitList(unittest.TestCase):

Expand Down
24 changes: 23 additions & 1 deletion traits/tests/test_trait_set_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from traits.api import HasTraits, Set, Str
from traits.trait_base import _validate_everything
from traits.trait_errors import TraitError
from traits.trait_set_object import TraitSet
from traits.trait_set_object import TraitSet, TraitSetEvent
from traits.trait_types import _validate_int


Expand Down Expand Up @@ -516,3 +516,25 @@ class Foo(HasTraits):

# then
notifier.assert_not_called()


class TestTraitSetEvent(unittest.TestCase):

def test_trait_set_event_str_representation(self):
""" Test string representation of the TraitSetEvent class. """
desired_repr = "TraitSetEvent(removed=set(), added=set())"
trait_set_event = TraitSetEvent()
self.assertEqual(desired_repr, str(trait_set_event))
self.assertEqual(desired_repr, repr(trait_set_event))

def test_trait_set_event_subclass_str_representation(self):
""" Test string representation of a subclass of the TraitSetEvent
class. """

class DifferentName(TraitSetEvent):
pass

desired_repr = "DifferentName(removed=set(), added=set())"
different_name_subclass = DifferentName()
self.assertEqual(desired_repr, str(different_name_subclass))
self.assertEqual(desired_repr, repr(different_name_subclass))
7 changes: 5 additions & 2 deletions traits/trait_dict_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ def __init__(self, *, removed=None, added=None, changed=None):
self.changed = changed

def __repr__(self):
return "TraitDictEvent(removed={!r}, added={!r}, changed={!r})".format(
self.removed, self.added, self.changed
return (
f"{self.__class__.__name__}("
f"removed={self.removed!r}, "
f"added={self.added!r}, "
f"changed={self.changed!r})"
)


Expand Down
7 changes: 5 additions & 2 deletions traits/trait_list_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ def __init__(self, index=0, removed=None, added=None):
self.added = added

def __repr__(self):
return "TraitListEvent(index={!r}, removed={!r}, added={!r})".format(
self.index, self.removed, self.added
return (
f"{self.__class__.__name__}("
f"index={self.index!r}, "
f"removed={self.removed!r}, "
f"added={self.added!r})"
)


Expand Down
6 changes: 4 additions & 2 deletions traits/trait_set_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ def __init__(self, *, removed=None, added=None):
self.added = added

def __repr__(self):
return "TraitSetEvent(removed={!r}, added={!r})".format(
self.removed, self.added
return (
f"{self.__class__.__name__}("
f"removed={self.removed!r}, "
f"added={self.added!r})"
)


Expand Down
14 changes: 14 additions & 0 deletions traits/util/tests/test_weakidddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,17 @@ def test_weak_keys_values(self):
self.assertEqual(len(wd), 1)
del values[0:2]
self.assertEqual(len(wd), 0)

def test_weak_id_dict_str_representation(self):
""" test string representation of the WeakIDDict class. """
weak_id_dict = WeakIDDict()
desired_repr = "<WeakIDDict at 0x{0:x}>".format(id(weak_id_dict))
self.assertEqual(desired_repr, str(weak_id_dict))
self.assertEqual(desired_repr, repr(weak_id_dict))

def test_weak_id_key_dict_str_representation(self):
""" test string representation of the WeakIDKeyDict class. """
weak_id_key_dict = WeakIDKeyDict()
desired_repr = f"<WeakIDKeyDict at 0x{id(weak_id_key_dict):x}>"
self.assertEqual(desired_repr, str(weak_id_key_dict))
self.assertEqual(desired_repr, repr(weak_id_key_dict))
2 changes: 1 addition & 1 deletion traits/util/weakiddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(self, dict=None):
self.update(dict)

def __repr__(self):
return "<WeakIDDict at 0x{0:x}>".format(id(self))
return f"<{self.__class__.__name__} at 0x{id(self):x}>"

def __delitem__(self, key):
del self.data[id(key)]
Expand Down