You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When load_entity autofetches a schema, it compiles a new class into osw.model.entity even if a packaged class is already registered for
that category IRI. The generated class then takes over the entry in
oold's type lookup, so every later resolution by IRI returns the
generated class instead of the packaged one.
Both classes claim the same category IRI, and the generated one holds
the slot.
Why it matters
Packaged behaviour is lost. The packaged classes carry typed
fields and helpers (unit enums, to_base(), and so on) that the
generated ones do not necessarily reproduce. Code that resolves a
reference gets the generated class and silently loses them.
References are dropped on assignment. A field declared as the
packaged class receives an instance of the generated class, so isinstance fails, and pydantic re-constructs the value from dict(value) rather than accepting it. For oold range fields the
value in __dict__ is None (the IRI lives in __iris__), so the
reference is lost with no error. Details and a reproduction in Reference is lost when a resolved node is re-validated into a different class for the same category OO-LD/oold-python#106.
Before fetching and compiling a schema, look the category IRI up in
oold's type registry and reuse the registered class if there is one.
Roughly:
cls=lookup_registered_type(category_iri) # oold _typesifclsisNone:
cls=fetch_and_compile(category_iri) # current path
Two details worth deciding explicitly:
Do not silently overwrite. If a class is generated for an IRI that
is already registered, that is a conflict. Either keep the first
registration, or log it loudly. Silent last-one-wins is what makes
this hard to spot.
autofetch_schema=False is not a workaround. Passing it for the
top-level load does not help, because the resolver used for nested
references calls load_entity with default parameters.
Workaround
Pass model_to_use explicitly for every load, including anything reached
by following a reference, or re-load second-level entities directly by
IRI.
Version
osw 1.1.2, oold 0.16.5, opensemantic.base 0.42.8.post1000002004006.
Summary
When
load_entityautofetches a schema, it compiles a new class intoosw.model.entityeven if a packaged class is already registered forthat category IRI. The generated class then takes over the entry in
oold's type lookup, so every later resolution by IRI returns the
generated class instead of the packaged one.
Measured
Both classes claim the same category IRI, and the generated one holds
the slot.
Why it matters
Packaged behaviour is lost. The packaged classes carry typed
fields and helpers (unit enums,
to_base(), and so on) that thegenerated ones do not necessarily reproduce. Code that resolves a
reference gets the generated class and silently loses them.
References are dropped on assignment. A field declared as the
packaged class receives an instance of the generated class, so
isinstancefails, and pydantic re-constructs the value fromdict(value)rather than accepting it. For ooldrangefields thevalue in
__dict__isNone(the IRI lives in__iris__), so thereference is lost with no error. Details and a reproduction in
Reference is lost when a resolved node is re-validated into a different class for the same category OO-LD/oold-python#106.
Concretely: a
Toolresolves its storage location, but the databaseserver behind it comes back
None, and the caller silently falls backto a local file
(_init_archive_database silently falls back to a local SQLite file OpenSemanticWorld-Packages/opensemantic.base-python#9).
Suggested fix
Before fetching and compiling a schema, look the category IRI up in
oold's type registry and reuse the registered class if there is one.
Roughly:
Two details worth deciding explicitly:
is already registered, that is a conflict. Either keep the first
registration, or log it loudly. Silent last-one-wins is what makes
this hard to spot.
autofetch_schema=Falseis not a workaround. Passing it for thetop-level load does not help, because the resolver used for nested
references calls
load_entitywith default parameters.Workaround
Pass
model_to_useexplicitly for every load, including anything reachedby following a reference, or re-load second-level entities directly by
IRI.