Skip to content

Commit 29d5ea9

Browse files
committed
Refactor enums into class since they're only used by that class
1 parent 18c3644 commit 29d5ea9

File tree

5 files changed

+76
-67
lines changed

5 files changed

+76
-67
lines changed

docs/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ Helpers
200200
... class C:
201201
... pass
202202
>>> attrs.inspect(C)
203-
ClassProps(is_exception=False, is_slotted=True, has_weakref_slot=True, is_frozen=False, kw_only=KeywordOnly.NO, collect_by_mro=False, init=True, repr=True, eq=True, order=True, hash=Hashability.UNHASHABLE, match_args=True, str=False, getstate_setstate=False, on_setattr=None, field_transformer=None)
203+
ClassProps(is_exception=False, is_slotted=True, has_weakref_slot=True, is_frozen=False, kw_only=ClassProps.KeywordOnly.NO, collect_by_mro=False, init=True, repr=True, eq=True, order=True, hash=ClassProps.Hashability.UNHASHABLE, match_args=True, str=False, getstate_setstate=False, on_setattr=None, field_transformer=None)
204204

205205
.. autoclass:: attrs.ClassProps
206206

src/attr/_make.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from functools import cached_property
1919
from typing import Any, NamedTuple, TypeVar
2020

21-
from attr._props import ClassProps, Hashability, KeywordOnly
21+
from attr._props import ClassProps
2222

2323
# We need to import _compat itself in addition to the _compat members to avoid
2424
# having the thread-local in the globals here.
@@ -440,7 +440,12 @@ def _transform_attrs(
440440

441441
fca = Attribute.from_counting_attr
442442
own_attrs = [
443-
fca(attr_name, ca, kw_only is not KeywordOnly.NO, anns.get(attr_name))
443+
fca(
444+
attr_name,
445+
ca,
446+
kw_only is not ClassProps.KeywordOnly.NO,
447+
anns.get(attr_name),
448+
)
444449
for attr_name, ca in ca_list
445450
]
446451

@@ -453,7 +458,7 @@ def _transform_attrs(
453458
cls, {a.name for a in own_attrs}
454459
)
455460

456-
if kw_only is KeywordOnly.FORCE:
461+
if kw_only is ClassProps.KeywordOnly.FORCE:
457462
own_attrs = [a.evolve(kw_only=True) for a in own_attrs]
458463
base_attrs = [a.evolve(kw_only=True) for a in base_attrs]
459464

@@ -685,7 +690,7 @@ def __init__(
685690
self._slots = props.is_slotted
686691
self._frozen = props.is_frozen
687692
self._weakref_slot = props.has_weakref_slot
688-
self._cache_hash = props.hash is Hashability.HASHABLE_CACHED
693+
self._cache_hash = props.hash is ClassProps.Hashability.HASHABLE_CACHED
689694
self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False))
690695
self._pre_init_has_args = False
691696
if self._has_pre_init:
@@ -1443,36 +1448,40 @@ def wrap(cls):
14431448
)
14441449

14451450
if is_exc:
1446-
hashability = Hashability.LEAVE_ALONE
1451+
hashability = ClassProps.Hashability.LEAVE_ALONE
14471452
elif hash is True:
14481453
hashability = (
1449-
Hashability.HASHABLE_CACHED
1454+
ClassProps.Hashability.HASHABLE_CACHED
14501455
if cache_hash
1451-
else Hashability.HASHABLE
1456+
else ClassProps.Hashability.HASHABLE
14521457
)
14531458
elif hash is False:
1454-
hashability = Hashability.LEAVE_ALONE
1459+
hashability = ClassProps.Hashability.LEAVE_ALONE
14551460
elif hash is None:
14561461
if auto_detect is True and _has_own_attribute(cls, "__hash__"):
1457-
hashability = Hashability.LEAVE_ALONE
1462+
hashability = ClassProps.Hashability.LEAVE_ALONE
14581463
elif eq is True and is_frozen is True:
14591464
hashability = (
1460-
Hashability.HASHABLE_CACHED
1465+
ClassProps.Hashability.HASHABLE_CACHED
14611466
if cache_hash
1462-
else Hashability.HASHABLE
1467+
else ClassProps.Hashability.HASHABLE
14631468
)
14641469
elif eq is False:
1465-
hashability = Hashability.LEAVE_ALONE
1470+
hashability = ClassProps.Hashability.LEAVE_ALONE
14661471
else:
1467-
hashability = Hashability.UNHASHABLE
1472+
hashability = ClassProps.Hashability.UNHASHABLE
14681473
else:
14691474
msg = "Invalid value for hash. Must be True, False, or None."
14701475
raise TypeError(msg)
14711476

14721477
if kw_only:
1473-
kwo = KeywordOnly.FORCE if force_kw_only else KeywordOnly.YES
1478+
kwo = (
1479+
ClassProps.KeywordOnly.FORCE
1480+
if force_kw_only
1481+
else ClassProps.KeywordOnly.YES
1482+
)
14741483
else:
1475-
kwo = KeywordOnly.NO
1484+
kwo = ClassProps.KeywordOnly.NO
14761485

14771486
props = ClassProps(
14781487
is_exception=is_exc,
@@ -1537,7 +1546,7 @@ def wrap(cls):
15371546

15381547
if props.is_hashable:
15391548
builder.add_hash()
1540-
elif props.hash is Hashability.UNHASHABLE:
1549+
elif props.hash is ClassProps.Hashability.UNHASHABLE:
15411550
builder.make_unhashable()
15421551

15431552
if props.init:

src/attr/_props.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,6 @@
1414
from ._make import Attribute
1515

1616

17-
class Hashability(enum.Enum):
18-
"""
19-
The hashability of a class.
20-
"""
21-
22-
HASHABLE = "hashable" # write a __hash__
23-
HASHABLE_CACHED = "hashable_cache" # write a __hash__ and cache the hash
24-
UNHASHABLE = "unhashable" # set __hash__ to None
25-
LEAVE_ALONE = "leave_alone" # don't touch __hash__
26-
27-
28-
class KeywordOnly(enum.Enum):
29-
"""
30-
How attributes should be treated regarding keyword-only parameters.
31-
"""
32-
33-
NO = "no" # attributes are not keyword-only
34-
YES = "yes" # attributes in current class without kw_only=False are keyword-only
35-
FORCE = "force" # all attributes are keyword-only
36-
37-
3817
class ClassProps(NamedTuple):
3918
"""
4019
Effective class properties as derived from parameters to attr.s() or
@@ -43,17 +22,38 @@ class ClassProps(NamedTuple):
4322
.. versionadded:: 25.4.0
4423
"""
4524

25+
class Hashability(enum.Enum):
26+
"""
27+
The hashability of a class.
28+
"""
29+
30+
HASHABLE = "hashable" # write a __hash__
31+
HASHABLE_CACHED = (
32+
"hashable_cache" # write a __hash__ and cache the hash
33+
)
34+
UNHASHABLE = "unhashable" # set __hash__ to None
35+
LEAVE_ALONE = "leave_alone" # don't touch __hash__
36+
37+
class KeywordOnly(enum.Enum):
38+
"""
39+
How attributes should be treated regarding keyword-only parameters.
40+
"""
41+
42+
NO = "no" # attributes are not keyword-only
43+
YES = "yes" # attributes in current class without kw_only=False are keyword-only
44+
FORCE = "force" # all attributes are keyword-only
45+
4646
is_exception: bool
4747
is_slotted: bool
4848
has_weakref_slot: bool
4949
is_frozen: bool
50-
kw_only: KeywordOnly
50+
kw_only: ClassProps.KeywordOnly
5151
collect_by_mro: bool
5252
init: bool
5353
repr: bool
5454
eq: bool
5555
order: bool
56-
hash: Hashability
56+
hash: ClassProps.Hashability
5757
match_args: bool
5858
str: bool
5959
getstate_setstate: bool
@@ -63,8 +63,8 @@ class ClassProps(NamedTuple):
6363
@property
6464
def is_hashable(self):
6565
return (
66-
self.hash is Hashability.HASHABLE
67-
or self.hash is Hashability.HASHABLE_CACHED
66+
self.hash is ClassProps.Hashability.HASHABLE
67+
or self.hash is ClassProps.Hashability.HASHABLE_CACHED
6868
)
6969

7070

tests/test_make.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
Attribute,
3030
ClassProps,
3131
Factory,
32-
Hashability,
33-
KeywordOnly,
3432
_AndValidator,
3533
_Attributes,
3634
_ClassBuilder,
@@ -185,7 +183,7 @@ def test_no_modifications(self):
185183
Does not attach __attrs_attrs__ to the class.
186184
"""
187185
C = make_tc()
188-
_transform_attrs(C, None, False, KeywordOnly.NO, True, None)
186+
_transform_attrs(C, None, False, ClassProps.KeywordOnly.NO, True, None)
189187

190188
assert None is getattr(C, "__attrs_attrs__", None)
191189

@@ -195,7 +193,7 @@ def test_normal(self):
195193
"""
196194
C = make_tc()
197195
attrs, _, _ = _transform_attrs(
198-
C, None, False, KeywordOnly.NO, True, None
196+
C, None, False, ClassProps.KeywordOnly.NO, True, None
199197
)
200198

201199
assert ["z", "y", "x"] == [a.name for a in attrs]
@@ -210,7 +208,7 @@ class C:
210208
pass
211209

212210
assert _Attributes((), [], {}) == _transform_attrs(
213-
C, None, False, KeywordOnly.NO, True, None
211+
C, None, False, ClassProps.KeywordOnly.NO, True, None
214212
)
215213

216214
def test_transforms_to_attribute(self):
@@ -219,7 +217,7 @@ def test_transforms_to_attribute(self):
219217
"""
220218
C = make_tc()
221219
attrs, base_attrs, _ = _transform_attrs(
222-
C, None, False, KeywordOnly.NO, True, None
220+
C, None, False, ClassProps.KeywordOnly.NO, True, None
223221
)
224222

225223
assert [] == base_attrs
@@ -237,7 +235,9 @@ class C:
237235
y = attr.ib()
238236

239237
with pytest.raises(ValueError) as e:
240-
_transform_attrs(C, None, False, KeywordOnly.NO, True, None)
238+
_transform_attrs(
239+
C, None, False, ClassProps.KeywordOnly.NO, True, None
240+
)
241241
assert (
242242
"No mandatory attributes allowed after an attribute with a "
243243
"default value or factory. Attribute in question: Attribute"
@@ -266,7 +266,7 @@ class C(B):
266266
y = attr.ib()
267267

268268
attrs, base_attrs, _ = _transform_attrs(
269-
C, None, False, KeywordOnly.YES, True, None
269+
C, None, False, ClassProps.KeywordOnly.YES, True, None
270270
)
271271

272272
assert len(attrs) == 3
@@ -282,7 +282,7 @@ class C(B):
282282
C,
283283
None,
284284
False,
285-
KeywordOnly.FORCE,
285+
ClassProps.KeywordOnly.FORCE,
286286
True,
287287
None,
288288
)
@@ -308,7 +308,7 @@ class C(Base):
308308
y = attr.ib()
309309

310310
attrs, base_attrs, _ = _transform_attrs(
311-
C, {"x": attr.ib()}, False, KeywordOnly.NO, True, None
311+
C, {"x": attr.ib()}, False, ClassProps.KeywordOnly.NO, True, None
312312
)
313313

314314
assert [] == base_attrs
@@ -540,9 +540,9 @@ class C:
540540
repr=True,
541541
eq=True,
542542
order=True,
543-
hash=Hashability.HASHABLE_CACHED,
543+
hash=ClassProps.Hashability.HASHABLE_CACHED,
544544
match_args=False,
545-
kw_only=KeywordOnly.FORCE,
545+
kw_only=ClassProps.KeywordOnly.FORCE,
546546
has_weakref_slot=True,
547547
collect_by_mro=False,
548548
str=True,
@@ -569,9 +569,9 @@ class CDef:
569569
repr=True,
570570
eq=True,
571571
order=True,
572-
hash=Hashability.UNHASHABLE,
572+
hash=ClassProps.Hashability.UNHASHABLE,
573573
match_args=True,
574-
kw_only=KeywordOnly.NO,
574+
kw_only=ClassProps.KeywordOnly.NO,
575575
has_weakref_slot=True,
576576
collect_by_mro=False,
577577
str=False,
@@ -2011,9 +2011,9 @@ class C:
20112011
repr=True,
20122012
eq=True,
20132013
order=False,
2014-
hash=Hashability.UNHASHABLE,
2014+
hash=ClassProps.Hashability.UNHASHABLE,
20152015
match_args=True,
2016-
kw_only=KeywordOnly.NO,
2016+
kw_only=ClassProps.KeywordOnly.NO,
20172017
has_weakref_slot=False,
20182018
collect_by_mro=True,
20192019
str=False,
@@ -2046,9 +2046,9 @@ class C:
20462046
repr=True,
20472047
eq=True,
20482048
order=False,
2049-
hash=Hashability.UNHASHABLE,
2049+
hash=ClassProps.Hashability.UNHASHABLE,
20502050
match_args=True,
2051-
kw_only=KeywordOnly.NO,
2051+
kw_only=ClassProps.KeywordOnly.NO,
20522052
has_weakref_slot=False,
20532053
collect_by_mro=True,
20542054
str=False,
@@ -2147,9 +2147,9 @@ def our_hasattr(obj, name, /) -> bool:
21472147
repr=True,
21482148
eq=True,
21492149
order=False,
2150-
hash=Hashability.UNHASHABLE,
2150+
hash=ClassProps.Hashability.UNHASHABLE,
21512151
match_args=True,
2152-
kw_only=KeywordOnly.NO,
2152+
kw_only=ClassProps.KeywordOnly.NO,
21532153
has_weakref_slot=True,
21542154
collect_by_mro=True,
21552155
str=False,

tests/test_next_gen.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import attrs
1616

1717
from attr._compat import PY_3_11_PLUS
18-
from attr._make import ClassProps, Hashability, KeywordOnly
18+
from attr._make import ClassProps
1919

2020

2121
@attrs.define
@@ -480,12 +480,12 @@ class C:
480480
is_exception=False,
481481
is_slotted=False,
482482
is_frozen=True,
483-
kw_only=KeywordOnly.YES,
483+
kw_only=ClassProps.KeywordOnly.YES,
484484
init=True,
485485
repr=True,
486486
eq=True,
487487
order=True,
488-
hash=Hashability.HASHABLE_CACHED,
488+
hash=ClassProps.Hashability.HASHABLE_CACHED,
489489
match_args=False,
490490
has_weakref_slot=True,
491491
collect_by_mro=True,
@@ -515,9 +515,9 @@ class C:
515515
repr=True,
516516
eq=True,
517517
order=False,
518-
hash=Hashability.HASHABLE, # b/c frozen
518+
hash=ClassProps.Hashability.HASHABLE, # b/c frozen
519519
match_args=True,
520-
kw_only=KeywordOnly.NO,
520+
kw_only=ClassProps.KeywordOnly.NO,
521521
has_weakref_slot=True,
522522
collect_by_mro=True,
523523
str=False,

0 commit comments

Comments
 (0)