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