1/*
2 * Implementation of the class PyObjCClass_Type, that is the class representing
3 * Objective-C classes.
4 *
5 */
6#include "pyobjc.h"
7
8#include <stddef.h>
9
10int PyObjCClass_SetHidden(PyObject* tp, SEL sel, BOOL classMethod, PyObject* metadata)
11{
12	PyObject* hidden;
13	if (classMethod) {
14		hidden = ((PyObjCClassObject*)tp)->hiddenClassSelectors;
15		if (hidden == NULL) {
16			hidden = PySet_New(NULL);
17			if (hidden == NULL) {
18				return -1;
19			}
20			((PyObjCClassObject*)tp)->hiddenClassSelectors = hidden;
21		}
22	} else {
23		hidden = ((PyObjCClassObject*)tp)->hiddenSelectors;
24		if (hidden == NULL) {
25			hidden = PySet_New(NULL);
26			if (hidden == NULL) {
27				return -1;
28			}
29			((PyObjCClassObject*)tp)->hiddenSelectors = hidden;
30		}
31	}
32	PyObject* v = PyBytes_InternFromString(sel_getName(sel));
33	int r = PyDict_SetItem(hidden, v, metadata);
34	Py_DECREF(v);
35	return r;
36}
37
38
39PyObject*
40PyObjCClass_HiddenSelector(PyObject* tp, SEL sel, BOOL classMethod)
41{
42	PyObject* mro = ((PyTypeObject*)tp)->tp_mro;
43	int i, n;
44
45	if (mro == NULL) {
46		return NO;
47	}
48	assert(PyTuple_Check(mro));
49	n = PyTuple_GET_SIZE(mro);
50	for (i = 0; i < n; i++) {
51		PyObject* base = PyTuple_GET_ITEM(mro, i);
52		if (PyObjCClass_Check(base)) {
53			PyObject* hidden;
54			if (classMethod) {
55				hidden = ((PyObjCClassObject*)base)->hiddenClassSelectors;
56			} else {
57				hidden = ((PyObjCClassObject*)base)->hiddenSelectors;
58			}
59			if (hidden != NULL) {
60				PyObject* v = PyBytes_InternFromString(sel_getName(sel));
61				if (v == NULL) {
62					PyErr_Clear();
63				} else {
64					PyObject* r = PyDict_GetItem(hidden, v);
65					Py_DECREF(v);
66					if (r == NULL) {
67						PyErr_Clear();
68					} else {
69						return r;
70					}
71				}
72			}
73		}
74	}
75
76	return NULL;
77}
78
79/*
80 * Support for NSData/NSMutableData to have buffer API
81 *
82 */
83
84#if PY_MAJOR_VERSION == 2
85static
86Py_ssize_t nsdata_getreadbuffer(PyObject *pyself, Py_ssize_t segment __attribute__((unused)), void **ptrptr) {
87	NSData *self = (NSData *)PyObjCObject_GetObject(pyself);
88	assert(segment == 0);
89	if (ptrptr != NULL) {
90		*ptrptr = (void *)[self bytes];
91	}
92	return (int)[self length];
93}
94
95static
96Py_ssize_t nsmutabledata_getwritebuffer(PyObject *pyself, Py_ssize_t segment __attribute__((unused)), void **ptrptr) {
97	NSMutableData *self = (NSMutableData *)PyObjCObject_GetObject(pyself);
98	assert(segment == 0);
99	if (ptrptr != NULL) {
100		*ptrptr = (void *)[self mutableBytes];
101	}
102	return (int)[self length];
103}
104
105static
106Py_ssize_t nsdata_getsegcount(PyObject *pyself, Py_ssize_t *lenp) {
107	NSData *self = (NSData *)PyObjCObject_GetObject(pyself);
108	if (lenp != NULL) {
109		*lenp = (Py_ssize_t)[self length];
110	}
111	return 1;
112}
113#endif
114
115#if PY_VERSION_HEX >= 0x02060000
116
117static int
118nsdata_getbuffer(PyObject* obj, Py_buffer* view, int flags)
119{
120	NSData *self = (NSData *)PyObjCObject_GetObject(obj);
121	int r = PyBuffer_FillInfo(view, obj, (void*)[self bytes], [self length], 1, flags);
122	return r;
123}
124
125static int
126nsmutabledata_getbuffer(PyObject* obj, Py_buffer* view, int flags)
127{
128	NSMutableData *self = (NSMutableData *)PyObjCObject_GetObject(obj);
129	int r;
130	if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) {
131		r = PyBuffer_FillInfo(view, obj, (void*)[self mutableBytes], [self length], 0, flags);
132	} else {
133		r = PyBuffer_FillInfo(view, obj, (void*)[self bytes], [self length], 1, flags);
134	}
135	return r;
136}
137
138#endif
139
140
141static PyBufferProcs nsdata_as_buffer = {
142#if PY_MAJOR_VERSION == 2
143	nsdata_getreadbuffer,
144	NULL,
145	nsdata_getsegcount,
146	NULL
147#if PY_VERSION_HEX >= 0x02060000
148	, nsdata_getbuffer
149	, NULL
150#endif
151
152#else	/* Py3K */
153	nsdata_getbuffer,
154	NULL,
155#endif
156
157};
158
159static PyBufferProcs nsmutabledata_as_buffer = {
160#if PY_MAJOR_VERSION == 2
161	nsdata_getreadbuffer,
162	nsmutabledata_getwritebuffer,
163	nsdata_getsegcount,
164	NULL
165#if PY_VERSION_HEX >= 0x02060000
166	, nsmutabledata_getbuffer
167	, NULL
168#endif
169
170#else	/* Py3K */
171	nsmutabledata_getbuffer,
172	NULL,
173#endif
174};
175
176
177PyDoc_STRVAR(class_doc,
178"objc_class(name, bases, dict) -> a new Objective-C class\n"
179"\n"
180"objc_class is the meta-type for Objective-C classes. It should not be\n"
181"necessary to manually create instances of this type, those are \n"
182"created by subclassing and existing Objective-C class.\n"
183"\n"
184"The list of bases must start with an existing Objective-C class, and \n"
185"cannot contain other Objective-C classes. The list may contain\n"
186"informal_interface objects, those are used during the calculation of\n"
187"method signatures and will not be visible in the list of base-classes\n"
188"of the created class."
189);
190
191PyObject* PyObjC_ClassExtender = NULL;
192
193static int add_class_fields(Class objc_class, PyObject* py_class, PyObject* dict, PyObject* protDict, PyObject* classDict);
194static int add_convenience_methods(Class cls, PyObject* type_dict);
195static int update_convenience_methods(PyObject* cls);
196
197/*
198 *
199 *  Class Registry
200 *
201 */
202
203/*!
204 * @const class_registry
205 * @discussion
206 *    This structure is used to keep references to all class objects created
207 *    by this module. This is necessary to be able to avoid creating two
208 *    wrappers for an Objective-C class.
209 *
210 *    The key is the Objective-C class, the value is its wrapper.
211 */
212static NSMapTable* class_registry = NULL;
213static NSMapTable* metaclass_to_class = NULL;
214
215/*!
216 * @function objc_class_register
217 * @abstract Add a class to the class registry
218 * @param objc_class An Objective-C class
219 * @param py_class   The python wrapper for the Objective-C class
220 * @result Returns -1 on error, 0 on success
221 */
222static int
223objc_class_register(Class objc_class, PyObject* py_class)
224{
225	if (class_registry == NULL) {
226		class_registry = NSCreateMapTable(
227			PyObjCUtil_PointerKeyCallBacks,
228			PyObjCUtil_PointerValueCallBacks,
229			PYOBJC_EXPECTED_CLASS_COUNT);
230	}
231
232	if (NSMapGet(class_registry, objc_class)) {
233		PyErr_BadInternalCall();
234		return -1;
235	}
236
237	Py_INCREF(py_class);
238	NSMapInsert(class_registry, objc_class, py_class);
239
240	return 0;
241}
242
243static int
244objc_metaclass_register(PyTypeObject* meta_class, Class class)
245{
246	if (metaclass_to_class == NULL) {
247		metaclass_to_class = NSCreateMapTable(
248			PyObjCUtil_PointerKeyCallBacks,
249			PyObjCUtil_PointerValueCallBacks,
250			PYOBJC_EXPECTED_CLASS_COUNT);
251	}
252
253	if (NSMapGet(metaclass_to_class, meta_class)) {
254		PyErr_BadInternalCall();
255		return -1;
256	}
257
258	Py_INCREF(meta_class);
259	NSMapInsert(metaclass_to_class, meta_class, class);
260
261	return 0;
262}
263
264static Class
265objc_metaclass_locate(PyObject* meta_class)
266{
267	Class result;
268
269	if (metaclass_to_class == NULL) return NULL;
270	if (meta_class == NULL) return NULL;
271
272	result = NSMapGet(metaclass_to_class, meta_class);
273	return result;
274}
275
276/*!
277 * @function objc_class_locate
278 * @abstract Find the Python wrapper for an Objective-C class
279 * @param objc_class An Objective-C class
280 * @result Returns the Python wrapper for the class, or NULL
281 * @discussion
282 *     This function does not raise an Python exception when the
283 *     wrapper cannot be found.
284 */
285static PyObject*
286objc_class_locate(Class objc_class)
287{
288	PyObject* result;
289
290	if (class_registry == NULL) return NULL;
291	if (objc_class == NULL) return NULL;
292
293	result = NSMapGet(class_registry, objc_class);
294	Py_XINCREF(result);
295	return result;
296}
297
298
299
300/* Create a new objective-C metaclass proxy
301 *
302 * Returns a new reference.
303 */
304static PyTypeObject*
305PyObjCClass_NewMetaClass(Class objc_class)
306{
307	PyTypeObject* result;
308	Class objc_meta_class = object_getClass(objc_class);
309
310	if (unlikely(class_isMetaClass(objc_class))) {
311		objc_meta_class = objc_class;
312	}
313
314	if (objc_meta_class == nil) {
315		Py_INCREF(&PyObjCClass_Type);
316		return &PyObjCClass_Type;
317	}
318
319	/* Create a metaclass proxy for the metaclass of the given class */
320	result = (PyTypeObject*)objc_class_locate(objc_meta_class);
321	if (result != NULL) {
322		return result;
323	}
324
325	Class super_class = nil;
326
327	if (unlikely(class_isMetaClass(objc_class))) {
328		super_class = class_getSuperclass(objc_meta_class);
329		if (!class_isMetaClass(super_class)) {
330			/* NSObject's metaclass inherits from NSObject, don't
331			 * model that in Python. */
332			super_class = nil;
333		}
334	} else {
335		super_class = class_getSuperclass(objc_class);
336	}
337
338	PyTypeObject* py_super_class;
339	if (super_class == nil) {
340		Py_INCREF(&PyObjCClass_Type);
341		py_super_class = &PyObjCClass_Type;
342	} else {
343		py_super_class = PyObjCClass_NewMetaClass(super_class);
344		if (py_super_class == NULL) {
345			return NULL;
346		}
347	}
348
349	/* We now know the superclass of our metaclass, build the actual
350	 * metaclass.
351	 */
352	PyObject* dict = PyDict_New();
353	PyObject* bases = PyTuple_New(1);
354
355	PyTuple_SET_ITEM(bases, 0, (PyObject*)py_super_class);
356
357	PyObject* args = PyTuple_New(3);
358	PyTuple_SetItem(args, 0,
359			PyText_FromString(class_getName(objc_class)));
360	PyTuple_SetItem(args, 1, bases);
361	PyTuple_SetItem(args, 2, dict);
362
363	result = (PyTypeObject*)PyType_Type.tp_new(&PyType_Type, args, NULL);
364	Py_DECREF(args);
365	if (result == NULL) return NULL;
366
367	if (objc_class_register(objc_meta_class, (PyObject*)result) == -1) {
368		Py_DECREF(result);
369		return NULL;
370	}
371
372	if (objc_metaclass_register(result, objc_class) == -1) {
373		/* Whoops, no such thing */
374		//objc_class_unregister(objc_meta_class);
375		return NULL;
376	}
377
378	return (PyTypeObject*)result;
379}
380
381
382/*
383 * Create a new objective-C class, as a subclass of 'type'. This is
384 * PyObjCClass_Type.tp_new.
385 *
386 * Note: This function creates new _classes_
387 */
388
389static int
390class_init(PyObject *cls, PyObject *args, PyObject *kwds)
391{
392	if (kwds != NULL) {
393		if (PyDict_Check(kwds) && PyDict_Size(kwds) == 1) {
394			if (PyDict_GetItemString(kwds, "protocols") != NULL) {
395				return PyType_Type.tp_init(cls, args, NULL);
396			}
397		}
398	}
399	return PyType_Type.tp_init(cls, args, kwds);
400}
401
402static PyObject*
403class_new(PyTypeObject* type __attribute__((__unused__)),
404		PyObject* args, PyObject* kwds)
405{
406static	char* keywords[] = { "name", "bases", "dict", "protocols", NULL };
407	char* name;
408	PyObject* bases;
409	PyObject* dict;
410	PyObject* old_dict;
411	PyObject* res;
412	PyObject* k;
413	PyObject* metadict;
414	PyObject* v;
415	Py_ssize_t i;
416	Py_ssize_t len;
417	Class      objc_class = NULL;
418	Class	   super_class = NULL;
419	PyObject*  py_super_class = NULL;
420	PyObjCClassObject* info;
421	PyObject* keys;
422	PyObject* protocols;
423	PyObject* real_bases;
424	PyObject* delmethod;
425	PyObject* useKVOObj;
426	Ivar var;
427	PyObject* protectedMethods = NULL;
428	PyObject* hiddenSelectors = NULL;
429	PyObject* hiddenClassSelectors = NULL;
430	PyObject* arg_protocols = NULL;
431	BOOL      isCFProxyClass = NO;
432	int       r;
433
434	if (!PyArg_ParseTupleAndKeywords(args, kwds, "sOO|O",
435			keywords, &name, &bases, &dict, &arg_protocols)) {
436		return NULL;
437	}
438
439	if (!PyTuple_Check(bases)) {
440		PyErr_SetString(PyExc_TypeError, "'bases' must be tuple");
441		return NULL;
442	}
443
444	len = PyTuple_Size(bases);
445	if (len < 1) {
446		PyErr_SetString(PyExc_TypeError, "'bases' must not be empty");
447		return NULL;
448	}
449
450	py_super_class = PyTuple_GET_ITEM(bases, 0);
451	if (py_super_class == NULL) {
452		return NULL;
453	}
454
455	if (py_super_class == PyObjC_NSCFTypeClass) {
456		/* A new subclass of NSCFType
457		 * -> a new proxy type for CoreFoundation classes
458		 */
459		isCFProxyClass = YES;
460
461
462	}
463
464	if (!PyObjCClass_Check(py_super_class)) {
465		PyErr_SetString(PyExc_TypeError,
466				"first base class must "
467				"be objective-C based");
468		return NULL;
469	}
470	super_class = PyObjCClass_GetClass(py_super_class);
471	if (super_class) {
472		PyObjCClass_CheckMethodList(py_super_class, 1);
473	}
474
475	protectedMethods = PyDict_New();
476	if (protectedMethods == NULL) {
477		return NULL;
478	}
479
480	hiddenSelectors = PyDict_New();
481	if (hiddenSelectors == NULL) {
482		Py_DECREF(protectedMethods);
483		return NULL;
484	}
485
486	hiddenClassSelectors = PyDict_New();
487	if (hiddenClassSelectors == NULL) {
488		Py_DECREF(protectedMethods);
489		Py_DECREF(hiddenSelectors);
490		return NULL;
491	}
492
493
494	/*
495	 * __pyobjc_protocols__ contains the list of protocols supported
496	 * by an existing class.
497	 */
498	protocols = PyObject_GetAttrString(py_super_class,
499		"__pyobjc_protocols__");
500	if (protocols == NULL) {
501		PyErr_Clear();
502		protocols = PyList_New(0);
503		if (protocols == NULL) {
504			Py_DECREF(protectedMethods);
505			Py_DECREF(hiddenSelectors);
506			Py_DECREF(hiddenClassSelectors);
507			return NULL;
508		}
509	} else {
510		PyObject* seq;
511		Py_ssize_t protocols_len;
512
513		seq = PySequence_Fast(protocols,
514			"__pyobjc_protocols__ not a sequence?");
515		if (seq == NULL) {
516			Py_DECREF(protectedMethods);
517			Py_DECREF(hiddenSelectors);
518			Py_DECREF(hiddenClassSelectors);
519			Py_DECREF(protocols);
520			return NULL;
521		}
522		Py_DECREF(protocols);
523
524		protocols_len = PySequence_Fast_GET_SIZE(seq);
525		protocols = PyList_New(protocols_len);
526		if (protocols == NULL) {
527			Py_DECREF(protectedMethods);
528			Py_DECREF(hiddenSelectors);
529			Py_DECREF(hiddenClassSelectors);
530			return NULL;
531		}
532		for (i = 0; i < protocols_len; i++) {
533			PyList_SET_ITEM(protocols, i,
534				PySequence_Fast_GET_ITEM(seq, i));
535			Py_INCREF(PySequence_Fast_GET_ITEM(seq, i));
536		}
537		Py_DECREF(seq);
538	}
539
540	real_bases = PyList_New(0);
541	if (real_bases == NULL) {
542		Py_DECREF(protocols);
543		Py_DECREF(protectedMethods);
544		Py_DECREF(hiddenSelectors);
545		Py_DECREF(hiddenClassSelectors);
546		return NULL;
547	}
548	PyList_Append(real_bases, py_super_class);
549	if (PyErr_Occurred()) {
550		Py_DECREF(protectedMethods);
551		Py_DECREF(hiddenSelectors);
552		Py_DECREF(hiddenClassSelectors);
553		Py_DECREF(protocols);
554		Py_DECREF(real_bases);
555		return NULL;
556	}
557
558	for (i = 1; i < len; i++) {
559		v = PyTuple_GET_ITEM(bases, i);
560		if (v == NULL) {
561			Py_DECREF(protocols);
562			Py_DECREF(real_bases);
563			Py_DECREF(protectedMethods);
564			Py_DECREF(hiddenSelectors);
565			Py_DECREF(hiddenClassSelectors);
566			return NULL;
567		}
568		if (PyObjCClass_Check(v)) {
569			Py_DECREF(protocols);
570			Py_DECREF(real_bases);
571			Py_DECREF(protectedMethods);
572			Py_DECREF(hiddenSelectors);
573			Py_DECREF(hiddenClassSelectors);
574			PyErr_SetString(PyExc_TypeError,
575					"multiple objective-C bases");
576			return NULL;
577		} else if (PyObjCInformalProtocol_Check(v)) {
578			r = PyList_Append(protocols, v);
579			if (r == -1) {
580				Py_DECREF(protocols);
581				Py_DECREF(real_bases);
582				Py_DECREF(protectedMethods);
583				Py_DECREF(hiddenSelectors);
584				Py_DECREF(hiddenClassSelectors);
585			}
586		} else if (PyObjCFormalProtocol_Check(v)) {
587			r = PyList_Append(protocols, v);
588			if (r == -1) {
589				Py_DECREF(protocols);
590				Py_DECREF(real_bases);
591				Py_DECREF(protectedMethods);
592				Py_DECREF(hiddenSelectors);
593				Py_DECREF(hiddenClassSelectors);
594			}
595		} else {
596			r = PyList_Append(real_bases, v);
597			if (r == -1) {
598				Py_DECREF(protocols);
599				Py_DECREF(real_bases);
600				Py_DECREF(protectedMethods);
601				Py_DECREF(hiddenSelectors);
602				Py_DECREF(hiddenClassSelectors);
603			}
604		}
605	}
606
607	if (arg_protocols != NULL) {
608		PyObject* seq;
609		Py_ssize_t i, seqlen;
610
611		seq = PySequence_Fast(arg_protocols,
612			"'protocols' not a sequence?");
613		if (seq == NULL) {
614			Py_DECREF(protocols);
615			Py_DECREF(real_bases);
616			Py_DECREF(protectedMethods);
617			Py_DECREF(hiddenSelectors);
618			Py_DECREF(hiddenClassSelectors);
619			return NULL;
620		}
621		seqlen = PySequence_Fast_GET_SIZE(seq);
622		for (i = 0; i < seqlen; i++) {
623			if (
624				PyObjCInformalProtocol_Check(PySequence_Fast_GET_ITEM(seq, i))
625			     || PyObjCFormalProtocol_Check(PySequence_Fast_GET_ITEM(seq, i))) {
626				r = PyList_Append(protocols,
627					PySequence_Fast_GET_ITEM(seq, i));
628				if (r == -1) {
629					Py_DECREF(seq);
630					Py_DECREF(protocols);
631					Py_DECREF(real_bases);
632					Py_DECREF(protectedMethods);
633					Py_DECREF(hiddenSelectors);
634					Py_DECREF(hiddenClassSelectors);
635					return NULL;
636				}
637			} else {
638				PyErr_Format(PyExc_TypeError,
639					"protocols list contains object that isn't an Objective-C protocol, but type %s",
640					Py_TYPE(PySequence_Fast_GET_ITEM(seq, i))->tp_name);
641				Py_DECREF(seq);
642				Py_DECREF(protocols);
643				Py_DECREF(real_bases);
644				Py_DECREF(protectedMethods);
645				Py_DECREF(hiddenSelectors);
646				Py_DECREF(hiddenClassSelectors);
647				return NULL;
648			}
649
650		}
651		Py_DECREF(seq);
652	}
653
654	/* Also look for '__pyobjc_protocols__' in the class dictionary,
655	 * makes it possible to write code that works in Python 2 as well
656	 * as python 3.
657	 */
658	arg_protocols = PyDict_GetItemString(dict, "__pyobjc_protocols__");
659	if (arg_protocols != NULL) {
660		PyObject* seq;
661		Py_ssize_t i, seqlen;
662
663		seq = PySequence_Fast(arg_protocols,
664			"'__pyobjc_protocols__' not a sequence?");
665		if (seq == NULL) {
666			Py_DECREF(protocols);
667			Py_DECREF(real_bases);
668			Py_DECREF(protectedMethods);
669			Py_DECREF(hiddenSelectors);
670			Py_DECREF(hiddenClassSelectors);
671			return NULL;
672		}
673		seqlen = PySequence_Fast_GET_SIZE(seq);
674		for (i = 0; i < seqlen; i++) {
675			if (
676				PyObjCInformalProtocol_Check(PySequence_Fast_GET_ITEM(seq, i))
677			     || PyObjCFormalProtocol_Check(PySequence_Fast_GET_ITEM(seq, i))) {
678				r = PyList_Append(protocols,
679					PySequence_Fast_GET_ITEM(seq, i));
680				if (r == -1) {
681					Py_DECREF(seq);
682					Py_DECREF(protocols);
683					Py_DECREF(real_bases);
684					Py_DECREF(protectedMethods);
685					Py_DECREF(hiddenSelectors);
686					Py_DECREF(hiddenClassSelectors);
687					return NULL;
688				}
689			} else {
690				PyErr_Format(PyExc_TypeError,
691					"protocols list contains object that isn't an Objective-C protocol, but type %s",
692					Py_TYPE(PySequence_Fast_GET_ITEM(seq, i))->tp_name);
693				Py_DECREF(seq);
694				Py_DECREF(protocols);
695				Py_DECREF(real_bases);
696				Py_DECREF(protectedMethods);
697				Py_DECREF(hiddenSelectors);
698				Py_DECREF(hiddenClassSelectors);
699				return NULL;
700			}
701
702		}
703		Py_DECREF(seq);
704	}
705
706	metadict = PyDict_New();
707	if (metadict == NULL) {
708		Py_DECREF(protocols);
709		Py_DECREF(real_bases);
710		Py_DECREF(protectedMethods);
711		Py_DECREF(hiddenSelectors);
712		Py_DECREF(hiddenClassSelectors);
713		return NULL;
714	}
715
716	if (isCFProxyClass) {
717		objc_class = nil;
718
719	} else {
720		/* First generate the objective-C class. This may change the
721		 * class dict.
722		 */
723		objc_class = PyObjCClass_BuildClass(super_class, protocols, name, dict, metadict, hiddenSelectors, hiddenClassSelectors);
724		if (objc_class == NULL) {
725			Py_DECREF(protocols);
726			Py_DECREF(metadict);
727			Py_DECREF(real_bases);
728			Py_DECREF(protectedMethods);
729			Py_DECREF(hiddenSelectors);
730			Py_DECREF(hiddenClassSelectors);
731			return NULL;
732		}
733
734		/* PyObjCClass_BuildClass may have changed the super_class */
735		super_class = class_getSuperclass(objc_class);
736		py_super_class = PyObjCClass_New(super_class);
737		if (py_super_class == NULL) {
738			(void)PyObjCClass_UnbuildClass(objc_class);
739			Py_DECREF(protocols);
740			Py_DECREF(real_bases);
741			Py_DECREF(metadict);
742			Py_DECREF(protectedMethods);
743			Py_DECREF(hiddenSelectors);
744			Py_DECREF(hiddenClassSelectors);
745			return NULL;
746		} else {
747			PyObjCClass_CheckMethodList(py_super_class, 1);
748		}
749
750		Py_DECREF(PyList_GET_ITEM(real_bases, 0));
751		PyList_SET_ITEM(real_bases, 0, py_super_class);
752	}
753
754	v = PyList_AsTuple(real_bases);
755	if (v == NULL) {
756		if (objc_class != nil) {
757			(void)PyObjCClass_UnbuildClass(objc_class);
758		}
759		Py_DECREF(metadict);
760		Py_DECREF(protocols);
761		Py_DECREF(real_bases);
762		Py_DECREF(protectedMethods);
763		Py_DECREF(hiddenSelectors);
764		Py_DECREF(hiddenClassSelectors);
765		return NULL;
766	}
767	Py_DECREF(real_bases);
768	real_bases = v;
769
770	/* Verify that the class conforms to all protocols it claims to
771	 * conform to.
772	 */
773	len = PyList_Size(protocols);
774	for (i = 0; i < len; i++) {
775		PyObject* p = PyList_GetItem(protocols, i);
776
777		if (p == NULL) {
778			PyErr_Clear();
779			continue;
780		}
781
782		if (PyObjCInformalProtocol_Check(p)) {
783			if (!PyObjCInformalProtocol_CheckClass(
784					p, name, py_super_class, dict)) {
785				Py_DECREF(real_bases);
786				Py_DECREF(protocols);
787				Py_DECREF(metadict);
788				Py_DECREF(protectedMethods);
789				Py_DECREF(hiddenSelectors);
790				Py_DECREF(hiddenClassSelectors);
791				(void)PyObjCClass_UnbuildClass(objc_class);
792				return NULL;
793			}
794		} else if (PyObjCFormalProtocol_Check(p)) {
795			if (!PyObjCFormalProtocol_CheckClass(
796					p, name, py_super_class, dict, metadict)) {
797				Py_DECREF(real_bases);
798				Py_DECREF(protocols);
799				Py_DECREF(metadict);
800				Py_DECREF(protectedMethods);
801				Py_DECREF(hiddenSelectors);
802				Py_DECREF(hiddenClassSelectors);
803				(void)PyObjCClass_UnbuildClass(objc_class);
804				return NULL;
805			}
806		}
807	}
808
809	/*
810	 * add __pyobjc_protocols__ to the class-dict.
811	 */
812	v = PyList_AsTuple(protocols);
813	if (v == NULL) {
814		Py_DECREF(real_bases);
815		Py_DECREF(protocols);
816		Py_DECREF(metadict);
817		Py_DECREF(protectedMethods);
818		Py_DECREF(hiddenSelectors);
819		Py_DECREF(hiddenClassSelectors);
820		(void)PyObjCClass_UnbuildClass(objc_class);
821		return NULL;
822	}
823
824	PyDict_SetItemString(dict, "__pyobjc_protocols__", v);
825	Py_DECREF(v);
826
827
828	/*
829	 * Users can define a __del__ method. We special-case this to
830	 * avoid triggering the default mechanisms for this method: The
831	 * method should only be called when the Objective-C side of the
832	 * instance is deallocated, not whenever the Python proxy is.
833	 */
834	delmethod = PyDict_GetItemString(dict, "__del__");
835	if (delmethod == NULL) {
836		PyErr_Clear();
837	} else {
838		Py_INCREF(delmethod);
839
840		if (isCFProxyClass) {
841			PyErr_SetString(PyObjCExc_Error,
842			    "cannot define __del__ on subclasses of NSCFType");
843			Py_DECREF(protocols);
844			Py_DECREF(real_bases);
845			Py_DECREF(metadict);
846			Py_DECREF(protectedMethods);
847			Py_DECREF(hiddenSelectors);
848			Py_DECREF(hiddenClassSelectors);
849			return NULL;
850		} else {
851			if (PyDict_DelItemString(dict, "__del__") < 0) {
852				if (objc_class != nil) {
853					(void)PyObjCClass_UnbuildClass(objc_class);
854				}
855				Py_DECREF(protocols);
856				Py_DECREF(real_bases);
857				Py_DECREF(metadict);
858				Py_DECREF(protectedMethods);
859				Py_DECREF(hiddenSelectors);
860				Py_DECREF(hiddenClassSelectors);
861				return NULL;
862			}
863		}
864	}
865
866	/* Add convenience methods like '__eq__'. Must do it before
867	 * call to super-class implementation, because '__*' methods
868	 * are treated specially there.
869	 */
870	old_dict = PyDict_Copy(dict);
871	if (old_dict == NULL) {
872		if (objc_class != nil) {
873			(void)PyObjCClass_UnbuildClass(objc_class);
874		}
875		Py_DECREF(protocols);
876		Py_DECREF(real_bases);
877		Py_DECREF(metadict);
878		Py_DECREF(protectedMethods);
879		Py_DECREF(hiddenSelectors);
880		Py_DECREF(hiddenClassSelectors);
881		return NULL;
882	}
883
884	if (objc_class != nil) {
885		if (add_convenience_methods(objc_class, dict) < 0) {
886			(void)PyObjCClass_UnbuildClass(objc_class);
887			Py_DECREF(old_dict);
888			Py_DECREF(protocols);
889			Py_DECREF(real_bases);
890			Py_DECREF(metadict);
891			Py_DECREF(protectedMethods);
892			Py_DECREF(hiddenSelectors);
893			Py_DECREF(hiddenClassSelectors);
894			return NULL;
895		}
896	}
897
898
899
900	PyTypeObject* metatype;
901	if (objc_class != nil) {
902		metatype = PyObjCClass_NewMetaClass(objc_class);
903		if (metatype == NULL) {
904			Py_DECREF(old_dict);
905			Py_DECREF(protocols);
906			Py_DECREF(real_bases);
907			Py_DECREF(metadict);
908			Py_DECREF(protectedMethods);
909			Py_DECREF(hiddenSelectors);
910			Py_DECREF(hiddenClassSelectors);
911			return NULL;
912		}
913		if (PyDict_Update(metatype->tp_dict, metadict) == -1) {
914			Py_DECREF(old_dict);
915			Py_DECREF(protocols);
916			Py_DECREF(real_bases);
917			Py_DECREF(metadict);
918			Py_DECREF(protectedMethods);
919			Py_DECREF(hiddenSelectors);
920			Py_DECREF(hiddenClassSelectors);
921			return NULL;
922		}
923	} else {
924		metatype = Py_TYPE(PyObjC_NSCFTypeClass);
925	}
926	Py_DECREF(metadict); metadict = NULL;
927
928	/* call super-class implementation */
929	args = Py_BuildValue("(sOO)", name, real_bases, dict);
930
931	/* The actual superclass might be different due to introduction
932	 * of magic intermediate classes, therefore explicitly refer to the
933	 * metatype we just created.
934	 */
935	res =  PyType_Type.tp_new(metatype, args, NULL);
936	Py_DECREF(metatype);
937	if (res == NULL) {
938		Py_DECREF(args);
939		Py_DECREF(real_bases);
940		Py_DECREF(protocols);
941		Py_DECREF(old_dict);
942		Py_DECREF(protectedMethods);
943		Py_DECREF(hiddenSelectors);
944		Py_DECREF(hiddenClassSelectors);
945		(void)PyObjCClass_UnbuildClass(objc_class);
946		return NULL;
947	}
948	Py_DECREF(args);
949	Py_DECREF(real_bases);
950	args = NULL;
951	real_bases = NULL;
952
953	Py_DECREF(protocols);
954	protocols = NULL;
955
956	if (objc_class != nil) {
957		/* Register the proxy as soon as possible, we can get
958		 * initialize calls very early on with the ObjC 2.0 runtime.
959		 */
960		PyObjC_RegisterPythonProxy(objc_class, res);
961
962		if (objc_class_register(objc_class, res) < 0) {
963			PyObjC_UnregisterPythonProxy(objc_class, res);
964			Py_DECREF(res);
965			Py_DECREF(old_dict);
966			Py_DECREF(protectedMethods);
967			Py_DECREF(hiddenSelectors);
968			Py_DECREF(hiddenClassSelectors);
969			(void)PyObjCClass_UnbuildClass(objc_class);
970			return NULL;
971		}
972
973		PyObjCClass_FinishClass(objc_class);
974	}
975
976
977	info = (PyObjCClassObject*)res;
978	info->class = objc_class;
979	if (isCFProxyClass) {
980		info->class = PyObjCClass_GetClass(PyObjC_NSCFTypeClass);
981	}
982	info->sel_to_py = NULL;
983	info->method_magic = PyObjC_methodlist_magic(objc_class);
984	info->dictoffset = 0;
985	info->useKVO = 0;
986	info->delmethod = delmethod;
987	info->hasPythonImpl = 1;
988	info->isCFWrapper = 0;
989	info->protectedMethods = protectedMethods;
990	info->hiddenSelectors = hiddenSelectors;
991	info->hiddenClassSelectors = hiddenClassSelectors;
992
993
994	var = class_getInstanceVariable(objc_class, "__dict__");
995	if (var != NULL) {
996		info->dictoffset = ivar_getOffset(var);
997	}
998
999	useKVOObj = PyDict_GetItemString(dict, "__useKVO__");
1000	if (useKVOObj != NULL) {
1001		info->useKVO = PyObject_IsTrue(useKVOObj);
1002	} else {
1003		info->useKVO = PyObjC_useKVO;
1004	}
1005
1006	if (isCFProxyClass) {
1007		/* Disable automatic KVO on pure CoreFoundation types */
1008		info->useKVO = 0;
1009	}
1010	keys = PyDict_Keys(dict);
1011	if (keys == NULL) {
1012		Py_DECREF(old_dict);
1013		return NULL;
1014	}
1015
1016	/* Merge the "difference" to pick up new selectors */
1017	len = PyList_GET_SIZE(keys);
1018	for (i=0; i < len; i++) {
1019		k = PyList_GET_ITEM(keys, i);
1020		if (PyDict_GetItem(old_dict, k) == NULL) {
1021			v = PyDict_GetItem(dict, k);
1022			if (v != NULL && PyObject_SetAttr(res, k, v) == -1) {
1023				PyErr_Clear();
1024			}
1025		}
1026	}
1027
1028	Py_DECREF(keys);
1029	Py_DECREF(old_dict);
1030
1031	/* This is an "extra" ref */
1032	Py_INCREF(res);
1033	return res;
1034}
1035
1036
1037static PyObject*
1038class_repr(PyObject* obj)
1039{
1040	Class cls = PyObjCClass_GetClass(obj);
1041
1042	if (cls) {
1043		const char* nm = class_getName(cls);
1044		if (strstr(nm, "NSCFType") != NULL) {
1045			return PyText_FromFormat(
1046				"<core-foundation class %s at %p>",
1047				((PyTypeObject*)obj)->tp_name, (void*)cls);
1048
1049		} else {
1050			return PyText_FromFormat(
1051				"<objective-c class %s at %p>",
1052				nm, (void*)cls);
1053		}
1054	} else {
1055		return PyText_FromFormat(
1056			"%s", "<objective-c class NIL>");
1057	}
1058}
1059
1060
1061static void
1062class_dealloc(PyObject* cls)
1063{
1064	char buf[1024];
1065
1066	snprintf(buf, sizeof(buf), "Deallocating objective-C class %s", ((PyTypeObject*)cls)->tp_name);
1067
1068	/* This should never happen */
1069	Py_FatalError(buf);
1070}
1071
1072void
1073PyObjCClass_CheckMethodList(PyObject* cls, int recursive)
1074{
1075	PyObjCClassObject* info;
1076	int		   magic;
1077
1078	info = (PyObjCClassObject*)cls;
1079
1080	if (info->class == NULL) return;
1081
1082	while (info->class != NULL) {
1083
1084		if ((info->method_magic !=
1085				(magic = PyObjC_methodlist_magic(info->class))) || (info->generation != PyObjC_MappingCount)) {
1086
1087			int r;
1088
1089			r = add_class_fields(
1090				info->class,
1091				cls,
1092				((PyTypeObject*)cls)->tp_dict,
1093				info->protectedMethods,
1094				Py_TYPE(cls)->tp_dict);
1095			if (r < 0) {
1096				PyErr_SetString(PyExc_RuntimeError,
1097					"Cannot rescan method table");
1098				return;
1099			}
1100			info->generation = PyObjC_MappingCount;
1101
1102			r =  update_convenience_methods(cls);
1103			if (r < 0) {
1104				PyErr_SetString(PyExc_RuntimeError,
1105					"Cannot rescan method table");
1106				return;
1107			}
1108			info->method_magic = magic;
1109			if (info->sel_to_py) {
1110				Py_XDECREF(info->sel_to_py);
1111				info->sel_to_py = PyDict_New();
1112			}
1113		}
1114
1115		if (!recursive) break;
1116		if (class_getSuperclass(info->class) == NULL) break;
1117		cls = PyObjCClass_New(class_getSuperclass(info->class));
1118		Py_DECREF(cls); /* We don't actually need the reference, convert to a borrowed one */
1119		info = (PyObjCClassObject*)cls;
1120	}
1121}
1122
1123
1124static PyObject*
1125class_getattro(PyObject* self, PyObject* name)
1126{
1127	PyObject* result = NULL;
1128	/* Python will look for a number of "private" attributes during
1129	 * normal operations, such as when building subclasses. Avoid a
1130	 * method rescan when that happens.
1131	 *
1132	 * NOTE: This method should be rewritten, copy the version of type()
1133	 *       and modify as needed, that would avoid unnecessary rescans
1134	 * 	 of superclasses. The same strategy is used in object_getattro.
1135	 *
1136	 * NOTE2: That rewrite should also cause this method to prefer class
1137	 *       methods over instance methods (and documentation should be
1138	 *       added that you shouldn't look up instance methods through the
1139	 *       class).
1140	 *
1141	 */
1142	if (PyUnicode_Check(name)
1143			&& PyObjC_is_ascii_prefix(name, "__", 2)
1144			&& !PyObjC_is_ascii_string(name, "__dict__")) {
1145		result = PyType_Type.tp_getattro(self, name);
1146		if (result != NULL) {
1147			return result;
1148		}
1149		PyErr_Clear();
1150	}
1151
1152#if PY_MAJOR_VERSION == 2
1153	else if (PyString_Check(name)
1154			&& strncmp(PyString_AS_STRING(name), "__", 2) == 0
1155			&& strcmp(PyString_AS_STRING(name), "__dict__") != 0) {
1156		result = PyType_Type.tp_getattro(self, name);
1157		if (result != NULL) {
1158			return result;
1159		}
1160		PyErr_Clear();
1161	}
1162#endif
1163	PyObjCClass_CheckMethodList(self, 1);
1164
1165	result = PyType_Type.tp_getattro(self, name);
1166	if (result != NULL) {
1167		return result;
1168	}
1169
1170
1171
1172	/* Try to find the method anyway */
1173	PyErr_Clear();
1174	if (PyUnicode_Check(name)) {
1175		PyObject* bytes = PyUnicode_AsEncodedString(name, NULL, NULL);
1176		if (bytes == NULL) {
1177			return NULL;
1178		}
1179		if (PyObjCClass_HiddenSelector(self, sel_getUid(PyBytes_AsString(bytes)), YES)) {
1180			Py_DECREF(bytes);
1181			PyErr_SetObject(PyExc_AttributeError, name);
1182			return NULL;
1183		}
1184		result = PyObjCSelector_FindNative(self, PyBytes_AsString(bytes));
1185		Py_DECREF(bytes);
1186#if PY_MAJOR_VERSION == 2
1187	} else if (PyString_Check(name)) {
1188		if (PyObjCClass_HiddenSelector(self, sel_getUid(PyString_AsString(name)), YES)) {
1189			PyErr_SetObject(PyExc_AttributeError, name);
1190			return NULL;
1191		}
1192		result = PyObjCSelector_FindNative(self, PyString_AsString(name));
1193#endif
1194	} else {
1195		PyErr_SetString(PyExc_TypeError, "Attribute name is not a string");
1196		return NULL;
1197	}
1198
1199	if (result != NULL) {
1200		int res = PyDict_SetItem(((PyTypeObject*)self)->tp_dict, name, result);
1201		PyObjCNativeSelector* x = (PyObjCNativeSelector*)result;
1202
1203		if (x->sel_flags & PyObjCSelector_kCLASS_METHOD) {
1204			x->sel_self = self;
1205			Py_INCREF(x->sel_self);
1206		}
1207		if (res < 0) {
1208			if (PyObjC_VerboseLevel) {
1209				PySys_WriteStderr(
1210					"PyObjC[class_getattro]: Cannot "
1211					"add new method to dict:\n");
1212				PyErr_Print();
1213			}
1214			PyErr_Clear();
1215		}
1216	}
1217	return result;
1218}
1219
1220static int
1221class_setattro(PyObject* self, PyObject* name, PyObject* value)
1222{
1223	int res;
1224	if (value == NULL) {
1225		/* delattr(), deny the operation when the name is bound
1226		 * to a selector.
1227		 */
1228		PyObject* old_value = class_getattro(self, name);
1229		if (old_value == NULL) {
1230			PyErr_Clear();
1231			return PyType_Type.tp_setattro(self, name, value);
1232
1233		} else if (PyObjCSelector_Check(old_value)) {
1234			Py_DECREF(old_value);
1235			PyErr_Format(PyExc_AttributeError,
1236				"Cannot remove selector %R in '%s'",
1237				name,
1238				Py_TYPE(self)->tp_name
1239			);
1240
1241			return -1;
1242		}
1243	} else if (PyObjCNativeSelector_Check(value)) {
1244		PyErr_SetString(PyExc_TypeError,
1245			"Assigning native selectors is not supported");
1246		return -1;
1247
1248
1249	} else if (((PyObjCClassObject*)self)->isCFWrapper) {
1250		/* This is a wrapper class for a CoreFoundation type
1251		 * that isn't tollfree bridged. Don't update the
1252		 * Objective-C class because all CF types share the
1253		 * same ObjC class (except for the toll-free bridged
1254		 * ones).
1255		 */
1256
1257	} else if (PyObjCSelector_Check(value)
1258			|| PyFunction_Check(value)
1259			|| PyMethod_Check(value)
1260			|| PyObject_TypeCheck(value, &PyClassMethod_Type)
1261		) {
1262		/*
1263		 * Assignment of a function: create a new method in the ObjC
1264		 * runtime.
1265		 */
1266		PyObject* newVal;
1267		Method curMethod;
1268		Class  curClass;
1269		int r;
1270		BOOL b;
1271
1272		newVal = PyObjCSelector_FromFunction(
1273				name, value, self, NULL);
1274		if (newVal == NULL) {
1275			return -1;
1276		}
1277		if (!PyObjCSelector_Check(newVal)) {
1278			Py_DECREF(newVal);
1279			PyErr_SetString(PyExc_ValueError,
1280					"cannot convert callable to selector");
1281			return -1;
1282		}
1283
1284		if (PyObjCSelector_IsClassMethod(newVal)) {
1285			curMethod = class_getClassMethod(
1286					PyObjCClass_GetClass(self),
1287					PyObjCSelector_GetSelector(newVal));
1288			curClass = object_getClass(
1289						PyObjCClass_GetClass(self));
1290		} else {
1291			curMethod = class_getInstanceMethod(
1292					PyObjCClass_GetClass(self),
1293					PyObjCSelector_GetSelector(newVal));
1294			curClass = PyObjCClass_GetClass(self);
1295		}
1296
1297		if (curMethod) {
1298			method_setImplementation(curMethod,
1299				PyObjCFFI_MakeIMPForPyObjCSelector(
1300					(PyObjCSelector*)newVal));
1301		} else {
1302			char* types = strdup(
1303				PyObjCSelector_Signature(newVal));
1304			if (types == NULL) {
1305				Py_DECREF(newVal);
1306				return -1;
1307			}
1308			b = class_addMethod(
1309				curClass,
1310				PyObjCSelector_GetSelector(newVal),
1311				PyObjCFFI_MakeIMPForPyObjCSelector(
1312					(PyObjCSelector*)newVal),
1313				types);
1314			if (!b) {
1315				free(types);
1316				Py_DECREF(newVal);
1317				return -1;
1318			}
1319		}
1320
1321
1322
1323		if (PyObjCClass_HiddenSelector(self, PyObjCSelector_GetSelector(newVal),
1324				PyObjCSelector_IsClassMethod(newVal))) {
1325			Py_DECREF(newVal);
1326		} else {
1327			if (PyObjCSelector_IsClassMethod(newVal)) {
1328				r = PyDict_SetItem(Py_TYPE(self)->tp_dict, name, newVal);
1329
1330			} else {
1331				r = PyDict_SetItem(((PyTypeObject*)self)->tp_dict, name, newVal);
1332			}
1333			Py_DECREF(newVal);
1334			if (r == -1) {
1335				PyErr_NoMemory();
1336				return -1;
1337			}
1338		}
1339		return 0;
1340	}
1341
1342	res = PyType_Type.tp_setattro(self, name, value);
1343	return res;
1344}
1345
1346static PyObject* class_richcompare(PyObject* self, PyObject* other, int op)
1347{
1348	Class self_class;
1349	Class other_class;
1350	int   v;
1351
1352	if (!PyObjCClass_Check(other)) {
1353		if (op == Py_EQ) {
1354			Py_INCREF(Py_False);
1355			return Py_False;
1356		} else if (op == Py_NE) {
1357			Py_INCREF(Py_True);
1358			return Py_True;
1359		} else {
1360			Py_INCREF(Py_NotImplemented);
1361			return Py_NotImplemented;
1362		}
1363	}
1364
1365	/* This is as arbitrary as the default tp_compare, but nicer for
1366	 * the user
1367	 */
1368	self_class = PyObjCClass_GetClass(self);
1369	other_class = PyObjCClass_GetClass(other);
1370
1371	if (self_class == other_class) {
1372		v = 0;
1373	} else if (!self_class) {
1374		v = -1;
1375	} else if (!other_class) {
1376		v = 1;
1377	} else {
1378
1379		v = strcmp(
1380			class_getName(self_class),
1381			class_getName(other_class));
1382	}
1383
1384	PyObject* result;
1385	switch (op) {
1386	case Py_EQ:
1387		result = (v == 0) ? Py_True : Py_False;
1388		break;
1389	case Py_NE:
1390		result = (v != 0) ? Py_True : Py_False;
1391		break;
1392	case Py_LE:
1393		result = (v <= 0) ? Py_True : Py_False;
1394		break;
1395	case Py_LT:
1396		result = (v < 0) ? Py_True : Py_False;
1397		break;
1398	case Py_GE:
1399		result = (v >= 0) ? Py_True : Py_False;
1400		break;
1401	case Py_GT:
1402		result = (v > 0) ? Py_True : Py_False;
1403		break;
1404	default:
1405		PyErr_BadArgument();
1406		return NULL;
1407	}
1408
1409	Py_INCREF(result);
1410	return result;
1411}
1412
1413#if PY_MAJOR_VERSION == 2
1414static int
1415class_compare(PyObject* self, PyObject* other)
1416{
1417	Class self_class;
1418	Class other_class;
1419	int   v;
1420
1421	if (!PyObjCClass_Check(other)) {
1422		PyErr_SetString(PyExc_NotImplementedError, "Cmp with other");
1423		return -1;
1424	}
1425
1426	/* This is as arbitrary as the default tp_compare, but nicer for
1427	 * the user
1428	 */
1429	self_class = PyObjCClass_GetClass(self);
1430	other_class = PyObjCClass_GetClass(other);
1431
1432	if (self_class == other_class) return 0;
1433	if (!self_class) return -1;
1434	if (!other_class) return 1;
1435
1436	v = strcmp(
1437		class_getName(self_class),
1438		class_getName(other_class));
1439
1440	/* Python requires -1, 0 or 1, but strcmp on MacOS X returns
1441	 * 'negative', 0 or 'positive'
1442	 */
1443	if (v < 0) return -1;
1444	if (v == 0) return 0;
1445	return 1;
1446}
1447
1448#else
1449#define class_compare 0
1450#endif
1451
1452static long
1453class_hash(PyObject* self)
1454{
1455	return (long)self;
1456}
1457
1458PyDoc_STRVAR(cls_get_classMethods_doc,
1459"The attributes of this field are the class methods of this object. This can\n"
1460"be used to force access to a class method."
1461);
1462static PyObject*
1463cls_get_classMethods(PyObject* self, void* closure __attribute__((__unused__)))
1464{
1465	return PyObjCMethodAccessor_New(self, 1);
1466}
1467
1468PyDoc_STRVAR(cls_get_instanceMethods_doc,
1469"The attributes of this field are the instance methods of this object. This \n"
1470"can be used to force access to an instance method."
1471);
1472static PyObject*
1473cls_get_instanceMethods(PyObject* self, void* closure __attribute__((__unused__)))
1474{
1475	return PyObjCMethodAccessor_New(self, 0);
1476}
1477
1478static PyObject*
1479cls_get__name__(PyObject* self, void* closure __attribute__((__unused__)))
1480{
1481	Class cls = PyObjCClass_GetClass(self);
1482	if (cls == NULL) {
1483		return PyText_FromString("objc.objc_class");
1484	} else {
1485		const char* nm = class_getName(cls);
1486		if (strstr(nm, "NSCFType") != NULL) {
1487			return PyText_FromString(((PyTypeObject*)self)->tp_name);
1488		} else {
1489			return PyText_FromString(nm);
1490		}
1491	}
1492}
1493
1494PyDoc_STRVAR(cls_version_doc, "get/set the version of a class");
1495static PyObject*
1496cls_get_version(PyObject* self, void* closure __attribute__((__unused__)))
1497{
1498	Class cls = PyObjCClass_GetClass(self);
1499	if (cls == NULL) {
1500		Py_INCREF(Py_None);
1501		return Py_None;
1502	} else {
1503		return PyInt_FromLong(class_getVersion(cls));
1504	}
1505}
1506static  int
1507cls_set_version(PyObject* self, PyObject* newVal, void* closure __attribute__((__unused__)))
1508{
1509	Class cls = PyObjCClass_GetClass(self);
1510	int   val;
1511	int   r;
1512
1513	r = depythonify_c_value(@encode(int), newVal, &val);
1514	if (r == -1) {
1515		return -1;
1516	}
1517	class_setVersion(cls, val);
1518	return 0;
1519}
1520
1521
1522static PyGetSetDef class_getset[] = {
1523	{
1524		"pyobjc_classMethods",
1525		cls_get_classMethods,
1526		NULL,
1527		cls_get_classMethods_doc,
1528		0
1529	},
1530	{
1531		"pyobjc_instanceMethods",
1532		cls_get_instanceMethods,
1533		NULL,
1534		cls_get_instanceMethods_doc,
1535		0
1536	},
1537	{
1538		"__version__",
1539		cls_get_version,
1540		cls_set_version,
1541		cls_version_doc,
1542		0
1543	},
1544
1545	{
1546		/* Access __name__ through a property: Objective-C name
1547		 * might change due to posing.
1548		 */
1549		"__name__",
1550		cls_get__name__,
1551		NULL,
1552		NULL,
1553		0
1554	},
1555	{ 0, 0, 0, 0, 0 }
1556};
1557
1558static PyMemberDef class_members[] = {
1559	{
1560		"__useKVO__",
1561		T_INT,
1562		offsetof(PyObjCClassObject, useKVO),
1563		0,
1564		"Use KVO notifications when setting attributes from Python",
1565	},
1566	{ NULL, 0, 0, 0, NULL}
1567};
1568
1569
1570PyTypeObject PyObjCClass_Type = {
1571	PyVarObject_HEAD_INIT(&PyType_Type, 0)
1572	"objc_class",				/* tp_name */
1573	sizeof (PyObjCClassObject),		/* tp_basicsize */
1574	0,					/* tp_itemsize */
1575	/* methods */
1576	class_dealloc,	 			/* tp_dealloc */
1577	0,					/* tp_print */
1578	0,					/* tp_getattr */
1579	0,					/* tp_setattr */
1580	class_compare,				/* tp_compare */
1581	class_repr,				/* tp_repr */
1582	0,					/* tp_as_number */
1583	0,					/* tp_as_sequence */
1584	0,		       			/* tp_as_mapping */
1585	class_hash,				/* tp_hash */
1586	0,					/* tp_call */
1587	0,					/* tp_str */
1588	class_getattro,				/* tp_getattro */
1589	class_setattro,				/* tp_setattro */
1590	0,					/* tp_as_buffer */
1591	Py_TPFLAGS_DEFAULT
1592		| Py_TPFLAGS_BASETYPE,		/* tp_flags */
1593	class_doc,				/* tp_doc */
1594	0,					/* tp_traverse */
1595	0,					/* tp_clear */
1596	class_richcompare,			/* tp_richcompare */
1597	0,					/* tp_weaklistoffset */
1598	0,					/* tp_iter */
1599	0,					/* tp_iternext */
1600	0,					/* tp_methods */
1601	class_members,					/* tp_members */
1602	class_getset,				/* tp_getset */
1603	&PyType_Type,				/* tp_base */
1604	0,					/* tp_dict */
1605	0,					/* tp_descr_get */
1606	0,					/* tp_descr_set */
1607	0,					/* tp_dictoffset */
1608	class_init,				/* tp_init */
1609	0,					/* tp_alloc */
1610	class_new,				/* tp_new */
1611	0,		        		/* tp_free */
1612	0,					/* tp_is_gc */
1613	0,					/* tp_bases */
1614	0,                                      /* tp_mro */
1615	0,                                      /* tp_cache */
1616	0,                                      /* tp_subclasses */
1617	0,                                      /* tp_weaklist */
1618	0                                       /* tp_del */
1619#if PY_VERSION_HEX >= 0x02060000
1620	, 0                                     /* tp_version_tag */
1621#endif
1622
1623};
1624
1625char*
1626PyObjC_SELToPythonName(SEL sel, char* buf, size_t buflen)
1627{
1628	size_t res = snprintf(buf, buflen, "%s", sel_getName(sel));
1629	char* cur;
1630
1631	if (res != strlen(sel_getName(sel))) {
1632		return NULL;
1633	}
1634	if (PyObjC_IsPythonKeyword(buf)) {
1635		res = snprintf(buf, buflen, "%s__", sel_getName(sel));
1636		if (res != 2+strlen(sel_getName(sel))) {
1637			return NULL;
1638		}
1639		return buf;
1640	}
1641	cur = strchr(buf, ':');
1642	while (cur) {
1643		*cur = '_';
1644		cur = strchr(cur, ':');
1645	}
1646	return buf;
1647}
1648
1649/*
1650 * Add methods and descriptors for the instance variables to the dict.
1651 *
1652 * Add only the items for this specific class, the items from the super-class
1653 * are found through inheritance.
1654 *
1655 * We add instance methods, class methods and instance variables in that
1656 * order, methods always override variables (most classes provide accessor
1657 * methods with the same name as the variables and this order is the least
1658 * surprising)
1659 */
1660static int
1661add_class_fields(Class objc_class, PyObject* py_class, PyObject* pubDict, PyObject* protDict, PyObject* classDict)
1662{
1663	Class     cls;
1664	Method*   methods;
1665	unsigned int method_count, i;
1666	PyObject* descr;
1667	char      selbuf[1024];
1668	PyObject* dict;
1669
1670	if (objc_class == NULL) return 0;
1671
1672	/*
1673	 * First add instance methods
1674	 */
1675
1676	methods = class_copyMethodList(objc_class, &method_count);
1677	for (i = 0; i < method_count; i++) {
1678		char* name;
1679		PyObject* curItem;
1680
1681		dict = pubDict;
1682		if (*sel_getName(method_getName(methods[i])) == '_') {
1683			if (PyObjC_HideProtected) {
1684				dict = protDict;
1685			}
1686		}
1687
1688		/* Check if the selector should be hidden */
1689		if (PyObjCClass_HiddenSelector(py_class,
1690					method_getName(methods[i]), NO)) {
1691			continue;
1692		}
1693
1694
1695		name = (char*)PyObjC_SELToPythonName(
1696					method_getName(methods[i]),
1697					selbuf,
1698					sizeof(selbuf));
1699		if (name == NULL) continue;
1700
1701		curItem = PyDict_GetItemString(dict, name);
1702		if (curItem == NULL) {
1703			PyErr_Clear();
1704		} else if (!PyObjCNativeSelector_Check(curItem)) {
1705			continue;
1706		}
1707
1708		descr = PyObjCSelector_NewNative(
1709				objc_class,
1710				method_getName(methods[i]),
1711				method_getTypeEncoding(methods[i]),
1712				NO);
1713
1714		if (PyDict_SetItemString(
1715				dict,
1716				name,
1717				descr) != 0) {
1718
1719			Py_DECREF(descr);
1720			free(methods);
1721			return -1;
1722		}
1723		Py_DECREF(descr);
1724	}
1725	free(methods);
1726
1727
1728
1729	/*
1730	 * Then add class methods
1731	 */
1732
1733
1734	cls = object_getClass(objc_class);
1735	methods = class_copyMethodList(cls, &method_count);
1736	for (i = 0; i < method_count; i++) {
1737		PyObject* curItem;
1738		char* name;
1739
1740		dict = classDict;
1741
1742		/* Check if the selector should be hidden */
1743		if (PyObjCClass_HiddenSelector(py_class,
1744					method_getName(methods[i]), YES)) {
1745			continue;
1746		}
1747
1748		name = PyObjC_SELToPythonName(
1749			method_getName(methods[i]),
1750			selbuf,
1751			sizeof(selbuf));
1752		if (name == NULL) continue;
1753
1754		curItem = PyDict_GetItemString(dict, name);
1755		if (curItem == NULL) {
1756		} else if (!PyObjCNativeSelector_Check(curItem)) {
1757			continue;
1758		}
1759
1760		descr = PyObjCSelector_NewNative(
1761			objc_class,
1762			method_getName(methods[i]),
1763			method_getTypeEncoding(methods[i]),
1764			YES);
1765
1766		if (PyDict_SetItemString(dict,
1767				selbuf,
1768				descr) != 0) {
1769			Py_DECREF(descr);
1770			free(methods);
1771			return -1;
1772		}
1773		Py_DECREF(descr);
1774	}
1775	free(methods);
1776
1777	return  0;
1778}
1779
1780/*
1781 * Create a new objective-C class  proxy.
1782 *
1783 * NOTES:
1784 * - proxies are subclasses of PyObjCClass_Type
1785 * - subclass relations in objetive-C are retained in python
1786 * - this looks a lot like PyObjCClass_Type.tp_new, but it is _not_ the
1787 *   same!
1788 *
1789 * Returns a new reference.
1790 */
1791PyObject*
1792PyObjCClass_New(Class objc_class)
1793{
1794	PyObject* args;
1795	PyObject* dict;
1796	PyObject* result;
1797	PyObject* bases;
1798	PyObjCClassObject* info;
1799	Ivar var;
1800	PyObject* protectedMethods;
1801	PyObject* hiddenSelectors;
1802	PyTypeObject* metaclass;
1803	const char* className;
1804
1805	result = objc_class_locate(objc_class);
1806	if (result != NULL) {
1807		return result;
1808	}
1809
1810
1811	if (class_isMetaClass(objc_class)) {
1812		result =  (PyObject*)PyObjCClass_NewMetaClass(objc_class);
1813		Py_DECREF(result);
1814		return result;
1815	}
1816
1817	protectedMethods = PyDict_New();
1818	if (protectedMethods == NULL) {
1819		return NULL;
1820	}
1821
1822	hiddenSelectors = PySet_New(NULL);
1823	if (hiddenSelectors == NULL) {
1824		Py_DECREF(protectedMethods);
1825		return NULL;
1826	}
1827
1828	metaclass = PyObjCClass_NewMetaClass(objc_class);
1829	if (metaclass == NULL) {
1830		Py_DECREF(hiddenSelectors);
1831		Py_DECREF(protectedMethods);
1832		return NULL;
1833	}
1834
1835
1836
1837	dict = PyDict_New();
1838	PyDict_SetItemString(dict, "__slots__", PyTuple_New(0));
1839
1840	bases = PyTuple_New(1);
1841
1842	if (class_getSuperclass(objc_class) == NULL) {
1843		PyTuple_SET_ITEM(bases, 0, (PyObject*)&PyObjCObject_Type);
1844		Py_INCREF(((PyObject*)&PyObjCObject_Type));
1845	} else {
1846		PyTuple_SET_ITEM(bases, 0,
1847			PyObjCClass_New(class_getSuperclass(objc_class)));
1848	}
1849	args = PyTuple_New(3);
1850	className = class_getName(objc_class);
1851	PyTuple_SetItem(args, 0, PyText_FromString(className));
1852	PyTuple_SetItem(args, 1, bases);
1853	PyTuple_SetItem(args, 2, dict);
1854	bases = NULL; dict = NULL;
1855
1856	result = PyType_Type.tp_new(metaclass, args, NULL);
1857	Py_DECREF(args); Py_DECREF(metaclass);
1858	if (result == NULL) {
1859		Py_DECREF(hiddenSelectors);
1860		Py_DECREF(protectedMethods);
1861		return NULL;
1862	}
1863
1864	info = (PyObjCClassObject*)result;
1865	info->class = objc_class;
1866	info->sel_to_py = NULL;
1867	info->method_magic = 0;
1868	info->dictoffset = 0;
1869	info->useKVO = 1;
1870	info->delmethod = NULL;
1871	info->hasPythonImpl = 0;
1872	info->isCFWrapper = 0;
1873	info->protectedMethods = protectedMethods;
1874	info->hiddenSelectors = hiddenSelectors;
1875
1876	objc_class_register(objc_class, result);
1877
1878	/*
1879	 * Support the buffer protocol in the wrappers for NSData and
1880	 * NSMutableData, the only two classes where this makes sense.
1881	 */
1882	if (strcmp(className, "NSMutableData") == 0) {
1883		((PyTypeObject *)result)->tp_as_buffer = &nsmutabledata_as_buffer;
1884#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
1885		((PyTypeObject *)result)->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
1886#endif
1887		PyType_Modified((PyTypeObject*)result);
1888		PyType_Ready((PyTypeObject *)result);
1889	} else if (strcmp(className, "NSData") == 0) {
1890		((PyTypeObject *)result)->tp_as_buffer = &nsdata_as_buffer;
1891#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 6
1892		((PyTypeObject *)result)->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
1893#endif
1894		PyType_Modified((PyTypeObject*)result);
1895		PyType_Ready((PyTypeObject *)result);
1896	} else if (strcmp(className, "NSBlock") == 0) {
1897		((PyTypeObject *)result)->tp_basicsize = sizeof(PyObjCBlockObject);
1898		PyType_Modified((PyTypeObject*)result);
1899		PyType_Ready((PyTypeObject *)result);
1900	}
1901
1902	var = class_getInstanceVariable(objc_class, "__dict__");
1903	if (var != NULL) {
1904		info->dictoffset = ivar_getOffset(var);
1905	}
1906
1907	if (PyObject_SetAttrString(result,
1908			"__module__", PyObjCClass_DefaultModule) < 0) {
1909		PyErr_Clear();
1910	}
1911
1912
1913	return result;
1914}
1915
1916PyObject*
1917PyObjCClass_ListProperties(PyObject* aClass)
1918{
1919	Class cls = Nil;
1920	Protocol* proto = nil;
1921
1922	if (PyObjCClass_Check(aClass)) {
1923		cls = PyObjCClass_GetClass(aClass);
1924		if (cls == Nil) {
1925			return NULL;
1926		}
1927	} else if (PyObjCFormalProtocol_Check(aClass)) {
1928		proto = PyObjCFormalProtocol_GetProtocol(aClass);
1929		if (proto == nil) {
1930			return NULL;
1931		}
1932	} else {
1933		PyErr_SetString(PyExc_TypeError,
1934		      "class must be an Objective-C class or formal protocol");
1935		return NULL;
1936	}
1937
1938	objc_property_t* props;
1939	unsigned int propcount, i;
1940	char buf[128];
1941
1942	if (cls == Nil) {
1943		return NULL;
1944	}
1945
1946	PyObject* result = PyList_New(0);
1947	if (result == NULL) {
1948		return NULL;
1949	}
1950
1951	if (class_copyPropertyList == NULL) {
1952		/* System without the 2.0 runtime and hence without
1953		 * native properties
1954		 */
1955		return result;
1956	}
1957
1958	if (cls) {
1959		props = class_copyPropertyList(cls, &propcount);
1960	} else {
1961		props = protocol_copyPropertyList(proto, &propcount);
1962	}
1963	if (props == NULL) {
1964		return result;
1965	}
1966
1967	for (i = 0; i < propcount; i++) {
1968		PyObject* item;
1969		PyObject* v;
1970		const char* name = property_getName(props[i]);
1971		const char* attr = property_getAttributes(props[i]);
1972		const char* e;
1973
1974		item = Py_BuildValue(
1975			"{sss"Py_ARG_BYTES"}",
1976			"name", name,
1977			"raw_attr", attr);
1978		if (item == NULL) {
1979			goto error;
1980		}
1981		if (PyList_Append(result, item) == -1) {
1982			Py_DECREF(item);
1983			goto error;
1984		}
1985		Py_DECREF(item);
1986
1987		if (*attr != 'T') {
1988			/* Attribute string doesn't conform to the
1989			 * 2.0 protocol, don't try to process it.
1990			 */
1991			continue;
1992		}
1993
1994		e = PyObjCRT_SkipTypeSpec(attr+1);
1995		if (e == NULL) {
1996			goto error;
1997		}
1998		if (e - (attr+1) > 127) {
1999			v = PyBytes_InternFromStringAndSize(attr+1, e - (attr+1));
2000		} else {
2001			PyObjCRT_RemoveFieldNames(buf, attr+1);
2002			v = PyBytes_InternFromString(buf);
2003		}
2004		if (v == NULL) {
2005			goto error;
2006		}
2007
2008		if (PyDict_SetItemString(item, "typestr", v) == -1) {
2009			Py_DECREF(v);
2010			goto error;
2011		}
2012		Py_DECREF(v); v = NULL;
2013
2014		attr = e;
2015		if (*attr == '"') {
2016			e = strchr(attr+1, '"');
2017			v = PyText_FromStringAndSize(attr+1, e-(attr+1));
2018			if (v == NULL) {
2019				goto error;
2020			}
2021			if (PyDict_SetItemString(item, "classname", v) == -1) {
2022				Py_DECREF(v);
2023				goto error;
2024			}
2025			Py_DECREF(v); v = NULL;
2026			attr = e + 1;
2027		}
2028
2029		if (*attr++ != ',') {
2030			/* Value doesn't conform to 2.0 protocol */
2031			continue;
2032		}
2033
2034		while (attr && *attr != '\0') {
2035			switch (*attr++) {
2036			case 'R':
2037				if (PyDict_SetItemString(item, "readonly", Py_True) < 0) {
2038					goto error;
2039				}
2040				break;
2041			case 'C':
2042				if (PyDict_SetItemString(item, "copy", Py_True) < 0) {
2043					goto error;
2044				}
2045				break;
2046			case '&':
2047				if (PyDict_SetItemString(item, "retain", Py_True) < 0) {
2048					goto error;
2049				}
2050				break;
2051			case 'N':
2052				if (PyDict_SetItemString(item, "nonatomic", Py_True) < 0) {
2053					goto error;
2054				}
2055				break;
2056			case 'D':
2057				if (PyDict_SetItemString(item, "dynamic", Py_True) < 0) {
2058					goto error;
2059				}
2060				break;
2061			case 'W':
2062				if (PyDict_SetItemString(item, "weak", Py_True) < 0) {
2063					goto error;
2064				}
2065				break;
2066			case 'P':
2067				if (PyDict_SetItemString(item, "collectable", Py_True) < 0) {
2068					goto error;
2069				}
2070				break;
2071			case 'G':
2072				e = strchr(attr, ',');
2073				if (e == NULL) {
2074					v = PyBytes_FromString(attr);
2075					attr = e;
2076				} else {
2077					v = PyBytes_FromStringAndSize(
2078						attr, e - attr);
2079					attr = e;
2080				}
2081				if (v == NULL) {
2082					goto error;
2083				}
2084				if (PyDict_SetItemString(item, "getter", v) < 0){
2085					Py_DECREF(v);
2086					goto error;
2087				}
2088				break;
2089			case 'S':
2090				e = strchr(attr, ',');
2091				if (e == NULL) {
2092					v = PyBytes_FromString(attr);
2093					attr = e;
2094				} else {
2095					v = PyBytes_FromStringAndSize(
2096						attr, e - attr);
2097					attr = e;
2098				}
2099				if (v == NULL) {
2100					goto error;
2101				}
2102				if (PyDict_SetItemString(item, "setter", v) < 0){
2103					Py_DECREF(v);
2104					goto error;
2105				}
2106				break;
2107			case 'V':
2108				attr = NULL;
2109				break;
2110			}
2111		}
2112	}
2113	free(props); props = NULL;
2114
2115	return result;
2116error:
2117	if (props) {
2118		free(props);
2119	}
2120	Py_XDECREF(result);
2121	return NULL;
2122}
2123
2124
2125Class
2126PyObjCClass_GetClass(PyObject* cls)
2127{
2128	if (!PyObjCClass_Check(cls)) {
2129		PyErr_Format(PyObjCExc_InternalError,
2130			"PyObjCClass_GetClass called for non-class (%s)",
2131			Py_TYPE(cls)->tp_name);
2132		return Nil;
2133	}
2134
2135	return ((PyObjCClassObject*)cls)->class;
2136}
2137
2138PyObject*
2139PyObjCClass_FindSelector(PyObject* cls, SEL selector, BOOL class_method)
2140{
2141	PyObjCClassObject* info;
2142	PyObject*          result;
2143
2144	if (!PyObjCClass_Check(cls)) {
2145		PyErr_Format(PyObjCExc_InternalError,
2146			"PyObjCClass_GetClass called for non-class (%s)",
2147			Py_TYPE(cls)->tp_name);
2148		return NULL;
2149	}
2150
2151	PyObjCClass_CheckMethodList(cls, 1);
2152
2153
2154	info = (PyObjCClassObject*)cls;
2155	if (info->sel_to_py == NULL) {
2156		info->sel_to_py = PyDict_New();
2157		if (info->sel_to_py == NULL) {
2158			return NULL;
2159		}
2160	}
2161
2162	if (PyObjCClass_HiddenSelector(cls, selector, class_method)) {
2163		PyErr_Format(PyExc_AttributeError,
2164			"No selector %s", sel_getName(selector));
2165		PyDict_SetItemString(info->sel_to_py,
2166				(char*)sel_getName(selector), Py_None);
2167		return NULL;
2168	}
2169
2170	/* First check the cache */
2171
2172	result = PyDict_GetItemString(info->sel_to_py,
2173				(char*)sel_getName(selector));
2174	if (result != NULL) {
2175		if (result == Py_None) {
2176			/* negative cache entry */
2177			PyErr_Format(PyExc_AttributeError,
2178				"No selector %s",
2179				sel_getName(selector));
2180			return NULL;
2181		}
2182		Py_INCREF(result);
2183		return result;
2184	}
2185
2186
2187	/* Not in the cache. Walk the MRO to check
2188	 * every method object.
2189	 *
2190	 * (We could also generate the most likely
2191	 * python name and check that, but the most
2192	 * likely reason we're called is that this
2193	 * method doesn't exist or isn't good enough)
2194	 */
2195
2196	PyObject* mro = ((PyTypeObject*)cls)->tp_mro;
2197	Py_ssize_t i, n;
2198
2199	n = PyTuple_GET_SIZE(mro);
2200	for (i = 0; i < n; i++) {
2201		PyObject* c = PyTuple_GET_ITEM(mro, i);
2202
2203		if (!PyObjCClass_Check(c)) {
2204			continue;
2205		}
2206
2207		PyObject* dict;
2208
2209		if (class_method) {
2210			dict = Py_TYPE(c)->tp_dict;
2211		} else {
2212			dict = ((PyTypeObject*)c)->tp_dict;
2213		}
2214
2215		PyObject* value;
2216		Py_ssize_t pos = 0;
2217
2218		while (PyDict_Next(dict, &pos, NULL, &value)) {
2219			if (!PyObjCSelector_Check(value)) continue;
2220
2221			if (sel_isEqual(PyObjCSelector_GetSelector(value), selector)) {
2222				PyDict_SetItemString(info->sel_to_py,
2223					(char*)sel_getName(selector), value);
2224				Py_INCREF(value);
2225				return value;
2226			}
2227		}
2228	}
2229
2230	/* If all else fails, ask the actual class (getattro also does this) */
2231	result = PyObjCSelector_FindNative(cls,
2232				sel_getName(selector));
2233	if (result) {
2234		return result;
2235	}
2236
2237	PyErr_Format(PyExc_AttributeError,
2238		"No selector %s", sel_getName(selector));
2239	PyDict_SetItemString(info->sel_to_py,
2240			(char*)sel_getName(selector), Py_None);
2241	return NULL;
2242}
2243
2244Py_ssize_t
2245PyObjCClass_DictOffset(PyObject* cls)
2246{
2247	return ((PyObjCClassObject*)cls)->dictoffset;
2248}
2249
2250PyObject*
2251PyObjCClass_GetDelMethod(PyObject* cls)
2252{
2253	PyObjCClassObject* info;
2254	info = (PyObjCClassObject*)cls;
2255	Py_XINCREF(info->delmethod);
2256	return info->delmethod;
2257}
2258
2259void
2260PyObjCClass_SetDelMethod(PyObject* cls, PyObject* m)
2261{
2262	PyObjCClassObject* info;
2263	info = (PyObjCClassObject*)cls;
2264	Py_XINCREF(m);
2265	Py_XDECREF(info->delmethod);
2266	info->delmethod = m;
2267}
2268
2269int
2270PyObjCClass_HasPythonImplementation(PyObject* cls)
2271{
2272	PyObjCClassObject* info;
2273	info = (PyObjCClassObject*)cls;
2274	return info->hasPythonImpl;
2275}
2276
2277
2278
2279/*!
2280 * @function add_convenience_methods
2281 * @abstract Add the convenience methods for a class wrapper
2282 * @param cls  An Objective-C class wrapper
2283 * @param type_dict the __dict__ for the new class
2284 * @result Returns -1 on error, 0 on success
2285 * @discussion
2286 *     This function calls the PyObjC_ClassExtender function (if one is
2287 *     registered) and then updates the class __dict__.
2288 */
2289static int
2290add_convenience_methods(Class cls, PyObject* type_dict)
2291{
2292	PyObject* super_class;
2293	PyObject* name;
2294	PyObject* res;
2295	PyObject* args;
2296
2297	if (PyObjC_ClassExtender == NULL || cls == nil) return 0;
2298
2299	if (class_getSuperclass(cls) == nil) {
2300		super_class = Py_None;
2301		Py_INCREF(super_class);
2302	} else {
2303		super_class = PyObjCClass_New(class_getSuperclass(cls));
2304		if (super_class == NULL) {
2305			return -1;
2306		}
2307	}
2308
2309	name = PyText_FromString(class_getName(cls));
2310	if (name == NULL) {
2311		Py_DECREF(super_class);
2312		return -1;
2313	}
2314
2315	args = PyTuple_New(3);
2316	if (args == NULL) {
2317		Py_DECREF(super_class);
2318		Py_DECREF(name);
2319		return -1;
2320	}
2321
2322	PyTuple_SET_ITEM(args, 0, super_class);
2323	PyTuple_SET_ITEM(args, 1, name);
2324	PyTuple_SET_ITEM(args, 2, type_dict);
2325	Py_INCREF(type_dict);
2326
2327	res = PyObject_CallObject(PyObjC_ClassExtender, args);
2328	Py_DECREF(args);
2329	if (res == NULL) {
2330		return -1;
2331	}
2332	Py_DECREF(res);
2333
2334	return 0;
2335}
2336
2337/*!
2338 * @function update_convenience_methods
2339 * @abstract Update the convenience methods for a class
2340 * @param cls  An Objective-C class wrapper
2341 * @result Returns -1 on error, 0 on success
2342 * @discussion
2343 *     This function calls the PyObjC_ClassExtender function (if one is
2344 *     registered) and then updates the class __dict__.
2345 *
2346 *     NOTE: We change the __dict__ using a setattro function because the type
2347 *     doesn't notice the existance of new special methods otherwise.
2348 *
2349 *     NOTE2: We use PyType_Type.tp_setattro instead of PyObject_SetAttr because
2350 *     the tp_setattro of Objective-C class wrappers does not allow some of
2351 *     the assignments we do here.
2352 */
2353static int
2354update_convenience_methods(PyObject* cls)
2355{
2356	PyObject* super_class;
2357	PyObject* name;
2358	PyObject* res;
2359	PyObject* args;
2360	Class     objc_cls;
2361	PyObject* dict;
2362	PyObject* keys;
2363	PyObject* v;
2364	Py_ssize_t i, len;
2365
2366	if (PyObjC_ClassExtender == NULL || cls == NULL) return 0;
2367
2368	if (!PyObjCClass_Check(cls)) {
2369		PyErr_SetString(PyExc_TypeError, "not a class");
2370		return -1;
2371	}
2372
2373	objc_cls = PyObjCClass_GetClass(cls);
2374
2375	if (class_getSuperclass(objc_cls) == nil) {
2376		super_class = Py_None;
2377		Py_INCREF(super_class);
2378	} else {
2379		super_class = PyObjCClass_New(class_getSuperclass(objc_cls));
2380		if (super_class == NULL) {
2381			return -1;
2382		}
2383	}
2384
2385	name = PyText_FromString(class_getName(objc_cls));
2386	if (name == NULL) {
2387		Py_DECREF(super_class);
2388		return -1;
2389	}
2390
2391	dict = /*PyDict_Copy*/(((PyTypeObject*)cls)->tp_dict);
2392	Py_INCREF(dict);
2393	if (dict == NULL) {
2394		Py_DECREF(super_class);
2395		Py_DECREF(name);
2396		return -1;
2397	}
2398
2399	args = PyTuple_New(3);
2400	if (args == NULL) {
2401		Py_DECREF(super_class);
2402		Py_DECREF(name);
2403		Py_DECREF(dict);
2404		return -1;
2405	}
2406
2407	PyTuple_SET_ITEM(args, 0, super_class);
2408	PyTuple_SET_ITEM(args, 1, name);
2409	PyTuple_SET_ITEM(args, 2, dict);
2410
2411	res = PyObject_Call(PyObjC_ClassExtender, args, NULL);
2412	if (res == NULL) {
2413		Py_DECREF(args);
2414		return -1;
2415	}
2416	Py_DECREF(res);
2417	keys = PyDict_Keys(dict);
2418	if (keys == NULL) {
2419		Py_DECREF(args);
2420		return -1;
2421	}
2422
2423	v = PySequence_Fast(keys, "PyDict_Keys didn't return a sequence");
2424	Py_DECREF(keys);
2425	if (v == NULL) {
2426		return -1;
2427	}
2428	keys = v;
2429
2430	len = PySequence_Fast_GET_SIZE(keys);
2431	for (i = 0; i < len; i++) {
2432		PyObject* k = PySequence_Fast_GET_ITEM(keys, i);
2433
2434		if (k == NULL) {
2435			PyErr_Clear();
2436			continue;
2437		}
2438
2439		if (PyUnicode_Check(k)) {
2440			if (!PyObjC_is_ascii_prefix(k, "__", 2)) {
2441				continue;
2442			} else if (
2443					PyObjC_is_ascii_string(k, "__dict__")
2444				    ||	PyObjC_is_ascii_string(k, "__bases__")
2445				    ||	PyObjC_is_ascii_string(k, "__slots__")
2446				    ||	PyObjC_is_ascii_string(k, "__mro__")
2447			     ) {
2448
2449				continue;
2450			}
2451#if PY_MAJOR_VERSION == 2
2452
2453		} else if (PyString_Check(k)) {
2454			char* n = PyString_AS_STRING(k);
2455			if (n[0] != '_' || n[1] != '_') {
2456				continue;
2457			}
2458			if (	   strcmp(n, "__dict__") == 0
2459				|| strcmp(n, "__bases__") == 0
2460				|| strcmp(n, "__slots__") == 0
2461				|| strcmp(n, "__mro__") == 0
2462			   ) {
2463
2464				continue;
2465			}
2466#endif
2467		} else {
2468			continue;
2469		}
2470
2471		v = PyDict_GetItem(dict, k);
2472		if (v == NULL) {
2473			PyErr_Clear();
2474			continue;
2475		}
2476		if (PyType_Type.tp_setattro(cls, k, v) == -1) {
2477			PyErr_Clear();
2478			continue;
2479		}
2480	}
2481	Py_DECREF(keys);
2482	Py_DECREF(args);
2483
2484	return 0;
2485}
2486
2487
2488PyObject* PyObjCClass_ClassForMetaClass(PyObject* meta)
2489{
2490	if (meta == NULL) return NULL;
2491
2492	return PyObjCClass_New(objc_metaclass_locate(meta));
2493}
2494
2495
2496int PyObjCClass_AddMethods(PyObject* classObject, PyObject** methods, Py_ssize_t methodCount)
2497{
2498	Class targetClass;
2499	Py_ssize_t methodIndex;
2500	int r;
2501	struct PyObjC_method *methodsToAdd;
2502	size_t curMethodIndex;
2503	struct PyObjC_method *classMethodsToAdd;
2504	size_t curClassMethodIndex;
2505	PyObject* extraDict = NULL;
2506	PyObject* metaDict = NULL;
2507
2508	targetClass  = PyObjCClass_GetClass(classObject);
2509	if (targetClass == NULL) {
2510		return -1;
2511	}
2512
2513	if (methodCount == 0) {
2514		return 0;
2515	}
2516
2517	extraDict = PyDict_New();
2518	if (extraDict == NULL) {
2519		return -1;
2520	}
2521
2522	metaDict = PyDict_New();
2523	if (metaDict == NULL) {
2524		Py_DECREF(extraDict);
2525		return -1;
2526	}
2527
2528	methodsToAdd = PyMem_Malloc(sizeof(*methodsToAdd) * methodCount);
2529	if (methodsToAdd == NULL) {
2530		Py_DECREF(extraDict);
2531		Py_DECREF(metaDict);
2532		PyErr_NoMemory();
2533		return -1;
2534	}
2535
2536	classMethodsToAdd = PyMem_Malloc(sizeof(*methodsToAdd) * methodCount);
2537	if (classMethodsToAdd == NULL) {
2538		Py_DECREF(extraDict);
2539		Py_DECREF(metaDict);
2540		PyMem_Free(methodsToAdd);
2541		PyErr_NoMemory();
2542		return -1;
2543	}
2544
2545	curMethodIndex = 0;
2546	curClassMethodIndex = 0;
2547
2548	for (methodIndex = 0; methodIndex < methodCount; methodIndex++) {
2549		PyObject* aMethod = methods[methodIndex];
2550		PyObject* name;
2551		struct PyObjC_method *objcMethod;
2552
2553		if (PyObjCNativeSelector_Check(aMethod)) {
2554			PyErr_Format(PyExc_TypeError,
2555				"Cannot add a native selector to other "
2556				"classes");
2557			goto cleanup_and_return_error;
2558		}
2559
2560		aMethod = PyObjCSelector_FromFunction(
2561			NULL,
2562			aMethod,
2563			classObject,
2564			NULL);
2565		if (aMethod == NULL) {
2566			PyErr_Format(PyExc_TypeError ,
2567			      "All objects in methodArray must be of "
2568			      "type <objc.selector>, <function>, "
2569			      " <method> or <classmethod>");
2570			goto cleanup_and_return_error;
2571		}
2572
2573		/* install in methods to add */
2574		if (PyObjCSelector_IsClassMethod(aMethod)) {
2575			objcMethod = classMethodsToAdd + curClassMethodIndex++;
2576		} else {
2577			objcMethod = methodsToAdd + curMethodIndex++;
2578		}
2579
2580		objcMethod->name = PyObjCSelector_GetSelector(aMethod);
2581		objcMethod->type = strdup(
2582				PyObjCSelector_Signature(aMethod));
2583
2584		PyObjC_RemoveInternalTypeCodes((char*)(objcMethod->type));
2585		if (objcMethod->type == NULL) {
2586			goto cleanup_and_return_error;
2587		}
2588		objcMethod->imp = PyObjCFFI_MakeIMPForPyObjCSelector(
2589			(PyObjCSelector*)aMethod);
2590
2591		name = PyObject_GetAttrString(aMethod, "__name__");
2592
2593#if PY_MAJOR_VERSION == 3
2594		if (PyBytes_Check(name)) {
2595			PyObject* t = PyUnicode_Decode(
2596					PyBytes_AsString(name),
2597					PyBytes_Size(name),
2598					NULL, NULL);
2599			if (t == NULL) {
2600				Py_DECREF(name); name = NULL;
2601				Py_DECREF(aMethod); aMethod = NULL;
2602				goto cleanup_and_return_error;
2603			}
2604			Py_DECREF(name);
2605			name = t;
2606		}
2607#endif
2608		if (PyObjCSelector_IsHidden(aMethod)) {
2609			r = PyObjCClass_SetHidden(classObject, objcMethod->name, PyObjCSelector_IsClassMethod(aMethod),
2610					(PyObject*)PyObjCSelector_GetMetadata(aMethod));
2611			if (r == -1) {
2612				goto cleanup_and_return_error;
2613			}
2614		}
2615
2616		r = 0;
2617		if (!PyObjCClass_HiddenSelector(classObject, objcMethod->name,
2618					PyObjCSelector_IsClassMethod(aMethod))) {
2619			if (PyObjCSelector_IsClassMethod(aMethod)) {
2620				r = PyDict_SetItem(metaDict, name, aMethod);
2621			} else {
2622				r = PyDict_SetItem(extraDict, name, aMethod);
2623			}
2624		}
2625		Py_DECREF(name); name = NULL;
2626		Py_DECREF(aMethod); aMethod = NULL;
2627		if (r == -1) {
2628			goto cleanup_and_return_error;
2629		}
2630	}
2631
2632	/* add the methods */
2633	if (curMethodIndex != 0) {
2634		class_addMethodList(targetClass, methodsToAdd, curMethodIndex);
2635	}
2636	PyMem_Free(methodsToAdd);
2637	if (curClassMethodIndex != 0) {
2638		class_addMethodList(object_getClass(targetClass),
2639				classMethodsToAdd, curClassMethodIndex);
2640	}
2641	PyMem_Free(classMethodsToAdd);
2642
2643	r = PyDict_Merge(((PyTypeObject*)classObject)->tp_dict, extraDict, 1);
2644	if (r == -1) goto cleanup_and_return_error;
2645
2646	r = PyDict_Merge(Py_TYPE(classObject)->tp_dict, metaDict, 1);
2647	if (r == -1) goto cleanup_and_return_error;
2648
2649	Py_DECREF(extraDict); extraDict = NULL;
2650	Py_DECREF(metaDict); metaDict = NULL;
2651
2652	return 0;
2653
2654cleanup_and_return_error:
2655	Py_XDECREF(metaDict);
2656	Py_XDECREF(extraDict);
2657	if (methodsToAdd) PyMem_Free(methodsToAdd);
2658	if (classMethodsToAdd) PyMem_Free(classMethodsToAdd);
2659	return -1;
2660}
2661