title: Python-C Api wrapper in Objective-C crashes with call to __getattr__ when passed a Python Object
body: <p>I'm in the process of writing a lightweight interface in Objective-C that is capable of executing python scripts and passing data back and forth between Objective-C and Python.  I've looked into PyObjC and ObjP and neither are what I'm looking for (and since I'm developing for iOS &lt;= 6.0.1 PyObjC won't compile do to the heavy use of NSMapTable's).</p>
  
  <p>So basically I created a Python Type in Objective-C called "ObjC_Class" (creative, no?) and I want this Python object to be nearly analogous to an ObjC object.  So I decided to override the <strong>__<em>getattr</em>__</strong> function of the class so I can access arbitrary methods and properties of the ObjC equivalent of that class.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>static PyObject * ObjC_Class_getattro(ObjC_Class *self, PyObject *name)
  {
      NSString *attrName = [NSString stringWithCString:PyString_AsString(name) encoding:NSUTF8StringEncoding];
  
      NSLog(@"Calling Object: %@", self-&gt;object);
      if([self-&gt;object respondsToSelector:NSSelectorFromString(attrName)])
      {
          methodName = attrName;
          //PyObject* (*fpFunc)(PyObject*,PyObject*) = ObjC_Class_msg_send;
          PyMethodDef methd = {[attrName UTF8String],ObjC_Class_msg_send,METH_VARARGS,[attrName UTF8String]};
          PyObject* pyName = PyString_FromString(methd.ml_name);
          PyObject* pyfoo = PyCFunction_NewEx(&amp;methd,(PyObject*)self,pyName);
          Py_DECREF(name);
  
          return pyfoo;
      }
      else
      {
          return name;
      }
  }
  </code></pre>
  
  <p>Now, it works perfectly fine when I say:</p>
  
  <p><strong>Example #1</strong></p>
  
  <pre><code>from ObjC import ObjC_Class
  new = ObjC_Class('UIView')
  new.backgroundColor("asdf", 42, "some_random_string") # This does not crash
  </code></pre>
  
  <p>But when I run:</p>
  
  <p><strong>Example #2</strong></p>
  
  <pre><code>from ObjC import ObjC_Class
  new = ObjC_Class('UIView')
  moreStuff = "some_random_string" # or "42" or [1,2,3] or anything else...
  new.backgroundColor("asdf", 42, moreStuff) # !!! This does crash
  </code></pre>
  
  <p>It crashes saying:</p>
  
  <pre><code>error: address doesn't contain a section that points to a section in a object file
  </code></pre>
  
  <p>I've seen this error when I try calling nonexistent functions but I can't imagine why the first would work but the second wouldn't.</p>
  
  <p>Here is the implementation of the ObjC_Class_msg_send function:</p>
  
  <pre><code>static PyObject* ObjC_Class_msg_send(PyObject *self, PyObject *args)
  {
      NSLog(@"Entering...");
      NSMutableArray *tmp = [[NSMutableArray alloc] init];
      for(int i=0;i&lt;PyTuple_Size(args);i++)
      {
          [tmp addObject:Py_to_ObjC(PyTuple_GetItem(args, i))];
      }
      NSLog(@"Object: %@, Method Name: %@, args: %@", ((ObjC_Class*)self)-&gt;object, methodName, tmp);
      methodName = @"";
      return PyString_FromString("Did it actually work!?!?!");
  }
  </code></pre>
  
  <p>When I run the example that passes a python variable into the function it crashes before ObjC_Class_msg_send is even called (but after ObjC_Class_getattro returns its value).</p>
  
  <p>(Oh and please excuse the sloppy code... I'm working on getting a simple proof-of-concept running before allocating too much time for this project)</p>
  
  <p>Something I failed to mention: My ObjC_Class has an element named 'object' which is of type 'id' which is what stores the reference to the Objective-C object that the Python object is representing...</p>
  
  <p>One more side note: I'm linking against Python 2.6(.3?) which has been mostly statically-linked</p>
  
  <p><strong>UPDATE</strong>
  I've managed to get it to stop crashing by <strike>defining fpFunc as static</strike> removing fpFunc altogether... I'm not even sure why I had it in there (stupid copy+paste...):</p>
  
  <pre><code>static PyObject * ObjC_Class_getattro(ObjC_Class *self, PyObject *name)
  {
      NSString *attrName = [NSString stringWithCString:PyString_AsString(name) encoding:NSUTF8StringEncoding];
  
      NSLog(@"Calling Object: %@", self-&gt;object);
      if([self-&gt;object respondsToSelector:NSSelectorFromString(attrName)])
      {
          methodName = attrName;
          //static PyObject* (*fpFunc)(PyObject*,PyObject*) = ObjC_Class_msg_send; // static now
          PyMethodDef methd = {[attrName UTF8String],ObjC_Class_msg_send,METH_VARARGS,[attrName UTF8String]};
          PyObject* pyName = PyString_FromString(methd.ml_name);
          PyObject* pyfoo = PyCFunction_NewEx(&amp;methd,(PyObject*)self,pyName);
          Py_DECREF(name);
  
          return pyfoo;
      }
      else
      {
          return name;
      }
  }
  </code></pre>
  
  <p>But... Now Python is throwing the error (when I pass a python variable in as an argument, i.e.: Example #2 above):</p>
  
  <pre><code>SystemError: Objects/methodobject.c:120: bad argument to internal function
  </code></pre>
  
  <p>:( I've never seen this one before...</p>