Allow subclassing of AttrsInstance and Protocol at once (#1172)

This commit is contained in:
Hynek Schlawack 2023-08-06 21:33:03 +02:00 committed by GitHub
parent 8f4e7e921b
commit c824bbe103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 2 deletions

View File

@ -93,7 +93,7 @@ jobs:
python -Im coverage html --skip-covered --skip-empty
# Report and write to summary.
python -Im coverage report | sed 's/^/ /' >> $GITHUB_STEP_SUMMARY
python -Im coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
# Report again and fail if under 100%.
python -Im coverage report --fail-under=100

1
.gitignore vendored
View File

@ -19,3 +19,4 @@ tmp*
attrs.docset
attrs.tgz
Justfile
t.py

View File

@ -0,0 +1,2 @@
`attrs.AttrsInstance` is now a `typing.Protocol` in both type hints and code.
This allows you to subclass it along with another `Protocol`.

View File

@ -133,6 +133,9 @@ exclude_lines = [
"pragma: no cover",
# PyPy is unacceptably slow under coverage.
"if PYPY:",
# not meant to be executed
': \.\.\.$',
'^ +\.\.\.$',
]

View File

@ -9,6 +9,7 @@ from typing import Callable
from . import converters, exceptions, filters, setters, validators
from ._cmp import cmp_using
from ._compat import Protocol
from ._config import get_run_validators, set_run_validators
from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types
from ._make import (
@ -31,7 +32,7 @@ ib = attr = attrib
dataclass = partial(attrs, auto_attribs=True) # happy Easter ;)
class AttrsInstance:
class AttrsInstance(Protocol):
pass

View File

@ -18,6 +18,15 @@ PY310 = sys.version_info[:2] >= (3, 10)
PY_3_12_PLUS = sys.version_info[:2] >= (3, 12)
if sys.version_info < (3, 8):
try:
from typing_extensions import Protocol
except ImportError: # pragma: no cover
Protocol = object
else:
from typing import Protocol # noqa: F401
def just_warn(*args, **kw):
warnings.warn(
"Running interpreter doesn't sufficiently support code object "

View File

@ -4,6 +4,8 @@ import types
import pytest
import attr
@pytest.fixture(name="mp")
def _mp():
@ -50,3 +52,13 @@ class TestMetadataProxy:
with pytest.raises(AttributeError, match="no attribute 'setdefault'"):
mp.setdefault("x")
def test_attrsinstance_subclass_protocol():
"""
It's possible to subclass AttrsInstance and Protocol at once.
"""
class Foo(attr.AttrsInstance, attr._compat.Protocol):
def attribute(self) -> int:
...