Make __attrs_attrs__ a tuple

Having a mutable and rather heavy data structure for something that is supposed
to be immutable doesn't seem to make sense.
This commit is contained in:
Hynek Schlawack 2015-03-23 09:16:43 +01:00
parent 46cbd75411
commit d964845899
4 changed files with 16 additions and 16 deletions

View File

@ -94,7 +94,7 @@ def attr(default=NOTHING, validator=None,
def _transform_attrs(cl, these):
"""
Transforms all `_CountingAttr`s on a class into `Attribute`s and saves the
list in `__attrs_attrs__`.
list as a tuple in `__attrs_attrs__`.
If *these* is passed, use that and don't look for them on the class.
"""
@ -113,11 +113,11 @@ def _transform_attrs(cl, these):
for name, ca
in iteritems(these)]
cl.__attrs_attrs__ = super_cls + [
cl.__attrs_attrs__ = tuple(super_cls + [
Attribute.from_counting_attr(name=attr_name, ca=ca)
for attr_name, ca
in sorted(ca_list, key=lambda e: e[1].counter)
]
])
had_default = False
for a in cl.__attrs_attrs__:
@ -357,7 +357,7 @@ def _add_init(cl):
def fields(cl):
"""
Returns the list of ``attrs`` attributes for a class.
Returns the tuple of ``attrs`` attributes for a class.
:param cl: Class to introspect.
:type cl: type
@ -365,7 +365,7 @@ def fields(cl):
:raise TypeError: If *cl* is not a class.
:raise ValueError: If *cl* is not an ``attrs`` class.
:rtype: :class:`list` of :class:`attr.Attribute`
:rtype: tuple of :class:`attr.Attribute`
"""
if not isinstance(cl, type):
raise TypeError("Passed object must be a class.")

View File

@ -56,7 +56,7 @@ Core
Instances of this class are frequently used for introspection purposes like:
- Class attributes on ``attrs``-decorated classes *after* ``@attr.s`` has been applied.
- :func:`fields` returns a list of them.
- :func:`fields` returns a tuple of them.
- Validators get them passed as the first argument.
.. warning::
@ -119,7 +119,7 @@ Helpers
... x = attr.ib()
... y = attr.ib()
>>> attr.fields(C)
[Attribute(name='x', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True), Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True)]
(Attribute(name='x', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True), Attribute(name='y', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True))
.. autofunction:: attr.has

View File

@ -44,12 +44,12 @@ class TestDarkMagic(object):
"""
`attr.fields` works.
"""
assert [
assert (
Attribute(name="x", default=foo, validator=None,
repr=True, cmp=True, hash=True, init=True),
Attribute(name="y", default=attr.Factory(list), validator=None,
repr=True, cmp=True, hash=True, init=True),
] == attr.fields(C2)
) == attr.fields(C2)
def test_asdict(self):
"""
@ -87,12 +87,12 @@ class TestDarkMagic(object):
`attr.make_class` works.
"""
PC = attr.make_class("PC", ["a", "b"])
assert [
assert (
Attribute(name="a", default=NOTHING, validator=None,
repr=True, cmp=True, hash=True, init=True),
Attribute(name="b", default=NOTHING, validator=None,
repr=True, cmp=True, hash=True, init=True),
] == attr.fields(PC)
) == attr.fields(PC)
def test_subclassing(self):
"""

View File

@ -65,7 +65,7 @@ class TestTransformAttrs(object):
_transform_attrs(C, None)
assert [] == C.__attrs_attrs__
assert () == C.__attrs_attrs__
@pytest.mark.parametrize("attribute", [
"z",
@ -107,9 +107,9 @@ class TestTransformAttrs(object):
y = attr()
_transform_attrs(C, {"x": attr()})
assert [
assert (
simple_attr("x"),
] == C.__attrs_attrs__
) == C.__attrs_attrs__
assert isinstance(C.y, _CountingAttr)
def test_recurse(self):
@ -129,10 +129,10 @@ class TestTransformAttrs(object):
_transform_attrs(D, None)
assert [
assert (
simple_attr("x"),
simple_attr("y"),
] == D.__attrs_attrs__
) == D.__attrs_attrs__
class TestAttributes(object):