Skip to content

Commit 594df3e

Browse files
committed
Kill by_name and use new APIs in assoc
1 parent 4d8d0be commit 594df3e

File tree

8 files changed

+18
-102
lines changed

8 files changed

+18
-102
lines changed

CHANGELOG.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ Changes:
1919
`#81 <https://github.com/hynek/attrs/issues/81>`_
2020
- ``attr.assoc`` now works with ``__slots__`` classes.
2121
`#84 <https://github.com/hynek/attrs/issues/84>`_
22-
- Add ``attr.by_name`` for accessing ``Attribute`` instances of class objects.
23-
``attr.by_name(C, "x")`` is therefore equivalent to the deprecated ``C.x``.
2422

2523

2624
----

docs/api.rst

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,19 +184,6 @@ See :ref:`asdict` for examples.
184184
>>> i1 == i2
185185
False
186186

187-
.. autofunction:: by_name
188-
189-
For example:
190-
191-
.. doctest::
192-
193-
>>> @attr.s
194-
... class C(object):
195-
... x = attr.ib()
196-
... y = attr.ib()
197-
>>> attr.by_name(C, "x")
198-
Attribute(name='x', default=NOTHING, validator=None, repr=True, cmp=True, hash=True, init=True, convert=None)
199-
200187
.. autofunction:: validate
201188

202189
For example:

docs/examples.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,15 @@ For the common case where you want to :func:`include <attr.filters.include>` or
199199
... password = attr.ib()
200200
... id = attr.ib()
201201
>>> attr.asdict(User("jane", "s33kred", 42),
202-
... filter=attr.filters.exclude(attr.by_name(User, "password"), int))
202+
... filter=attr.filters.exclude(attr.fields(User).password, int))
203203
{'login': 'jane'}
204204
>>> @attr.s
205205
... class C(object):
206206
... x = attr.ib()
207207
... y = attr.ib()
208208
... z = attr.ib()
209209
>>> attr.asdict(C("foo", "2", 3),
210-
... filter=attr.filters.include(int, attr.by_name(C, "x")))
210+
... filter=attr.filters.include(int, attr.fields(C).x)))
211211
{'z': 3, 'x': 'foo'}
212212

213213

src/attr/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from ._funcs import (
44
asdict,
55
assoc,
6-
by_name,
76
has,
87
)
98
from ._make import (
@@ -52,7 +51,6 @@
5251
"attrib",
5352
"attributes",
5453
"attrs",
55-
"by_name",
5654
"exceptions",
5755
"fields",
5856
"filters",

src/attr/_compat.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22

33
import sys
44

5-
__all__ = [
6-
"PY2",
7-
"isclass", "TYPE", "exec_", "iteritems", "iterkeys", "lru_cache",
8-
]
9-
105

116
PY2 = sys.version_info[0] == 2
127

@@ -27,14 +22,7 @@ def iteritems(d):
2722

2823
def iterkeys(d):
2924
return d.iterkeys()
30-
31-
def lru_cache(maxsize=128, typed=False):
32-
def wrapper(func):
33-
return func # lol upgrade
34-
return wrapper
3525
else:
36-
from functools import lru_cache
37-
3826
def isclass(klass):
3927
return isinstance(klass, type)
4028

src/attr/_funcs.py

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import copy
44

5-
from ._compat import iteritems, lru_cache
5+
from ._compat import iteritems
66
from ._make import NOTHING, fields, _obj_setattr
77
from .exceptions import AttrsAttributeNotFoundError
88

@@ -79,14 +79,6 @@ def has(cls):
7979
return getattr(cls, "__attrs_attrs__", None) is not None
8080

8181

82-
@lru_cache()
83-
def _make_attr_map(cls):
84-
"""
85-
Create a dictionary of attr_name: attribute pairs for *cls*.
86-
"""
87-
return {a.name: a for a in fields(cls)}
88-
89-
9082
def assoc(inst, **changes):
9183
"""
9284
Copy *inst* and apply *changes*.
@@ -102,32 +94,13 @@ def assoc(inst, **changes):
10294
class.
10395
"""
10496
new = copy.copy(inst)
105-
attr_map = _make_attr_map(new.__class__)
97+
attrs = fields(inst.__class__)
10698
for k, v in iteritems(changes):
107-
a = attr_map.get(k, NOTHING)
99+
a = getattr(attrs, k, NOTHING)
108100
if a is NOTHING:
109101
raise AttrsAttributeNotFoundError(
110102
"{k} is not an attrs attribute on {cl}."
111103
.format(k=k, cl=new.__class__)
112104
)
113105
_obj_setattr(new, k, v)
114106
return new
115-
116-
117-
def by_name(cls, attr_name):
118-
"""
119-
Return the :class:`attr.Attribute` of *attr_name* from *cls*.
120-
121-
:raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't
122-
be found on *cls*.
123-
:raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs``
124-
class.
125-
126-
.. versionadded:: 16.2.0
127-
"""
128-
try:
129-
return _make_attr_map(cls)[attr_name]
130-
except KeyError:
131-
raise AttrsAttributeNotFoundError(
132-
"%r has no attrs attribute %r" % (cls, attr_name)
133-
)

tests/test_filters.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66

77
import pytest
88

9-
from attr._make import attributes, attr
9+
from attr._make import attributes, attr, fields
1010
from attr.filters import _split_what, include, exclude
11-
from attr._funcs import by_name
1211

1312

1413
@attributes
@@ -38,28 +37,28 @@ class TestInclude(object):
3837
@pytest.mark.parametrize("incl,value", [
3938
((int,), 42),
4039
((str,), "hello"),
41-
((str, by_name(C, "a")), 42),
42-
((str, by_name(C, "b")), "hello"),
40+
((str, fields(C).a), 42),
41+
((str, fields(C).b), "hello"),
4342
])
4443
def test_allow(self, incl, value):
4544
"""
4645
Return True if a class or attribute is whitelisted.
4746
"""
4847
i = include(*incl)
49-
assert i(by_name(C, "a"), value) is True
48+
assert i(fields(C).a, value) is True
5049

5150
@pytest.mark.parametrize("incl,value", [
5251
((str,), 42),
5352
((int,), "hello"),
54-
((str, by_name(C, "b")), 42),
55-
((int, by_name(C, "b")), "hello"),
53+
((str, fields(C).b), 42),
54+
((int, fields(C).b), "hello"),
5655
])
5756
def test_drop_class(self, incl, value):
5857
"""
5958
Return False on non-whitelisted classes and attributes.
6059
"""
6160
i = include(*incl)
62-
assert i(by_name(C, "a"), value) is False
61+
assert i(fields(C).a, value) is False
6362

6463

6564
class TestExclude(object):
@@ -69,25 +68,25 @@ class TestExclude(object):
6968
@pytest.mark.parametrize("excl,value", [
7069
((str,), 42),
7170
((int,), "hello"),
72-
((str, by_name(C, "b")), 42),
73-
((int, by_name(C, "b")), "hello"),
71+
((str, fields(C).b), 42),
72+
((int, fields(C).b), "hello"),
7473
])
7574
def test_allow(self, excl, value):
7675
"""
7776
Return True if class or attribute is not blacklisted.
7877
"""
7978
e = exclude(*excl)
80-
assert e(by_name(C, "a"), value) is True
79+
assert e(fields(C).a, value) is True
8180

8281
@pytest.mark.parametrize("excl,value", [
8382
((int,), 42),
8483
((str,), "hello"),
85-
((str, by_name(C, "a")), 42),
86-
((str, by_name(C, "b")), "hello"),
84+
((str, fields(C).a), 42),
85+
((str, fields(C).b), "hello"),
8786
])
8887
def test_drop_class(self, excl, value):
8988
"""
9089
Return True on non-blacklisted classes and attributes.
9190
"""
9291
e = exclude(*excl)
93-
assert e(by_name(C, "a"), value) is False
92+
assert e(fields(C).a, value) is False

tests/test_funcs.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from attr._funcs import (
1616
asdict,
1717
assoc,
18-
by_name,
1918
has,
2019
)
2120
from attr._make import (
@@ -248,29 +247,3 @@ class C(object):
248247
y = attr()
249248

250249
assert C(3, 2) == assoc(C(1, 2), x=3)
251-
252-
253-
class TestByName(object):
254-
@given(simple_classes())
255-
def test_inexisting_attribute(self, C):
256-
"""
257-
Getting an inexisting attribute raises an InvalidAttributeError.
258-
"""
259-
# No generated class will have a four letter attribute.
260-
with pytest.raises(AttrsAttributeNotFoundError) as e:
261-
by_name(C, "aaaa")
262-
263-
assert (
264-
"<class 'attr._make.HypClass'> has no attrs attribute 'aaaa'"
265-
) == e.value.args[0]
266-
267-
@given(simple_classes())
268-
def test_existing_attribute(self, C):
269-
"""
270-
Works for existing attributes for all kinds of attrs classes.
271-
"""
272-
for attr_name in (a.name for a in C.__attrs_attrs__):
273-
attr = by_name(C, attr_name)
274-
275-
assert attr_name == attr.name
276-
assert attr in C.__attrs_attrs__

0 commit comments

Comments
 (0)