diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f9b0a2ae50abce5..512e88bebbea87d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,8 @@ Changes: - ``attr.asdict``\ 's ``dict_factory`` arguments is now propagated on recursion. `#45 `_ +- ``attr.asdict`` and ``attr.has`` are significantly faster. + `#48 `_ ---- diff --git a/src/attr/_funcs.py b/src/attr/_funcs.py index 07f4495dff80a95..a1461a35968d037 100644 --- a/src/attr/_funcs.py +++ b/src/attr/_funcs.py @@ -3,7 +3,7 @@ import copy from ._compat import iteritems -from ._make import Attribute, NOTHING, fields +from ._make import Attribute, NOTHING, _fast_attrs_iterate def asdict(inst, recurse=True, filter=None, dict_factory=dict): @@ -30,7 +30,7 @@ def asdict(inst, recurse=True, filter=None, dict_factory=dict): .. versionadded:: 16.0.0 *dict_factory* """ - attrs = fields(inst.__class__) + attrs = _fast_attrs_iterate(inst) rv = dict_factory() for a in attrs: v = getattr(inst, a.name) @@ -71,12 +71,7 @@ def has(cl): :rtype: :class:`bool` """ - try: - fields(cl) - except ValueError: - return False - else: - return True + return getattr(cl, "__attrs_attrs__", None) is not None def assoc(inst, **changes): diff --git a/tests/test_funcs.py b/tests/test_funcs.py index 7dc47dd193ec47f..d7b3193eb56ea56 100644 --- a/tests/test_funcs.py +++ b/tests/test_funcs.py @@ -15,12 +15,12 @@ from attr._funcs import ( asdict, assoc, - fields, has, ) from attr._make import ( attr, attributes, + fields, ) MAPPING_TYPES = (dict, OrderedDict)