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