tcod-ecs 5.2.1__tar.gz → 5.2.2__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.1
2
2
  Name: tcod-ecs
3
- Version: 5.2.1
3
+ Version: 5.2.2
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
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '5.2.1'
16
- __version_tuple__ = version_tuple = (5, 2, 1)
15
+ __version__ = version = '5.2.2'
16
+ __version_tuple__ = version_tuple = (5, 2, 2)
@@ -22,6 +22,7 @@ from typing import (
22
22
  from weakref import WeakKeyDictionary, WeakValueDictionary
23
23
 
24
24
  import attrs
25
+ from sentinel_value import sentinel
25
26
  from typing_extensions import Self
26
27
 
27
28
  import tcod.ecs.callbacks
@@ -41,6 +42,8 @@ T = TypeVar("T")
41
42
  _T1 = TypeVar("_T1")
42
43
  _T2 = TypeVar("_T2")
43
44
 
45
+ _raise: Final = sentinel("_raise")
46
+
44
47
  _entity_table: WeakKeyDictionary[Registry, WeakValueDictionary[object, Entity]] = WeakKeyDictionary()
45
48
  """A weak table of registries and unique identifiers to entity objects.
46
49
 
@@ -134,6 +137,10 @@ class Entity:
134
137
  This creates a new unique entity and assigns an :any:`IsA` relationship with `self` to the new entity.
135
138
  The :any:`IsA` relation is the only data this new entity directly holds.
136
139
 
140
+ Immutable components inherited from the parent are always copy-on-write for its child instances.
141
+
142
+ Keep in mind that components/tags/relations inherited from the parent are not removable from the child instance.
143
+
137
144
  Example::
138
145
 
139
146
  # 'child = entity.instantiate()' is equivalent to the following:
@@ -149,14 +156,18 @@ class Entity:
149
156
  >>> child.components[str] # Inherits components from parent
150
157
  'baz'
151
158
  >>> parent.components[str] = "foo"
152
- >>> child.components[str] # Changes in parent and reflected in children
159
+ >>> child.components[str] # Changes in parent are reflected in children
153
160
  'foo'
154
161
  >>> child.components[str] += "bar" # In-place assignment operators will copy-on-write immutable objects
155
162
  >>> child.components[str]
156
163
  'foobar'
157
164
  >>> parent.components[str]
158
165
  'foo'
159
- >>> del child.components[str]
166
+ >>> child.components.pop(str, None) # Revert the component to the inherited value
167
+ 'foobar'
168
+ >>> child.components[str]
169
+ 'foo'
170
+ >>> child.components.pop(str, None) # Safe to call .pop with default when the value isn't set on the child
160
171
  >>> child.components[str]
161
172
  'foo'
162
173
 
@@ -530,16 +541,16 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
530
541
  return self
531
542
 
532
543
  @overload
533
- def get(self, __key: ComponentKey[T]) -> T | None: ...
544
+ def get(self, __key: ComponentKey[T], /) -> T | None: ...
534
545
  @overload
535
- def get(self, __key: ComponentKey[T], __default: _T1) -> T | _T1: ...
546
+ def get(self, __key: ComponentKey[T], /, default: _T1) -> T | _T1: ...
536
547
 
537
- def get(self, __key: ComponentKey[T], __default: _T1 | None = None) -> T | _T1:
548
+ def get(self, __key: ComponentKey[T], /, default: _T1 | None = None) -> T | _T1:
538
549
  """Return a component, returns None or a default value when the component is missing."""
539
550
  try:
540
551
  return self[__key]
541
552
  except KeyError:
542
- return __default # type: ignore[return-value] # https://github.com/python/mypy/issues/3737
553
+ return default # type: ignore[return-value] # https://github.com/python/mypy/issues/3737
543
554
 
544
555
  def setdefault(self, __key: ComponentKey[T], __default: T) -> T: # type: ignore[override]
545
556
  """Assign a default value if a component is missing, then returns the current value."""
@@ -549,6 +560,48 @@ class EntityComponents(MutableMapping[Union[Type[Any], Tuple[object, Type[Any]]]
549
560
  self[__key] = __default
550
561
  return __default
551
562
 
563
+ @overload
564
+ def pop(self, __key: ComponentKey[T], /) -> T | None: ...
565
+ @overload
566
+ def pop(self, __key: ComponentKey[T], /, default: _T1) -> T | _T1: ...
567
+
568
+ def pop(
569
+ self,
570
+ __key: ComponentKey[T],
571
+ /,
572
+ default: _T1 = _raise, # type: ignore[assignment] # https://github.com/python/mypy/issues/3737
573
+ ) -> T | _T1:
574
+ """Remove a component directly from this entity.
575
+
576
+ Returns the removed value.
577
+ If the value is missing returns `default`.
578
+ If `default` is unset then raises :any:`KeyError` instead.
579
+
580
+ Operates directly on the entity without traversal.
581
+
582
+ >>> parent = registry[object()]
583
+ >>> parent.components[str] = "foo"
584
+ >>> child = parent.instantiate()
585
+ >>> child.components[str] = "bar"
586
+ >>> child.components.pop(str, None)
587
+ 'bar'
588
+ >>> child.components.pop(str, None)
589
+ >>> child.components[str]
590
+ 'foo'
591
+ >>> child.components.pop(str)
592
+ Traceback (most recent call last):
593
+ ...
594
+ KeyError: <class 'str'>
595
+ """
596
+ _components = self.entity.registry._components_by_entity.get(self.entity, {})
597
+ if __key not in _components:
598
+ if default is _raise:
599
+ raise KeyError(__key)
600
+ return default
601
+ value: T | _T1 = _components[__key]
602
+ del self[__key]
603
+ return value
604
+
552
605
 
553
606
  @attrs.define(eq=False, frozen=True, weakref_slot=False)
554
607
  class EntityTags(MutableSet[Any]):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes