Skip to content

Commit b1d60c3

Browse files
Update divisions constraints to match data and fix bug
* Widen `AdminLevel` from `uint8` to `int32` to match divisions data currently being generated. * Fix Pydantic rebinding self in model constraint validator
1 parent d903525 commit b1d60c3

5 files changed

Lines changed: 17 additions & 10 deletions

File tree

packages/overture-schema-divisions-theme/src/overture/schema/divisions/types.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@
33
from pydantic import Field
44

55
from overture.schema.system.field_constraint import UniqueItemsConstraint
6-
from overture.schema.system.primitive import uint8
6+
from overture.schema.system.primitive import int32
77

88
from .models import HierarchyItem
99

1010
AdminLevel = NewType(
1111
"AdminLevel",
1212
Annotated[
13-
uint8,
13+
int32,
1414
Field(
1515
description="Integer representing the division's position in its country's administrative hierarchy, where lower numbers correspond to higher level administrative units.",
16+
ge=0,
17+
le=16,
1618
),
1719
],
1820
)

packages/overture-schema-divisions-theme/tests/division_area_baseline_schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@
457457
"properties": {
458458
"admin_level": {
459459
"description": "Integer representing the division's position in its country's administrative hierarchy, where lower numbers correspond to higher level administrative units.",
460-
"maximum": 255,
460+
"maximum": 16,
461461
"minimum": 0,
462462
"title": "Admin Level",
463463
"type": "integer"

packages/overture-schema-divisions-theme/tests/division_baseline_schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@
524524
"properties": {
525525
"admin_level": {
526526
"description": "Integer representing the division's position in its country's administrative hierarchy, where lower numbers correspond to higher level administrative units.",
527-
"maximum": 255,
527+
"maximum": 16,
528528
"minimum": 0,
529529
"title": "Admin Level",
530530
"type": "integer"

packages/overture-schema-divisions-theme/tests/division_boundary_baseline_schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@
370370
"properties": {
371371
"admin_level": {
372372
"description": "Integer representing the division's position in its country's administrative hierarchy, where lower numbers correspond to higher level administrative units.",
373-
"maximum": 255,
373+
"maximum": 16,
374374
"minimum": 0,
375375
"title": "Admin Level",
376376
"type": "integer"

packages/overture-schema-system/src/overture/schema/system/model_constraint/model_constraint.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ def __init__(self, name: str | None = None):
5656
)
5757
self.__name = name
5858

59-
def __validate_instance(self, model_instance: BaseModel) -> BaseModel:
60-
self.validate_instance(model_instance)
61-
return model_instance
62-
6359
@property
6460
def name(self) -> str:
6561
"""Returns the name of the constraint, e.g. "FooConstraint" or "@foo"."""
@@ -126,6 +122,15 @@ def decorate(self, model_class: type[BaseModel]) -> type[BaseModel]:
126122
metadata = Metadata.retrieve_from(model_class, Metadata()).copy() # type: ignore[union-attr]
127123
model_constraints = (*ModelConstraint.get_model_constraints(model_class), self)
128124
metadata[_MODEL_CONSTRAINT_KEY] = model_constraints
125+
# Capture the constraint in a closure rather than passing a bound method.
126+
# Some Pydantic versions unwrap bound methods passed through __validators__
127+
# and rebind `self` to the model instance, breaking the dispatch.
128+
constraint = self
129+
130+
def _after_validator(model_instance: BaseModel) -> BaseModel:
131+
constraint.validate_instance(model_instance)
132+
return model_instance
133+
129134
new_model_class = create_model(
130135
model_class.__name__,
131136
__config__=config,
@@ -135,7 +140,7 @@ def decorate(self, model_class: type[BaseModel]) -> type[BaseModel]:
135140
__validators__={
136141
self.name: cast(
137142
Callable[..., Any],
138-
model_validator(mode="after")(self.__validate_instance),
143+
model_validator(mode="after")(_after_validator),
139144
)
140145
},
141146
__metadata__=metadata,

0 commit comments

Comments
 (0)