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