Skip to content

Commit

Permalink
feat: setting a non-dynamic field is an error
Browse files Browse the repository at this point in the history
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
  • Loading branch information
henryiii committed Sep 18, 2024
1 parent 182eee5 commit 6dcae95
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
14 changes: 13 additions & 1 deletion pyproject_metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,20 @@ class StandardMetadata:
"""

metadata_version: str | None = None
_locked_metadata: bool = False

def __post_init__(self) -> None:
self.validate()

def __setattr__(self, name: str, value: Any) -> None:
if self._locked_metadata and name.replace('_', '-') not in set(self.dynamic) | {
'metadata-version',
'dynamic-metadata',
}:
msg = f'Field "{name}" is not dynamic'
raise AttributeError(msg)
super().__setattr__(name, value)

def validate(self, *, warn: bool = True) -> None:
if self.auto_metadata_version not in KNOWN_METADATA_VERSIONS:
msg = f'The metadata_version must be one of {KNOWN_METADATA_VERSIONS} or None (default)'
Expand Down Expand Up @@ -661,7 +671,7 @@ def from_pyproject(
else None
)

return cls(
self = cls(
name=name,
version=version,
description=description,
Expand All @@ -683,6 +693,8 @@ def from_pyproject(
dynamic_metadata=dynamic_metadata or [],
metadata_version=metadata_version,
)
self._locked_metadata = True
return self

def as_rfc822(self) -> RFC822Message:
message = RFC822Message()
Expand Down
19 changes: 19 additions & 0 deletions tests/test_standard_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,25 @@ def test_version_dynamic() -> None:
metadata.version = packaging.version.Version('1.2.3')


def test_modify_dynamic() -> None:
metadata = pyproject_metadata.StandardMetadata.from_pyproject(
{
'project': {
'name': 'example',
'version': '1.2.3',
'dynamic': [
'requires-python',
],
},
}
)
metadata.requires_python = packaging.specifiers.SpecifierSet('>=3.12')
with pytest.raises(
AttributeError, match=re.escape('Field "version" is not dynamic')
):
metadata.version = packaging.version.Version('1.2.3')


def test_missing_keys_warns() -> None:
with pytest.warns(
pyproject_metadata.ConfigurationWarning,
Expand Down

0 comments on commit 6dcae95

Please sign in to comment.