Ensure that bare attributes with default None are removed too (#556)

Fixes #523
This commit is contained in:
Hynek Schlawack 2019-07-23 13:19:10 +02:00 committed by Łukasz Langa
parent 4a1b3a1436
commit dc1b5a01e9
4 changed files with 23 additions and 1 deletions

View File

@ -0,0 +1 @@
When collecting attributes using ``@attr.s(auto_attribs=True)``, attributes with a default of ``None`` are now deleted too.

View File

@ -0,0 +1 @@
When collecting attributes using ``@attr.s(auto_attribs=True)``, attributes with a default of ``None`` are now deleted too.

View File

@ -42,6 +42,9 @@ _hash_cache_field = "_attrs_cached_hash"
_empty_metadata_singleton = metadata_proxy({})
# Unique object for unequivocal getattr() defaults.
_sentinel = object()
class _Nothing(object):
"""
@ -504,7 +507,7 @@ class _ClassBuilder(object):
for name in self._attr_names:
if (
name not in base_names
and getattr(cls, name, None) is not None
and getattr(cls, name, _sentinel) != _sentinel
):
try:
delattr(cls, name)

View File

@ -265,3 +265,20 @@ class TestAnnotations:
x: int
assert 1 == C(1).x
def test_removes_none_too(self):
"""
Regression test for #523: make sure defaults that are set to None are
removed too.
"""
@attr.s(auto_attribs=True)
class C:
x: int = 42
y: typing.Any = None
with pytest.raises(AttributeError):
C.x
with pytest.raises(AttributeError):
C.y