Add _repr_pretty_ for IPython
This commit is contained in:
parent
cdf39c3464
commit
e5dcb746ad
|
@ -37,6 +37,15 @@ class Namespace(MutableMapping):
|
|||
raise KeyError(repr(name))
|
||||
return namespacify(attr)
|
||||
|
||||
def __setitem__(self, name: Any, value: Any) -> None:
|
||||
setattr(self, name, value)
|
||||
|
||||
def __delitem__(self, name: Any) -> None:
|
||||
try:
|
||||
delattr(self, name)
|
||||
except AttributeError:
|
||||
raise KeyError(repr(name))
|
||||
|
||||
def __iter__(self) -> Iterator:
|
||||
return iter(self.__dict__)
|
||||
|
||||
|
@ -49,14 +58,14 @@ class Namespace(MutableMapping):
|
|||
def __str__(self) -> str:
|
||||
return str(self.__dict__)
|
||||
|
||||
def _repr_pretty_(self, p: Any, cycle: bool) -> None:
|
||||
# IPython's pretty printing
|
||||
if cycle:
|
||||
p.text('{}(...)'.format(self.__class__.__name__))
|
||||
else:
|
||||
p.text('{}('.format(self.__class__.__name__))
|
||||
p.pretty(self.__dict__)
|
||||
p.text(')')
|
||||
|
||||
def copy(self) -> 'Namespace':
|
||||
return self.__class__(self.__dict__)
|
||||
|
||||
def __setitem__(self, name: Any, value: Any) -> None:
|
||||
setattr(self, name, value)
|
||||
|
||||
def __delitem__(self, name: Any) -> None:
|
||||
try:
|
||||
delattr(self, name)
|
||||
except AttributeError:
|
||||
raise KeyError(repr(name))
|
||||
|
|
|
@ -34,6 +34,15 @@ class ClassRegistry(Dict[str, Callable]):
|
|||
self.check(key, value)
|
||||
super().__setitem__(key, value)
|
||||
|
||||
def _repr_pretty_(self, p: Any, cycle: bool) -> None:
|
||||
# IPython's pretty printing
|
||||
if cycle:
|
||||
p.text('{}(...)'.format(self.__class__.__name__))
|
||||
else:
|
||||
p.text('{}('.format(self.__class__.__name__))
|
||||
p.pretty(dict(self))
|
||||
p.text(')')
|
||||
|
||||
@property
|
||||
def metaclass(self) -> type:
|
||||
class RegistryMetaclass(type):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from types import MappingProxyType
|
||||
from typing import List, Set, Iterable, Iterator, Any
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call
|
||||
from objtools.collections import namespacify, Namespace
|
||||
|
||||
|
||||
|
@ -69,29 +70,6 @@ class TestNamespace(TestCase):
|
|||
with self.assertRaises(AttributeError):
|
||||
ns.b
|
||||
|
||||
def test_iter(self) -> None:
|
||||
ns: Namespace = Namespace(a=1, b=2)
|
||||
iterator: Iterator = iter(ns)
|
||||
self.assertEqual(next(iterator), 'a')
|
||||
self.assertEqual(next(iterator), 'b')
|
||||
|
||||
def test_len(self) -> None:
|
||||
self.assertEqual(len(Namespace(a=1, b=2)), 2)
|
||||
self.assertEqual(len(Namespace()), 0)
|
||||
|
||||
def test_repr(self) -> None:
|
||||
self.assertEqual(repr(Namespace()), 'Namespace({})')
|
||||
self.assertEqual(repr(Namespace(a=1)), "Namespace({'a': 1})")
|
||||
|
||||
def test_str(self) -> None:
|
||||
self.assertEqual(str(Namespace()), '{}')
|
||||
self.assertEqual(str(Namespace(a=1)), "{'a': 1}")
|
||||
|
||||
def test_copy(self) -> None:
|
||||
ns: Namespace = Namespace(a=1, b=2)
|
||||
self.assertEqual(ns.copy(), ns)
|
||||
self.assertIsNot(ns.copy(), ns)
|
||||
|
||||
def test_set(self) -> None:
|
||||
ns: Any = Namespace(a=4)
|
||||
ns.a = 1
|
||||
|
@ -111,3 +89,44 @@ class TestNamespace(TestCase):
|
|||
del ns.c
|
||||
with self.assertRaises(KeyError):
|
||||
del ns['c']
|
||||
|
||||
def test_iter(self) -> None:
|
||||
ns: Namespace = Namespace(a=1, b=2)
|
||||
iterator: Iterator = iter(ns)
|
||||
self.assertEqual(next(iterator), 'a')
|
||||
self.assertEqual(next(iterator), 'b')
|
||||
|
||||
def test_len(self) -> None:
|
||||
self.assertEqual(len(Namespace(a=1, b=2)), 2)
|
||||
self.assertEqual(len(Namespace()), 0)
|
||||
|
||||
def test_repr(self) -> None:
|
||||
self.assertEqual(repr(Namespace()), 'Namespace({})')
|
||||
self.assertEqual(repr(Namespace(a=1)), "Namespace({'a': 1})")
|
||||
|
||||
def test_str(self) -> None:
|
||||
self.assertEqual(str(Namespace()), '{}')
|
||||
self.assertEqual(str(Namespace(a=1)), "{'a': 1}")
|
||||
|
||||
def test_repr_pretty(self) -> None:
|
||||
p = MagicMock(spec_set=['text', 'pretty'])
|
||||
Namespace(a=1)._repr_pretty_(p, cycle=False)
|
||||
self.assertEqual(p.text.call_count, 2)
|
||||
self.assertEqual(p.pretty.call_count, 1)
|
||||
self.assertListEqual(p.text.call_args_list, [
|
||||
call('Namespace('),
|
||||
call(')'),
|
||||
])
|
||||
self.assertEqual(p.pretty.call_args, call({'a': 1}))
|
||||
|
||||
def test_repr_pretty_cycle(self) -> None:
|
||||
p = MagicMock(spec_set=['text', 'pretty'])
|
||||
Namespace(a=1)._repr_pretty_(p, cycle=True)
|
||||
self.assertEqual(p.text.call_count, 1)
|
||||
self.assertFalse(p.pretty.called)
|
||||
self.assertEqual(p.text.call_args, call('Namespace(...)'))
|
||||
|
||||
def test_copy(self) -> None:
|
||||
ns: Namespace = Namespace(a=1, b=2)
|
||||
self.assertEqual(ns.copy(), ns)
|
||||
self.assertIsNot(ns.copy(), ns)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from unittest import TestCase
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import patch, call, MagicMock
|
||||
from objtools.registry import ClassRegistry
|
||||
|
||||
|
||||
|
@ -61,3 +61,21 @@ class TestRegistry(TestCase):
|
|||
pass
|
||||
|
||||
self.assertDictEqual(registry, {'foo': Thing})
|
||||
|
||||
def test_repr_pretty(self) -> None:
|
||||
p = MagicMock(spec_set=['text', 'pretty'])
|
||||
ClassRegistry(a=object)._repr_pretty_(p, cycle=False)
|
||||
self.assertEqual(p.text.call_count, 2)
|
||||
self.assertEqual(p.pretty.call_count, 1)
|
||||
self.assertListEqual(p.text.call_args_list, [
|
||||
call('ClassRegistry('),
|
||||
call(')'),
|
||||
])
|
||||
self.assertEqual(p.pretty.call_args, call({'a': object}))
|
||||
|
||||
def test_repr_pretty_cycle(self) -> None:
|
||||
p = MagicMock(spec_set=['text', 'pretty'])
|
||||
ClassRegistry(a=object)._repr_pretty_(p, cycle=True)
|
||||
self.assertEqual(p.text.call_count, 1)
|
||||
self.assertFalse(p.pretty.called)
|
||||
self.assertEqual(p.text.call_args, call('ClassRegistry(...)'))
|
||||
|
|
Loading…
Reference in New Issue