Skip to content

Commit 1ef86f2

Browse files
committed
simplify protocols by making _SupportsSprite inherit from _HasImageAndRect
1 parent 0569dbe commit 1ef86f2

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

buildconfig/stubs/pygame/sprite.pyi

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,30 @@ from pygame.typing import Point, RectLike
3030
_THasRect = TypeVar("_THasRect", bound=_HasRect)
3131

3232
# non-generic Group, used in Sprite
33-
_Group = AbstractGroup[_SpriteSupportsGroup]
33+
_Group = AbstractGroup[_SupportsSprite]
34+
35+
# define some useful protocols first, which sprite functions accept
36+
# sprite functions don't need all sprite attributes to be present in the
37+
# arguments passed, they only use a few which are marked in the below protocols
38+
class _HasRect(Protocol):
39+
@property
40+
def rect(self) -> Optional[Union[FRect, Rect]]: ...
41+
42+
# image in addition to rect
43+
class _HasImageAndRect(_HasRect, Protocol):
44+
@property
45+
def image(self) -> Optional[Surface]: ...
46+
47+
# mask in addition to rect
48+
class _HasMaskAndRect(_HasRect, Protocol):
49+
mask: Mask
50+
51+
# radius in addition to rect
52+
class _HasRadiusAndRect(_HasRect, Protocol):
53+
radius: float
3454

3555
# protocol helps with structural subtyping for typevars in sprite group generics
36-
class _SupportsSprite(Protocol):
56+
class _SupportsSprite(_HasImageAndRect, Protocol):
3757
@property
3858
def image(self) -> Optional[Surface]: ...
3959
@image.setter
@@ -102,40 +122,17 @@ class DirtySprite(_SupportsDirtySprite):
102122
# used as a workaround for typing.Self because it is added in python 3.11
103123
_TGroup = TypeVar("_TGroup", bound=AbstractGroup)
104124

105-
# define some useful protocols first, which sprite functions accept
106-
# sprite functions don't need all sprite attributes to be present in the
107-
# arguments passed, they only use a few which are marked in the below protocols
108-
class _HasRect(Protocol):
109-
@property
110-
def rect(self) -> Optional[Union[FRect, Rect]]: ...
111-
112-
# image in addition to rect
113-
class _HasImageAndRect(_HasRect, Protocol):
114-
@property
115-
def image(self) -> Optional[Surface]: ...
116-
117-
# mask in addition to rect
118-
class _HasMaskAndRect(_HasRect, Protocol):
119-
mask: Mask
120-
121-
# radius in addition to rect
122-
class _HasRadiusAndRect(_HasRect, Protocol):
123-
radius: float
124-
125-
class _SpriteSupportsGroup(_SupportsSprite, _HasImageAndRect, Protocol): ...
126-
class _DirtySpriteSupportsGroup(_SupportsDirtySprite, _HasImageAndRect, Protocol): ...
127-
128-
# typevar bound to Sprite, _SpriteSupportsGroup Protocol ensures sprite
125+
# typevar bound to Sprite, _SupportsSprite Protocol ensures sprite
129126
# subclass passed to group has image and rect attributes
130-
_TSprite = TypeVar("_TSprite", bound=_SpriteSupportsGroup)
131-
_TSprite2 = TypeVar("_TSprite2", bound=_SpriteSupportsGroup)
127+
_TSprite = TypeVar("_TSprite", bound=_SupportsSprite)
128+
_TSprite2 = TypeVar("_TSprite2", bound=_SupportsSprite)
132129

133130
# almost the same as _TSprite but bound to DirtySprite
134-
_TDirtySprite = TypeVar("_TDirtySprite", bound=_DirtySpriteSupportsGroup)
131+
_TDirtySprite = TypeVar("_TDirtySprite", bound=_SupportsDirtySprite)
135132

136133
_SpriteOrIterable = Union[_TSprite, Iterable[_SpriteOrIterable]]
137134

138-
# Below code demonstrates the advantages of the _SpriteSupportsGroup protocol
135+
# Below code demonstrates the advantages of the _SupportsSprite protocol
139136

140137
# typechecker should error, regular Sprite does not support Group.draw due to
141138
# missing image and rect attributes
@@ -159,7 +156,7 @@ class AbstractGroup(Generic[_TSprite]):
159156
spritedict: dict[_TSprite, Optional[Union[FRect, Rect]]]
160157
lostsprites: list[Union[FRect, Rect]]
161158
def __class_getitem__(
162-
cls, item: type[_SupportsSpriteGroup], /
159+
cls, item: type[_SupportsSprite], /
163160
) -> types.GenericAlias: ...
164161
def __init__(self) -> None: ...
165162
def __len__(self) -> int: ...

0 commit comments

Comments
 (0)