dpmcore.services.semantic
Semantic validation of DPM-XL expressions against the loaded DPM
dictionary. Release-aware: accepts release_id or release_code.
SemanticService
- class dpmcore.services.semantic.SemanticService(session)[source]
Bases:
objectValidate DPM-XL expressions against the data dictionary.
- Parameters:
session (
Session) – An open SQLAlchemy session bound to a DPM database.
- __init__(session)[source]
Build the service bound to
session.- Parameters:
session (Session)
- Return type:
None
- validate(expression, release_id=None, release_code=None, *, precondition_expression=None, precondition_operation_vid=None)[source]
Full semantic validation of expression and its optional gate.
Returns a
SemanticResult— never raises on validation failure.A referenced parameter’s declared type is also checked against co-scoped operations already in the database (raising
3-8on a clash). This lookup only runs when the expression actually references a parameter and is scoped in SQL to co-located operations, so it adds no overhead to a parameter-free database.When
precondition_expressionis supplied, both halves are validated against the same release, resolved once, andis_validbecomes the verdict for the pair —Falseif either half failed, since a row whose gate does not resolve is not evaluable.preconditioncarries the gate’s own verdict anderror_sourcenames the failing half. Two checks then apply that a single expression never sees:The gate is validated as a gate, so its result must be a boolean (
2-1). A numeric selection is a valid expression but not a valid precondition.Parameter declarations are cross-checked across the halves (
3-8). A gate co-executes with its expression, so a parameter bound across them must declare one type.
The halves are evaluated gate-first, so the per-call state this service publishes (
ast,oc_data,oc_tables,oc_parameters,oc_operations_data) describes the main expression when the call returns — what existing consumers of this method already rely on.- Parameters:
expression (
str) – The DPM-XL expression to validate.release_id (
Optional[int]) – Optional release ID filter. When neither this norrelease_codeis given, defaults to the latest release.release_code (
Optional[str]) – Optional release code (mutually exclusive withrelease_id).precondition_expression (
Optional[str]) – Optional DPM-XL gate expression. Keyword-only, and appended after the pre-existing arguments, sovalidate(expr, 5)still meansrelease_id=5. WhenNone, the result is exactly as before this argument existed:preconditionisNoneandis_validdescribesexpressionalone.precondition_operation_vid (
Optional[int]) – Optional VID of a separately persistedOperationVersiongating this one (itsprecondition_operation_vidself-FK), distinct fromprecondition_expression. Cross-checked against the current module scope whenexpressionis valid (7-3/7-4/7-5); a VID with nothing to check against is accepted.
- Return type:
SemanticResult
- class dpmcore.services.semantic.SemanticResult(is_valid, error_message, error_code, expression, results=None, warning=None, parameters=<factory>, precondition=None, error_source=None)[source]
Outcome of a semantic validation.
When a
precondition_expressionis supplied,is_validis the verdict for the pair: it isFalseif either the expression or its gate failed, because a row whose gate does not resolve is not evaluable. The gate’s own independent verdict isprecondition;error_sourcesays which half a failure belongs to —"expression","precondition", or"both"— so attribution never needs string matching.error_messagenames every failure that occurred, each from the gate prefixed"Precondition: ", andwarningmerges both halves’ warnings the same way, so a caller reading only the outer result never misses half the story.error_codeholds a single value: the expression’s when it failed, otherwise the gate’s.preconditionisNoneexactly when the caller supplied no gate — never as a way of signalling that one failed. On that nested resulterror_sourceis"precondition"whenever it failed, since it describes the gate alone.- Parameters:
is_valid (bool)
error_message (str | None)
error_code (str | None)
expression (str)
results (Any | None)
warning (str | None)
parameters (tuple[ParameterInfo, ...])
precondition (SemanticResult | None)
error_source (str | None)
-
parameters:
tuple[ParameterInfo,...]
-
precondition:
Optional[SemanticResult] = None
ParameterInfo
- class dpmcore.services.semantic.ParameterInfo(code, declared_type, default=None)[source]
Declared metadata for a parameter referenced by an expression.
This is the runtime-binding contract: dpmcore reports which parameters an expression needs (and their declared types/defaults); the downstream engine resolves and binds their values.
is_setis a derived property (Setprefix of the canonicaldeclared_type), not a stored field, so there is one source of truth for set-ness.