1/*
2 * Implementation of 'native' and 'python' selectors
3 *
4 * TODO:
5 * - Maybe it is better to fold the three types into one, especially because
6 *   only one of them is exposed to python code.
7 */
8#include "pyobjc.h"
9
10#include "compile.h" /* from Python */
11#include "opcode.h"
12
13#include <objc/Object.h>
14
15/*
16 * First section deals with registering replacement signatures for methods.
17 * This is meant to be used to add _C_IN, _C_OUT and _C_INOUT specifiers for
18 * pass-by-reference parameters.
19 *
20 * We register class names because the actual class may not yet be available.
21 * The list of replacements is not sorted in any way, it is expected to be
22 * short and the list won't be checked very often.\
23 *
24 * Alternative implementation: { SEL: [ (class_name, signature), ... ], ... }
25 */
26static PyObject* replacement_signatures = NULL;
27
28int
29ObjC_SignatureForSelector(char* class_name, SEL selector, char* signature)
30{
31	PyObject* replacement;
32	PyObject* name_str;
33	PyObject* selector_str;;
34	int r;
35
36	if (replacement_signatures == NULL) {
37		replacement_signatures = PyObjC_NewRegistry();
38		if (replacement_signatures == NULL) {
39			return -1;
40		}
41	}
42
43	replacement = PyString_FromString(signature);
44	if (replacement == NULL)  {
45		return -1;
46	}
47
48	name_str = PyString_FromString(class_name);
49	if (name_str == NULL)  {
50		Py_DECREF(replacement);
51		return -1;
52	}
53
54	selector_str = PyString_FromString(sel_getName(selector));
55	if (name_str == NULL)  {
56		Py_DECREF(replacement);
57		Py_DECREF(name_str);
58		return -1;
59	}
60
61	r = PyObjC_AddToRegistry(replacement_signatures, name_str, selector_str,
62			replacement);
63
64	Py_DECREF(replacement);
65	Py_DECREF(name_str);
66	Py_DECREF(selector_str);
67
68	return r;
69}
70
71static char*
72PyObjC_FindReplacementSignature(Class cls, SEL selector)
73{
74	PyObject* replacement;
75	char* result;
76
77
78	if (replacement_signatures == NULL) {
79		return NULL;
80	}
81
82	replacement = PyObjC_FindInRegistry(
83			replacement_signatures, cls, selector);
84	if (replacement == NULL) {
85		return NULL;
86	}
87
88	result = PyString_AsString(replacement);
89	Py_DECREF(replacement);
90
91	return result;
92}
93
94static char* pysel_default_signature(PyObject* callable);
95
96/* Need to check instance-method implementation! */
97/* Maybe we can subclass 'PyMethod_Type' */
98
99/*
100 * Base type for objective-C selectors
101 *
102 * selectors are callable objects with the following attributes:
103 * - 'signature': The objective-C signature of the method
104 * - 'selector':  The name in the objective-C runtime
105 */
106
107PyObjCMethodSignature*
108PyObjCSelector_GetMetadata(PyObject* _self)
109{
110	PyObjCSelector* self = (PyObjCSelector*)_self;
111
112	if (self->sel_methinfo == NULL) {
113		self->sel_methinfo = PyObjCMethodSignature_ForSelector(
114			self->sel_class,
115			self->sel_selector,
116			self->sel_python_signature);
117		if (self->sel_methinfo == NULL) return NULL;
118
119		if (PyObjCPythonSelector_Check(_self)) {
120			Py_ssize_t i;
121
122			((PyObjCPythonSelector*)_self)->numoutput = 0;
123			for (i = 0; i < ((PyObjCPythonSelector*)_self)->sel_methinfo->ob_size; i++) {
124				if (((PyObjCPythonSelector*)_self)->sel_methinfo->argtype[i].type[0] == _C_OUT) {
125					((PyObjCPythonSelector*)_self)->numoutput ++;
126				}
127			}
128		}
129	}
130	return self->sel_methinfo;
131}
132
133
134PyDoc_STRVAR(sel_metadata_doc, "Return a dict that describes the metadata for this method, including metadata for the 2 hidden ObjC parameters (self and _sel) ");
135static PyObject* sel_metadata(PyObject* self)
136{
137	PyObject* result = PyObjCMethodSignature_AsDict(PyObjCSelector_GetMetadata(self));
138	int r;
139
140	if (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kCLASS_METHOD) {
141		r = PyDict_SetItemString(result, "classmethod", Py_True);
142	} else {
143		r = PyDict_SetItemString(result, "classmethod", Py_False);
144	}
145	if (r == -1) {
146		Py_DECREF(result);
147		return NULL;
148	}
149
150	if (((PyObjCSelector*)self)->sel_flags & PyObjCSelector_kRETURNS_UNINITIALIZED) {
151		r = PyDict_SetItemString(result, "return_uninitialized_object", Py_True);
152		if (r == -1) {
153			Py_DECREF(result);
154			return NULL;
155		}
156	}
157	return result;
158}
159
160static PyMethodDef sel_methods[] = {
161	{
162		  "__metadata__",
163	    	  (PyCFunction)sel_metadata,
164	          METH_NOARGS,
165		  sel_metadata_doc
166	},
167	{ 0, 0, 0, 0 }
168};
169
170static PyObject*
171pysel_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
172
173PyDoc_STRVAR(base_self_doc, "'self' object for bound methods, None otherwise");
174static PyObject*
175base_self(PyObject* _self, void* closure __attribute__((__unused__)))
176{
177	PyObjCSelector* self = (PyObjCSelector*)_self;
178	if (self->sel_self) {
179		Py_INCREF(self->sel_self);
180		return self->sel_self;
181	} else {
182		Py_INCREF(Py_None);
183		return Py_None;
184	}
185}
186
187PyDoc_STRVAR(base_signature_doc, "Objective-C signature for the method");
188static PyObject*
189base_signature(PyObject* _self, void* closure __attribute__((__unused__)))
190{
191	PyObjCSelector* self = (PyObjCSelector*)_self;
192	return PyString_FromString(self->sel_python_signature);
193}
194
195PyDoc_STRVAR(base_native_signature_doc, "original Objective-C signature for the method");
196static PyObject*
197base_native_signature(PyObject* _self, void* closure __attribute__((__unused__)))
198{
199	PyObjCSelector* self = (PyObjCSelector*)_self;
200	if (self->sel_native_signature == NULL) {
201		Py_INCREF(Py_None);
202		return Py_None;
203	}
204
205	return PyString_FromString(self->sel_native_signature);
206}
207
208static int
209base_signature_setter(PyObject* _self, PyObject* newVal, void* closure __attribute__((__unused__)))
210{
211	PyObjCNativeSelector* self = (PyObjCNativeSelector*)_self;
212	char* t;
213	if (!PyString_Check(newVal)) {
214		PyErr_SetString(PyExc_TypeError, "signature must be string");
215		return -1;
216	}
217
218	t = PyObjCUtil_Strdup(PyString_AsString(newVal));
219	if (t == NULL) {
220		PyErr_NoMemory();
221		return -1;
222	}
223
224	PyMem_Free(self->sel_python_signature);
225	self->sel_python_signature = t;
226	return 0;
227}
228
229PyDoc_STRVAR(base_selector_doc, "Objective-C name for the method");
230static PyObject*
231base_selector(PyObject* _self, void* closure __attribute__((__unused__)))
232{
233	PyObjCSelector* self = (PyObjCSelector*)_self;
234	return PyString_FromString(sel_getName(self->sel_selector));
235}
236
237PyDoc_STRVAR(base_class_doc, "Objective-C Class that defines the method");
238static PyObject*
239base_class(PyObject* _self, void* closure __attribute__((__unused__)))
240{
241	PyObjCNativeSelector* self = (PyObjCNativeSelector*)_self;
242	if (self->sel_class != nil) {
243		return PyObjCClass_New(self->sel_class);
244	}
245	Py_INCREF(Py_None);
246	return Py_None;
247}
248
249PyDoc_STRVAR(base_class_method_doc,
250	"True if this is a class method, False otherwise");
251static PyObject*
252base_class_method(PyObject* _self, void* closure __attribute__((__unused__)))
253{
254	PyObjCNativeSelector* self = (PyObjCNativeSelector*)_self;
255	return PyBool_FromLong(0 != (self->sel_flags & PyObjCSelector_kCLASS_METHOD));
256}
257
258PyDoc_STRVAR(base_required_doc,
259	"True if this is a required method, False otherwise");
260static PyObject*
261base_required(PyObject* _self, void* closure __attribute__((__unused__)))
262{
263	PyObjCNativeSelector* self = (PyObjCNativeSelector*)_self;
264	return PyBool_FromLong(0 != (self->sel_flags & PyObjCSelector_kREQUIRED));
265}
266
267
268
269
270static PyGetSetDef base_getset[] = {
271	{
272		"isRequired",
273		base_required,
274		0,
275		base_required_doc,
276		0
277	},
278	{
279		"isClassMethod",
280		base_class_method,
281		0,
282		base_class_method_doc,
283		0
284	},
285	{
286		"definingClass",
287		base_class,
288		0,
289		base_class_doc,
290		0
291	},
292	{
293		"signature",
294		base_signature,
295		base_signature_setter,
296		base_signature_doc,
297		0
298	},
299	{
300		"native_signature",
301		base_native_signature,
302		0,
303		base_native_signature_doc,
304		0
305	},
306	{
307		"self",
308		base_self,
309		0,
310		base_self_doc,
311		0
312	},
313	{
314		"selector",
315		base_selector,
316		0,
317		base_selector_doc,
318		0
319	},
320	{
321		"__name__",
322		base_selector,
323		0,
324		base_selector_doc,
325		0
326	},
327	{ 0, 0, 0, 0, 0 }
328};
329
330
331static void
332sel_dealloc(PyObject* object)
333{
334	PyObjCSelector* self = (PyObjCSelector*)object;
335	Py_XDECREF(self->sel_methinfo);
336	self->sel_methinfo = NULL;
337
338	PyMem_Free(self->sel_python_signature);
339	self->sel_python_signature = NULL;
340
341	if (self->sel_native_signature != NULL) {
342		PyMem_Free(self->sel_native_signature);
343		self->sel_native_signature = NULL;
344	}
345	if (self->sel_self) {
346		Py_DECREF(self->sel_self);
347		self->sel_self = NULL;
348	}
349	object->ob_type->tp_free(object);
350}
351
352static int
353base_descr_set(
354		PyObject* self __attribute__((__unused__)),
355		PyObject* obj __attribute__((__unused__)), PyObject* value)
356{
357	if (value == NULL) {
358		PyErr_SetString(PyExc_TypeError, "cannot delete a method");
359	} else {
360		/* Dummy, setattr of the class deals with this */
361		PyErr_SetString(PyExc_TypeError, "cannot change a method");
362	}
363	return -1;
364}
365
366
367PyDoc_STRVAR(base_selector_type_doc,
368"selector(function, [, selector] [, signature] [, isClassMethod=0]\n"
369"    [, returnType] [, argumentTypes] [, isRequired=True]) -> selector\n"
370"\n"
371"Return an Objective-C method from a function. The other arguments \n"
372"specify attributes of the Objective-C method.\n"
373"\n"
374"function:\n"
375"  A function object with at least one argument. The first argument will\n"
376"  be used to pass 'self'. This argument may be None when defining an\n"
377"  informal_protocol object. The function must not be a ``staticmethod``\n"
378"  instance. \n"
379"selector:\n"
380"  The name of the Objective-C method. The default value of this\n"
381"  attribute is the name of the function, with all underscores replaced\n"
382"  by colons.\n"
383"signature:\n"
384"  Method signature for the Objective-C method. This should be a raw\n"
385"  Objective-C method signature, including specifications for 'self' and\n"
386"  '_cmd'. The default value a signature that describes a method with\n"
387"  arguments of type 'id' and a return-value of the same type.\n"
388"argumentTypes, returnType:\n"
389"  Alternative method for specifying the method signature. returnType is\n"
390"  the return type and argumentTypes describes the list of arguments. The \n"
391"  returnType is optional and defaults to 'void' (e.g. no return value).\n"
392"  Both are specified using a subset of the Py_BuildValue syntax:\n"
393"  - s, z, S: an NSString (id)\n"
394"  - b: a byte (char)\n"
395"  - h: a short integer (short int)\n"
396"  - i: an integer (int)\n"
397"  - l: a long integer (long int)\n"
398"  - c: a single character (char)\n"
399"  - f: a single precision float (float)\n"
400"  - d: a double precision float (double)\n"
401"  - O: any object (id)\n"
402"  It is not allowed to specify both 'argumentTypes' and 'signature'\n"
403"isClassMethod:\n"
404"  True if the method is a class method, false otherwise. The default is \n"
405"  False, unless the function is an instance of ``classmethod``.\n"
406"isRequired:\n"
407"  True if this is a required method in an informal protocol, False\n"
408"  otherwise. The default value is 'True'. This argument is only used\n"
409"  when defining an 'informal_protocol' object.\n"
410);
411PyTypeObject PyObjCSelector_Type = {
412	PyObject_HEAD_INIT(&PyType_Type)
413	0,					/* ob_size */
414	"objc.selector",			/* tp_name */
415	sizeof(PyObjCSelector),			/* tp_basicsize */
416	0,					/* tp_itemsize */
417	/* methods */
418	sel_dealloc,	 			/* tp_dealloc */
419	0,					/* tp_print */
420	0,					/* tp_getattr */
421	0,					/* tp_setattr */
422	0,					/* tp_compare */
423	0,					/* tp_repr */
424	0,					/* tp_as_number */
425	0,					/* tp_as_sequence */
426	0,		       			/* tp_as_mapping */
427	0,					/* tp_hash */
428	0,					/* tp_call */
429	0,					/* tp_str */
430	PyObject_GenericGetAttr,		/* tp_getattro */
431	0,					/* tp_setattro */
432	0,					/* tp_as_buffer */
433	Py_TPFLAGS_DEFAULT,			/* tp_flags */
434 	base_selector_type_doc,			/* tp_doc */
435 	0,					/* tp_traverse */
436 	0,					/* tp_clear */
437	0,					/* tp_richcompare */
438	0,					/* tp_weaklistoffset */
439	0,					/* tp_iter */
440	0,					/* tp_iternext */
441	sel_methods,				/* tp_methods */
442	0,					/* tp_members */
443	base_getset,				/* tp_getset */
444	0,					/* tp_base */
445	0,					/* tp_dict */
446	0,					/* tp_descr_get */
447	base_descr_set,				/* tp_descr_set */
448	0,					/* tp_dictoffset */
449	0,					/* tp_init */
450	0,					/* tp_alloc */
451	pysel_new,				/* tp_new */
452	0,		        		/* tp_free */
453	0,					/* tp_is_gc */
454	0,                                      /* tp_bases */
455	0,                                      /* tp_mro */
456	0,                                      /* tp_cache */
457	0,                                      /* tp_subclasses */
458	0,                                      /* tp_weaklist */
459	0                                       /* tp_del */
460#if PY_VERSION_HEX >= 0x02060000
461	, 0                                     /* tp_version_tag */
462#endif
463
464};
465
466
467/*
468 * Selector type for 'native' selectors (that is, selectors that are not
469 * implemented as python methods)
470 */
471static PyObject*
472objcsel_repr(PyObject* _self)
473{
474	PyObjCNativeSelector* sel = (PyObjCNativeSelector*)_self;
475	PyObject *rval;
476	if (sel->sel_self == NULL) {
477		rval = PyString_FromFormat("<unbound native-selector %s in %s>", sel_getName(sel->sel_selector), class_getName(sel->sel_class));
478	} else {
479		PyObject* selfrepr = PyObject_Repr(sel->sel_self);
480		if (selfrepr == NULL) {
481			return NULL;
482		}
483		if (!PyString_Check(selfrepr)) {
484			Py_DECREF(selfrepr);
485			return NULL;
486		}
487		rval = PyString_FromFormat("<native-selector %s of %s>", sel_getName(sel->sel_selector), PyString_AS_STRING(selfrepr));
488		Py_DECREF(selfrepr);
489	}
490	return rval;
491}
492
493
494static PyObject*
495objcsel_call(PyObject* _self, PyObject* args, PyObject* kwds)
496{
497	PyObjCNativeSelector* self = (PyObjCNativeSelector*)_self;
498	PyObject* pyself = self->sel_self;
499	PyObjC_CallFunc execute = NULL;
500	PyObject* res;
501	PyObject* pyres;
502
503	if (kwds != NULL && PyObject_Size(kwds) != 0) {
504		PyErr_SetString(PyExc_TypeError,
505		    "Objective-C selectorrs don't support keyword arguments");
506		return NULL;
507	}
508
509	if (pyself == NULL) {
510		int       argslen;
511		argslen = PyTuple_Size(args);
512		if (argslen < 1) {
513			PyErr_SetString(PyExc_TypeError,
514				"Missing argument: self");
515			return NULL;
516		}
517		pyself = PyTuple_GET_ITEM(args, 0);
518		if (pyself == NULL) {
519			return NULL;
520		}
521	}
522
523	if (self->sel_call_func) {
524		execute = self->sel_call_func;
525	} else {
526		execute = PyObjC_FindCallFunc(
527				self->sel_class,
528				self->sel_selector);
529		if (execute == NULL) return NULL;
530		self->sel_call_func = execute;
531	}
532
533	if (self->sel_self != NULL) {
534		pyres = res = execute((PyObject*)self, self->sel_self, args);
535		if (pyres != NULL
536			&& PyTuple_Check(pyres)
537			&& PyTuple_GET_SIZE(pyres) > 1
538			&& PyTuple_GET_ITEM(pyres, 0) == pyself) {
539			pyres = pyself;
540		}
541
542		if (PyObjCObject_Check(self) && (((PyObjCObject*)self->sel_self)->flags & PyObjCObject_kUNINITIALIZED)) {
543			if (self->sel_self != pyres && !PyErr_Occurred()) {
544				PyObjCObject_ClearObject(pyself);
545			}
546		}
547	} else {
548		PyObject* arglist;
549		PyObject* myClass;
550		Py_ssize_t i;
551		Py_ssize_t argslen;
552
553		argslen = PyTuple_Size(args);
554		arglist = PyTuple_New(argslen - 1);
555		for (i = 1; i < argslen; i++) {
556			PyObject* v = PyTuple_GET_ITEM(args, i);
557			if (v == NULL) {
558				Py_DECREF(arglist);
559				return NULL;
560			}
561
562			PyTuple_SET_ITEM(arglist, i-1, v);
563			Py_INCREF(v);
564		}
565
566		myClass = PyObjCClass_New(self->sel_class);
567		if (!(PyObject_IsInstance(pyself, myClass)
568			|| (PyString_Check(pyself) && class_isSubclassOf(self->sel_class, [NSString class]))
569			|| (PyUnicode_Check(pyself) && class_isSubclassOf(self->sel_class, [NSString class]))
570		)) {
571			Py_DECREF(arglist);
572			Py_DECREF(myClass);
573			PyErr_Format(PyExc_TypeError,
574				"Expecting instance of %s as self, got one "
575				"of %s", class_getName(self->sel_class),
576				pyself->ob_type->tp_name);
577			return NULL;
578		}
579		Py_DECREF(myClass);
580
581
582		pyres = res = execute((PyObject*)self, pyself, arglist);
583		if (pyres != NULL
584			&& PyTuple_Check(pyres)
585			&& PyTuple_GET_SIZE(pyres) > 1
586			&& PyTuple_GET_ITEM(pyres, 0) == pyself) {
587			pyres = pyself;
588		}
589
590		Py_DECREF(arglist);
591	}
592
593	if (pyres && PyObjCObject_Check(pyres)) {
594		if (self->sel_flags & PyObjCSelector_kRETURNS_UNINITIALIZED) {
595			((PyObjCObject*)pyres)->flags |= PyObjCObject_kUNINITIALIZED;
596		} else if (((PyObjCObject*)pyself)->flags & PyObjCObject_kUNINITIALIZED) {
597			((PyObjCObject*)pyself)->flags &=
598				~PyObjCObject_kUNINITIALIZED;
599			if (self->sel_self && self->sel_self != pyres && !PyErr_Occurred()) {
600				PyObjCObject_ClearObject(self->sel_self);
601			}
602		}
603	}
604
605	return res;
606}
607
608static PyObject*
609objcsel_descr_get(PyObject* _self, PyObject* volatile obj, PyObject* class)
610{
611	PyObjCNativeSelector* meth = (PyObjCNativeSelector*)_self;
612	PyObjCNativeSelector* result;
613
614	if (meth->sel_self != NULL || obj == Py_None) {
615		Py_INCREF(meth);
616		return (PyObject*)meth;
617	}
618
619	if (class != nil && PyType_Check(class) && PyType_IsSubtype((PyTypeObject*)class, &PyObjCClass_Type)) {
620		class = PyObjCClass_ClassForMetaClass(class);
621	}
622
623	/* Bind 'self' */
624	if (meth->sel_flags & PyObjCSelector_kCLASS_METHOD) {
625		obj = class;
626	}
627	result = PyObject_New(PyObjCNativeSelector, &PyObjCNativeSelector_Type);
628	result->sel_selector   = meth->sel_selector;
629	result->sel_python_signature  = PyObjCUtil_Strdup(meth->sel_python_signature);
630	if (result->sel_python_signature == NULL) {
631		Py_DECREF(result);
632		return NULL;
633	}
634
635	if (meth->sel_native_signature != NULL) {
636		result->sel_native_signature = PyObjCUtil_Strdup(meth->sel_native_signature);
637		if (result->sel_native_signature == NULL) {
638			Py_DECREF(result);
639			return NULL;
640		}
641	} else {
642		result->sel_native_signature = NULL;
643	}
644	result->sel_flags = meth->sel_flags;
645	result->sel_class = meth->sel_class;
646
647	if (meth->sel_call_func == NULL) {
648		meth->sel_call_func = PyObjC_FindCallFunc(meth->sel_class,
649			meth->sel_selector);
650	}
651	result->sel_call_func = meth->sel_call_func;
652
653	result->sel_methinfo = PyObjCSelector_GetMetadata((PyObject*)meth);
654	if (result->sel_methinfo) {
655		Py_INCREF(result->sel_methinfo);
656	} else {
657		PyErr_Clear();
658	}
659
660	result->sel_self = obj;
661	if (result->sel_self) {
662		Py_INCREF(result->sel_self);
663	}
664
665	return (PyObject*)result;
666}
667
668
669
670PyTypeObject PyObjCNativeSelector_Type = {
671	PyObject_HEAD_INIT(&PyType_Type)
672	0,					/* ob_size */
673	"objc.native_selector",			/* tp_name */
674	sizeof(PyObjCNativeSelector),		/* tp_basicsize */
675	0,					/* tp_itemsize */
676	/* methods */
677	sel_dealloc,				/* tp_dealloc */
678	0,					/* tp_print */
679	0,					/* tp_getattr */
680	0,					/* tp_setattr */
681	0,					/* tp_compare */
682	objcsel_repr,				/* tp_repr */
683	0,					/* tp_as_number */
684	0,					/* tp_as_sequence */
685	0,		       			/* tp_as_mapping */
686	0,					/* tp_hash */
687	objcsel_call,				/* tp_call */
688	0,					/* tp_str */
689	PyObject_GenericGetAttr,		/* tp_getattro */
690	0,					/* tp_setattro */
691	0,					/* tp_as_buffer */
692	Py_TPFLAGS_DEFAULT,			/* tp_flags */
693 	0,					/* tp_doc */
694 	0,					/* tp_traverse */
695 	0,					/* tp_clear */
696	0,					/* tp_richcompare */
697	0,					/* tp_weaklistoffset */
698	0,					/* tp_iter */
699	0,					/* tp_iternext */
700	0,					/* tp_methods */
701	0,					/* tp_members */
702	0,					/* tp_getset */
703	&PyObjCSelector_Type,			/* tp_base */
704	0,					/* tp_dict */
705	objcsel_descr_get,			/* tp_descr_get */
706	0,					/* tp_descr_set */
707	0,					/* tp_dictoffset */
708	0,					/* tp_init */
709	0,					/* tp_alloc */
710	0,					/* tp_new */
711	0,		        		/* tp_free */
712	0,					/* tp_is_gc */
713	0,                                      /* tp_bases */
714	0,                                      /* tp_mro */
715	0,                                      /* tp_cache */
716	0,                                      /* tp_subclasses */
717	0,                                      /* tp_weaklist */
718	0                                       /* tp_del */
719#if PY_VERSION_HEX >= 0x02060000
720	, 0                                     /* tp_version_tag */
721#endif
722
723};
724
725
726
727static Class Object_class = nil;
728
729PyObject*
730PyObjCSelector_FindNative(PyObject* self, const char* name)
731{
732	volatile SEL   sel = PyObjCSelector_DefaultSelector(name);
733	PyObject* retval;
734
735	NSMethodSignature* methsig;
736	char  buf[1024];
737
738	if (Object_class == nil) {
739		Object_class = [Object class];
740	}
741
742	if (name[0] == '_' && name[1] == '_') {
743		/* No known Objective-C class has methods whose name
744		 * starts with '__' or '_:'. This allows us to shortcut
745		 * lookups for special names, which speeds up tools like
746		 * pydoc.
747		 */
748		PyErr_Format(PyExc_AttributeError,
749			"No attribute %s", name);
750		return NULL;
751	}
752
753	if (PyObjCClass_Check(self)) {
754		Class cls = PyObjCClass_GetClass(self);
755
756		if (!cls) {
757			PyErr_Format(PyExc_AttributeError,
758				"No attribute %s", name);
759			return NULL;
760		}
761		if (strcmp(class_getName(cls), "_NSZombie") == 0) {
762			PyErr_Format(PyExc_AttributeError,
763				"No attribute %s", name);
764			return NULL;
765		}
766
767		if (strcmp(class_getName(cls), "NSProxy") == 0) {
768			if (sel == @selector(methodSignatureForSelector:)) {
769				PyErr_Format(PyExc_AttributeError,
770					"Accessing NSProxy.%s is not supported",
771					name);
772				return NULL;
773			}
774		}
775
776		NS_DURING
777			if ([cls instancesRespondToSelector:sel]) {
778				methsig = [cls instanceMethodSignatureForSelector:sel];
779				retval = PyObjCSelector_NewNative(cls, sel,
780					PyObjC_NSMethodSignatureToTypeString(methsig, buf, sizeof(buf)), 0);
781			} else if ((cls != Object_class) && nil != (methsig = [(NSObject*)cls methodSignatureForSelector:sel])) {
782				retval = PyObjCSelector_NewNative(cls, sel,
783					PyObjC_NSMethodSignatureToTypeString(
784						methsig, buf, sizeof(buf)), 1);
785			} else {
786				PyErr_Format(PyExc_AttributeError,
787					"No attribute %s", name);
788				retval = NULL;
789			}
790		NS_HANDLER
791			PyErr_Format(PyExc_AttributeError,
792				"No attribute %s", name);
793			retval = NULL;
794
795		NS_ENDHANDLER
796
797		return retval;
798
799	} else if (PyObjCObject_Check(self)) {
800		id object;
801
802		object = PyObjCObject_GetObject(self);
803
804		if (nil != (methsig = [object methodSignatureForSelector:sel])){
805			PyObjCNativeSelector* res;
806
807			res =  (PyObjCNativeSelector*)PyObjCSelector_NewNative(
808				object_getClass(object), sel,
809				PyObjC_NSMethodSignatureToTypeString(methsig,
810					buf, sizeof(buf)), 0);
811			if (res != NULL) {
812				/* Bind the method to self */
813				res->sel_self = self;
814				Py_INCREF(res->sel_self);
815			}
816			return (PyObject*)res;
817		} else {
818			PyErr_Format(PyExc_AttributeError,
819				"No attribute %s", name);
820			return NULL;
821		}
822	} else {
823		PyErr_SetString(PyExc_RuntimeError,
824			"PyObjCSelector_FindNative called on plain "
825			"python object");
826		return NULL;
827	}
828}
829
830
831PyObject*
832PyObjCSelector_NewNative(Class class,
833			SEL selector, const char* signature, int class_method)
834{
835	PyObjCNativeSelector* result;
836	const char* native_signature = signature;
837	char* repl_sig;
838
839	repl_sig = PyObjC_FindReplacementSignature(class, selector);
840	if (repl_sig) {
841		signature = repl_sig;
842	}
843
844	result = PyObject_New(PyObjCNativeSelector, &PyObjCNativeSelector_Type);
845	if (result == NULL) return NULL;
846
847	result->sel_selector = selector;
848	result->sel_python_signature = PyObjCUtil_Strdup(signature);
849	result->sel_native_signature = PyObjCUtil_Strdup(native_signature);
850	if (result->sel_python_signature == NULL) {
851		Py_DECREF(result);
852		return NULL;
853	}
854	result->sel_self = NULL;
855	result->sel_class = class;
856	result->sel_call_func = NULL;
857	result->sel_methinfo = NULL;
858	result->sel_flags = 0;
859	if (class_method) {
860		result->sel_flags |= PyObjCSelector_kCLASS_METHOD;
861	}
862	if (sel_isEqual(selector, @selector(alloc)) || sel_isEqual(selector, @selector(allocWithZone:))) {
863		  result->sel_flags |= PyObjCSelector_kRETURNS_UNINITIALIZED;
864	}
865	return (PyObject*)result;
866}
867
868
869static char gSheetMethodSignature[] = { _C_VOID, _C_ID, _C_SEL, _C_ID, _C_INT, _C_PTR , _C_VOID, 0 };
870
871PyObject*
872PyObjCSelector_New(PyObject* callable,
873	SEL selector, char* signature, int class_method, Class cls)
874{
875	PyObjCPythonSelector* result;
876	if (signature == NULL) {
877		const char* selname = sel_getName(selector);
878		size_t len = strlen(selname);
879		if (len > 30 && strcmp(selname+len-30, "DidEnd:returnCode:contextInfo:") == 0) {
880			signature = PyObjCUtil_Strdup(gSheetMethodSignature);
881		} else {
882			signature = pysel_default_signature(callable);
883		}
884	} else {
885		signature = PyObjCUtil_Strdup(signature);
886	}
887	if (signature == NULL) return NULL;
888
889	result = PyObject_New(PyObjCPythonSelector, &PyObjCPythonSelector_Type);
890	if (result == NULL) return NULL;
891
892	result->sel_selector = selector;
893	result->sel_python_signature = signature;
894	result->sel_native_signature = PyObjCUtil_Strdup(signature);
895	if (result->sel_native_signature == NULL) {
896		Py_DECREF(result);
897		return NULL;
898	}
899	PyObjC_RemoveInternalTypeCodes(result->sel_native_signature);
900
901	result->sel_self = NULL;
902	result->sel_class = cls;
903	result->sel_flags = 0;
904	result->sel_methinfo = NULL; /* We might not know the class right now */
905
906	if (PyObjCPythonSelector_Check(callable)) {
907		callable = ((PyObjCPythonSelector*)callable)->callable;
908	}
909	if (PyFunction_Check(callable)) {
910		result->argcount = ((PyCodeObject*)PyFunction_GetCode(callable))->co_argcount;
911	}  else if (PyMethod_Check(callable)) {
912		if (PyMethod_Self(callable) == NULL) {
913			result->argcount = ((PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable)))->co_argcount;
914		} else {
915			result->argcount = ((PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable)))->co_argcount - 1;
916		}
917	} else if (callable == Py_None) {
918		result->argcount = 0;
919
920	} else {
921		/* Should not happen... */
922		result->argcount = -1;
923		abort();
924
925	}
926
927	if (class_method) {
928		result->sel_flags |= PyObjCSelector_kCLASS_METHOD;
929	}
930	if (sel_isEqual(selector, @selector(alloc)) || sel_isEqual(selector, @selector(allocWithZone:))) {
931		  result->sel_flags |= PyObjCSelector_kRETURNS_UNINITIALIZED;
932	}
933
934	result->callable = callable;
935	Py_INCREF(result->callable);
936
937	return (PyObject*)result;
938}
939
940
941/*
942 * Selector type for python selectors (that is, selectors that are
943 * implemented as python methods)
944 *
945 * This one can be allocated from python code.
946 */
947
948static PyObject*
949pysel_repr(PyObject* _self)
950{
951	PyObjCPythonSelector* sel = (PyObjCPythonSelector*)_self;
952	PyObject *rval;
953
954	if (sel->sel_self == NULL) {
955		if (sel->sel_class) {
956			rval = PyString_FromFormat("<unbound selector %s of %s at %p>", sel_getName(sel->sel_selector), class_getName(sel->sel_class), sel);
957		} else {
958			rval = PyString_FromFormat("<unbound selector %s at %p>", sel_getName(sel->sel_selector), sel);
959		}
960	} else {
961		PyObject* selfrepr = PyObject_Repr(sel->sel_self);
962		if (selfrepr == NULL) {
963			return NULL;
964		}
965		if (!PyString_Check(selfrepr)) {
966			Py_DECREF(selfrepr);
967			return NULL;
968		}
969		rval = PyString_FromFormat("<selector %s of %s>", sel_getName(sel->sel_selector), PyString_AS_STRING(selfrepr));
970		Py_DECREF(selfrepr);
971	}
972	return rval;
973}
974
975
976/*
977 * Calling the method from Python is sligtly complicated by the fact that
978 * output arguments are optionally present (both in the method signature
979 * and the actual argument list).
980 *
981 * pysel_call needs to compensate for this, which is done by this function.
982 */
983static PyObject*
984compensate_arglist(PyObject* _self, PyObject* args, PyObject* kwds)
985{
986	/* XXX: need to do a full metadata processing run here to get exactly the right
987	 * semantics, we also have to do a metadata run on the result!
988	 */
989	PyObjCPythonSelector* self = (PyObjCPythonSelector*)_self;
990	BOOL argsmatch;
991	Py_ssize_t i;
992	Py_ssize_t first_arg;
993
994	if (self->sel_methinfo == NULL) {
995		/* Make sure we actually have metadata */
996		PyObjCSelector_GetMetadata(_self);
997	}
998	if (self->numoutput == 0) {
999		Py_INCREF(args);
1000		return args;
1001	}
1002
1003
1004	if (kwds && PyDict_Size(kwds) != 0) {
1005		/* XXX: we cannot do anything here without reimplementing Python's argument
1006		 * matching code...
1007		 */
1008		Py_INCREF(args);
1009		return args;
1010	}
1011
1012	argsmatch = ((PyTuple_Size(args) + (self->sel_self?1:0)) == self->argcount);
1013
1014	first_arg = self->sel_self ? 0 : 1;
1015
1016	if (self->argcount == self->sel_methinfo->ob_size-1) { /* the selector has an implicit '_sel' argument as well */
1017		/* All arguments are present, including output arguments */
1018		if (argsmatch) {
1019			for (i = 2; i < self->sel_methinfo->ob_size; i++) {
1020				if (self->sel_methinfo->argtype[i].type[0] == _C_OUT) {
1021					PyObject* a = PyTuple_GET_ITEM(args, first_arg + i - 2);
1022					if (a != Py_None && a != PyObjC_NULL) {
1023						PyErr_Format(PyExc_TypeError,
1024							"argument %" PY_FORMAT_SIZE_T "d is an output argument but is passed a value other than None or objc.NULL (%s)",
1025							i-1-first_arg, PyObject_REPR(args));
1026						return NULL;
1027					}
1028				}
1029			}
1030			Py_INCREF(args);
1031			return args;
1032		} else {
1033			if ((PyTuple_Size(args) + (self->sel_self?1:0)) != (self->argcount - self->numoutput)) {
1034				/* There's the wrong number of arguments */
1035				PyErr_Format(PyExc_TypeError,
1036					"expecting %" PY_FORMAT_SIZE_T "d arguments, got %" PY_FORMAT_SIZE_T "d", self->argcount - (self->sel_self?1:0), PyTuple_Size(args));
1037				return NULL;
1038			}
1039
1040			PyObject* real_args;
1041			Py_ssize_t pyarg;
1042
1043
1044			real_args = PyTuple_New(self->argcount - (self->sel_self?1:0));
1045			if (real_args == NULL) {
1046				return NULL;
1047			}
1048
1049			pyarg = 0;
1050			if (self->sel_self == NULL) {
1051				pyarg = 1;
1052				PyTuple_SET_ITEM(real_args, 0, PyTuple_GET_ITEM(args, 0));
1053				Py_INCREF(PyTuple_GET_ITEM(args, 0));
1054			}
1055
1056			PyObjCMethodSignature* methinfo = PyObjCSelector_GetMetadata(_self);
1057			for (i = 2; i < methinfo->ob_size; i++) {
1058				if (methinfo->argtype[i].type[0] == _C_OUT) {
1059					PyTuple_SET_ITEM(real_args, i-2+first_arg, Py_None);
1060					Py_INCREF(Py_None);
1061				} else {
1062					PyTuple_SET_ITEM(real_args, i-2+first_arg, PyTuple_GET_ITEM(args, pyarg));
1063					Py_INCREF(PyTuple_GET_ITEM(args, pyarg));
1064					pyarg++;
1065				}
1066			}
1067
1068			return real_args;
1069		}
1070
1071	} else {
1072		/* Not all arguments are present, output arguments should
1073		 * be excluded.
1074		 */
1075		if (argsmatch) {
1076			Py_INCREF(args);
1077			return args;
1078		} else {
1079			if (PyTuple_Size(args) + (self->sel_self?1:0) != self->argcount + self->numoutput) {
1080				/* There's the wrong number of arguments */
1081				PyErr_Format(PyExc_TypeError,
1082					"expecting %" PY_FORMAT_SIZE_T "d arguments, got %" PY_FORMAT_SIZE_T "d", self->argcount - (self->sel_self?1:0), PyTuple_Size(args));
1083				return NULL;
1084			}
1085			PyObject* real_args;
1086			Py_ssize_t pyarg;
1087
1088			real_args = PyTuple_New(self->argcount - (self->sel_self?1:0));
1089			if (real_args == NULL) {
1090				return NULL;
1091			}
1092
1093			pyarg = 0;
1094			if (self->sel_self == NULL) {
1095				pyarg = 1;
1096				PyTuple_SET_ITEM(real_args, 0, PyTuple_GET_ITEM(args, 0));
1097				Py_INCREF(PyTuple_GET_ITEM(args, 0));
1098			}
1099
1100			PyObjCMethodSignature* methinfo = PyObjCSelector_GetMetadata(_self);
1101			for (i = 2; i < methinfo->ob_size; i++) {
1102				if (methinfo->argtype[i].type[0] != _C_OUT) {
1103					PyTuple_SET_ITEM(real_args, pyarg, PyTuple_GET_ITEM(args, i-2+first_arg));
1104					Py_INCREF(PyTuple_GET_ITEM(args, i-2+first_arg));
1105					pyarg++;
1106				}
1107			}
1108
1109			return real_args;
1110		}
1111	}
1112}
1113
1114static PyObject*
1115pysel_call(PyObject* _self, PyObject* args, PyObject* kwargs)
1116{
1117	PyObjCPythonSelector* self = (PyObjCPythonSelector*)_self;
1118	PyObject* result;
1119
1120	if (self->callable == NULL) {
1121		PyErr_Format(PyExc_TypeError,
1122			"Calling abstract methods with selector %s",
1123			sel_getName(self->sel_selector));
1124		return NULL;
1125	}
1126
1127	args = compensate_arglist(_self, args, kwargs);
1128	if (args == NULL) {
1129		return NULL;
1130	}
1131
1132	if (!PyMethod_Check(self->callable)) {
1133		if (self->sel_self == NULL) {
1134			PyObject* self_arg;
1135			if (PyTuple_Size(args) < 1) {
1136				Py_DECREF(args);
1137				PyErr_SetString(PyObjCExc_Error, "need self argument");
1138				return NULL;
1139			}
1140			self_arg = PyTuple_GET_ITEM(args, 0);
1141			if (!PyObjCObject_Check(self_arg) && !PyObjCClass_Check(self_arg)) {
1142				Py_DECREF(args);
1143				PyErr_Format(PyExc_TypeError,
1144					"Expecting an Objective-C class or "
1145					"instance as self, got a %s",
1146					self_arg->ob_type->tp_name);
1147				return NULL;
1148			}
1149		}
1150
1151		/* normal function code will perform other checks */
1152	}
1153
1154	/*
1155	 * Assume callable will check arguments
1156	 */
1157	if (self->sel_self == NULL) {
1158		result  = PyObject_Call(self->callable, args, kwargs);
1159		Py_DECREF(args);
1160
1161	} else {
1162		Py_ssize_t argc = PyTuple_Size(args);
1163		PyObject* actual_args = PyTuple_New(argc+1);
1164		Py_ssize_t i;
1165
1166		if (actual_args == NULL) {
1167			return NULL;
1168		}
1169		Py_INCREF(self->sel_self);
1170		PyTuple_SetItem(actual_args, 0, self->sel_self);
1171		for (i = 0; i < argc; i++) {
1172			PyObject* v = PyTuple_GET_ITEM(args, i);
1173			Py_XINCREF(v);
1174			PyTuple_SET_ITEM(actual_args, i+1, v);
1175		}
1176		result = PyObject_Call(self->callable,
1177			actual_args, kwargs);
1178		Py_DECREF(actual_args);
1179		Py_DECREF(args);
1180	}
1181
1182	if ( result && (self->sel_self) && (PyObjCObject_Check(self->sel_self)) &&
1183	     ((PyObjCObject*)self->sel_self)->flags & PyObjCObject_kUNINITIALIZED) {
1184
1185	     ((PyObjCObject*)self->sel_self)->flags &= ~PyObjCObject_kUNINITIALIZED;
1186
1187	}
1188
1189	return result;
1190}
1191
1192static char*
1193pysel_default_signature(PyObject* callable)
1194{
1195	PyCodeObject* func_code;
1196	Py_ssize_t    arg_count;
1197	char*         result;
1198	const unsigned char *buffer;
1199	Py_ssize_t    buffer_len;
1200	Py_ssize_t    i;
1201	int           was_none;
1202
1203	if (PyFunction_Check(callable)) {
1204		func_code = (PyCodeObject*)PyFunction_GetCode(callable);
1205	} else if (PyMethod_Check(callable)) {
1206		func_code = (PyCodeObject*)PyFunction_GetCode(PyMethod_Function(callable));
1207	} else {
1208		PyErr_SetString(PyExc_TypeError,
1209			"Cannot calculate default method signature");
1210		return NULL;
1211	}
1212
1213	arg_count = func_code->co_argcount;
1214	if (arg_count < 1) {
1215		PyErr_SetString(PyExc_TypeError,
1216			"Objective-C callable methods must take at least one argument");
1217		return NULL;
1218	}
1219
1220
1221	/* arguments + return-type + selector */
1222	result = PyMem_Malloc(arg_count+3);
1223	if (result == 0) {
1224		PyErr_NoMemory();
1225		return NULL;
1226	}
1227
1228	/* We want: v@:@... (final sequence of arg_count-1 @-chars) */
1229	memset(result, _C_ID, arg_count+2);
1230	result[0] = _C_VOID;
1231	result[2] = _C_SEL;
1232	result[arg_count+2] = '\0';
1233
1234	if (PyObject_AsReadBuffer(func_code->co_code, (const void **)&buffer, &buffer_len)) {
1235		return NULL;
1236	}
1237
1238	/*
1239	   Scan bytecode to find return statements.  If any non-bare return
1240	   statement exists, then set the return type to @ (id).
1241	*/
1242	was_none = 0;
1243	for (i=0; i<buffer_len; ++i) {
1244		int op = buffer[i];
1245		if (op == LOAD_CONST && buffer[i+1] == 0 && buffer[i+2] == 0) {
1246			was_none = 1;
1247		} else {
1248			if (op == RETURN_VALUE) {
1249				if (!was_none) {
1250					result[0] = _C_ID;
1251					break;
1252				}
1253			}
1254			was_none = 0;
1255		}
1256		if (op >= HAVE_ARGUMENT) {
1257			i += 2;
1258		}
1259	}
1260	return result;
1261}
1262
1263static SEL
1264pysel_default_selector(PyObject* callable)
1265{
1266	char buf[1024];
1267	char* cur;
1268	PyObject* name = PyObject_GetAttrString(callable, "__name__");
1269
1270	if (name == NULL) return NULL;
1271
1272	if (!PyString_Check(name)) {
1273		return NULL;
1274	}
1275
1276	strncpy(buf, PyString_AS_STRING(name), sizeof(buf)-1);
1277
1278	cur = strchr(buf, '_');
1279	while (cur != NULL) {
1280		*cur = ':';
1281		cur = strchr(cur, '_');
1282	}
1283	return sel_registerName(buf);
1284}
1285
1286SEL
1287PyObjCSelector_DefaultSelector(const char* methname)
1288{
1289	char buf[1024];
1290	char* cur;
1291	Py_ssize_t ln;
1292
1293	strncpy(buf, methname, sizeof(buf)-1);
1294	ln = strlen(buf);
1295
1296	cur = buf + ln;
1297	if (cur - buf > 3) {
1298		if (cur[-1] != '_') {
1299			return sel_registerName(buf);
1300		}
1301
1302		if (cur[-1] == '_' && cur[-2] == '_') {
1303			cur[-2] = '\0';
1304			if (PyObjC_IsPythonKeyword(buf)) {
1305				return sel_registerName(buf);
1306			}
1307			cur[-2] = '_';
1308		}
1309	}
1310
1311	/* Skip leading underscores, '_doFoo_' is probably '_doFoo:' in
1312	 * Objective-C, not ':doFoo:'.
1313	 *
1314	 * Also if the name starts and ends with two underscores, return
1315	 * it unmodified. This avoids mangling of Python's special methods.
1316	 *
1317	 * Both are heuristics and could be the wrong choice, but either
1318	 * form is very unlikely to exist in ObjC code.
1319	 */
1320	cur = buf;
1321
1322	if (ln > 5) {
1323		if (cur[0] == '_' && cur[1] == '_' &&
1324		    cur[ln-1] == '_' && cur[ln-2] == '_') {
1325			return sel_registerName(buf);
1326		}
1327	}
1328
1329	while (*cur == '_') {
1330		cur++;
1331	}
1332
1333	/* Replace all other underscores by colons */
1334	cur = strchr(cur, '_');
1335	while (cur != NULL) {
1336		*cur = ':';
1337		cur = strchr(cur, '_');
1338	}
1339	return sel_registerName(buf);
1340}
1341
1342static char
1343pytype_to_objc(char val)
1344{
1345	switch (val) {
1346	case 's': case 'z': case 'S': return _C_ID;
1347	case 'b': return _C_CHR;
1348	case 'h': return _C_SHT;
1349	case 'i': return _C_INT;
1350	case 'l': return _C_LNG;
1351	case 'c': return _C_CHR;
1352	case 'f': return _C_FLT;
1353	case 'd': return _C_DBL;
1354	case 'O': return _C_ID;
1355	default:
1356		PyErr_Format(PyExc_ValueError, "Unrecognized type character: %c", val);
1357		return 0;
1358	}
1359}
1360
1361static char*
1362python_signature_to_objc(char* rettype, char* argtypes, char* buf,
1363	size_t buflen)
1364{
1365	char* result = buf;
1366
1367	if (buflen < 4) {
1368		PyErr_SetString(PyExc_RuntimeError,
1369			"Too small buffer for python_signature_to_objc");
1370		return NULL;
1371	}
1372	if (rettype) {
1373		if (*rettype == 0) {
1374			*buf = _C_VOID;
1375		} else if (rettype[1] != 0) {
1376			PyErr_SetString(PyExc_ValueError,
1377				"Only recognizing simple type specifiers");
1378			return NULL;
1379		}
1380		*buf = pytype_to_objc(*rettype);
1381		if (*buf == 0) return NULL;
1382	} else {
1383		*buf = _C_VOID;
1384	}
1385	buf++;
1386
1387	/* self and selector, required */
1388	*buf++ = '@';
1389	*buf++ = ':';
1390
1391	buflen -= 3;
1392
1393	if (!argtypes) {
1394		*buf++ = '\0';
1395		return result;
1396	}
1397
1398	/* encode arguments */
1399	while (buflen > 0 && *argtypes) {
1400		*buf = pytype_to_objc(*argtypes++);
1401		if (*buf == 0) return NULL;
1402		buf++;
1403		buflen --;
1404	}
1405
1406	if (buflen == 0) {
1407		PyErr_SetString(PyExc_RuntimeError,
1408			"Too small buffer for python_signature_to_objc");
1409		return NULL;
1410	}
1411	*buf = 0;
1412	return result;
1413}
1414
1415
1416/* TODO: Check value of 'signature' */
1417static PyObject*
1418pysel_new(PyTypeObject* type __attribute__((__unused__)),
1419	  PyObject* args, PyObject* kwds)
1420{
1421static	char*	keywords[] = { "function", "selector", "signature",
1422				"isClassMethod", "argumentTypes",
1423				"returnType", "isRequired", NULL };
1424	PyObjCPythonSelector* result;
1425	PyObject* callable;
1426	char*     signature = NULL;
1427	char* 	  argtypes = NULL;
1428	char*     rettype = NULL;
1429	char*	  selector = NULL;
1430	SEL       objc_selector;
1431	int	  class_method = 0;
1432	char      signature_buf[1024];
1433	int       required = 1;
1434
1435	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ssissi:selector",
1436			keywords, &callable, &selector, &signature,
1437			&class_method, &argtypes, &rettype, &required)) {
1438		return NULL;
1439	}
1440
1441	if (signature != NULL && (rettype != NULL || argtypes != NULL)) {
1442		PyErr_SetString(PyExc_TypeError,
1443			"selector: provide either the objective-C signature, "
1444			"or the python signature but not both");
1445		return NULL;
1446	}
1447
1448	if (rettype || argtypes) {
1449		signature = python_signature_to_objc(rettype, argtypes,
1450			signature_buf, sizeof(signature_buf));
1451		if (signature == NULL) return NULL;
1452	} else if (signature != NULL) {
1453		/* Check if the signature string is valid */
1454		const char* cur;
1455
1456		cur = signature;
1457		while (*cur != '\0') {
1458			cur = PyObjCRT_SkipTypeSpec(cur);
1459			if (cur == NULL) {
1460				PyErr_SetString(
1461					PyExc_ValueError,
1462					"invalid signature");
1463				return NULL;
1464			}
1465		}
1466	}
1467
1468
1469	if (callable != Py_None && !PyCallable_Check(callable)) {
1470		PyErr_SetString(PyExc_TypeError,
1471			"argument 'method' must be callable");
1472		return NULL;
1473	}
1474
1475	if (PyObject_TypeCheck(callable, &PyClassMethod_Type)) {
1476		/* Special treatment for 'classmethod' instances */
1477		PyObject* tmp = PyObject_CallMethod(callable, "__get__", "OO",
1478				Py_None, &PyList_Type);
1479		if (tmp == NULL) {
1480			return NULL;
1481		}
1482
1483		if (PyFunction_Check(tmp)) {
1484			/* A 'staticmethod' instance, cannot convert */
1485			Py_DECREF(tmp);
1486			PyErr_SetString(PyExc_TypeError,
1487					"cannot use staticmethod as the "
1488					"callable for a selector.");
1489			return NULL;
1490		}
1491
1492		callable = PyObject_GetAttrString(tmp, "im_func");
1493		Py_DECREF(tmp);
1494		if (callable == NULL) {
1495			return NULL;
1496		}
1497	} else {
1498		Py_INCREF(callable);
1499	}
1500
1501	if (selector == NULL) {
1502		objc_selector = pysel_default_selector(callable);
1503	} else {
1504		objc_selector = sel_registerName(selector);
1505	}
1506
1507	result = (PyObjCPythonSelector*)PyObjCSelector_New(callable,
1508			objc_selector, signature, class_method, nil);
1509	Py_DECREF(callable);
1510	if (!result) {
1511		return NULL;
1512	}
1513	if (required) {
1514		result->sel_flags |= PyObjCSelector_kREQUIRED;
1515	}
1516	return (PyObject *)result;
1517}
1518
1519static PyObject*
1520pysel_descr_get(PyObject* _meth, PyObject* obj, PyObject* class)
1521{
1522	PyObjCPythonSelector* meth = (PyObjCPythonSelector*)_meth;
1523	PyObjCPythonSelector* result;
1524
1525	if (meth->sel_self != NULL || obj == Py_None) {
1526		Py_INCREF(meth);
1527		return (PyObject*)meth;
1528	}
1529
1530	/* Bind 'self' */
1531	if (meth->sel_flags & PyObjCSelector_kCLASS_METHOD) {
1532		obj = class;
1533		if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject*)obj, &PyObjCClass_Type)) {
1534			obj = PyObjCClass_ClassForMetaClass(obj);
1535		}
1536	}
1537	result = PyObject_New(PyObjCPythonSelector, &PyObjCPythonSelector_Type);
1538	result->sel_selector   = meth->sel_selector;
1539	result->sel_class   = meth->sel_class;
1540	result->sel_python_signature  = PyObjCUtil_Strdup(meth->sel_python_signature);
1541	if (result->sel_python_signature == NULL) {
1542		Py_DECREF(result);
1543		return NULL;
1544	}
1545	if (meth->sel_native_signature) {
1546		result->sel_native_signature  = PyObjCUtil_Strdup(meth->sel_native_signature);
1547		if (result->sel_native_signature == NULL) {
1548			Py_DECREF(result);
1549			return NULL;
1550		}
1551	} else {
1552		result->sel_native_signature = NULL;
1553	}
1554
1555	result->sel_methinfo = PyObjCSelector_GetMetadata((PyObject*)meth);
1556	Py_XINCREF(result->sel_methinfo);
1557	result->argcount = meth->argcount;
1558	result->numoutput = meth->numoutput;
1559
1560	result->sel_self       = obj;
1561	result->sel_flags = meth->sel_flags;
1562	result->callable = meth->callable;
1563	if (result->sel_self) {
1564		Py_INCREF(result->sel_self);
1565	}
1566	if (result->callable) {
1567		Py_INCREF(result->callable);
1568	}
1569	return (PyObject*)result;
1570}
1571
1572
1573static void
1574pysel_dealloc(PyObject* obj)
1575{
1576	Py_DECREF(((PyObjCPythonSelector*)obj)->callable);
1577	(((PyObjCPythonSelector*)obj)->callable) = NULL;
1578	sel_dealloc(obj);
1579}
1580
1581PyDoc_STRVAR(pysel_get_callable_doc,
1582"Returns the python 'function' that implements this method.\n"
1583"\n"
1584);
1585static PyObject*
1586pysel_get_callable(PyObject* _self, void* closure __attribute__((__unused__)))
1587{
1588	PyObjCPythonSelector* self = (PyObjCPythonSelector*)_self;
1589	Py_INCREF(self->callable);
1590	return self->callable;
1591}
1592
1593PyDoc_STRVAR(pysel_docstring_doc,
1594	"The document string for a method");
1595static PyObject*
1596pysel_docstring(PyObject* _self, void* closure __attribute__((__unused__)))
1597{
1598	PyObjCPythonSelector* self = (PyObjCPythonSelector*)_self;
1599
1600	PyObject* docstr = PyObject_GetAttrString(self->callable, "__doc__");
1601	return docstr;
1602}
1603
1604static PyGetSetDef pysel_getset[] = {
1605	{
1606		"callable",
1607		pysel_get_callable,
1608		0,
1609		pysel_get_callable_doc,
1610		0
1611	},
1612	{
1613		"__doc__",
1614		pysel_docstring,
1615		0,
1616		pysel_docstring_doc,
1617		0
1618	},
1619
1620	{
1621		NULL,
1622		NULL,
1623		NULL,
1624		NULL,
1625		0
1626	}
1627};
1628
1629PyTypeObject PyObjCPythonSelector_Type = {
1630	PyObject_HEAD_INIT(&PyType_Type)
1631	0,					/* ob_size */
1632	"objc.python_selector",			/* tp_name */
1633	sizeof(PyObjCPythonSelector),		/* tp_basicsize */
1634	0,					/* tp_itemsize */
1635	/* methods */
1636	pysel_dealloc,	 			/* tp_dealloc */
1637	0,					/* tp_print */
1638	0,					/* tp_getattr */
1639	0,					/* tp_setattr */
1640	0,					/* tp_compare */
1641	pysel_repr,				/* tp_repr */
1642	0,					/* tp_as_number */
1643	0,					/* tp_as_sequence */
1644	0,		       			/* tp_as_mapping */
1645	0,					/* tp_hash */
1646	pysel_call,				/* tp_call */
1647	0,					/* tp_str */
1648	PyObject_GenericGetAttr,		/* tp_getattro */
1649	0,					/* tp_setattro */
1650	0,					/* tp_as_buffer */
1651	Py_TPFLAGS_DEFAULT,			/* tp_flags */
1652 	0,					/* tp_doc */
1653 	0,					/* tp_traverse */
1654 	0,					/* tp_clear */
1655	0,					/* tp_richcompare */
1656	0,					/* tp_weaklistoffset */
1657	0,					/* tp_iter */
1658	0,					/* tp_iternext */
1659	0,					/* tp_methods */
1660	0,					/* tp_members */
1661	pysel_getset,				/* tp_getset */
1662	&PyObjCSelector_Type,			/* tp_base */
1663	0,					/* tp_dict */
1664	pysel_descr_get,			/* tp_descr_get */
1665	0,					/* tp_descr_set */
1666	0,					/* tp_dictoffset */
1667	0,					/* tp_init */
1668	0,					/* tp_alloc */
1669	0,					/* tp_new */
1670	0,		        		/* tp_free */
1671	0,					/* tp_is_gc */
1672	0,                                      /* tp_bases */
1673	0,                                      /* tp_mro */
1674	0,                                      /* tp_cache */
1675	0,                                      /* tp_subclasses */
1676	0,                                      /* tp_weaklist */
1677	0                                       /* tp_del */
1678#if PY_VERSION_HEX >= 0x02060000
1679	, 0                                     /* tp_version_tag */
1680#endif
1681
1682};
1683
1684char* PyObjCSelector_Signature(PyObject* obj)
1685{
1686	return ((PyObjCSelector*)obj)->sel_python_signature;
1687}
1688
1689Class
1690PyObjCSelector_GetClass(PyObject* sel)
1691{
1692	if (!PyObjCNativeSelector_Check(sel)) {
1693		PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector");
1694		return NULL;
1695	}
1696	return ((PyObjCNativeSelector*)sel)->sel_class;
1697}
1698
1699SEL
1700PyObjCSelector_GetSelector(PyObject* sel)
1701{
1702	if (!PyObjCSelector_Check(sel)) {
1703		PyErr_SetString(PyExc_TypeError, "Expecting PyObjCSelector");
1704		return NULL;
1705	}
1706	return ((PyObjCSelector*)sel)->sel_selector;
1707}
1708
1709
1710int   PyObjCSelector_Required(PyObject* obj)
1711{
1712	return (((PyObjCSelector*)obj)->sel_flags & PyObjCSelector_kREQUIRED) != 0;
1713}
1714
1715int   PyObjCSelector_IsClassMethod(PyObject* obj)
1716{
1717	return (PyObjCSelector_GetFlags(obj) & PyObjCSelector_kCLASS_METHOD) != 0;
1718}
1719
1720int   PyObjCSelector_GetFlags(PyObject* obj)
1721{
1722	return ((PyObjCSelector*)obj)->sel_flags;
1723}
1724
1725
1726/*
1727 * Find the signature of 'selector' in the list of protocols.
1728 */
1729static char*
1730find_protocol_signature(PyObject* protocols, SEL selector, int is_class_method)
1731{
1732	Py_ssize_t len;
1733	Py_ssize_t i;
1734	PyObject* proto;
1735	PyObject* info;
1736
1737	if (!PyList_Check(protocols)) {
1738		PyErr_Format(PyObjCExc_InternalError,
1739			"Protocol-list is not a 'list', but '%s'",
1740			protocols->ob_type->tp_name);
1741		return NULL;
1742	}
1743
1744	/* First try the explicit protocol definitions */
1745	len = PyList_GET_SIZE(protocols);
1746	for (i = 0; i < len; i++) {
1747		proto = PyList_GET_ITEM(protocols, i);
1748		if (proto == NULL) {
1749			PyErr_Clear();
1750			continue;
1751		}
1752
1753		if (PyObjCFormalProtocol_Check(proto)) {
1754			const char* signature;
1755
1756			signature = PyObjCFormalProtocol_FindSelectorSignature(
1757					proto, selector, is_class_method
1758			);
1759			if (signature != NULL) {
1760				return (char*)signature;
1761			}
1762		}
1763
1764		info = PyObjCInformalProtocol_FindSelector(proto, selector, is_class_method);
1765		if (info != NULL) {
1766			return PyObjCSelector_Signature(info);
1767		}
1768	}
1769
1770	/* Then check if another protocol users this selector */
1771	proto = PyObjCInformalProtocol_FindProtocol(selector);
1772	if (proto == NULL) {
1773		PyErr_Clear();
1774		return NULL;
1775	}
1776
1777	info = PyObjCInformalProtocol_FindSelector(proto, selector, is_class_method);
1778	if (info != NULL) {
1779		if (PyList_Append(protocols, proto) < 0) {
1780			return NULL;
1781		}
1782		Py_INCREF(proto);
1783		return PyObjCSelector_Signature(info);
1784	}
1785
1786	return NULL;
1787}
1788
1789PyObject*
1790PyObjCSelector_FromFunction(
1791	PyObject* pyname,
1792	PyObject* callable,
1793	PyObject* template_class,
1794	PyObject* protocols)
1795{
1796	char*     oc_name;
1797	SEL	  selector;
1798	Method    meth;
1799	int       is_class_method = 0;
1800	Class     oc_class = PyObjCClass_GetClass(template_class);
1801	PyObject* value;
1802	PyObject* super_sel;
1803
1804	if (oc_class == NULL) {
1805		return NULL;
1806	}
1807
1808	if (PyObjCPythonSelector_Check(callable)) {
1809		PyObjCPythonSelector* result;
1810
1811		if (((PyObjCPythonSelector*)callable)->callable == NULL || ((PyObjCPythonSelector*)callable)->callable == Py_None) {
1812			PyErr_SetString(PyExc_ValueError, "selector object without callable");
1813			return NULL;
1814		}
1815		result = PyObject_New(PyObjCPythonSelector, &PyObjCPythonSelector_Type);
1816		result->sel_selector = ((PyObjCPythonSelector*)callable)->sel_selector;
1817		result->numoutput = ((PyObjCPythonSelector*)callable)->numoutput;
1818		result->argcount = ((PyObjCPythonSelector*)callable)->argcount;
1819		result->sel_methinfo = PyObjCSelector_GetMetadata(callable);
1820		Py_XINCREF(result->sel_methinfo);
1821		result->sel_class   = oc_class;
1822		result->sel_python_signature  = PyObjCUtil_Strdup(
1823				((PyObjCPythonSelector*)callable)->sel_python_signature);
1824		if (result->sel_python_signature == NULL) {
1825			Py_DECREF(result);
1826			return NULL;
1827		}
1828		result->sel_native_signature = NULL;
1829		result->sel_self       = NULL;
1830		result->sel_flags = ((PyObjCPythonSelector*)callable)->sel_flags;
1831		result->callable = ((PyObjCPythonSelector*)callable)->callable;
1832		if (result->callable) {
1833			Py_INCREF(result->callable);
1834		}
1835		return (PyObject*)result;
1836	}
1837
1838	if (!PyFunction_Check(callable) && !PyMethod_Check(callable) &&
1839		(callable->ob_type != &PyClassMethod_Type)) {
1840
1841		PyErr_SetString(PyExc_TypeError,
1842				"expecting function, method or classmethod");
1843		return NULL;
1844	}
1845
1846
1847	if (callable->ob_type == &PyClassMethod_Type) {
1848		/*
1849		 * This is a 'classmethod' or 'staticmethod'. 'classmethods'
1850		 * will be converted to class 'selectors', 'staticmethods' are
1851		 * returned as-is.
1852		 */
1853		PyObject* tmp;
1854		is_class_method = 1;
1855		tmp = PyObject_CallMethod(callable, "__get__", "OO",
1856				Py_None, template_class);
1857		if (tmp == NULL) {
1858			return NULL;
1859		}
1860
1861		if (PyFunction_Check(tmp)) {
1862			/* A 'staticmethod', don't convert to a selector */
1863			Py_DECREF(tmp);
1864			Py_INCREF(callable);
1865			return callable;
1866		}
1867
1868		callable = PyObject_GetAttrString(tmp, "im_func");
1869		Py_DECREF(tmp);
1870		if (callable == NULL) {
1871			return NULL;
1872		}
1873	}
1874
1875	if (pyname == NULL) {
1876		/* No name specified, use the function name */
1877		pyname = PyObject_GetAttrString(callable, "__name__");
1878		if (pyname == NULL) {
1879			return NULL;
1880		}
1881		oc_name = PyString_AS_STRING(pyname);
1882		selector = PyObjCSelector_DefaultSelector(oc_name);
1883		Py_DECREF(pyname);
1884		oc_name = NULL;
1885
1886	} else if (!PyString_Check(pyname)) {
1887		PyErr_SetString(PyExc_TypeError,
1888			"method name must be a string");
1889		return NULL;
1890	} else {
1891		oc_name = PyString_AS_STRING(pyname);
1892		selector = PyObjCSelector_DefaultSelector(oc_name);
1893	}
1894
1895	/* XXX: This seriously fails if a class method has a different signature
1896	 * than an instance method of the same name!
1897	 *
1898	 *
1899	 * We eagerly call PyObjCClass_FindSelector because some ObjC
1900	 * classes are not fully initialized until they are actually used,
1901	 * and the code below doesn't seem to count but PyObjCClass_FindSelector
1902	 * is.
1903	 */
1904	super_sel = PyObjCClass_FindSelector(template_class, selector, is_class_method);
1905
1906	if (is_class_method) {
1907		meth = class_getClassMethod(oc_class, selector);
1908	} else {
1909		meth = class_getInstanceMethod(oc_class, selector);
1910
1911		if (!meth && !sel_isEqual(selector, @selector(copyWithZone:)) && !sel_isEqual(selector, @selector(mutableCopyWithZone:))) {
1912		        /* Look for a classmethod, but don't do that for copyWithZone:
1913			 * because that method is commonly defined in Python, and
1914			 * overriding "NSObject +copyWithZone:" is almost certainly
1915			 * not the intended behaviour.
1916			 */
1917			meth = class_getClassMethod(oc_class, selector);
1918			if (meth) {
1919				is_class_method = 1;
1920			}
1921		}
1922	}
1923
1924	if (meth) {
1925		/* The function overrides a method in the
1926		 * objective-C class.
1927		 *
1928		 * Get the signature through the python wrapper,
1929		 * the user may have specified a more exact
1930		 * signature!
1931		 */
1932		if (super_sel == NULL) {
1933			return NULL;
1934		}
1935
1936		value = PyObjCSelector_New(
1937			callable,
1938			selector,
1939			PyObjCSelector_Signature(super_sel),
1940			is_class_method,
1941			oc_class);
1942		Py_DECREF(super_sel);
1943	} else {
1944		char* signature = NULL;
1945
1946		PyErr_Clear(); /* The call to PyObjCClass_FindSelector failed */
1947		if (protocols != NULL) {
1948			signature = find_protocol_signature(
1949					protocols, selector, is_class_method);
1950			if (signature == NULL && PyErr_Occurred()) {
1951				return NULL;
1952			}
1953		}
1954
1955		value = PyObjCSelector_New(
1956			callable,
1957			selector,
1958			signature,
1959			is_class_method,
1960			oc_class);
1961	}
1962	return value;
1963}
1964
1965PyObject* PyObjCSelector_Copy(PyObject* selector)
1966{
1967	if (PyObjCPythonSelector_Check(selector)) {
1968		return pysel_descr_get(selector, NULL, NULL);
1969	} else if (PyObjCNativeSelector_Check(selector)) {
1970		return objcsel_descr_get(selector, NULL, NULL);
1971	} else {
1972		PyErr_SetString(PyExc_TypeError, "copy non-selector");
1973		return NULL;
1974	}
1975}
1976