Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_class creates class which can not read text data back #1346

Closed
t-b opened this issue Apr 1, 2021 · 2 comments
Closed

get_class creates class which can not read text data back #1346

t-b opened this issue Apr 1, 2021 · 2 comments
Labels
category: bug errors in the code or code behavior

Comments

@t-b
Copy link
Collaborator

t-b commented Apr 1, 2021

pynwb: 1.4.0
hdfm: 2.1.0
python 3.7.4
h5py 2.10.0
Windows

Below is a MWE and the backtrace.

I'm a bit suprised I had to pass a list at

data = ["abcd"]

into UserCommentDevice.

I'd be glad to hear about workarounds.

MWE:

from pynwb.spec import NWBNamespaceBuilder, NWBGroupSpec, NWBAttributeSpec, NWBDatasetSpec
from pynwb import load_namespaces, get_class

name = 'test_multicontainerinterface'
ns_path = name + ".namespace.yaml"
ext_source = name + ".extensions.yaml"

ns_builder = NWBNamespaceBuilder(name + ' extensions', name, version='0.1.0')
ns_builder.include_type('NWBDataInterface', namespace='core')
ns_builder.include_type('NWBData', namespace='core')

user_comment_string = NWBDatasetSpec('device specific user text notes',
                                            neurodata_type_def='UserCommentString',
                                            neurodata_type_inc='NWBData',
                                            dtype="text")

potato_sack = NWBGroupSpec(neurodata_type_def='PotatoSack',
                           neurodata_type_inc='NWBDataInterface',
                           name='potato_sack',
                           doc='A sack of potatoes', quantity='?',
                           datasets=[user_comment_string])

ns_builder.add_spec(ext_source, potato_sack)
ns_builder.export(ns_path)

from pynwb import register_class, load_namespaces
from pynwb.file import MultiContainerInterface, NWBContainer

load_namespaces(ns_path)

UserCommentString = get_class("UserCommentString", name)

@register_class('PotatoSack', name)
class PotatoSack(MultiContainerInterface):

    __clsconf__ = {
        'attr': 'user_comment_string',
        'type': UserCommentString,
        'add': 'add_potato',
        'get': 'get_potato',
        'create': 'create_potato',
    }


####################
# Then use the objects (again, this would often be done in a different file).

from pynwb import NWBHDF5IO, NWBFile
from datetime import datetime
from dateutil.tz import tzlocal

# You can add potatoes to a potato sack in different ways
potato_sack = PotatoSack(user_comment_string=UserCommentString(name='potato1', data = ["abcd"]))

nwbfile = NWBFile("a file with metadata", "NB123A", datetime(2018, 6, 1, tzinfo=tzlocal()))

pmod = nwbfile.create_processing_module('module_name', 'desc')
pmod.add_container(potato_sack)

with NWBHDF5IO('test_multicontainerinterface.nwb', 'w') as io:
    io.write(nwbfile)

####################
# This is how you read the NWB file (again, this would often be done in a
# different file).

load_namespaces(ns_path)
io = NWBHDF5IO('test_multicontainerinterface.nwb', 'r')
nwb = io.read()
$ python extensions.py
Traceback (most recent call last):
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1137, in construct
    obj.__init__(**kwargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 560, in func_call
    pargs = _check_args(args, kwargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 553, in _check_args
    raise ExceptionType(msg)
TypeError: TypeMap.__get_cls_dict.<locals>.__init__: incorrect type for 'data' (got 'str', expected 'ndarray, list, tuple, Dataset, HDMFDataset, AbstractDataChunkIterator, DataIO or Data')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "extensions.py", line 69, in <module>
    nwb = io.read()
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\backends\hdf5\h5tools.py", line 414, in read
    return call_docval_func(super().read, kwargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 405, in call_docval_func
    return func(*fargs, **fkwargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\backends\io.py", line 36, in read
    container = self.__manager.construct(f_builder)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 238, in construct
    result = self.__type_map.construct(builder, self, None)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 857, in construct
    return obj_mapper.construct(builder, build_manager, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1105, in construct
    subspecs = self.__get_subspec_values(builder, self.spec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1035, in __get_subspec_values
    self.__get_sub_builders(groups, spec.groups, manager, ret)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1085, in __get_sub_builders
    ret.update(self.__get_subspec_values(sub_builder, subspec, manager))
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1035, in __get_subspec_values
    self.__get_sub_builders(groups, spec.groups, manager, ret)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1077, in __get_sub_builders
    sub_builder = self.__flatten(sub_builder, subspec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in __flatten
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in <listcomp>
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 234, in construct
    result = self.__type_map.construct(builder, self, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 857, in construct
    return obj_mapper.construct(builder, build_manager, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1105, in construct
    subspecs = self.__get_subspec_values(builder, self.spec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1035, in __get_subspec_values
    self.__get_sub_builders(groups, spec.groups, manager, ret)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1077, in __get_sub_builders
    sub_builder = self.__flatten(sub_builder, subspec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in __flatten
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in <listcomp>
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 234, in construct
    result = self.__type_map.construct(builder, self, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 857, in construct
    return obj_mapper.construct(builder, build_manager, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1105, in construct
    subspecs = self.__get_subspec_values(builder, self.spec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1036, in __get_subspec_values
    self.__get_sub_builders(datasets, spec.datasets, manager, ret)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1077, in __get_sub_builders
    sub_builder = self.__flatten(sub_builder, subspec, manager)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in __flatten
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1090, in <listcomp>
    tmp = [manager.construct(b) for b in sub_builder]
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 234, in construct
    result = self.__type_map.construct(builder, self, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\manager.py", line 857, in construct
    return obj_mapper.construct(builder, build_manager, parent)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\utils.py", line 561, in func_call
    return func(args[0], **pargs)
  File "C:\users\thomas\Anaconda3\envs\pynwb\lib\site-packages\hdmf\build\objectmapper.py", line 1140, in construct
    raise Exception(msg) from ex
Exception: Could not construct UserCommentString object due to: TypeMap.__get_cls_dict.<locals>.__init__: incorrect type for 'data' (got 'str', expected 'ndarray, list, tuple, Dataset, HDMFDataset, AbstractDataChunkIterator, DataIO or Data')
@t-b t-b added the category: bug errors in the code or code behavior label Apr 1, 2021
@oruebel
Copy link
Contributor

oruebel commented Aug 19, 2021

@t-b sorry, I just noticed that we seemed to have missed this issue. Is this still a problem?

@t-b
Copy link
Collaborator Author

t-b commented Aug 20, 2021

Thanks for pinging. Indeed this is fixed with pynwb
5fcd364 (Add environment-ros3.yml to MANIFEST.in (#1398), 2021-08-13), hdmf b3437314 (Remove regex test for setting an unsettable property (#664), 2021-08-16) and h5py 3.3.

@t-b t-b closed this as completed Aug 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: bug errors in the code or code behavior
Projects
None yet
Development

No branches or pull requests

2 participants