olebole / python-cpl

Python bindings for CPL recipes
http://pypi.python.org/pypi/python-cpl
GNU General Public License v2.0
10 stars 5 forks source link

Error with Python 3.7 and .calib .param attributes #18

Closed saimn closed 5 years ago

saimn commented 6 years ago

Printing these attributes with Python 3.7 raise a KeyError (it seems that Python tries to find a .keys() method):

In [1]: import cpl; cpl.Recipe.path = '/home/conseil/.local/lib'; print(cpl.__version__)
0.7.3

In [2]: recipe = cpl.Recipe('muse_scibasic')

In [3]: recipe.param                  
Out[3]: ---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/miniconda3/envs/cpl/lib/python3.7/site-packages/IPython/core/formatters.py in __call__(self, obj)
    700                 type_pprinters=self.type_printers,
    701                 deferred_pprinters=self.deferred_printers)
--> 702             printer.pretty(obj)
    703             printer.flush()                                                
    704             return stream.getvalue()                               

~/miniconda3/envs/cpl/lib/python3.7/site-packages/IPython/lib/pretty.py in pretty(self, obj)
    398                         if cls is not object \            
    399                                 and callable(cls.__dict__.get('__repr__')):
--> 400                             return _repr_pprint(obj, self, cycle)
    401
    402             return _default_pprint(obj, self, cycle)

~/miniconda3/envs/cpl/lib/python3.7/site-packages/IPython/lib/pretty.py in _repr_pprint(obj, p, cycle)
    693     """A pprint that just redirects to the normal repr function."""
    694     # Find newlines and replace them with p.break_()
--> 695     output = repr(obj)
    696     for idx,output_line in enumerate(output.splitlines()):
    697         if idx:

~/miniconda3/envs/cpl/lib/python3.7/site-packages/cpl/param.py in __repr__(self)
    233
    234     def __repr__(self):
--> 235         return repr(dict(self))
    236
    237     def __eq__(self, other):

~/miniconda3/envs/cpl/lib/python3.7/site-packages/cpl/param.py in __getattr__(self, key)
    217
    218     def __getattr__(self, key):
--> 219         return self[key]
    220
    221     def __setattr__(self, key, value):

~/miniconda3/envs/cpl/lib/python3.7/site-packages/cpl/param.py in __getitem__(self, key)
    188
    189     def __getitem__(self, key):
--> 190         return self._dict[key]
    191
    192     def __setitem__(self, key, value):

KeyError: 'keys'

And the same for recipe.calib.

olebole commented 6 years ago

It seems that the dict() constructor changed in Python 3.7. A pragmatic solution would be to create the dict from an iterator, i.e. replace repr(dict(self)) with repr(dict(iter(self))). However, I still don't understand fully why it fails -- it looks like because Python is doing Duck Typing here and assumes cpl.ParameterList is a dict, while it should use it as an ordinary iterable.

saimn commented 5 years ago

Thanks!

saimn commented 5 years ago

Hi Ole, Any chance that you could make a new release with this fix ? This is a blocking issue for people using my reduction package on Python 3.7. Thanks

olebole commented 5 years ago

Ah, sorry; I uploaded the fixed version now to pypi.

saimn commented 5 years ago

Many thanks!