Skip to content

Commit c57c51d

Browse files
committed
Add literal string support to includer and exclude filters
1 parent 9cf2ed5 commit c57c51d

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
.pytest_cache
1111
.tox
1212
.vscode
13+
.venv*
1314
build
1415
dist
1516
docs/_build

src/attr/filters.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def _split_what(what):
1313
"""
1414
return (
1515
frozenset(cls for cls in what if isinstance(cls, type)),
16+
frozenset(cls for cls in what if isinstance(cls, str)),
1617
frozenset(cls for cls in what if isinstance(cls, Attribute)),
1718
)
1819

@@ -22,14 +23,19 @@ def include(*what):
2223
Include *what*.
2324
2425
:param what: What to include.
25-
:type what: `list` of `type` or `attrs.Attribute`\\ s
26+
:type what: `list` of classes `type`, field names `str` or
27+
`attrs.Attribute`\\ s
2628
2729
:rtype: `callable`
2830
"""
29-
cls, attrs = _split_what(what)
31+
cls, names, attrs = _split_what(what)
3032

3133
def include_(attribute, value):
32-
return value.__class__ in cls or attribute in attrs
34+
return (
35+
value.__class__ in cls
36+
or attribute.name in names
37+
or attribute in attrs
38+
)
3339

3440
return include_
3541

@@ -39,13 +45,18 @@ def exclude(*what):
3945
Exclude *what*.
4046
4147
:param what: What to exclude.
42-
:type what: `list` of classes or `attrs.Attribute`\\ s.
48+
:type what: `list` of classes `type`, field names `str` or
49+
`attrs.Attribute`\\ s.
4350
4451
:rtype: `callable`
4552
"""
46-
cls, attrs = _split_what(what)
53+
cls, names, attrs = _split_what(what)
4754

4855
def exclude_(attribute, value):
49-
return value.__class__ not in cls and attribute not in attrs
56+
return not (
57+
value.__class__ in cls
58+
or attribute.name in names
59+
or attribute in attrs
60+
)
5061

5162
return exclude_

src/attr/filters.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ from typing import Any, Union
22

33
from . import Attribute, _FilterType
44

5-
def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ...
6-
def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ...
5+
def include(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ...
6+
def exclude(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ...

tests/test_filters.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ def test_splits(self):
3030
"""
3131
assert (
3232
frozenset((int, str)),
33+
frozenset(("abcd", "123")),
3334
frozenset((fields(C).a,)),
34-
) == _split_what((str, fields(C).a, int))
35+
) == _split_what((str, "123", fields(C).a, int, "abcd"))
3536

3637

3738
class TestInclude:
@@ -46,6 +47,10 @@ class TestInclude:
4647
((str,), "hello"),
4748
((str, fields(C).a), 42),
4849
((str, fields(C).b), "hello"),
50+
(("a",), 42),
51+
(("a",), "hello"),
52+
(("a", str), 42),
53+
(("a", fields(C).b), "hello"),
4954
],
5055
)
5156
def test_allow(self, incl, value):
@@ -62,6 +67,10 @@ def test_allow(self, incl, value):
6267
((int,), "hello"),
6368
((str, fields(C).b), 42),
6469
((int, fields(C).b), "hello"),
70+
(("b",), 42),
71+
(("b",), "hello"),
72+
(("b", str), 42),
73+
(("b", fields(C).b), "hello"),
6574
],
6675
)
6776
def test_drop_class(self, incl, value):
@@ -84,6 +93,10 @@ class TestExclude:
8493
((int,), "hello"),
8594
((str, fields(C).b), 42),
8695
((int, fields(C).b), "hello"),
96+
(("b",), 42),
97+
(("b",), "hello"),
98+
(("b", str), 42),
99+
(("b", fields(C).b), "hello"),
87100
],
88101
)
89102
def test_allow(self, excl, value):
@@ -100,6 +113,10 @@ def test_allow(self, excl, value):
100113
((str,), "hello"),
101114
((str, fields(C).a), 42),
102115
((str, fields(C).b), "hello"),
116+
(("a",), 42),
117+
(("a",), "hello"),
118+
(("a", str), 42),
119+
(("a", fields(C).b), "hello"),
103120
],
104121
)
105122
def test_drop_class(self, excl, value):

0 commit comments

Comments
 (0)