Motivation
Part of #608. Validating a file that uses multiple independent extension namespaces requires resolving a data type (its spec, its ancestor hierarchy, and its subtypes) without knowing up front which namespace defines it. NamespaceCatalog today only exposes namespace-scoped lookups (get_spec(namespace, data_type), get_hierarchy(namespace, data_type), is_sub_data_type(namespace, ...)), so a caller that only has a bare data_type (e.g. read off a builder) cannot resolve it across all loaded namespaces. The build layer already has the analogous namespace-agnostic pattern in TypeMap.get_dt_container_cls(data_type, namespace=None).
This issue adds the missing spec-layer capability. It is additive (no breaking changes) and independently useful.
Proposed API on NamespaceCatalog (src/hdmf/spec/namespace.py)
Follow the existing namespace=None ⇒ search all convention used by TypeMap.get_dt_container_cls:
get_spec(namespace=None, data_type=...): when namespace is None, find the owning namespace and return its spec; raise ValueError if unknown. Existing two-arg behavior unchanged.
get_hierarchy(namespace=None, data_type=...): when namespace is None, return the owning namespace's hierarchy (already includes cross-namespace ancestors, since a namespace's catalog is loaded with its transitive dependency types); () for unknown types.
is_sub_data_type(namespace=None, ...): make namespace optional for symmetry.
get_subtypes(data_type, recursive=True) (new): union of subtypes across all namespaces (deduped). The per-namespace SpecCatalog.get_subtypes already exists; this spans namespaces. This is the primitive that lets validation accept a subtype defined in another namespace.
type_key / type_keys property (new): the catalog owns its spec classes (group_spec_cls, etc.), so it can authoritatively report its type key(s) (data_type, plus at most one override per HDMF's rule).
These compose the existing per-namespace SpecCatalog methods (get_subtypes, get_hierarchy) and do not duplicate resolve_all_specs (which resolves inc-specs in place rather than providing a query index).
Acceptance criteria
- Namespace-agnostic
get_spec/get_hierarchy/is_sub_data_type resolve a type defined in any loaded namespace; two-arg forms unchanged.
get_subtypes(dt) returns subtypes defined in any namespace (including a subtype in a sibling extension namespace).
type_keys reflects the catalog's spec classes.
- Unit tests in
tests/unit/spec_tests/ build a catalog with a shared dependency namespace plus two independent extension namespaces and assert the above, with no validator involved.
This unblocks the ValidatorMap change tracked separately for #608.
Motivation
Part of #608. Validating a file that uses multiple independent extension namespaces requires resolving a data type (its spec, its ancestor hierarchy, and its subtypes) without knowing up front which namespace defines it.
NamespaceCatalogtoday only exposes namespace-scoped lookups (get_spec(namespace, data_type),get_hierarchy(namespace, data_type),is_sub_data_type(namespace, ...)), so a caller that only has a baredata_type(e.g. read off a builder) cannot resolve it across all loaded namespaces. The build layer already has the analogous namespace-agnostic pattern inTypeMap.get_dt_container_cls(data_type, namespace=None).This issue adds the missing spec-layer capability. It is additive (no breaking changes) and independently useful.
Proposed API on
NamespaceCatalog(src/hdmf/spec/namespace.py)Follow the existing
namespace=None ⇒ search allconvention used byTypeMap.get_dt_container_cls:get_spec(namespace=None, data_type=...): whennamespace is None, find the owning namespace and return its spec; raiseValueErrorif unknown. Existing two-arg behavior unchanged.get_hierarchy(namespace=None, data_type=...): whennamespace is None, return the owning namespace's hierarchy (already includes cross-namespace ancestors, since a namespace's catalog is loaded with its transitive dependency types);()for unknown types.is_sub_data_type(namespace=None, ...): makenamespaceoptional for symmetry.get_subtypes(data_type, recursive=True)(new): union of subtypes across all namespaces (deduped). The per-namespaceSpecCatalog.get_subtypesalready exists; this spans namespaces. This is the primitive that lets validation accept a subtype defined in another namespace.type_key/type_keysproperty (new): the catalog owns its spec classes (group_spec_cls, etc.), so it can authoritatively report its type key(s) (data_type, plus at most one override per HDMF's rule).These compose the existing per-namespace
SpecCatalogmethods (get_subtypes,get_hierarchy) and do not duplicateresolve_all_specs(which resolves inc-specs in place rather than providing a query index).Acceptance criteria
get_spec/get_hierarchy/is_sub_data_typeresolve a type defined in any loaded namespace; two-arg forms unchanged.get_subtypes(dt)returns subtypes defined in any namespace (including a subtype in a sibling extension namespace).type_keysreflects the catalog's spec classes.tests/unit/spec_tests/build a catalog with a shared dependency namespace plus two independent extension namespaces and assert the above, with no validator involved.This unblocks the
ValidatorMapchange tracked separately for #608.