tcod-ecs 5.3.0__tar.gz → 5.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tcod-ecs
3
- Version: 5.3.0
3
+ Version: 5.4.0
4
4
  Summary: A type-hinted Entity Component System based on Python dictionaries and sets.
5
5
  Author-email: Kyle Benesch <4b796c65+github@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -16,7 +16,7 @@ License-File: LICENSE
16
16
  Requires-Dist: attrs >=23.1.0
17
17
  Requires-Dist: cattrs >=23.1.2
18
18
  Requires-Dist: sentinel-value >=1.0.0
19
- Requires-Dist: typing-extensions >=4.4.0
19
+ Requires-Dist: typing-extensions >=4.9.0
20
20
  Requires-Dist: attrs >=22.2.0 ; extra == "test"
21
21
  Requires-Dist: pytest >=7.2.0 ; extra == "test"
22
22
  Requires-Dist: pytest-cov >=4.0.0 ; extra == "test"
@@ -22,7 +22,7 @@ dependencies = [
22
22
  "attrs >=23.1.0",
23
23
  "cattrs >=23.1.2",
24
24
  "sentinel-value >=1.0.0",
25
- "typing-extensions >=4.4.0",
25
+ "typing-extensions >=4.9.0",
26
26
  ]
27
27
 
28
28
  [tool.setuptools_scm]
@@ -89,6 +89,7 @@ line-length = 120
89
89
  [tool.ruff.lint] # https://docs.astral.sh/ruff/rules/
90
90
  select = ["ALL"]
91
91
  ignore = [
92
+ "A005", # stdlib-module-shadowing, workaround VSCode treating all modules as local
92
93
  "COM", # flake8-commas, handled by formatter
93
94
  "E501", # line-too-long
94
95
  "S101", # assert
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '5.3.0'
21
- __version_tuple__ = version_tuple = (5, 3, 0)
20
+ __version__ = version = '5.4.0'
21
+ __version_tuple__ = version_tuple = (5, 4, 0)
@@ -2,7 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- import warnings
6
5
  from typing import (
7
6
  TYPE_CHECKING,
8
7
  Any,
@@ -23,7 +22,7 @@ from weakref import WeakKeyDictionary, WeakValueDictionary
23
22
 
24
23
  import attrs
25
24
  from sentinel_value import sentinel
26
- from typing_extensions import Self
25
+ from typing_extensions import Self, deprecated
27
26
 
28
27
  import tcod.ecs.callbacks
29
28
  import tcod.ecs.query
@@ -74,17 +73,16 @@ class Entity:
74
73
  """This entities unique identifier."""
75
74
 
76
75
  @property
76
+ @deprecated("Use '.registry' instead of '.world'")
77
77
  def world(self) -> Registry:
78
78
  """Deprecated alias for registry.
79
79
 
80
80
  .. deprecated:: 5.1
81
81
  Use :any:`registry` instead.
82
82
  """
83
- if __debug__:
84
- warnings.warn("Use '.registry' instead of '.world'", DeprecationWarning, stacklevel=2)
85
83
  return self.registry
86
84
 
87
- def __new__(cls, registry: Registry, uid: object = object) -> Entity: # noqa: PYI034
85
+ def __new__(cls, registry: Registry, uid: object = object) -> Self | Entity:
88
86
  """Return a unique entity for the given `registry` and `uid`.
89
87
 
90
88
  If an entity already exists with a matching `registry` and `uid` then that entity is returned.
@@ -126,10 +124,10 @@ class Entity:
126
124
 
127
125
  .. versionadded:: 4.2.0
128
126
  """
129
- self.components(traverse=()).clear()
130
- self.tags(traverse=()).clear()
131
- self.relation_tags_many(traverse=()).clear()
132
- self.relation_components(traverse=()).clear()
127
+ self.components.clear()
128
+ self.tags.clear()
129
+ self.relation_tags_many.clear()
130
+ self.relation_components.clear()
133
131
 
134
132
  def instantiate(self) -> Self:
135
133
  """Return a new entity which inherits the components, tags, and relations of this entity.
@@ -284,13 +282,13 @@ class Entity:
284
282
  return EntityRelationsExclusive(self, (IsA,))
285
283
 
286
284
  @property
285
+ @deprecated("The '.relation_tags' attribute has been renamed to '.relation_tag'", category=FutureWarning)
287
286
  def relation_tags(self) -> EntityRelationsExclusive:
288
287
  """Access an entities exclusive relations.
289
288
 
290
289
  .. deprecated:: 3.2
291
290
  This attribute was renamed to :any:`relation_tag`.
292
291
  """
293
- warnings.warn("The '.relation_tags' attribute has been renamed to '.relation_tag'", FutureWarning, stacklevel=2)
294
292
  return EntityRelationsExclusive(self, (IsA,))
295
293
 
296
294
  @property
@@ -303,12 +301,8 @@ class Entity:
303
301
  """
304
302
  return EntityRelations(self, (IsA,))
305
303
 
306
- def _set_name(self, value: object, stacklevel: int = 1) -> None:
307
- warnings.warn(
308
- "The name feature has been deprecated and will be removed.",
309
- FutureWarning,
310
- stacklevel=stacklevel + 1,
311
- )
304
+ @deprecated("The name feature has been deprecated and will be removed.", category=FutureWarning)
305
+ def _set_name(self, value: object) -> None:
312
306
  old_name = self.name
313
307
  if old_name is not None: # Remove self from names
314
308
  del self.registry._names_by_name[old_name]
@@ -333,8 +327,9 @@ class Entity:
333
327
  return self.registry._names_by_entity.get(self)
334
328
 
335
329
  @name.setter
330
+ @deprecated("The name feature has been deprecated and will be removed.", category=FutureWarning)
336
331
  def name(self, value: object) -> None:
337
- self._set_name(value, stacklevel=2)
332
+ self._set_name(value)
338
333
 
339
334
  def __repr__(self) -> str:
340
335
  """Return a representation of this entity.
@@ -410,17 +405,13 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
410
405
  """
411
406
  return self.__class__(self.entity, tuple(traverse))
412
407
 
413
- def set(self, value: object, *, _stacklevel: int = 1) -> None:
408
+ @deprecated("Setting values without an explicit key has been deprecated.", category=FutureWarning)
409
+ def set(self, value: object) -> None:
414
410
  """Assign or overwrite a component, automatically deriving the key.
415
411
 
416
412
  .. deprecated:: 3.1
417
413
  Setting values without an explicit key has been deprecated.
418
414
  """
419
- warnings.warn(
420
- "Setting values without an explicit key has been deprecated.",
421
- FutureWarning,
422
- stacklevel=_stacklevel + 1,
423
- )
424
415
  key = value.__class__
425
416
  self[key] = value
426
417
 
@@ -498,15 +489,17 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
498
489
  """Return the number of components belonging to this entity."""
499
490
  return len(self.keys())
500
491
 
501
- def update_values(self, values: Iterable[object], *, _stacklevel: int = 1) -> None:
492
+ @deprecated("Setting values without an explicit key has been deprecated.", category=FutureWarning)
493
+ def update_values(self, values: Iterable[object]) -> None:
502
494
  """Add or overwrite multiple components inplace, deriving the keys from the values.
503
495
 
504
496
  .. deprecated:: 3.1
505
497
  Setting values without an explicit key has been deprecated.
506
498
  """
507
499
  for value in values:
508
- self.set(value, _stacklevel=_stacklevel + 1)
500
+ self.set(value)
509
501
 
502
+ @deprecated("This method has been deprecated. Iterate over items instead.", category=FutureWarning)
510
503
  def by_name_type(self, name_type: type[_T1], component_type: type[_T2]) -> Iterator[tuple[_T1, type[_T2]]]:
511
504
  """Iterate over all of an entities component keys with a specific (name_type, component_type) combination.
512
505
 
@@ -515,7 +508,6 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
515
508
  .. deprecated:: 3.1
516
509
  This method has been deprecated. Iterate over items instead.
517
510
  """
518
- warnings.warn("This method has been deprecated. Iterate over items instead.", FutureWarning, stacklevel=2)
519
511
  # Naive implementation until I feel like optimizing it
520
512
  for key in self:
521
513
  if not isinstance(key, tuple):
@@ -561,7 +553,7 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
561
553
  return __default
562
554
 
563
555
  @overload
564
- def pop(self, __key: ComponentKey[T], /) -> T | None: ...
556
+ def pop(self, __key: ComponentKey[T], /) -> T: ...
565
557
  @overload
566
558
  def pop(self, __key: ComponentKey[T], /, default: _T1) -> T | _T1: ...
567
559
 
@@ -602,6 +594,12 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
602
594
  del self[__key]
603
595
  return value
604
596
 
597
+ def clear(self) -> None:
598
+ """Remove any components stored directly in this entity."""
599
+ if self.traverse:
600
+ return self(traverse=()).clear()
601
+ return super().clear()
602
+
605
603
 
606
604
  @attrs.define(eq=False, frozen=True, weakref_slot=False)
607
605
  class EntityTags(MutableSet[Any]):
@@ -950,6 +948,13 @@ class EntityComponentRelationMapping(Generic[T], MutableMapping[Entity, T]):
950
948
  """Validate attributes."""
951
949
  assert isinstance(self.entity, Entity), self.entity
952
950
 
951
+ def __call__(self, *, traverse: Iterable[object]) -> Self:
952
+ """Update this view with alternative parameters, such as a specific traversal relation.
953
+
954
+ .. versionadded:: 5.4
955
+ """
956
+ return self.__class__(self.entity, self.key, tuple(traverse))
957
+
953
958
  def __getitem__(self, target: Entity) -> T:
954
959
  """Return the component related to a target entity."""
955
960
  _relation_components_by_entity = self.entity.registry._relation_components_by_entity
@@ -1009,6 +1014,12 @@ class EntityComponentRelationMapping(Generic[T], MutableMapping[Entity, T]):
1009
1014
  """Return the count of targets for this component relation."""
1010
1015
  return len(self.keys())
1011
1016
 
1017
+ def clear(self) -> None:
1018
+ """Remove any components stored directly in this entity relation."""
1019
+ if self.traverse:
1020
+ return self(traverse=()).clear()
1021
+ return super().clear()
1022
+
1012
1023
 
1013
1024
  @attrs.define(eq=False, frozen=True, weakref_slot=False)
1014
1025
  class EntityComponentRelations(MutableMapping[ComponentKey[Any], EntityComponentRelationMapping[Any]]):
@@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any, Iterable, Iterator, Protocol, TypeVar, ov
9
9
  from weakref import WeakKeyDictionary, WeakSet
10
10
 
11
11
  import attrs
12
- from typing_extensions import Self
12
+ from typing_extensions import Self, deprecated
13
13
 
14
14
  import tcod.ecs.entity
15
15
  from tcod.ecs.constants import IsA
@@ -333,14 +333,13 @@ class BoundQuery:
333
333
  _query: _Query = attrs.field(factory=_QueryLogicalAnd)
334
334
 
335
335
  @property
336
+ @deprecated("Use '.registry' instead of '.world'")
336
337
  def world(self) -> Registry:
337
338
  """Deprecated alias for registry.
338
339
 
339
340
  .. deprecated:: 5.1
340
341
  Use :any:`registry` instead.
341
342
  """
342
- if __debug__:
343
- warnings.warn("Use '.registry' instead of '.world'", DeprecationWarning, stacklevel=2)
344
343
  return self.registry
345
344
 
346
345
  def get_entities(self) -> AbstractSet[Entity]:
@@ -7,6 +7,7 @@ from collections import defaultdict
7
7
  from typing import TYPE_CHECKING, Any, DefaultDict, Dict, Final, Iterable, Mapping, NoReturn, Set, TypeVar
8
8
 
9
9
  import attrs
10
+ from typing_extensions import deprecated
10
11
 
11
12
  import tcod.ecs._converter
12
13
  import tcod.ecs.query
@@ -151,6 +152,10 @@ class Registry:
151
152
  """
152
153
 
153
154
  @property
155
+ @deprecated(
156
+ "The 'registry.global_' attribute has been deprecated. Use 'registry[None]' to access this entity.",
157
+ category=FutureWarning,
158
+ )
154
159
  def global_(self) -> Entity:
155
160
  """A unique globally accessible entity.
156
161
 
@@ -168,11 +173,6 @@ class Registry:
168
173
  >>> registry[None].components[("turn", int)]
169
174
  0
170
175
  """
171
- warnings.warn(
172
- "The 'registry.global_' attribute has been deprecated. Use 'registry[None]' to access this entity.",
173
- FutureWarning,
174
- stacklevel=2,
175
- )
176
176
  return Entity(self, None)
177
177
 
178
178
  def __setstate__(self, state: dict[str, Any]) -> None:
@@ -300,12 +300,12 @@ class Registry:
300
300
  if isinstance(components, Mapping):
301
301
  entity.components.update(components)
302
302
  elif components:
303
- entity.components.update_values(components, _stacklevel=2)
303
+ entity.components.update_values(components)
304
304
  entity_tags = entity.tags
305
305
  for tag in tags:
306
306
  entity_tags.add(tag)
307
307
  if name is not None:
308
- entity._set_name(name, stacklevel=2)
308
+ entity._set_name(name)
309
309
  return entity
310
310
 
311
311
  @property
@@ -1,4 +1,4 @@
1
- """Common type-hints for tcod.ecs.""" # noqa: A005
1
+ """Common type-hints for tcod.ecs."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes