Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "metaobjects"
version = "0.9.0"
version = "0.10.0"
description = "Cross-language metadata standard: declare typed entities once, generate idiomatic drift-checked code across languages — Python port."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,10 @@ def _render_shared_enums_module(self, entities: list[MetaObject]) -> EmittedFile
]
for e in shared:
parts += ["", f"class {e.name}(str, Enum):"]
parts += [f' {m} = "{m}"' for m in e.values]
# Member names follow the Python convention (UPPER_CASE constants); the
# value preserves the wire form, so ``Enum("statistical")`` and
# ``member == "statistical"`` still work (str-enum).
parts += [f' {m.upper()} = "{m}"' for m in e.values]
parts.append("")
return EmittedFile(path="enums.py", content=ruff_format("\n".join(parts)))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

import metaobjects.core_types # noqa: F401 — side-effect: registers attr classes

from metaobjects import MetaDataLoader
import json

from metaobjects import InMemoryStringSource, MetaDataFormat, MetaDataLoader
from metaobjects.meta.core.object.meta_object import MetaObject
from metaobjects.codegen.config import GenConfig
from metaobjects.codegen.generator import GenContext
Expand Down Expand Up @@ -69,3 +71,29 @@ def test_provided_enum_with_no_module_config_is_a_codegen_error_naming_the_enum(
with pytest.raises(ValueError) as excinfo:
_emit(GenConfig(out_dir="")) # no provided module configured
assert "Currency" in str(excinfo.value)


def _emit_doc(doc: dict) -> dict[str, str]:
root = MetaDataLoader().load(
[InMemoryStringSource(json.dumps(doc), id="m.json", format=MetaDataFormat.JSON)]
).root
entities = [o for o in root.own_children() if isinstance(o, MetaObject)]
ctx = GenContext(
entities=entities, loaded_root=root, matches=lambda _e: True,
config=GenConfig(out_dir=""), warn=lambda _m: None,
)
return {f.path: f.content for f in EntityModelGenerator().generate(ctx)}


def test_shared_enum_members_are_uppercase_with_wire_value_preserved() -> None:
"""Python enum members follow the UPPER_CASE constant convention; the value keeps
the wire form, so ``Enum("statistical")`` and ``member == "statistical"`` still work."""
enums = _emit_doc({"metadata.root": {"package": "a::b", "children": [
{"field.enum": {"name": "NumericalType", "abstract": True,
"@values": ["none", "statistical", "search_web"]}},
{"object.value": {"name": "M", "children": [
{"field.enum": {"name": "nt", "extends": "a::b::NumericalType"}}]}},
]}})["enums.py"]
assert 'STATISTICAL = "statistical"' in enums
assert 'SEARCH_WEB = "search_web"' in enums
assert 'statistical = "statistical"' not in enums # member is not the lowercase value
Loading