Commits

Ronald Oussoren committed b582f59

selector, struct-wrapper, struct-sockaddr cleanup

* Rename socketsupport.m to struct-sockaddr.m and
add header with prototypes (moved from pyobjc.h)

* Whitespace cleanup

* Use C99 struct initialization

* Some refcount cleanups (such as using Py_CLEAR)

* The function "objc.setSignatureForSelector" has been removed (and was deprecated
in 2.3), use the metadata system instead."

* The 'returnTypes' and 'argumentTypes' parameters for 'objc.selector' have
been removed (they were deprecated in version 2.5). These were an attempt
to use type encodings as used in :c:func:`Py_BuildValue` and AFAIK were never
used in real code.

  • Participants
  • Parent commits fc4a4c9

Comments (0)

Files changed (16)

pyobjc-core/Doc/api/module-objc.rst

                      (or 'void' when the function does not contain a return statement with a value).
    :param isClassMethod: Used to specify if a method is a class method (default is :data:`True` if *function* is a :class:`classmethod`
                      and :data:`False` otherwise)
-   :param returnType: Alternative method for specifying the method return type, using the syntax of :c:func:`Py_BuildValue`.
-   :param argumentTypes: Alternative method for specifying argument types, using the syntax of :c:func:`Py_BuildValue`.
    :param isRequired:    Specify if the method is required (defaults to :data:`True`), used in the definition of protocols.
 
-   The arguments *returnType* and *argumentTypes* are deprecated in PyObjC 2.5, they are confusing and can only specify
-   a subset of types.
-
    .. data:: callable
 
       Read-only property with access to the underlying callable (the *function* argument to the constructor).

pyobjc-core/Doc/metadata/manual.rst

 ---------------------
 
 One or the arguments for :func:`loadBundleFunctions`, :func:`loadFunctionList` and :func:`registerMetaDataForSelector`
-contains (or "is" for :func:`registerMetaDataForSelector`) a metadata dictionary containing information about function 
+contains (or "is" for :func:`registerMetaDataForSelector`) a metadata dictionary containing information about function
 and method interfaces that cannot be extract from a basic type signature for that function or method.
 
-Copies of these structures can be also retrieved at runtime using the *__metadata__()* method on both :class:`function` 
+Copies of these structures can be also retrieved at runtime using the *__metadata__()* method on both :class:`function`
 and :class:`selector` objects, which makes it possible to introspect the metadata information when needed.
 
 The metadata is a Python dictionary with a particular structure (all keys are optional):
 
 * *arguments*: A dictionary containing more information on arguments. The keys of this dictionary are integers
   with the argument offset (for methods index 0 is the first implicit argument, index 2 is the first argument that is
-  visible in a prototype). The values are metadata dictionaries for the arguments and are decribed 
+  visible in a prototype). The values are metadata dictionaries for the arguments and are decribed
   :ref:`later on <manual-metadata-argument-metadata>`.
 
   In metadata that is returned the *__metadata__()* method of :class:`function` and :class:`selector` objects the
 
 * *c_array_delimited_by_null*: If present and the value is :data:`True`, and the function is a variadic function, the
   variable part of the function argument list is a list of values where the last item of the list is a null value. All elements
-  of the list are the same type, that of the last type that is present in the prototype. 
+  of the list are the same type, that of the last type that is present in the prototype.
 
   In python the function is called with the additional arguments after the fixed arguments (just like in C), but without
   a null value at the end of the argument array.
-  
+
   An example of such a function is `execlp(3) <http://www.manpages.info/macosx/execl.3.html>`_
 
-* *c_array_length_in_arg*: If present and the value is an integer, and the function is a variadic function, the 
+* *c_array_length_in_arg*: If present and the value is an integer, and the function is a variadic function, the
   variable part of the function argument list is a list of values and the value for this key indicates which function
-  argument contains the length of that list. All elements of the list are the same type, that of the last type that 
+  argument contains the length of that list. All elements of the list are the same type, that of the last type that
   is present in the prototype.
 
   In python the function is called with the additional arguments after the fixed arguments (just like in C).
 Keys not listed above will be ignored by the bridge.
 
 .. note::
-   
+
    The bridge currently does not copy the metadata when you register it with the functions listed above. Don't rely
    on that behavior, it might change in a future release and changes to metadata dictionaries may or may not affect
    bridge behavior (basicly depending on if the change occurs before or after the bridge first uses the metadata)
 
 * When the type is :c:type:`id` and the Objective-C instance responds to the "-count" selector the length
   of the C array is the result of calling that selector.
- 
+
 * In all other cases the length cannot be calculated and the bridge raises an exception.
 
   .. _manual-metadata-argument-metadata:
 
   This key is always present in the metadata returned by the *__metadata__()* method.
 
-* *type_override*: A byte string with value :data:`_C_IN`, :data:`_C_OUT` or :data:`_C_INOUT` to indicate that the 
+* *type_override*: A byte string with value :data:`_C_IN`, :data:`_C_OUT` or :data:`_C_INOUT` to indicate that the
   argument is an input, output or input/output argument. Ignored unless the *type* is a pointer type that isn't a
   CoreFoundation instance.
 
 * *printf_format*: If present and the value is :data:`True` the argument value is a printf(3) style format string for
   a variadic function or method. Ignored unless the function or method actually is variadic.
 
-* *sel_of_type*: A byte string that describes the expected selector prototype for arguments of the :data:`_C_SEL`. 
+* *sel_of_type*: A byte string that describes the expected selector prototype for arguments of the :data:`_C_SEL`.
 
   Used by the decorator :func:`selectorFor` to calculate the signature of the decorated method.
 
-* *already_retained*: Value :data:`True` indicates that the return value, or a pass-by-reference output parameter, is 
-  returned to the caller with an increased reference count. An Objective-C caller will have to call "-retain" on the value 
+* *already_retained*: Value :data:`True` indicates that the return value, or a pass-by-reference output parameter, is
+  returned to the caller with an increased reference count. An Objective-C caller will have to call "-retain" on the value
   when the value is no longer used.
 
   Used by the bridge to correctly maintain the Objective-C reference count. Python users do not have to maintain the
   reference count themselfes.
 
-* *already_cfretained*: Value :data:`True` indicates that the return value, or a pass-by-reference output parameter, is 
-  returned to the caller with an increased reference count. An Objective-C caller will have to call "CFRelease" on the value 
+* *already_cfretained*: Value :data:`True` indicates that the return value, or a pass-by-reference output parameter, is
+  returned to the caller with an increased reference count. An Objective-C caller will have to call "CFRelease" on the value
   when the value is no longer used.
 
   Used by the bridge to correctly maintain the Objective-C reference count. Python users do not have to maintain the
   reference count themselfes.
 
-  .. note:: 
+  .. note::
 
-     Use either *already_retained*, or *already_cfretained* but not both. 
+     Use either *already_retained*, or *already_cfretained* but not both.
 
      The two different keys are present to be able to support Objective-C Garbage Collection: in process with GC enabled
      the CoreFoundation and Cocoa retain count APIs behave differently. Because GC is on the way out and PyObjC doesn't
      properly support GC anyway it is better to use *already_retained* where approprate and not use *already_cfretained*.
 
 
-* *c_array_delimited_by_null*: When :data:`True`, and the argument or return value *type* is a pointer type, the value 
-  is a C array with a null value at the end. Python users do not have to supply the null value on calls, and the bridge 
+* *c_array_delimited_by_null*: When :data:`True`, and the argument or return value *type* is a pointer type, the value
+  is a C array with a null value at the end. Python users do not have to supply the null value on calls, and the bridge
   will strip the null value in return values.
 
   When the *type_override* is :data:`_C_IN` or :data:`_C_INOUT` the input value must be a sequence of values (list, tuple,
   pointer should be passed to the Objective-C function or a buffer object of the appropriate structure, and with enough
   room to store the function output including the null delimiter.
 
-* *c_array_length_in_arg*: The argument or return value is a C array where the length of the array is specified in 
+* *c_array_length_in_arg*: The argument or return value is a C array where the length of the array is specified in
   another argument. Ignored when the *type* is not a pointer type. The value for this key is either a single integer, or
   two integers (for :data:`_C_INOUT` arguments).
 
 
   For results the bridge will return a value of :class:`varlist`.
 
-  For arguments with *type_override* value :data:`_C_IN` or :data:`_C_INOUT` the value for the arugment must be a Python sequence 
+  For arguments with *type_override* value :data:`_C_IN` or :data:`_C_INOUT` the value for the arugment must be a Python sequence
   and the bridge will allocate a C array that is long enough to contain all items of that sequence; alternatively the argument
-  can be a Python buffer object (simular to :data:`_C_OUT` arugments).  For :data:`_C_OUT` arguments the value for the argument 
-  must be either :data:`NULL` or a Python buffer object that will be passed to the function. 
+  can be a Python buffer object (simular to :data:`_C_OUT` arugments).  For :data:`_C_OUT` arguments the value for the argument
+  must be either :data:`NULL` or a Python buffer object that will be passed to the function.
 
-* *c_array_length_in_result*: Only valid for argument metadata. When the argument *type* is a pointer type and the 
+* *c_array_length_in_result*: Only valid for argument metadata. When the argument *type* is a pointer type and the
   *type_override* is :data:`_C_INOUT` or :data:`_C_OUT` the usuable length of the array is calculated from the return value.
 
   The size of the buffer that needs to be allocated is determined using one of the other *c_array...* keys in the metadata
   dictionary.
 
-* *null_accepted*: If :data:`True` and the argument is a pointer it is safe to pass a :data:`NULL` as the value. 
+* *null_accepted*: If :data:`True` and the argument is a pointer it is safe to pass a :data:`NULL` as the value.
   Defaults to :data:`True`.
 
   This key is not used in return value metadata.
 
-  .. note:: 
+  .. note::
      The metadata that is currently shipped with PyObjC does not contain *null_accepted* data. This means that the bridge
      won't check if it safe to pass :data:`NULL` as a value for pointer arguments, read the Cocoa documentation to check
      if passing :data:`NULL` is safe.
 
   When this value is :data:`True` the argument must be a global object that is annotated with the decorator
   :func:`callbackFor`. That decorator ensures that the C representation of the function is always present to ensure that
-  it is safe to store a reference on the Objective-C side of the bridge. 
+  it is safe to store a reference on the Objective-C side of the bridge.
 
 API description
 ---------------
       *bundle_path* must be an absolute path.
 
    .. note::
-      
+
       The current implementation loads *all* Objective-C classes into *module_globals*, as
       testing if a class is located in a specific bundle is fairly expensive and slowed down
       application initialization too much.
 
 Creating and registering types
 ..............................
-   
+
 .. function:: registerCFSignature(name, encoding, typeId[, tollfreeName])
 
    Register a CoreFoundation based type with the bridge. If *tollfreeName* is specified
-   the type is tollfree bridged to that Objective-C class. 
+   the type is tollfree bridged to that Objective-C class.
 
    The value of *typeId* is :data:`None` for tollfree bridged types, and the result
    of the "GetTypeID" function for the type for other types.
 
 .. function:: createOpaquePointerType(name, typestr, doc)
 
-   Return a wrapper type for opaque pointers ("handles") of a given type. 
-   The type will be registered with the bridge and will be used to wrap 
+   Return a wrapper type for opaque pointers ("handles") of a given type.
+   The type will be registered with the bridge and will be used to wrap
    values with the given type signature.
 
 
 
    * *name* is a string with the name of the structure, for example "NSPoint".
 
-   * *typestr* is the encoded type of the structure and can optionally 
+   * *typestr* is the encoded type of the structure and can optionally
      contain embedded field names
 
    * *fieldnames* is a list with the field names, the value can be :data:`None`
 
 .. function:: registerStructAlias(typestr, structType)
 
-   Tell the brige that structures with encoding *typestr* should also be 
+   Tell the brige that structures with encoding *typestr* should also be
    coverted to Python using *structType* (a type created using :func:`createStructType`).
 
    .. deprecated:: 2.5
 
 .. function:: createStructAlias(name, typestr, structType)
 
-   Tell the brige that structures with encoding *typestr* should also be 
-   coverted to Python using *structType* (a type created using 
+   Tell the brige that structures with encoding *typestr* should also be
+   coverted to Python using *structType* (a type created using
    :func:`createStructType`).
 
    This also adds a class method named *name* to :class:`objc.ivar`. This class
 
    Loads a list of global variables (constants) from a bundle and adds proxy objects for
    them to the *module_globals* dictionary. If *skip_undefined* is :data:`True` (the default)
-   the function will skip entries that don't refer to existing variables, otherwise it 
+   the function will skip entries that don't refer to existing variables, otherwise it
    raises an :exc:`error` exception for these variables.
 
    *variableInfo* is a sequence of variable descriptions. Every description is a tuple
 .. function:: loadSpecialVar(bundle, module_globals, typeid, name[, skip_undefined])
 
    This function loads a global variable from a bundle and adds it to the *module_globals*
-   dictionary. The variable should be a CoreFoundation based type, with a value that 
+   dictionary. The variable should be a CoreFoundation based type, with a value that
    is not a valid pointer.
 
    If *skip_undefined* is :data:`True` (the default) the function won't raise and exception
 
    Loads a list of functions from a bundle and adds proxy objects for
    them to the *module_globals* dictionary. If *skip_undefined* is :data:`True` (the default)
-   the function will skip entries that don't refer to existing functions, otherwise it 
+   the function will skip entries that don't refer to existing functions, otherwise it
    raises an :exc:`error` exception for these functions.
 
    *bundle* is either an *NSBundle* instance, or :data:`None`. When a bundle is specified
    any bundle (including the main program and Python extensions).
 
    *functionInfo* is a sequence of function descriptions. Every description is a tuple
-   of two or four elements: the function name (a string) and signature (a byte string) and 
+   of two or four elements: the function name (a string) and signature (a byte string) and
    optionally a value for the "\__doc__" attribute and a metadata dictionary.
 
    The structure of the metadata dictionary is descripted in the section `Metadata dictionaries`_.
    .. warning:: ``readonly==False`` is not supported at the moment.
 
    .. versionadded:: 3.0
-
-.. function:: setSignatureForSelector(class_name, selector, signature)
-
-   .. deprecated:: 2.3
-
-   Use the metadata system instead
-
-   Register a replacement signature for a specific selector. This can
-   be used to provide a more exact signature for a method.
-
-

pyobjc-core/Modules/objc/module.m

     return PyObjC_GetClassList();
 }
 
-PyDoc_STRVAR(set_signature_for_selector_doc,
-    "setSignatureForSelector(class_name, selector, signature) -> None\n"
-    "\n"
-    "Register a replacement signature for a specific selector. This \n"
-    "can be used to provide a more exact signature for a method.\n"
-    "\n"
-    "This function is deprecated, use the new metadata machinery.\n"
-    "");
-static PyObject*
-set_signature_for_selector(PyObject* self __attribute__((__unused__)), PyObject* args, PyObject* kwds)
-{
-static     char* keywords[] = { "class_name", "selector", "signature", NULL };
-    char* class_name;
-    char* selector;
-    char* signature;
-    SEL   sel;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "sss:setSignatureForSelector",
-            keywords, &class_name, &selector, &signature)) {
-        return NULL;
-    }
-
-    if (PyErr_WarnEx(PyExc_DeprecationWarning,
-        "Use the new metadata machinery", 1) < 0) {
-
-        return NULL;
-    }
-
-    sel = sel_getUid(selector);
-
-    if (ObjC_SignatureForSelector(class_name, sel, signature) < 0) {
-        return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
 PyDoc_STRVAR(setNSNumberWrapper_doc,
     "_setNSNumberWrapper(wrapper) -> None\n"
     "\n"
     { "currentBundle", (PyCFunction)currentBundle, METH_NOARGS, currentBundle_doc },
     { "getClassList", (PyCFunction)getClassList, METH_NOARGS, getClassList_doc },
     { "_setClassExtender", (PyCFunction)set_class_extender, METH_VARARGS|METH_KEYWORDS, set_class_extender_doc  },
-    { "setSignatureForSelector", (PyCFunction)set_signature_for_selector, METH_VARARGS|METH_KEYWORDS, set_signature_for_selector_doc },
     { "recycleAutoreleasePool", (PyCFunction)recycle_autorelease_pool, METH_VARARGS|METH_KEYWORDS, recycle_autorelease_pool_doc },
     { "removeAutoreleasePool", (PyCFunction)remove_autorelease_pool, METH_VARARGS|METH_KEYWORDS, remove_autorelease_pool_doc },
     { "_setNSNumberWrapper", (PyCFunction)setNSNumberWrapper, METH_VARARGS|METH_KEYWORDS, setNSNumberWrapper_doc },

pyobjc-core/Modules/objc/pyobjc.h

 #include "class-descriptor.h"
 #include "class-list.h"
 #include "struct-wrapper.h"
+#include "struct-sockaddr.h"
 #include "method-imp.h"
 #include "bundle-variables.h"
 #include "function.h"
 extern PyObject* PyObjC_NULL;
 extern PyObject* PyObjCInitNULL(void);
 
-/* socketsupport.m */
-int PyObjC_SockAddrFromPython(PyObject*, void*);
-PyObject* PyObjC_SockAddrToPython(void*);
-
 /* module.m */
 extern PyObject* PyObjC_TypeStr2CFTypeID;
 extern PyObject* PyObjC_AdjustSelf(PyObject* self);

pyobjc-core/Modules/objc/selector.h

 #define PyObjCSelector_kRETURNS_UNINITIALIZED 0x000010
 
 #define PyObjCSelector_HEAD \
-    PyObject_HEAD             \
-    const char*    sel_python_signature;  \
-    const char*     sel_native_signature; \
-    SEL        sel_selector;    \
-    PyObject*    sel_self;    \
-    Class        sel_class;    \
-    int        sel_flags;    \
+    PyObject_HEAD             			\
+    const char*    sel_python_signature;  	\
+    const char*     sel_native_signature;	\
+    SEL        sel_selector;    		\
+    PyObject*    sel_self;    			\
+    Class        sel_class;    			\
+    int        sel_flags;    			\
     PyObjCMethodSignature* sel_methinfo;
 
 
 #define PyObjCNativeSelector_Check(obj) PyObject_TypeCheck(obj, &PyObjCNativeSelector_Type)
 #define PyObjCPythonSelector_Check(obj) PyObject_TypeCheck(obj, &PyObjCPythonSelector_Type)
 
-PyObject* PyObjCSelector_Copy(PyObject* obj);
-const char* PyObjCSelector_Signature(PyObject* obj);
+extern PyObject* PyObjCSelector_Copy(PyObject* obj);
+extern const char* PyObjCSelector_Signature(PyObject* obj);
 #define PyObjCSelector_GetNativeSignature(obj) (((PyObjCSelector*)obj)->sel_native_signature)
-SEL   PyObjCSelector_GetSelector(PyObject* obj);
-int   PyObjCSelector_GetFlags(PyObject* obj);
-Class PyObjCSelector_GetClass(PyObject* obj);
-int   PyObjCSelector_Required(PyObject* obj);
-int   PyObjCSelector_IsClassMethod(PyObject* obj);
-int   PyObjCSelector_IsHidden(PyObject* obj);
-int ObjC_SignatureForSelector(char* class_name, SEL selector, char* signature);
-PyObjCMethodSignature* PyObjCSelector_GetMetadata(PyObject* _self);
-
-
-
-PyObject* PyObjCSelector_NewNative(Class class, SEL selector, const char* signature, int class_method) ;
-PyObject* PyObjCSelector_FindNative(PyObject* self, const char* name);
+extern SEL PyObjCSelector_GetSelector(PyObject* obj);
+extern int PyObjCSelector_GetFlags(PyObject* obj);
+extern Class PyObjCSelector_GetClass(PyObject* obj);
+extern int PyObjCSelector_Required(PyObject* obj);
+extern int PyObjCSelector_IsClassMethod(PyObject* obj);
+extern int PyObjCSelector_IsHidden(PyObject* obj);
+extern PyObjCMethodSignature* PyObjCSelector_GetMetadata(PyObject* _self);
+extern PyObject* PyObjCSelector_NewNative(Class class, SEL selector, const char* signature, int class_method) ;
+extern PyObject* PyObjCSelector_FindNative(PyObject* self, const char* name);
 
 #define PyObjCSelector_GET_CLASS(obj) (((PyObjCSelector*)(obj))->sel_class)
 #define PyObjCSelector_GET_SELECTOR(obj) (((PyObjCSelector*)(obj))->sel_selector)
 
-PyObject* PyObjCSelector_New(PyObject* callable, SEL selector, const char* signature, int class_method, Class class) ;
-SEL PyObjCSelector_DefaultSelector(const char* methname);
-
-
-PyObject*
-PyObjCSelector_FromFunction(
-    PyObject* pyname,
-    PyObject* callable,
-    PyObject* template_class,
-    PyObject* protocols);
-
+extern PyObject* PyObjCSelector_New(PyObject* callable, SEL selector, const char* signature, int class_method, Class class) ;
+extern SEL PyObjCSelector_DefaultSelector(const char* methname);
+extern PyObject* PyObjCSelector_FromFunction(PyObject* pyname, PyObject* callable, PyObject* template_class, PyObject* protocols);
 
 #endif /* PyObjC_SELECTOR_H */

pyobjc-core/Modules/objc/selector.m

 /*
  * Implementation of 'native' and 'python' selectors
- *
- * TODO:
- * - Maybe it is better to fold the three types into one, especially because
- *   only one of them is exposed to python code.
  */
 #include "pyobjc.h"
 
 
 #include <objc/Object.h>
 
-/*
- * First section deals with registering replacement signatures for methods.
- * This is meant to be used to add _C_IN, _C_OUT and _C_INOUT specifiers for
- * pass-by-reference parameters.
- *
- * We register class names because the actual class may not yet be available.
- * The list of replacements is not sorted in any way, it is expected to be
- * short and the list won't be checked very often.\
- *
- * Alternative implementation: { SEL: [ (class_name, signature), ... ], ... }
- */
-static PyObject* replacement_signatures = NULL;
-
-int
-ObjC_SignatureForSelector(char* class_name, SEL selector, char* signature)
-{
-    PyObject* replacement;
-    PyObject* name_str;
-    PyObject* selector_str;;
-    int r;
-
-    if (replacement_signatures == NULL) {
-        replacement_signatures = PyObjC_NewRegistry();
-        if (replacement_signatures == NULL) {
-            return -1;
-        }
-    }
-
-    replacement = PyBytes_FromString(signature);
-    if (replacement == NULL)  {
-        return -1;
-    }
-
-    name_str = PyText_FromString(class_name);
-    if (name_str == NULL)  {
-        Py_DECREF(replacement);
-        return -1;
-    }
-
-    selector_str = PyText_FromString(sel_getName(selector));
-    if (name_str == NULL)  {
-        Py_DECREF(replacement);
-        Py_DECREF(name_str);
-        return -1;
-    }
-
-    r = PyObjC_AddToRegistry(replacement_signatures, name_str, selector_str,
-            replacement);
-
-    Py_DECREF(replacement);
-    Py_DECREF(name_str);
-    Py_DECREF(selector_str);
-
-    return r;
-}
-
-static char*
-PyObjC_FindReplacementSignature(Class cls, SEL selector)
-{
-    PyObject* replacement;
-    char* result;
-
-
-    if (replacement_signatures == NULL) {
-        return NULL;
-    }
-
-    replacement = PyObjC_FindInRegistry(
-            replacement_signatures, cls, selector);
-    if (replacement == NULL) {
-        return NULL;
-    }
-
-    result = PyBytes_AsString(replacement);
-    Py_DECREF(replacement);
-
-    return result;
-}
+static Class Object_class = nil;
 
 static char* pysel_default_signature(PyObject* callable);
-
-/* Need to check instance-method implementation! */
-/* Maybe we can subclass 'PyMethod_Type' */
+static PyObject* pysel_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
 
 /*
  * Base type for objective-C selectors
             self->sel_selector,
             self->sel_python_signature,
             PyObjCNativeSelector_Check(self)
-            );
+        );
+
         if (self->sel_methinfo == NULL) return NULL;
 
         if (PyObjCPythonSelector_Check(_self)) {
             }
         }
     }
+
     return self->sel_methinfo;
 }
 
     PyObject* result = PyObjCMethodSignature_AsDict(PyObjCSelector_GetMetadata(self));
     int r;
 
-    if (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kCLASS_METHOD) {
-        r = PyDict_SetItemString(result, "classmethod", Py_True);
-    } else {
-        r = PyDict_SetItemString(result, "classmethod", Py_False);
-    }
+    r = PyDict_SetItemString(result, "classmethod",
+        (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kCLASS_METHOD) ? Py_True : Py_False);
     if (r == -1) {
         Py_DECREF(result);
         return NULL;
     }
 
-    if (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kHIDDEN) {
-        r = PyDict_SetItemString(result, "hidden", Py_True);
-    } else {
-        r = PyDict_SetItemString(result, "hidden", Py_False);
-    }
+    r = PyDict_SetItemString(result, "hidden",
+            (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kHIDDEN) ? Py_True : Py_False);
+
     if (r == -1) {
         Py_DECREF(result);
         return NULL;
     { 0, 0, 0, 0 }
 };
 
-static PyObject*
-pysel_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
 
 PyDoc_STRVAR(base_self_doc, "'self' object for bound methods, None otherwise");
+
 static PyObject*
 base_self(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 }
 
 PyDoc_STRVAR(base_signature_doc, "Objective-C signature for the method");
+
 static PyObject*
 base_signature(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 
 
 PyDoc_STRVAR(base_native_signature_doc, "original Objective-C signature for the method");
+
 static PyObject*
 base_native_signature(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 }
 
 PyDoc_STRVAR(base_hidden_doc, "If True the method is not directly accessible as an object attribute");
+
 static PyObject*
 base_hidden(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 }
 
 PyDoc_STRVAR(base_selector_doc, "Objective-C name for the method");
+
 static PyObject*
 base_selector(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 }
 
 PyDoc_STRVAR(base_name_doc, "Name for the method");
+
 static PyObject*
 base_name(PyObject* _self, void* closure __attribute__((__unused__)))
 {
     PyObjCSelector* self = (PyObjCSelector*)_self;
     char buf[2048];
     const char* name;
+
     name = PyObjC_SELToPythonName(
         self->sel_selector, buf, sizeof(buf));
-#if PY_MAJOR_VERSION == 2
-    return PyString_FromString(name);
-#else
-    return PyUnicode_FromString(name);
-#endif
+
+    return PyText_FromString(name);
 }
 
 PyDoc_STRVAR(base_class_doc, "Objective-C Class that defines the method");
     if (self->sel_class != nil) {
         return PyObjCClass_New(self->sel_class);
     }
+
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyDoc_STRVAR(base_class_method_doc,
     "True if this is a class method, False otherwise");
+
 static PyObject*
 base_class_method(PyObject* _self, void* closure __attribute__((__unused__)))
 {
 
 PyDoc_STRVAR(base_required_doc,
     "True if this is a required method, False otherwise");
+
 static PyObject*
 base_required(PyObject* _self, void* closure __attribute__((__unused__)))
 {
     return PyBool_FromLong(0 != (self->sel_flags & PyObjCSelector_kREQUIRED));
 }
 
-
-
 static PyGetSetDef base_getset[] = {
     {
         "isHidden",
     { 0, 0, 0, 0, 0 }
 };
 
-
 static void
 sel_dealloc(PyObject* object)
 {
     PyObjCSelector* self = (PyObjCSelector*)object;
-    Py_XDECREF(self->sel_methinfo);
-    self->sel_methinfo = NULL;
+    Py_CLEAR(self->sel_methinfo);
 
     PyMem_Free((char*)self->sel_python_signature);
     self->sel_python_signature = NULL;
         PyMem_Free((char*)self->sel_native_signature);
         self->sel_native_signature = NULL;
     }
-    if (self->sel_self) {
-        Py_DECREF(self->sel_self);
-        self->sel_self = NULL;
-    }
+    Py_CLEAR(self->sel_self);
     Py_TYPE(object)->tp_free(object);
 }
 
-#if 0
-/* This isn't needed and causes selectors to be classified as *data* instead
- * of *method* selectors.
- */
-static int
-base_descr_set(
-        PyObject* self __attribute__((__unused__)),
-        PyObject* obj __attribute__((__unused__)), PyObject* value)
-{
-    if (value == NULL) {
-        PyErr_SetString(PyExc_TypeError, "cannot delete a method");
-    } else {
-        /* Dummy, setattr of the class deals with this */
-        PyErr_SetString(PyExc_TypeError, "cannot change a method");
-    }
-    return -1;
-}
-#endif
-
-
 PyDoc_STRVAR(base_selector_type_doc,
 "selector(function, [, selector] [, signature] [, isClassMethod=0]\n"
-"    [, returnType] [, argumentTypes] [, isRequired=True]) -> selector\n"
+"    [, isRequired=True]) -> selector\n"
 "\n"
 "Return an Objective-C method from a function. The other arguments \n"
 "specify attributes of the Objective-C method.\n"
 "  be used to pass 'self'. This argument may be None when defining an\n"
 "  informal_protocol object. The function must not be a ``staticmethod``\n"
 "  instance. \n"
+"\n"
 "selector:\n"
 "  The name of the Objective-C method. The default value of this\n"
 "  attribute is the name of the function, with all underscores replaced\n"
 "  by colons.\n"
+"\n"
 "signature:\n"
 "  Method signature for the Objective-C method. This should be a raw\n"
 "  Objective-C method signature, including specifications for 'self' and\n"
 "  '_cmd'. The default value a signature that describes a method with\n"
 "  arguments of type 'id' and a return-value of the same type.\n"
-"argumentTypes, returnType:\n"
-"  Alternative method for specifying the method signature. returnType is\n"
-"  the return type and argumentTypes describes the list of arguments. The \n"
-"  returnType is optional and defaults to 'void' (e.g. no return value).\n"
-"  Both are specified using a subset of the Py_BuildValue syntax:\n"
-"  - s, z, S: an NSString (id)\n"
-"  - b: a byte (char)\n"
-"  - h: a short integer (short int)\n"
-"  - i: an integer (int)\n"
-"  - l: a long integer (long int)\n"
-"  - c: a single character (char)\n"
-"  - f: a single precision float (float)\n"
-"  - d: a double precision float (double)\n"
-"  - O: any object (id)\n"
-"  It is not allowed to specify both 'argumentTypes' and 'signature'\n"
+"\n"
 "isClassMethod:\n"
 "  True if the method is a class method, false otherwise. The default is \n"
 "  False, unless the function is an instance of ``classmethod``.\n"
+"\n"
 "isRequired:\n"
 "  True if this is a required method in an informal protocol, False\n"
 "  otherwise. The default value is 'True'. This argument is only used\n"
 );
 PyTypeObject PyObjCSelector_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "objc.selector",            /* tp_name */
-    sizeof(PyObjCSelector),            /* tp_basicsize */
-    0,                    /* tp_itemsize */
-    /* methods */
-    sel_dealloc,                 /* tp_dealloc */
-    0,                    /* tp_print */
-    0,                    /* tp_getattr */
-    0,                    /* tp_setattr */
-    0,                    /* tp_compare */
-    0,                    /* tp_repr */
-    0,                    /* tp_as_number */
-    0,                    /* tp_as_sequence */
-    0,                           /* tp_as_mapping */
-    0,                    /* tp_hash */
-    0,                    /* tp_call */
-    0,                    /* tp_str */
-    PyObject_GenericGetAttr,        /* tp_getattro */
-    0,                    /* tp_setattro */
-    0,                    /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,            /* tp_flags */
-     base_selector_type_doc,            /* tp_doc */
-     0,                    /* tp_traverse */
-     0,                    /* tp_clear */
-    0,                    /* tp_richcompare */
-    0,                    /* tp_weaklistoffset */
-    0,                    /* tp_iter */
-    0,                    /* tp_iternext */
-    sel_methods,                /* tp_methods */
-    0,                    /* tp_members */
-    base_getset,                /* tp_getset */
-    0,                    /* tp_base */
-    0,                    /* tp_dict */
-    0,                    /* tp_descr_get */
-#if 0
-    /* See above */
-    base_descr_set,                /* tp_descr_set */
-#else
-    0,                     /* tp_descr_set */
-#endif
-    0,                    /* tp_dictoffset */
-    0,                    /* tp_init */
-    0,                    /* tp_alloc */
-    pysel_new,                /* tp_new */
-    0,                        /* tp_free */
-    0,                    /* tp_is_gc */
-    0,                                      /* tp_bases */
-    0,                                      /* tp_mro */
-    0,                                      /* tp_cache */
-    0,                                      /* tp_subclasses */
-    0,                                      /* tp_weaklist */
-    0                                       /* tp_del */
-#if PY_VERSION_HEX >= 0x02060000
-    , 0                                     /* tp_version_tag */
-#endif
-
+    .tp_name        = "objc.selector",
+    .tp_basicsize   = sizeof(PyObjCSelector),
+    .tp_itemsize    = 0,
+    .tp_dealloc     = sel_dealloc,
+    .tp_getattro    = PyObject_GenericGetAttr,
+    .tp_flags       = Py_TPFLAGS_DEFAULT,
+    .tp_doc         = base_selector_type_doc,
+    .tp_methods     = sel_methods,
+    .tp_getset      = base_getset,
+    .tp_new         = pysel_new,
 };
 
 
     PyObject *rval;
     if (sel->sel_self == NULL) {
         rval = PyText_FromFormat("<unbound native-selector %s in %s>", sel_getName(sel->sel_selector), class_getName(sel->sel_class));
+
     } else {
 #if PY_MAJOR_VERSION == 2
         PyObject* selfrepr = PyObject_Repr(sel->sel_self);
         if (selfrepr == NULL) {
             return NULL;
         }
+
         if (!PyString_Check(selfrepr)) {
             Py_DECREF(selfrepr);
             return NULL;
         }
+
         rval = PyText_FromFormat("<native-selector %s of %s>", sel_getName(sel->sel_selector), PyString_AS_STRING(selfrepr));
         Py_DECREF(selfrepr);
+
 #else
         rval = PyUnicode_FromFormat("<native-selector %s of %R>", sel_getName(sel->sel_selector),
                     sel->sel_self);
 #endif
     }
+
     return rval;
 }
 
 {
     if (op == Py_EQ || op == Py_NE) {
         if (PyObjCNativeSelector_Check(a) && PyObjCNativeSelector_Check(b)) {
+
             PyObjCNativeSelector* sel_a = (PyObjCNativeSelector*)a;
             PyObjCNativeSelector* sel_b = (PyObjCNativeSelector*)b;
             int same = 1;
             if (op == Py_EQ) {
                 Py_INCREF(Py_False);
                 return Py_False;
+
             } else {
                 Py_INCREF(Py_False);
                 return Py_True;
             }
         }
+
     } else {
         PyErr_SetString(PyExc_TypeError, "Cannot use '<', '<=', '>=' and '>' with objc.selector");
         return NULL;
     }
 
     if (pyself == NULL) {
-        Py_ssize_t       argslen;
+        Py_ssize_t argslen;
         argslen = PyTuple_Size(args);
         if (argslen < 1) {
             PyErr_SetString(PyExc_TypeError,
                 "Missing argument: self");
             return NULL;
         }
+
         pyself = PyTuple_GET_ITEM(args, 0);
         if (pyself == NULL) {
             return NULL;
     if (self->sel_self != NULL) {
         pyres = res = execute((PyObject*)self, self->sel_self, args);
         if (pyres != NULL
-            && PyTuple_Check(pyres)
-            && PyTuple_GET_SIZE(pyres) >= 1
-            && PyTuple_GET_ITEM(pyres, 0) == pyself) {
+                && PyTuple_Check(pyres)
+                && PyTuple_GET_SIZE(pyres) >= 1
+                && PyTuple_GET_ITEM(pyres, 0) == pyself) {
+
             pyres = pyself;
         }
 
                 PyObjCObject_ClearObject(self->sel_self);
             }
         }
+
     } else {
         PyObject* arglist;
         PyObject* myClass;
 
         argslen = PyTuple_Size(args);
         arglist = PyTuple_New(argslen - 1);
+
         for (i = 1; i < argslen; i++) {
             PyObject* v = PyTuple_GET_ITEM(args, i);
             if (v == NULL) {
 #endif
             || (PyUnicode_Check(pyself) && class_isSubclassOf(self->sel_class, [NSString class]))
         )) {
+
             Py_DECREF(arglist);
             Py_DECREF(myClass);
             PyErr_Format(PyExc_TypeError,
         }
         Py_DECREF(myClass);
 
-
         pyres = res = execute((PyObject*)self, pyself, arglist);
         if (pyres != NULL
             && PyTuple_Check(pyres)
     } else {
         result->sel_native_signature = NULL;
     }
+
     result->sel_flags = meth->sel_flags;
     result->sel_class = meth->sel_class;
 
             meth->sel_call_func = PyObjC_FindCallFunc(PyObjCClass_GetClass(class_obj),
                 meth->sel_selector);
             Py_CLEAR(class_obj);
+
         } else {
             meth->sel_call_func = PyObjC_FindCallFunc(meth->sel_class,
                 meth->sel_selector);
 
 PyTypeObject PyObjCNativeSelector_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "objc.native_selector",            /* tp_name */
-    sizeof(PyObjCNativeSelector),        /* tp_basicsize */
-    0,                    /* tp_itemsize */
-    /* methods */
-    sel_dealloc,                /* tp_dealloc */
-    0,                    /* tp_print */
-    0,                    /* tp_getattr */
-    0,                    /* tp_setattr */
-    0,                    /* tp_compare */
-    objcsel_repr,                /* tp_repr */
-    0,                    /* tp_as_number */
-    0,                    /* tp_as_sequence */
-    0,                           /* tp_as_mapping */
-    0,                    /* tp_hash */
-    objcsel_call,                /* tp_call */
-    0,                    /* tp_str */
-    PyObject_GenericGetAttr,        /* tp_getattro */
-    0,                    /* tp_setattro */
-    0,                    /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,            /* tp_flags */
-     0,                    /* tp_doc */
-     0,                    /* tp_traverse */
-     0,                    /* tp_clear */
-    objcsel_richcompare,            /* tp_richcompare */
-    0,                    /* tp_weaklistoffset */
-    0,                    /* tp_iter */
-    0,                    /* tp_iternext */
-    0,                    /* tp_methods */
-    0,                    /* tp_members */
-    objcsel_getset,                /* tp_getset */
-    &PyObjCSelector_Type,            /* tp_base */
-    0,                    /* tp_dict */
-    objcsel_descr_get,            /* tp_descr_get */
-    0,                    /* tp_descr_set */
-    0,                    /* tp_dictoffset */
-    0,                    /* tp_init */
-    0,                    /* tp_alloc */
-    0,                    /* tp_new */
-    0,                        /* tp_free */
-    0,                    /* tp_is_gc */
-    0,                                      /* tp_bases */
-    0,                                      /* tp_mro */
-    0,                                      /* tp_cache */
-    0,                                      /* tp_subclasses */
-    0,                                      /* tp_weaklist */
-    0                                       /* tp_del */
-#if PY_VERSION_HEX >= 0x02060000
-    , 0                                     /* tp_version_tag */
-#endif
-
+    .tp_name = "objc.native_selector",
+    .tp_basicsize = sizeof(PyObjCNativeSelector),
+    .tp_itemsize = 0,
+    .tp_dealloc = sel_dealloc,
+    .tp_repr = objcsel_repr,
+    .tp_call = objcsel_call,
+    .tp_getattro = PyObject_GenericGetAttr,
+    .tp_flags = Py_TPFLAGS_DEFAULT,
+    .tp_richcompare = objcsel_richcompare,
+    .tp_getset = objcsel_getset,
+    .tp_base = &PyObjCSelector_Type,
+    .tp_descr_get = objcsel_descr_get,
 };
 
-
-
-static Class Object_class = nil;
-
 PyObject*
 PyObjCSelector_FindNative(PyObject* self, const char* name)
 {
-    volatile SEL   sel = PyObjCSelector_DefaultSelector(name);
+    SEL sel = PyObjCSelector_DefaultSelector(name);
     PyObject* retval;
 
     NSMethodSignature* methsig;
-    char  buf[2048]; /* 1024  XXX: yes, some signatures are actually longer than 1K bytes */
+    char buf[2048];
 
     if (PyObjCObject_Check(self)) {
         if (PyObjCClass_HiddenSelector((PyObject*)Py_TYPE(self), sel, NO)) {
                 "No attribute %s", name);
             return NULL;
         }
+
     } else {
         if (PyObjCClass_HiddenSelector(self, sel, YES)) {
             PyErr_Format(PyExc_AttributeError,
                 "No attribute %s", name);
             return NULL;
         }
+
         if (strcmp(class_getName(cls), "_NSZombie") == 0) {
             PyErr_Format(PyExc_AttributeError,
                 "No attribute %s", name);
                     "No attribute %s", name);
                 retval = NULL;
             }
+
         NS_HANDLER
             PyObjCErr_FromObjC(localException);
-            PyErr_Print();
             PyErr_Format(PyExc_AttributeError,
                 "No attribute %s", name);
             retval = NULL;
         NS_ENDHANDLER
 
         return retval;
+
     } else {
         PyErr_SetString(PyExc_RuntimeError,
             "PyObjCSelector_FindNative called on plain "
 {
     PyObjCNativeSelector* result;
     const char* native_signature = signature;
-    char* repl_sig;
-
-
-    repl_sig = PyObjC_FindReplacementSignature(class, selector);
-    if (repl_sig) {
-        signature = repl_sig;
-    }
 
     if (signature == NULL) {
         PyErr_Format(PyExc_RuntimeError,
         Py_DECREF(result);
         return NULL;
     }
+
     PyObjC_RemoveInternalTypeCodes((char*)result->sel_native_signature);
 
     result->sel_self = NULL;
     if (PyObjCPythonSelector_Check(callable)) {
         callable = ((PyObjCPythonSelector*)callable)->callable;
     }
+
     if (PyFunction_Check(callable)) {
         result->argcount = ((PyCodeObject*)PyFunction_GetCode(callable))->co_argcount;
-    }  else if (PyMethod_Check(callable)) {
+
+    } else if (PyMethod_Check(callable)) {
         if (PyMethod_Self(callable) == NULL) {
             result->argcount = ((PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable)))->co_argcount;
+
         } else {
             result->argcount = ((PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable)))->co_argcount - 1;
         }
+
     } else if (callable == Py_None) {
         result->argcount = 0;
 
     } else {
-        /* Should not happen... */
+        /* XXX: Should not happen... */
         result->argcount = 0;
         const char* s = sel_getName(selector);
         while ((s = strchr(s, ':')) != NULL) {
 }
 
 
-static PyObject* pysel_richcompare(PyObject* a, PyObject* b, int op)
+static PyObject*
+pysel_richcompare(PyObject* a, PyObject* b, int op)
 {
     if (op == Py_EQ || op == Py_NE) {
         if (PyObjCPythonSelector_Check(a) && PyObjCPythonSelector_Check(b)) {
     if (sel->sel_self == NULL) {
         if (sel->sel_class) {
             rval = PyText_FromFormat("<unbound selector %s of %s at %p>", sel_getName(sel->sel_selector), class_getName(sel->sel_class), sel);
+
         } else {
             rval = PyText_FromFormat("<unbound selector %s at %p>", sel_getName(sel->sel_selector), sel);
         }
+
     } else {
 #if PY_MAJOR_VERSION == 2
         PyObject* selfrepr = PyObject_Repr(sel->sel_self);
         if (selfrepr == NULL) {
             return NULL;
         }
+
         if (!PyString_Check(selfrepr)) {
             Py_DECREF(selfrepr);
             return NULL;
         }
+
         rval = PyText_FromFormat("<selector %s of %s>", sel_getName(sel->sel_selector), PyString_AS_STRING(selfrepr));
         Py_DECREF(selfrepr);
+
 #else
         rval = PyText_FromFormat("<selector %s of %R>", sel_getName(sel->sel_selector), sel->sel_self);
 #endif
         return args;
     }
 
-
     if (kwds && PyDict_Size(kwds) != 0) {
         /* XXX: we cannot do anything here without reimplementing Python's argument
          * matching code...
             }
             Py_INCREF(args);
             return args;
+
         } else {
             if ((PyTuple_Size(args) + (self->sel_self?1:0)) != (self->argcount - self->numoutput)) {
                 /* There's the wrong number of arguments */
     }
 }
 
+
 static PyObject*
 pysel_call(PyObject* _self, PyObject* args, PyObject* kwargs)
 {
                 PyErr_SetString(PyObjCExc_Error, "need self argument");
                 return NULL;
             }
+
             self_arg = PyTuple_GET_ITEM(args, 0);
+
             if (!PyObjCObject_Check(self_arg) && !PyObjCClass_Check(self_arg)) {
                 Py_DECREF(args);
                 PyErr_Format(PyExc_TypeError,
         if (actual_args == NULL) {
             return NULL;
         }
+
         Py_INCREF(self->sel_self);
         PyTuple_SetItem(actual_args, 0, self->sel_self);
+
         for (i = 0; i < argc; i++) {
             PyObject* v = PyTuple_GET_ITEM(args, i);
             Py_XINCREF(v);
             PyTuple_SET_ITEM(actual_args, i+1, v);
         }
-        result = PyObject_Call(self->callable,
-            actual_args, kwargs);
+
+        result = PyObject_Call(self->callable, actual_args, kwargs);
         Py_DECREF(actual_args);
         Py_DECREF(args);
     }
 
     if (PyFunction_Check(callable)) {
         func_code = (PyCodeObject*)PyFunction_GetCode(callable);
+
     } else if (PyMethod_Check(callable)) {
         func_code = (PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable));
+
     } else {
         PyErr_SetString(PyExc_TypeError,
             "Cannot calculate default method signature");
     } else if (PyString_Check(name)) {
         strncpy(buf, PyString_AS_STRING(name), sizeof(buf)-1);
 #endif
+
     } else  {
         return NULL;
     }
     return sel_registerName(buf);
 }
 
-static char
-pytype_to_objc(char val)
-{
-    switch (val) {
-    case 's': case 'z': case 'S': return _C_ID;
-    case 'b': return _C_CHR;
-    case 'h': return _C_SHT;
-    case 'i': return _C_INT;
-    case 'l': return _C_LNG;
-    case 'c': return _C_CHR;
-    case 'f': return _C_FLT;
-    case 'd': return _C_DBL;
-    case 'O': return _C_ID;
-    default:
-        PyErr_Format(PyExc_ValueError, "Unrecognized type character: %c", val);
-        return 0;
-    }
-}
-
-static char*
-python_signature_to_objc(char* rettype, char* argtypes, char* buf,
-    size_t buflen)
-{
-    char* result = buf;
-
-    if (buflen < 4) {
-        PyErr_SetString(PyExc_RuntimeError,
-            "Too small buffer for python_signature_to_objc");
-        return NULL;
-    }
-    if (rettype) {
-        if (*rettype == 0) {
-            *buf = _C_VOID;
-        } else if (rettype[1] != 0) {
-            PyErr_SetString(PyExc_ValueError,
-                "Only recognizing simple type specifiers");
-            return NULL;
-        }
-        *buf = pytype_to_objc(*rettype);
-        if (*buf == 0) return NULL;
-    } else {
-        *buf = _C_VOID;
-    }
-    buf++;
-
-    /* self and selector, required */
-    *buf++ = '@';
-    *buf++ = ':';
-
-    buflen -= 3;
-
-    if (!argtypes) {
-        *buf++ = '\0';
-        return result;
-    }
-
-    /* encode arguments */
-    while (buflen > 0 && *argtypes) {
-        *buf = pytype_to_objc(*argtypes++);
-        if (*buf == 0) return NULL;
-        buf++;
-        buflen --;
-    }
-
-    if (buflen == 0) {
-        PyErr_SetString(PyExc_RuntimeError,
-            "Too small buffer for python_signature_to_objc");
-        return NULL;
-    }
-    *buf = 0;
-    return result;
-}
-
-
-/* TODO: Check value of 'signature' */
 static PyObject*
 pysel_new(PyTypeObject* type __attribute__((__unused__)),
       PyObject* args, PyObject* kwds)
 {
-static    char*    keywords[] = { "function", "selector", "signature",
-                "isClassMethod", "argumentTypes",
-                "returnType", "isRequired", "isHidden", NULL };
+static char* keywords[] = { "function", "selector", "signature",
+                "isClassMethod", "isRequired", "isHidden", NULL };
     PyObjCPythonSelector* result;
     PyObject* callable;
-    char*     signature = NULL;
-    char*       argtypes = NULL;
-    char*     rettype = NULL;
-    char*      selector = NULL;
-    SEL       objc_selector;
-    int      class_method = 0;
-    char      signature_buf[1024];
-    int       required = 1;
-    int       hidden = 0;
+    char* signature = NULL;
+    char* selector = NULL;
+    SEL objc_selector;
+    int class_method = 0;
+    int required = 1;
+    int hidden = 0;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds,
-                "O|"Py_ARG_BYTES Py_ARG_BYTES"issii:selector",
+            "O|"Py_ARG_BYTES Py_ARG_BYTES"iii",
             keywords, &callable, &selector, &signature,
-            &class_method, &argtypes, &rettype, &required, &hidden)) {
+            &class_method, &required, &hidden)) {
         return NULL;
     }
 
-    if (signature != NULL && (rettype != NULL || argtypes != NULL)) {
-        PyErr_SetString(PyExc_TypeError,
-            "selector: provide either the objective-C signature, "
-            "or the python signature but not both");
-        return NULL;
-    }
-
-    if (rettype || argtypes) {
-        signature = python_signature_to_objc(rettype, argtypes,
-            signature_buf, sizeof(signature_buf));
-        if (signature == NULL) return NULL;
-    } else if (signature != NULL) {
+    if (signature != NULL) {
         /* Check if the signature string is valid */
         const char* cur;
 
         }
     }
 
-
     if (callable != Py_None && !PyCallable_Check(callable)) {
         PyErr_SetString(PyExc_TypeError,
             "argument 'method' must be callable");
 
     if (PyObject_TypeCheck(callable, &PyClassMethod_Type)) {
         /* Special treatment for 'classmethod' instances */
-        PyObject* tmp = PyObject_CallMethod(callable, "__get__", "OO",
-                Py_None, &PyList_Type);
+        PyObject* tmp = PyObject_CallMethod(callable, "__get__", "OO", Py_None, &PyList_Type);
         if (tmp == NULL) {
             return NULL;
         }
 #if PY_MAJOR_VERSION == 2
         callable = PyObject_GetAttrString(tmp, "im_func");
 #else
-        callable = PyObject_GetAttrString(tmp, "__funct__");
+        callable = PyObject_GetAttrString(tmp, "__func__");
 #endif
         Py_DECREF(tmp);
         if (callable == NULL) {
             return NULL;
         }
+
     } else {
         Py_INCREF(callable);
     }
     if (!result) {
         return NULL;
     }
+
     if (required) {
         result->sel_flags |= PyObjCSelector_kREQUIRED;
     }
+
     if (hidden) {
         result->sel_flags |= PyObjCSelector_kHIDDEN;
     }
             obj = PyObjCClass_ClassForMetaClass(obj);
         }
     }
+
     result = PyObject_New(PyObjCPythonSelector, &PyObjCPythonSelector_Type);
     result->sel_selector   = meth->sel_selector;
     result->sel_class   = meth->sel_class;
     result->sel_python_signature  = PyObjCUtil_Strdup(meth->sel_python_signature);
+
     if (result->sel_python_signature == NULL) {
         Py_DECREF(result);
         return NULL;
     }
+
     if (meth->sel_native_signature) {
         result->sel_native_signature  = PyObjCUtil_Strdup(meth->sel_native_signature);
         if (result->sel_native_signature == NULL) {
             Py_DECREF(result);
             return NULL;
         }
+
     } else {
         result->sel_native_signature = NULL;
     }
     result->sel_self       = obj;
     result->sel_flags = meth->sel_flags;
     result->callable = meth->callable;
+
     if (result->sel_self) {
         Py_INCREF(result->sel_self);
     }
+
     if (result->callable) {
         Py_INCREF(result->callable);
     }
+
     return (PyObject*)result;
 }
 
 static void
 pysel_dealloc(PyObject* obj)
 {
-    Py_DECREF(((PyObjCPythonSelector*)obj)->callable);
-    (((PyObjCPythonSelector*)obj)->callable) = NULL;
+    Py_CLEAR(((PyObjCPythonSelector*)obj)->callable);
     sel_dealloc(obj);
 }
 
 
 PyTypeObject PyObjCPythonSelector_Type = {
     PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "objc.python_selector",            /* tp_name */
-    sizeof(PyObjCPythonSelector),        /* tp_basicsize */
-    0,                    /* tp_itemsize */
-    /* methods */
-    pysel_dealloc,                 /* tp_dealloc */
-    0,                    /* tp_print */
-    0,                    /* tp_getattr */
-    0,                    /* tp_setattr */
-    0,                    /* tp_compare */
-    pysel_repr,                /* tp_repr */
-    0,                    /* tp_as_number */
-    0,                    /* tp_as_sequence */
-    0,                           /* tp_as_mapping */
-    pysel_hash,                /* tp_hash */
-    pysel_call,                /* tp_call */
-    0,                    /* tp_str */
-    PyObject_GenericGetAttr,        /* tp_getattro */
-    0,                    /* tp_setattro */
-    0,                    /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT,            /* tp_flags */
-     0,                    /* tp_doc */
-     0,                    /* tp_traverse */
-     0,                    /* tp_clear */
-    pysel_richcompare,            /* tp_richcompare */
-    0,                    /* tp_weaklistoffset */
-    0,                    /* tp_iter */
-    0,                    /* tp_iternext */
-    0,                    /* tp_methods */
-    0,                    /* tp_members */
-    pysel_getset,                /* tp_getset */
-    &PyObjCSelector_Type,            /* tp_base */
-    0,                    /* tp_dict */
-    pysel_descr_get,            /* tp_descr_get */
-    0,                    /* tp_descr_set */
-    0,                    /* tp_dictoffset */
-    0,                    /* tp_init */
-    0,                    /* tp_alloc */
-    0,                    /* tp_new */
-    0,                        /* tp_free */
-    0,                    /* tp_is_gc */
-    0,                                      /* tp_bases */
-    0,                                      /* tp_mro */
-    0,                                      /* tp_cache */
-    0,                                      /* tp_subclasses */
-    0,                                      /* tp_weaklist */
-    0                                       /* tp_del */
-#if PY_VERSION_HEX >= 0x02060000
-    , 0                                     /* tp_version_tag */
-#endif
-
+    .tp_name        = "objc.python_selector",
+    .tp_basicsize   = sizeof(PyObjCPythonSelector),
+    .tp_itemsize    = 0,
+    .tp_dealloc     = pysel_dealloc,
+    .tp_repr        = pysel_repr,
+    .tp_hash        = pysel_hash,
+    .tp_call        = pysel_call,
+    .tp_getattro    = PyObject_GenericGetAttr,
+    .tp_flags       = Py_TPFLAGS_DEFAULT,
+    .tp_richcompare = pysel_richcompare,
+    .tp_getset      = pysel_getset,
+    .tp_base        = &PyObjCSelector_Type,
+    .tp_descr_get   = pysel_descr_get,
 };
 
 const char* PyObjCSelector_Signature(PyObject* obj)
         PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector");
         return NULL;
     }
+
     return ((PyObjCNativeSelector*)sel)->sel_class;
 }
 
         PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector");
         return NULL;
     }
+
     return ((PyObjCSelector*)sel)->sel_selector;
 }
 
 static const char*
 find_protocol_signature(PyObject* protocols, SEL selector, int is_class_method)
 {
-    Py_ssize_t len;
     Py_ssize_t i;
     PyObject* proto;
     PyObject* info;
     }
 
     /* First try the explicit protocol definitions */
-    len = PyList_GET_SIZE(protocols);
-    for (i = 0; i < len; i++) {
+    for (i = 0; i < PyList_GET_SIZE(protocols); i++) {
         proto = PyList_GET_ITEM(protocols, i);
         if (proto == NULL) {
             PyErr_Clear();
             continue;
         }
+        Py_INCREF(proto);
 
         if (PyObjCFormalProtocol_Check(proto)) {
             const char* signature;
                     proto, selector, is_class_method
             );
             if (signature != NULL) {
+                Py_DECREF(proto);
                 return (char*)signature;
             }
         }
 
         info = PyObjCInformalProtocol_FindSelector(proto, selector, is_class_method);
+        Py_DECREF(proto);
         if (info != NULL) {
             return PyObjCSelector_Signature(info);
         }
         if (PyList_Append(protocols, proto) < 0) {
             return NULL;
         }
-        Py_INCREF(proto);
         return PyObjCSelector_Signature(info);
     }
 
     PyObject* template_class,
     PyObject* protocols)
 {
-    SEL      selector;
-    Method    meth;
-    int       is_class_method = 0;
-    Class     oc_class = PyObjCClass_GetClass(template_class);
+    SEL selector;
+    Method meth;
+    int is_class_method = 0;
+    Class oc_class = PyObjCClass_GetClass(template_class);
     PyObject* value;
     PyObject* super_sel;
 
         return NULL;
     }
 
-
     if (PyObjCPythonSelector_Check(callable)) {
         PyObjCPythonSelector* result;
 
             return NULL;
         }
         result->sel_native_signature = NULL;
-        result->sel_self       = NULL;
+        result->sel_self = NULL;
         result->sel_flags = ((PyObjCPythonSelector*)callable)->sel_flags;
         result->callable = ((PyObjCPythonSelector*)callable)->callable;
         if (result->callable) {
     if (!PyFunction_Check(callable) && !PyMethod_Check(callable) &&
         (Py_TYPE(callable) != &PyClassMethod_Type)) {
 
-        PyErr_SetString(PyExc_TypeError,
-                "expecting function, method or classmethod");
+        PyErr_SetString(PyExc_TypeError, "expecting function, method or classmethod");
         return NULL;
     }
 
-
     if (Py_TYPE(callable) == &PyClassMethod_Type) {
         /*
          * This is a 'classmethod' or 'staticmethod'. 'classmethods'
             selector = PyObjCSelector_DefaultSelector(
                     PyString_AsString(pyname));
 #endif
+
         } else {
             PyErr_SetString(PyExc_TypeError, "Function name is not a string");
             return NULL;
         }
+
     } else if (PyUnicode_Check(pyname)) {
         PyObject* bytes = PyUnicode_AsEncodedString(pyname, NULL, NULL);
+
         if (bytes == NULL) {
             return NULL;
         }
+
         selector = PyObjCSelector_DefaultSelector(
                 PyBytes_AsString(bytes));
         Py_DECREF(bytes);
         selector = PyObjCSelector_DefaultSelector(
             PyString_AS_STRING(pyname));
 #endif
+
     } else {
         PyErr_SetString(PyExc_TypeError,
             "method name must be a string");
     /* XXX: This seriously fails if a class method has a different signature
      * than an instance method of the same name!
      *
-     *
      * We eagerly call PyObjCClass_FindSelector because some ObjC
      * classes are not fully initialized until they are actually used,
      * and the code below doesn't seem to count but PyObjCClass_FindSelector
 
     if (is_class_method) {
         meth = class_getClassMethod(oc_class, selector);
+
     } else {
         meth = class_getInstanceMethod(oc_class, selector);
 
         if (!meth && !sel_isEqual(selector, @selector(copyWithZone:)) && !sel_isEqual(selector, @selector(mutableCopyWithZone:))) {
-                /* Look for a classmethod, but don't do that for copyWithZone:
+            /* Look for a classmethod, but don't do that for copyWithZone:
              * because that method is commonly defined in Python, and
              * overriding "NSObject +copyWithZone:" is almost certainly
              * not the intended behaviour.
         }
 
         value = PyObjCSelector_New(
-            callable,
-            selector,
-            typestr,
-            is_class_method,
+            callable, selector,
+            typestr, is_class_method,
             oc_class);
         Py_XDECREF(super_sel);
+
     } else {
         const char* signature = NULL;
 
         if (protocols != NULL) {
             signature = find_protocol_signature(
                     protocols, selector, is_class_method);
+
             if (signature == NULL && PyErr_Occurred()) {
                 return NULL;
             }
             is_class_method,
             oc_class);
     }
+
     if (PyObjCClass_HiddenSelector(template_class, selector, PyObjCSelector_IsClassMethod(value))) {
         ((PyObjCSelector*)value)->sel_flags |= PyObjCSelector_kHIDDEN;
     }
 {
     if (PyObjCPythonSelector_Check(selector)) {
         return pysel_descr_get(selector, NULL, NULL);
+
     } else if (PyObjCNativeSelector_Check(selector)) {
         return objcsel_descr_get(selector, NULL, NULL);
+
     } else {
         PyErr_SetString(PyExc_TypeError, "copy non-selector");
         return NULL;

pyobjc-core/Modules/objc/socketsupport.m

-/*
- * Converting socketaddresses to/from Python in a way that is compatible with
- * the socket module.
- *
- * This code reimplements parts of the socket module, sadly enough the socket
- * module doesn't have enough of a public C API to do this otherwise.
- */
-
-#include "pyobjc.h"
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-static PyObject* socket_error = NULL;
-static PyObject* socket_gaierror = NULL;
-
-static int
-setup_exceptions(void)
-{
-    PyObject* mod;
-
-    mod = PyImport_ImportModule("socket");
-    if (mod == NULL) {
-        return -1;
-    }
-
-    Py_XDECREF(socket_error);
-    socket_error = PyObject_GetAttrString(mod, "error");
-    if (socket_error == NULL) {
-        Py_DECREF(mod);
-        return -1;
-    }
-
-    Py_XDECREF(socket_gaierror);
-    socket_gaierror = PyObject_GetAttrString(mod, "gaierror");
-    if (socket_gaierror == NULL) {
-        Py_DECREF(mod);
-        return -1;
-    }
-
-    Py_DECREF(mod);
-    return 0;
-}
-
-static PyObject*
-set_gaierror(int error)
-{
-    if (error == EAI_SYSTEM) {
-        if (socket_error == NULL) {
-            if (setup_exceptions() == -1) {
-                return NULL;
-            }
-        }
-        PyErr_SetFromErrno(socket_error);
-        return NULL;
-    }
-
-    PyObject* v = Py_BuildValue("is", error, gai_strerror(error));
-    if (v != NULL) {
-        if (socket_gaierror == NULL) {
-            if (setup_exceptions() == -1) {
-                return NULL;
-            }
-        }
-        PyErr_SetObject(socket_gaierror, v);
-        Py_DECREF(v);
-        return NULL;
-    }
-    return NULL;
-}
-
-static PyObject*
-makeipaddr(struct sockaddr* addr, int addrlen)
-{
-    char buf[NI_MAXHOST];
-    int r;
-
-    r = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0,
-            NI_NUMERICHOST);
-    if (r) {
-        return set_gaierror(r);
-    }
-    return PyBytes_FromString(buf);
-}
-
-static int
-setipaddr(char* name, struct sockaddr* addr_ret, size_t addr_ret_size, int af)
-{
-    struct addrinfo hints, *res;
-    int error;
-    int d1, d2, d3, d4;
-    char ch;
-
-    memset((void *) addr_ret, '\0', sizeof(*addr_ret));
-    if (name[0] == '\0') {
-        int siz;
-        memset(&hints, 0, sizeof(hints));
-        hints.ai_family = af;
-        hints.ai_socktype = SOCK_DGRAM;    /*dummy*/
-        hints.ai_flags = AI_PASSIVE;
-        error = getaddrinfo(NULL, "0", &hints, &res);
-        /* We assume that those thread-unsafe getaddrinfo() versions
-           *are* safe regarding their return value, ie. that a
-           subsequent call to getaddrinfo() does not destroy the
-           outcome of the first call. */
-        if (error) {
-            set_gaierror(error);
-            return -1;
-        }
-        switch (res->ai_family) {
-        case AF_INET:
-            siz = 4;
-            break;
-        case AF_INET6:
-            siz = 16;
-            break;
-        default:
-            freeaddrinfo(res);
-            PyErr_SetString(socket_error,
-                "unsupported address family");
-            return -1;
-        }
-        if (res->ai_next) {
-            freeaddrinfo(res);
-            PyErr_SetString(socket_error,
-                "wildcard resolved to multiple address");
-            return -1;
-        }
-        if (res->ai_addrlen < addr_ret_size)
-            addr_ret_size = res->ai_addrlen;
-        memcpy(addr_ret, res->ai_addr, addr_ret_size);
-        freeaddrinfo(res);
-        return siz;
-    }
-    if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
-        struct sockaddr_in *sinaddr;
-        if (af != AF_INET && af != AF_UNSPEC) {
-            PyErr_SetString(socket_error,
-                "address family mismatched");
-            return -1;
-        }
-        sinaddr = (struct sockaddr_in *)addr_ret;
-        memset((void *) sinaddr, '\0', sizeof(*sinaddr));
-        sinaddr->sin_family = AF_INET;
-        sinaddr->sin_len = sizeof(*sinaddr);
-        sinaddr->sin_addr.s_addr = INADDR_BROADCAST;
-        return sizeof(sinaddr->sin_addr);
-    }
-    if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
-        0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
-        0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
-        struct sockaddr_in *sinaddr;
-        sinaddr = (struct sockaddr_in *)addr_ret;
-        sinaddr->sin_addr.s_addr = htonl(
-            ((long) d1 << 24) | ((long) d2 << 16) |
-            ((long) d3 << 8) | ((long) d4 << 0));
-        sinaddr->sin_family = AF_INET;
-        sinaddr->sin_len = sizeof(*sinaddr);
-        return 4;
-    }
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family = af;
-    error = getaddrinfo(name, NULL, &hints, &res);
-    if (error) {
-        set_gaierror(error);
-        return -1;
-    }
-    if (res->ai_addrlen < addr_ret_size)
-        addr_ret_size = res->ai_addrlen;
-    memcpy((char *) addr_ret, res->ai_addr, addr_ret_size);
-    freeaddrinfo(res);
-    switch (addr_ret->sa_family) {
-    case AF_INET:
-        return 4;
-    case AF_INET6:
-        return 16;
-    default:
-        PyErr_SetString(socket_error, "unknown address family");
-        return -1;
-    }
-}
-
-PyObject*
-PyObjC_SockAddrToPython(void* value)
-{
-    switch (((struct sockaddr*)value)->sa_family) {
-    case AF_INET:
-        {
-            struct sockaddr_in* a = (struct sockaddr_in*)value;
-            PyObject* addrobj = makeipaddr((struct sockaddr*)a, sizeof(*a));
-            if (addrobj != NULL) {
-                return Py_BuildValue("Ni", addrobj,
-                        ntohs(a->sin_port));
-            }
-            return NULL;
-        }
-
-    case AF_INET6:
-        {
-            struct sockaddr_in6* a = (struct sockaddr_in6*)value;
-            PyObject* addrobj = makeipaddr((struct sockaddr*)a, sizeof(*a));
-            if (addrobj != NULL) {
-                return Py_BuildValue("Niii", addrobj,
-                        ntohs(a->sin6_port),
-                        a->sin6_flowinfo,
-                        a->sin6_scope_id);
-            }
-            return NULL;
-        }
-
-    default:
-        PyErr_Format(PyExc_ValueError,
-            "Don't know how to convert sockaddr family %d",
-            ((struct sockaddr*)value)->sa_family
-        );
-        return NULL;
-    }
-}
-
-int
-PyObjC_SockAddrFromPython(PyObject* value, void* buffer)
-{
-    if (PyTuple_Size(value) == 2) {
-        /* IPv4 address */
-        struct sockaddr_in* addr = (struct sockaddr_in*)buffer;
-        char* host;
-        int port, result;
-
-        if (!PyArg_ParseTuple(value, "eti:getsockaddrarg",