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