def test_manual_argument_list_with_custom_repr(self): X = generate_repr(("A", lambda x: str(x**2)))(self.define_class()) self.assertRegex(repr(X()), "<X object\\(A=4\\) at 0x[0-9a-fA-F]+>") X = generate_repr(("A", lambda x: str(x**2)), ("B", None)) X = X(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=4, B='A string'\\) at 0x[0-9a-fA-F]+>") X = generate_repr( ("B", None), ("A", lambda x: str(x**2)), ("ComplexMember", lambda x: ".".join(str(v) for v in x))) X = X(self.define_class()) self.assertRegex( repr(X()), "<X object\\(B='A string', A=4, " "ComplexMember=3\\.2\\.1\\) at 0x[0-9a-fA-F]+>") # Combine normal strings with tuples. X = generate_repr("A", ("B", str), "ComplexMember", ("Q", lambda x: "OVERRIDE")) X = X(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, B=A string, " "ComplexMember=\\[3, 2, 1\\], Q=OVERRIDE\\) at " "0x[0-9a-fA-F]+>")
def test_duplicate_member(self): X = generate_repr("A", "A")(self.define_class()) self.assertRegex(repr(X()), "<X object\\(A=2, A=2\\) at 0x[0-9a-fA-F]+>") X = generate_repr("A", "B", "A")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, B='A string', A=2\\) at " "0x[0-9a-fA-F]+>")
def test_getter_like_functions(self): X = generate_repr("getter_like_function")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(getter_like_function=\\['A', 'B'\\]\\) " "at 0x[0-9a-fA-F]+>") X = generate_repr("defaulted_getter_like_function") X = X(self.define_class()) self.assertRegex( repr(X()), "<X object\\(defaulted_getter_like_function=\\(33, " "34, 35\\)\\) at 0x[0-9a-fA-F]+>")
def test_properties(self): X = generate_repr("getter")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(getter='getter\\(\\)'\\) at " "0x[0-9a-fA-F]+>") X = generate_repr("A", "getter", "defaulted_getter") X = X(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, getter='getter\\(\\)', " "defaulted_getter=6\\) at 0x[0-9a-fA-F]+>")
def test_manual_argument_list(self): X = generate_repr("A")(self.define_class()) self.assertRegex(repr(X()), "<X object\\(A=2\\) at 0x[0-9a-fA-F]+>") X = generate_repr("A", "B")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, B='A string'\\) at 0x[0-9a-fA-F]+>") X = generate_repr("A", "B", "ComplexMember")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, B='A string', ComplexMember=\\[3, " "2, 1\\]\\) at 0x[0-9a-fA-F]+>") X = generate_repr("A", "B", "ComplexMember", "Q")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(A=2, B='A string', " "ComplexMember=\\[3, 2, 1\\]\\, Q=0\\.5\\) at " "0x[0-9a-fA-F]+>") # Switch order. X = generate_repr("ComplexMember", "A")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(ComplexMember=\\[3, 2, 1\\], A=2\\) at " "0x[0-9a-fA-F]+>") X = generate_repr("Q", "ComplexMember", "A", "B")(self.define_class()) self.assertRegex( repr(X()), "<X object\\(Q=0\\.5, ComplexMember=\\[3, 2, 1\\], " "A=2, B='A string'\\) at 0x[0-9a-fA-F]+>")
def subaspect(cls, subcls): """ The sub-aspectclass decorator. See :class:`coalib.bearlib.aspects.Root` for description and usage. """ aspectname = subcls.__name__ sub_qualname = '%s.%s' % (cls.__qualname__, aspectname) docs = getattr(subcls, 'docs', None) aspectdocs = Documentation( subcls.__doc__, **{ attr: getattr(docs, attr, '') for attr in list(signature(Documentation).parameters.keys()) [1:] }) # search for tastes in the sub-aspectclass subtastes = {} for name, member in getmembers(subcls): if isinstance(member, Taste): # tell the taste its own name member.name = name # tell its owner name member.aspect_name = sub_qualname subtastes[name] = member class Sub(subcls, aspectbase, metaclass=aspectclass): __module__ = subcls.__module__ parent = cls docs = aspectdocs _tastes = subtastes members = sorted(Sub.tastes) if members: Sub = generate_repr(*members)(Sub) Sub.__name__ = aspectname Sub.__qualname__ = sub_qualname cls.subaspects[aspectname] = Sub setattr(cls, aspectname, Sub) return Sub
def subaspect(cls, subcls): """ The sub-aspectclass decorator. See :class:`coalib.bearlib.aspects.Root` for description and usage. """ aspectname = subcls.__name__ sub_qualname = '%s.%s' % (cls.__qualname__, aspectname) docs = getattr(subcls, 'Docs', None) aspectdocs = Documentation(subcls.__doc__, **{ attr: getattr(docs, attr, '') for attr in list(signature(Documentation).parameters.keys())[1:]}) # search for tastes in the sub-aspectclass subtastes = {} for name, member in getmembers(subcls): if isinstance(member, Taste): # tell the taste its own name member.name = name # tell its owner name member.aspect_name = sub_qualname subtastes[name] = member class Sub(subcls, aspectbase, metaclass=aspectclass): __module__ = subcls.__module__ parent = cls docs = aspectdocs _tastes = subtastes members = sorted(Sub.tastes) if members: Sub = generate_repr(*members)(Sub) Sub.__name__ = aspectname Sub.__qualname__ = sub_qualname cls.subaspects[aspectname] = Sub setattr(cls, aspectname, Sub) return Sub
def subaspect(cls, subcls): """ The sub-aspectclass decorator. See :class:`coalib.bearlib.aspectclasses.Root` for description and usage. """ aspectname = subcls.__name__ docs = getattr(subcls, 'docs', None) aspectdocs = Documentation(subcls.__doc__, **{ attr: getattr(docs, attr, '') for attr in [ 'example', 'example_language', 'importance_reason', 'fix_suggestions', ]}) # search for tastes int the sub-aspectclass subtastes = {name: member for name, member in getmembers(subcls) if isinstance(member, Taste)} class Sub(subcls, aspectbase, metaclass=aspectclass): __module__ = subcls.__module__ parent = cls docs = aspectdocs _tastes = subtastes members = sorted(Sub.tastes) if members: Sub = generate_repr(*members)(Sub) Sub.__name__ = aspectname Sub.__qualname__ = '%s.%s' % (cls.__qualname__, aspectname) cls.subaspects[aspectname] = Sub setattr(cls, aspectname, Sub) return Sub
def test_auto_repr(self): X = generate_repr()(self.define_class()) x = X() self.assertRegex( repr(x), "<X object\\(A=2, B='A string', ComplexMember=\\[3, " "2, 1\\], defaulted_getter=6, getter='getter\\(\\)', " "one=1, Q=0\\.5\\) at 0x[0-9a-fA-F]+>") # Insert member after instantation. x.Z = 17 self.assertRegex( repr(x), "<X object\\(A=2, B='A string', ComplexMember=\\[3, " "2, 1\\], defaulted_getter=6, getter='getter\\(\\)', " "one=1, Q=0\\.5, Z=17\\) at 0x[0-9a-fA-F]+>") # Test alphabetical order a bit more. x.Ba = 4 x.g_mem = 0 self.assertRegex( repr(x), "<X object\\(A=2, B='A string', Ba=4, " "ComplexMember=\\[3, 2, 1\\], defaulted_getter=6, " "g_mem=0, getter='getter\\(\\)', one=1, Q=0\\.5, " "Z=17\\) at 0x[0-9a-fA-F]+>")
def test_invalid_attribute(self): X = generate_repr("A", "B", "INVALID")(self.define_class()) self.assertRaises(AttributeError, repr, X()) X = generate_repr("A", "polynome")(self.define_class()) self.assertRaises(TypeError, repr, X())