Skip to content

Commit 111a8e3

Browse files
0.1.6 (#2)
* Bumps version to 0.1.5.1 Updates the package version to 0.1.5.1 in pyproject.toml and uv.lock. This increment addresses a minor release. * Implements immutability for value objects Ensures that value objects are immutable after initialization by preventing attribute reassignment and deletion. This enhances data integrity and prevents unintended modifications to value object state. * Bumps version to 0.1.6 Updates the package version to 0.1.6 in pyproject.toml and uv.lock. This version bump reflects changes and improvements. * Implements immutability for value objects Ensures that value objects are immutable after initialization by preventing attribute reassignment and deletion. This enhances data integrity and prevents unintended modifications to value object state. * Bumps version to 0.1.6 Updates the package version to 0.1.6 in pyproject.toml and uv.lock. This version bump reflects changes and improvements.
1 parent 42b51d6 commit 111a8e3

4 files changed

Lines changed: 33 additions & 7 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "ddd-value-objects"
3-
version = "0.1.5.1"
3+
version = "0.1.6"
44
description = "A collection of base classes for Domain-Driven Design (DDD) value objects and entities in Python"
55
readme = "README.md"
66
license = {text = "MIT"}

src/ddd_value_objects/composite_value_object.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,26 @@
77

88
class CompositeValueObject(ABC, Generic[T]):
99
def __init__(self, value: T):
10-
self._value = value
10+
# Convert dictionary to a more immutable form if possible,
11+
# but at least prevent reassignment of _value
1112
self._ensure_value_is_defined(value)
13+
object.__setattr__(self, '_value', dict(value))
14+
object.__setattr__(self, '_initialized', True)
15+
16+
def __setattr__(self, name: str, value: Any) -> None:
17+
if getattr(self, '_initialized', False):
18+
raise TypeError(f"{self.__class__.__name__} is immutable")
19+
object.__setattr__(self, name, value)
20+
21+
def __delattr__(self, name: str) -> None:
22+
if getattr(self, '_initialized', False):
23+
raise TypeError(f"{self.__class__.__name__} is immutable")
24+
object.__delattr__(self, name)
25+
26+
@property
27+
def value(self) -> T:
28+
# Return a copy to prevent mutation of the internal dictionary
29+
return dict(self._value)
1230

1331
def equals(self, other: 'CompositeValueObject[T]') -> bool:
1432
return other.__class__ == self.__class__ and other.value == self._value
@@ -30,6 +48,3 @@ def _ensure_value_is_defined(self, value: Optional[T]) -> None:
3048
if value is None:
3149
raise InvalidArgumentError("Value must be defined")
3250

33-
@property
34-
def value(self) -> T:
35-
return self._value

src/ddd_value_objects/value_object.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,19 @@
99

1010
class ValueObject(ABC, Generic[Primitives]):
1111
def __init__(self, value: Primitives):
12-
self._value = value
12+
object.__setattr__(self, '_value', value)
1313
self._ensure_value_is_defined(value)
14+
object.__setattr__(self, '_initialized', True)
15+
16+
def __setattr__(self, name: str, value: Any) -> None:
17+
if getattr(self, '_initialized', False):
18+
raise TypeError(f"{self.__class__.__name__} is immutable")
19+
object.__setattr__(self, name, value)
20+
21+
def __delattr__(self, name: str) -> None:
22+
if getattr(self, '_initialized', False):
23+
raise TypeError(f"{self.__class__.__name__} is immutable")
24+
object.__delattr__(self, name)
1425

1526
def equals(self, other: 'ValueObject[Primitives]') -> bool:
1627
return other.__class__ == self.__class__ and other.value == self._value

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)