In dandi-cli we try to automagically import needed extensions (from those which we know about) if we detect that there is a missing namespace. We react on KeyError which has "not a namespace" in its message. And I believe it was working ok across the dandisets we have. But trying now, it seems we would get a non-descriptive of the underlying cause exception (IIRC we use load_namespaces= to be able to load files produced with prior versions of pynwb et al, although it seems not even in effect due to those warnings you could see below):
*$> DUECREDIT_ENABLE=1 python -c 'import pynwb; pynwb.NWBHDF5IO("sub-699733573/sub-699733573_ses-715093703.nwb", "r", load_namespaces=True).read()'
/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'hdmf-common' version 1.1.3 because version 1.3.0 is already loaded.
warn("Ignoring cached namespace '%s' version %s because version %s is already loaded."
/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'core' version 2.2.2 because version 2.2.5 is already loaded.
warn("Ignoring cached namespace '%s' version %s because version %s is already loaded."
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/backends/hdf5/h5tools.py", line 420, in read
return call_docval_func(super().read, kwargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 423, in call_docval_func
return func(*fargs, **fkwargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/backends/io.py", line 41, in read
container = self.__manager.construct(f_builder)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 282, in construct
result = self.__type_map.construct(builder, self, None)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 959, in construct
return obj_mapper.construct(builder, build_manager, parent)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1210, in construct
subspecs = self.__get_subspec_values(builder, self.spec, manager)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1190, in __get_sub_builders
ret.update(self.__get_subspec_values(sub_builder, subspec, manager))
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1190, in __get_sub_builders
ret.update(self.__get_subspec_values(sub_builder, subspec, manager))
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1182, in __get_sub_builders
sub_builder = self.__flatten(sub_builder, subspec, manager)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1195, in __flatten
tmp = [manager.construct(b) for b in sub_builder]
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1195, in <listcomp>
tmp = [manager.construct(b) for b in sub_builder]
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 278, in construct
result = self.__type_map.construct(builder, self, parent)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 954, in construct
obj_mapper = self.get_map(builder)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 874, in get_map
container_cls = self.get_cls(obj)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 807, in get_cls
return self.get_container_cls(namespace, data_type)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 730, in get_container_cls
cls = ExtenderMeta(str(data_type), bases, d)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 755, in __init__
func(name, bases, classdict)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/container.py", line 136, in __gather_fields
raise ValueError("Field '%s' cannot be defined in %s. It already exists on base class %s."
ValueError: Field 'description' cannot be defined in EcephysProbe. It already exists on base class Device.
DueCredit Report:
- HDMF: Hierarchical Data Modeling Framework for Modern Science Data Standards / hdmf/ (v 2.3.0) [1]
- Scientific tools library / numpy (v 1.18.5) [2]
2 packages cited
0 modules cited
0 functions cited
References
----------
[1] Tritt, A.J. et al., 2019. HDMF: Hierarchical Data Modeling Framework for Modern Science Data Standards. In 2019 IEEE International Conference on Big Data (Big Data). pp. 165–179.
[2] Van Der Walt, S., Colbert, S.C. & Varoquaux, G., 2011. The NumPy array: a structure for efficient numerical computation. Computing in Science & Engineering, 13(2), pp.22–30.
pynwb 1.4.0
it seems to load ok if I import needed extension first
```shell
*$> python -c 'import pynwb, allensdk.brain_observatory.ecephys.nwb; pynwb.NWBHDF5IO("sub-699733573/sub-699733573_ses-715093703.nwb", "r", load_namespaces=True).read()'
/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'hdmf-common' version 1.1.3 because version 1.3.0 is already loaded.
warn("Ignoring cached namespace '%s' version %s because version %s is already loaded."
/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'core' version 2.2.2 because version 2.2.5 is already loaded.
warn("Ignoring cached namespace '%s' version %s because version %s is already loaded."
```
and if I run without load_namespaces=True, and without pre-importing the extension I do get that expected exception
```shell
*$> python -c 'import pynwb; pynwb.NWBHDF5IO("sub-699733573/sub-699733573_ses-715093703.nwb", "r").read()'
Traceback (most recent call last):
File "", line 1, in
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/backends/hdf5/h5tools.py", line 420, in read
return call_docval_func(super().read, kwargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 423, in call_docval_func
return func(*fargs, **fkwargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/backends/io.py", line 41, in read
container = self.__manager.construct(f_builder)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 282, in construct
result = self.__type_map.construct(builder, self, None)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 959, in construct
return obj_mapper.construct(builder, build_manager, parent)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1210, in construct
subspecs = self.__get_subspec_values(builder, self.spec, manager)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1190, in __get_sub_builders
ret.update(self.__get_subspec_values(sub_builder, subspec, manager))
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1182, in __get_sub_builders
sub_builder = self.__flatten(sub_builder, subspec, manager)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1195, in __flatten
tmp = [manager.construct(b) for b in sub_builder]
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1195, in
tmp = [manager.construct(b) for b in sub_builder]
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 278, in construct
result = self.__type_map.construct(builder, self, parent)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/manager.py", line 959, in construct
return obj_mapper.construct(builder, build_manager, parent)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1210, in construct
subspecs = self.__get_subspec_values(builder, self.spec, manager)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1139, in __get_subspec_values
self.__get_sub_builders(groups, spec.groups, manager, ret)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/build/objectmapper.py", line 1168, in __get_sub_builders
for parent_dt in manager.namespace_catalog.get_hierarchy(ns, dt):
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/utils.py", line 580, in func_call
return func(args[0], **pargs)
File "/home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py", line 327, in get_hierarchy
raise KeyError("'%s' not a namespace" % namespace)
KeyError: "'ndx-aibs-ecephys' not a namespace"
```
Overall -- it relates to a discussion of exceptions we had somewhere -- could somehow there be consistent identification of needing an extension loaded and raising a dedicated exception (e.g. MissingNWBExtensionError) raised?
Related question: should we or should we not generally use load_namespaces=True in our attempt to open some .nwb file which might have been produced with some prior version of pynwb?
How "safe" it is to not load some of the older namespaces (those core and hdmf-common as informed about in the warnings above) while loading the others?
Python Executable: Conda
Python Version: Python 3.8
Operating System: The Best Linux
HDMF Version: Version of PyNWB used -- hm... me confused, `2.3.0: 1.4.0`? ;-) consider #1336
Description
In dandi-cli we try to automagically import needed extensions (from those which we know about) if we detect that there is a missing namespace. We react on
KeyError
which has "not a namespace" in its message. And I believe it was working ok across the dandisets we have. But trying now, it seems we would get a non-descriptive of the underlying cause exception (IIRC we useload_namespaces=
to be able to load files produced with prior versions of pynwb et al, although it seems not even in effect due to those warnings you could see below):pynwb 1.4.0
it seems to load ok if I import needed extension first
```shell *$> python -c 'import pynwb, allensdk.brain_observatory.ecephys.nwb; pynwb.NWBHDF5IO("sub-699733573/sub-699733573_ses-715093703.nwb", "r", load_namespaces=True).read()' /home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'hdmf-common' version 1.1.3 because version 1.3.0 is already loaded. warn("Ignoring cached namespace '%s' version %s because version %s is already loaded." /home/yoh/miniconda3/lib/python3.8/site-packages/hdmf/spec/namespace.py:484: UserWarning: Ignoring cached namespace 'core' version 2.2.2 because version 2.2.5 is already loaded. warn("Ignoring cached namespace '%s' version %s because version %s is already loaded." ```and if I run without load_namespaces=True, and without pre-importing the extension I do get that expected exception
```shell *$> python -c 'import pynwb; pynwb.NWBHDF5IO("sub-699733573/sub-699733573_ses-715093703.nwb", "r").read()' Traceback (most recent call last): File "Overall -- it relates to a discussion of exceptions we had somewhere -- could somehow there be consistent identification of needing an extension loaded and raising a dedicated exception (e.g.
MissingNWBExtensionError
) raised?Related question: should we or should we not generally use
load_namespaces=True
in our attempt to open some .nwb file which might have been produced with some prior version of pynwb?How "safe" it is to not load some of the older namespaces (those
core
andhdmf-common
as informed about in the warnings above) while loading the others?Steps to Reproduce
Download a file from https://girder.dandiarchive.org/api/v1/item/5eda859399f25d97bd27985d/download (a sample file from DANDI:000021), which was likely produced by some prior pynwb (or matnwb, @bendichter might know better ;) ) and try the above
Environment