Conversation
cdadbae to
56cc780
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #198 +/- ##
==========================================
+ Coverage 95.98% 96.00% +0.01%
==========================================
Files 140 140
Lines 9797 9827 +30
Branches 568 569 +1
==========================================
+ Hits 9404 9434 +30
Misses 275 275
Partials 118 118 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
56cc780 to
f473ab1
Compare
|
I think we need a flag to differentiate the different questions the method might be ansering
I don't know what I would call such a parameter, |
…solve their registered names Signed-off-by: Ryan Feuss <ryan.feuss@CubistSystematic.com>
f473ab1 to
2274372
Compare
Agreed, have added a flag and associated test that preserves existing behavior by default |
Summary
Fixes
get_registered_names()returning[]for models whose parent sub-registry has been orphaned by anadd(..., overwrite=True)call.When a sub-registry is replaced in the root (e.g. during a config reload),
add()removes(root, name)from the old sub-registry's_registrations, breaking the chain. Models still referencing the old sub-registry dead-end at the empty_registrationsand can no longer resolve their names — silently breaking any downstream logic that depends on registry-path lookup (e.g. cache evaluators keyed by model name).What's included
_RegistryMixin._was_registeredPrivateAttr(default=False)added alongside_registrationsTrueinModelRegistry.add()the first time a model is added to any parentget_registered_names()— orphan fallback branchelif isinstance(self, ModelRegistry) and self._was_registered and self.name:branch beforereturn [][f"/{self.name}"], reconstructing their path from the immutable.nameattribute_registrationspointing to it, so the existing recursion assembles the full path correctlyisinstance(never fires for plainBaseModeloverwrites),_was_registered(never fires for local unrooted registries),self.name(belt-and-suspenders against root, whosenameis"")What's NOT included
ModelRegistry.add()de-registration logic — the removal of old registrations on overwrite is intentional and testedget_registered_names()— all existing callers handle a non-empty return correctlyTests
1 new test
test_orphaned_subregistry_resolves_namecovering the 2-level deep case (/foo/bar/model_name), with registry cleanup infinally. All 40 existing registry tests pass unchanged — includingtest_add_twiceandtest_add_two_placeswhich verify that local unrooted sub-registries remain invisible.test_pickle_consistencyintest_base_serialize.pywas updated to reflect that_was_registeredis now included in__pydantic_private__during pickling. The hard-coded expected bytes were regenerated accordingly; the test's purpose (proving deterministic pickle output across runs) is unchanged.