def test_handles_missing_meta_on_class(self): """ If the class hasn't a __module__ or __qualname__, the method hasn't either. """ class C(object): pass b = _ClassBuilder( C, these=None, slots=False, frozen=False, weakref_slot=True, auto_attribs=False, kw_only=False, cache_hash=False, ) b._cls = {} # no __module__; no __qualname__ def fake_meth(self): pass fake_meth.__module__ = "42" fake_meth.__qualname__ = "23" rv = b._add_method_dunders(fake_meth) assert "42" == rv.__module__ == fake_meth.__module__ assert "23" == rv.__qualname__ == fake_meth.__qualname__
def test_repr(self): """ repr of builder itself makes sense. """ class C(object): pass b = _ClassBuilder(C, None, True, True, False) assert "<_ClassBuilder(cls=C)>" == repr(b)
def test_returns_self(self): """ All methods return the builder for chaining. """ class C(object): x = attr.ib() b = _ClassBuilder(C, None, True, True, False) cls = b.add_cmp().add_hash().add_init().add_repr("ns").add_str() \ .build_class() assert "ns.C(x=1)" == repr(cls(1))
def test_handles_missing_meta_on_class(self): """ If the class hasn't a __module__ or __qualname__, the method hasn't either. """ class C(object): pass b = _ClassBuilder( C, these=None, slots=False, frozen=False, auto_attribs=False, ) b._cls = {} # no __module__; no __qualname__ def fake_meth(self): pass fake_meth.__module__ = "42" fake_meth.__qualname__ = "23" rv = b._add_method_dunders(fake_meth) assert "42" == rv.__module__ == fake_meth.__module__ assert "23" == rv.__qualname__ == fake_meth.__qualname__
def wrap(cls): if getattr(cls, "__class__", None) is None: raise TypeError("attrs only works with new-style classes.") is_exc = auto_exc is True and issubclass(cls, BaseException) builder = _ClassBuilder( cls, these, slots, frozen, weakref_slot, auto_attribs, kw_only, cache_hash, is_exc, ) _hook_builder_before_doing_anything(builder, disallow_empties=disallow_empties) if repr is True: builder.add_repr(repr_ns) if str is True: builder.add_str() if cmp is True and not is_exc: builder.add_cmp() if hash is not True and hash is not False and hash is not None: # Can't use `hash in` because 1 == True for example. raise TypeError("Invalid value for hash. Must be True, False, or None.") elif hash is False or (hash is None and cmp is False): if cache_hash: raise TypeError( "Invalid value for cache_hash. To use hash caching," " hashing must be either explicitly or implicitly " "enabled." ) elif ( hash is True or (hash is None and cmp is True and frozen is True) and is_exc is False ): builder.add_hash() else: if cache_hash: raise TypeError( "Invalid value for cache_hash. To use hash caching," " hashing must be either explicitly or implicitly " "enabled." ) builder.make_unhashable() if init is True: builder.add_init() else: if cache_hash: raise TypeError( "Invalid value for cache_hash. To use hash caching," " init must be True." ) return builder.build_class()