Tristan Croll added the comment: OK, a further clue. First, a little more detail on how my project is arranged (to re-iterate, this works without complaint in Python 3.5):
Rather than use my SWIG output directly, I've created a further wrapper layer in Python to add functions/syntactic sugar that would be difficult to achieve in SWIG, add a bit of extra documentation, and bury some classes that may be occasionally useful but don't really need to be in the primary API. The SWIG output Python library I name clipper_core, and I use the following class decorators for classes in the front-end API to reduce the amount of code (Python and SWIG) needed: def mappedclass(old_cls): ''' Ensures that objects returned from functions in the clipper_core library are instantiated in Python as the derived class with the extra functionality. ''' def decorator(cls): def __newnew__(thiscls, *args, **kwargs): if thiscls == old_cls: return object.__new__(cls) return object.__new__(thiscls) old_cls.__new__ = __newnew__ return cls return decorator def getters_to_properties(*funcs): ''' Class decorator. Add the names of any getter functions with void arguments (e.g. Coord_grid.u()) to convert them to properties. If you want the property name to be different from the function name, add the desired name and the function name as a tuple (e.g. ('uvw', '_get_uvw')) ''' def property_factory(func): def getter(self): return getattr(super(self.__class__, self), func)() prop = property(getter) return prop def decorator(cls): for func in funcs: if type(func) == tuple: setattr(cls, func[0], property_factory(func[1])) else: setattr(cls, func, property_factory(func)) return cls return decorator def format_to_string(cls): ''' Class decorator to redirect the Clipper format() function to __str__, to provide pretty printing of the object. ''' def format(self): return super(self.__class__,self).format() def __str__(self): return self.format setattr(cls, 'format', property(format)) setattr(cls, '__str__', __str__) return cls Experimenting this morning with the following two classes: @format_to_string @mappedclass(clipper_core.Cell_descr) class Cell_descr(clipper_core.Cell_descr): def __init__(self, abc, angles): ''' __init__(self, abc, angles) -> Cell_descr Args: abc ([float*3]): cell dimensions in Angstroms angles ([float*3]): alpha, beta and gamma angles in degrees ''' clipper_core.Cell_descr.__init__(self, *abc, *angles) @format_to_string @getters_to_properties('cell_descr', 'matrix_frac', 'matrix_orth', 'metric_real', 'metric_reci', 'volume') @mappedclass(clipper_core.Cell) class Cell(clipper_core.Cell): ''' Define a crystallographic unit cell using the lengths of the three sides a, b, c (in Angstroms) and the three angles alpha, beta, gamma (in degrees). ''' def __init__(self, abc, angles): ''' __init__(self, abc, angles) -> Cell Args: abc ([float*3]): cell dimensions in Angstroms angles ([float*3]): alpha, beta and gamma angles in degrees ''' cell_descr = Cell_descr(abc, angles) #cell_descr = clipper_core.Cell_descr(*abc, *angles) clipper_core.Cell.__init__(self, cell_descr) def __eq__(self, other): return self.equals(other) Then: import clipper cell = clipper.cell([100,100,100],[90,90,90]) cell.cell_descr SystemError Traceback (most recent call last) <ipython-input-4-c5072ce3ae97> in <module>() ----> 1 c.cell_descr /home/tic20/apps/chimerax/lib/python3.6/site-packages/chimerax/clipper/clipper_decorators.py in getter(self) 87 def property_factory(func): 88 def getter(self): ---> 89 return getattr(super(self.__class__, self), func)() 90 prop = property(getter) 91 return prop /home/tic20/apps/chimerax/lib/python3.6/site-packages/chimerax/clipper/lib/clipper_python_core/clipper.py in cell_descr(self) 8249 8250 """ -> 8251 return _clipper.Cell_cell_descr(self) 8252 8253 __swig_destroy__ = _clipper.delete_Cell SystemError: Objects/tupleobject.c:81: bad argument to internal function ... but if I comment out the derived Cell_descr class and switch to the alternate cell_descr constructor in Cell.__init__(), then it works as expected. I have tried commenting out the other class decorators, with no effect - so it would seem it's what's happening in the @mappedclass decorator that is causing my troubles. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue29758> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com