This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Tristan Croll
Recipients Tristan Croll, brett.cannon, serhiy.storchaka, vstinner
Date 2017-03-09.19:11:32
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1489086692.73.0.00346379210738.issue29758@psf.upfronthosting.co.za>
In-reply-to
Content
I've cross-posted the following to the SWIG bug tracker. Hopefully someone can find an answer, because I'm getting nowhere.

If I have two classes Foo and Bar (where Bar has a function get_foo() that returns a Foo object) defined in the SWIG-generated library foobar, and wrap them as follows:

```
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

@mappedclass(foobar.Foo)
class Foo(foobar.Foo):
    pass

@mappedclass(foobar.Bar)
class Bar(foobar.Bar):
    def get_foo(self):
        return super(Bar, self).get_foo()

```

then in Python 3.5:
```
f = Foo()
b = Bar()
b.get_foo()
```
all work. In Python 3.6:

```
f = Foo()
b = Bar()
```
... both work, but
`b.get_foo()`
yields the error as per my OP. Real-world examples:

Constructor (works without trouble in both versions)
```
SWIGINTERN PyObject *_wrap_new_Cell_descr__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  clipper::Cell_descr *result = 0 ;
  
  if(!PyArg_UnpackTuple(args,(char *)"new_Cell_descr",0,0)) SWIG_fail;
  {
    try
    {
      result = (clipper::Cell_descr *)new clipper::Cell_descr();
    } catch (clipper::Message_fatal m)
    {
      SWIG_exception(SWIG_RuntimeError, m.text().c_str() );
      SWIG_fail;
    } catch (std::out_of_range e)
    {
      const char *errString;
      if ( !strcmp(e.what(), "" ) ) {
        errString = "Index out of range!";
      } else {
        errString = e.what();
      }
      SWIG_exception(SWIG_IndexError, errString );
      SWIG_fail;
    } catch (std::length_error e)
    {
      SWIG_exception(SWIG_ValueError, e.what() );
      SWIG_fail;
    } catch (std::invalid_argument e)
    {
      SWIG_exception(SWIG_ValueError, e.what() );
      SWIG_fail;
    } catch (std::exception e)
    {
      SWIG_exception(SWIG_UnknownError, e.what() );
      SWIG_fail;
    } catch (...)
    {
      SWIG_exception(SWIG_UnknownError, "Unknown error" );
      SWIG_fail;
    }
    
  }
  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_clipper__Cell_descr, SWIG_POINTER_NEW |  0 );
  return resultobj;
fail:
  return NULL;
}
```

Getter (fails under the above conditions):
```
SWIGINTERN PyObject *_wrap_Cell_cell_descr(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  clipper::Cell *arg1 = (clipper::Cell *) 0 ;
  void *argp1 = 0 ;
  int res1 = 0 ;
  PyObject * obj0 = 0 ;
  clipper::Cell_descr result;
  
  if(!PyArg_UnpackTuple(args,(char *)"Cell_cell_descr",1,1,&obj0)) SWIG_fail;
  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_clipper__Cell, 0 |  0 );
  if (!SWIG_IsOK(res1)) {
    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Cell_cell_descr" "', argument " "1"" of type '" "clipper::Cell *""'"); 
  }
  arg1 = reinterpret_cast< clipper::Cell * >(argp1);
  {
    try
    {
      result = clipper_Cell_cell_descr(arg1);
    } catch (clipper::Message_fatal m)
    {
      SWIG_exception(SWIG_RuntimeError, m.text().c_str() );
      SWIG_fail;
    } catch (std::out_of_range e)
    {
      const char *errString;
      if ( !strcmp(e.what(), "" ) ) {
        errString = "Index out of range!";
      } else {
        errString = e.what();
      }
      SWIG_exception(SWIG_IndexError, errString );
      SWIG_fail;
    } catch (std::length_error e)
    {
      SWIG_exception(SWIG_ValueError, e.what() );
      SWIG_fail;
    } catch (std::invalid_argument e)
    {
      SWIG_exception(SWIG_ValueError, e.what() );
      SWIG_fail;
    } catch (std::exception e)
    {
      SWIG_exception(SWIG_UnknownError, e.what() );
      SWIG_fail;
    } catch (...)
    {
      SWIG_exception(SWIG_UnknownError, "Unknown error" );
      SWIG_fail;
    }
    
  }
  resultobj = SWIG_NewPointerObj((new clipper::Cell_descr(static_cast< const clipper::Cell_descr& >(result))), SWIGTYPE_p_clipper__Cell_descr, SWIG_POINTER_OWN |  0 );
  return resultobj;
fail:
  return NULL;
}
```
History
Date User Action Args
2017-03-09 19:11:32Tristan Crollsetrecipients: + Tristan Croll, brett.cannon, vstinner, serhiy.storchaka
2017-03-09 19:11:32Tristan Crollsetmessageid: <1489086692.73.0.00346379210738.issue29758@psf.upfronthosting.co.za>
2017-03-09 19:11:32Tristan Crolllinkissue29758 messages
2017-03-09 19:11:32Tristan Crollcreate