Summary
The TypeScript port has a declarative config (metaobjects.config.ts — defineConfig with a targets registry), so a project's codegen surface is described once and both meta gen and meta verify --codegen read it. A platform gate is then just:
npx meta verify --templates --codegen
The Python port is flags-only. There is no config file and no targets registry, so everything a target needs — output directory, generator selection, entity allowlist, provider module — has to be passed on the command line. In practice that means it lives in CI shell scripts, which is exactly where configuration goes stale.
server/python/src/metaobjects/codegen/KNOWN_GAPS.md already anticipates this ("once the Python codegen grows per-target output directories (mirroring the TS targets registry)"), so this is a request to schedule what is already acknowledged.
What it looks like downstream
An adopter generating two separate Python model directories from one metadata tree ends up with, per gate:
PYTHONPATH=<dir-containing-provider> metaobjects gen <metadata-dir> \
--out "$tmp" --generators entity \
--entities Aaa,Bbb,Ccc,Ddd,Eee,Fff,Ggg,Hhh,Iii,Jjj,Kkk,Lll,Mmm,Nnn \
--provider my_provider:provider \
&& diff -ru --exclude='__pycache__' <committed-dir> "$tmp"
Three problems follow from that:
- The entity list is duplicated into every place the gate runs — a local gate script plus one or more CI workflows. Add a model, update two of the three, and the new one is silently ungated. (An adopter hit exactly this: a committed generated directory sat several emitter minor-versions stale because nothing re-derived it, and the fix — consolidating the list into one shared script — is itself only a workaround for the missing config.)
PYTHONPATH= is required to make a consumer provider importable as a top-level module, because the provider is named by module:symbol with no config-relative resolution.
- The gate is a hand-written gen-to-temp-and-diff, rather than
verify --codegen (see the companion issue about verify --generators).
Proposed API
A metaobjects.config.py (or .yaml) beside the metadata:
config = {
"providers": ["my_provider:provider"],
"targets": [
{"out": "pkg/models/generated", "generators": ["entity"], "entities": [...]},
{"out": "pkg/other/generated", "generators": ["entity"], "entities": [...]},
],
}
metaobjects gen with no arguments runs every target.
metaobjects verify --codegen with no arguments checks every target.
- Provider module resolution relative to the config file, removing the
PYTHONPATH requirement.
That is the same ergonomics the TS side already has, and it makes the duplicated-list failure mode structurally impossible rather than merely documented.
Scope
Python port only. No metamodel or vocabulary change, so no coordinated multi-port release.
Relationship to the other issue
Independent but complementary. verify --codegen --generators alone is enough to delete the hand-written diff scripts; the config file is what stops the entity lists living in CI at all. Either helps; together they reduce a multi-file shell gate to one command.
Filed against 0.20.11.
Summary
The TypeScript port has a declarative config (
metaobjects.config.ts—defineConfigwith a targets registry), so a project's codegen surface is described once and bothmeta genandmeta verify --codegenread it. A platform gate is then just:The Python port is flags-only. There is no config file and no targets registry, so everything a target needs — output directory, generator selection, entity allowlist, provider module — has to be passed on the command line. In practice that means it lives in CI shell scripts, which is exactly where configuration goes stale.
server/python/src/metaobjects/codegen/KNOWN_GAPS.mdalready anticipates this ("once the Python codegen grows per-target output directories (mirroring the TS targets registry)"), so this is a request to schedule what is already acknowledged.What it looks like downstream
An adopter generating two separate Python model directories from one metadata tree ends up with, per gate:
Three problems follow from that:
PYTHONPATH=is required to make a consumer provider importable as a top-level module, because the provider is named bymodule:symbolwith no config-relative resolution.verify --codegen(see the companion issue aboutverify --generators).Proposed API
A
metaobjects.config.py(or.yaml) beside the metadata:metaobjects genwith no arguments runs every target.metaobjects verify --codegenwith no arguments checks every target.PYTHONPATHrequirement.That is the same ergonomics the TS side already has, and it makes the duplicated-list failure mode structurally impossible rather than merely documented.
Scope
Python port only. No metamodel or vocabulary change, so no coordinated multi-port release.
Relationship to the other issue
Independent but complementary.
verify --codegen --generatorsalone is enough to delete the hand-written diff scripts; the config file is what stops the entity lists living in CI at all. Either helps; together they reduce a multi-file shell gate to one command.Filed against 0.20.11.