Changeset 391 for python/trunk/Objects/descrobject.c
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Objects/descrobject.c
r2 r391 7 7 descr_dealloc(PyDescrObject *descr) 8 8 { 9 10 11 12 9 _PyObject_GC_UNTRACK(descr); 10 Py_XDECREF(descr->d_type); 11 Py_XDECREF(descr->d_name); 12 PyObject_GC_Del(descr); 13 13 } 14 14 … … 16 16 descr_name(PyDescrObject *descr) 17 17 { 18 19 20 21 18 if (descr->d_name != NULL && PyString_Check(descr->d_name)) 19 return PyString_AS_STRING(descr->d_name); 20 else 21 return "?"; 22 22 } 23 23 … … 25 25 descr_repr(PyDescrObject *descr, char *format) 26 26 { 27 28 27 return PyString_FromFormat(format, descr_name(descr), 28 descr->d_type->tp_name); 29 29 } 30 30 … … 32 32 method_repr(PyMethodDescrObject *descr) 33 33 { 34 return descr_repr((PyDescrObject *)descr, 35 34 return descr_repr((PyDescrObject *)descr, 35 "<method '%s' of '%s' objects>"); 36 36 } 37 37 … … 39 39 member_repr(PyMemberDescrObject *descr) 40 40 { 41 return descr_repr((PyDescrObject *)descr, 42 41 return descr_repr((PyDescrObject *)descr, 42 "<member '%s' of '%s' objects>"); 43 43 } 44 44 … … 46 46 getset_repr(PyGetSetDescrObject *descr) 47 47 { 48 return descr_repr((PyDescrObject *)descr, 49 48 return descr_repr((PyDescrObject *)descr, 49 "<attribute '%s' of '%s' objects>"); 50 50 } 51 51 … … 53 53 wrapperdescr_repr(PyWrapperDescrObject *descr) 54 54 { 55 return descr_repr((PyDescrObject *)descr, 56 55 return descr_repr((PyDescrObject *)descr, 56 "<slot wrapper '%s' of '%s' objects>"); 57 57 } 58 58 … … 60 60 descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) 61 61 { 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 62 if (obj == NULL) { 63 Py_INCREF(descr); 64 *pres = (PyObject *)descr; 65 return 1; 66 } 67 if (!PyObject_TypeCheck(obj, descr->d_type)) { 68 PyErr_Format(PyExc_TypeError, 69 "descriptor '%s' for '%s' objects " 70 "doesn't apply to '%s' object", 71 descr_name((PyDescrObject *)descr), 72 descr->d_type->tp_name, 73 obj->ob_type->tp_name); 74 *pres = NULL; 75 return 1; 76 } 77 return 0; 78 78 } 79 79 … … 81 81 classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) 82 82 { 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 83 /* Ensure a valid type. Class methods ignore obj. */ 84 if (type == NULL) { 85 if (obj != NULL) 86 type = (PyObject *)obj->ob_type; 87 else { 88 /* Wot - no type?! */ 89 PyErr_Format(PyExc_TypeError, 90 "descriptor '%s' for type '%s' " 91 "needs either an object or a type", 92 descr_name((PyDescrObject *)descr), 93 descr->d_type->tp_name); 94 return NULL; 95 } 96 } 97 if (!PyType_Check(type)) { 98 PyErr_Format(PyExc_TypeError, 99 "descriptor '%s' for type '%s' " 100 "needs a type, not a '%s' as arg 2", 101 descr_name((PyDescrObject *)descr), 102 descr->d_type->tp_name, 103 type->ob_type->tp_name); 104 return NULL; 105 } 106 if (!PyType_IsSubtype((PyTypeObject *)type, descr->d_type)) { 107 PyErr_Format(PyExc_TypeError, 108 "descriptor '%s' for type '%s' " 109 "doesn't apply to type '%s'", 110 descr_name((PyDescrObject *)descr), 111 descr->d_type->tp_name, 112 ((PyTypeObject *)type)->tp_name); 113 return NULL; 114 } 115 return PyCFunction_New(descr->d_method, type); 116 116 } 117 117 … … 119 119 method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) 120 120 { 121 122 123 124 125 121 PyObject *res; 122 123 if (descr_check((PyDescrObject *)descr, obj, &res)) 124 return res; 125 return PyCFunction_New(descr->d_method, obj); 126 126 } 127 127 … … 129 129 member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) 130 130 { 131 132 133 134 135 131 PyObject *res; 132 133 if (descr_check((PyDescrObject *)descr, obj, &res)) 134 return res; 135 return PyMember_GetOne((char *)obj, descr->d_member); 136 136 } 137 137 … … 139 139 getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) 140 140 { 141 142 143 144 145 146 147 148 149 150 151 141 PyObject *res; 142 143 if (descr_check((PyDescrObject *)descr, obj, &res)) 144 return res; 145 if (descr->d_getset->get != NULL) 146 return descr->d_getset->get(obj, descr->d_getset->closure); 147 PyErr_Format(PyExc_AttributeError, 148 "attribute '%.300s' of '%.100s' objects is not readable", 149 descr_name((PyDescrObject *)descr), 150 descr->d_type->tp_name); 151 return NULL; 152 152 } 153 153 … … 155 155 wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) 156 156 { 157 158 159 160 161 157 PyObject *res; 158 159 if (descr_check((PyDescrObject *)descr, obj, &res)) 160 return res; 161 return PyWrapper_New((PyObject *)descr, obj); 162 162 } 163 163 164 164 static int 165 165 descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, 166 167 { 168 169 170 171 172 173 174 175 176 177 178 179 166 int *pres) 167 { 168 assert(obj != NULL); 169 if (!PyObject_TypeCheck(obj, descr->d_type)) { 170 PyErr_Format(PyExc_TypeError, 171 "descriptor '%.200s' for '%.100s' objects " 172 "doesn't apply to '%.100s' object", 173 descr_name(descr), 174 descr->d_type->tp_name, 175 obj->ob_type->tp_name); 176 *pres = -1; 177 return 1; 178 } 179 return 0; 180 180 } 181 181 … … 183 183 member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) 184 184 { 185 186 187 188 189 185 int res; 186 187 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) 188 return res; 189 return PyMember_SetOne((char *)obj, descr->d_member, value); 190 190 } 191 191 … … 193 193 getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) 194 194 { 195 196 197 198 199 200 201 202 203 204 205 206 195 int res; 196 197 if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) 198 return res; 199 if (descr->d_getset->set != NULL) 200 return descr->d_getset->set(obj, value, 201 descr->d_getset->closure); 202 PyErr_Format(PyExc_AttributeError, 203 "attribute '%.300s' of '%.100s' objects is not writable", 204 descr_name((PyDescrObject *)descr), 205 descr->d_type->tp_name); 206 return -1; 207 207 } 208 208 … … 210 210 methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) 211 211 { 212 Py_ssize_t argc; 213 PyObject *self, *func, *result; 214 215 /* Make sure that the first argument is acceptable as 'self' */ 216 assert(PyTuple_Check(args)); 217 argc = PyTuple_GET_SIZE(args); 218 if (argc < 1) { 219 PyErr_Format(PyExc_TypeError, 220 "descriptor '%.300s' of '%.100s' " 221 "object needs an argument", 222 descr_name((PyDescrObject *)descr), 223 descr->d_type->tp_name); 224 return NULL; 225 } 226 self = PyTuple_GET_ITEM(args, 0); 227 if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { 228 PyErr_Format(PyExc_TypeError, 229 "descriptor '%.200s' " 230 "requires a '%.100s' object " 231 "but received a '%.100s'", 232 descr_name((PyDescrObject *)descr), 233 descr->d_type->tp_name, 234 self->ob_type->tp_name); 235 return NULL; 236 } 237 238 func = PyCFunction_New(descr->d_method, self); 239 if (func == NULL) 240 return NULL; 241 args = PyTuple_GetSlice(args, 1, argc); 242 if (args == NULL) { 243 Py_DECREF(func); 244 return NULL; 245 } 246 result = PyEval_CallObjectWithKeywords(func, args, kwds); 247 Py_DECREF(args); 248 Py_DECREF(func); 249 return result; 212 Py_ssize_t argc; 213 PyObject *self, *func, *result; 214 215 /* Make sure that the first argument is acceptable as 'self' */ 216 assert(PyTuple_Check(args)); 217 argc = PyTuple_GET_SIZE(args); 218 if (argc < 1) { 219 PyErr_Format(PyExc_TypeError, 220 "descriptor '%.300s' of '%.100s' " 221 "object needs an argument", 222 descr_name((PyDescrObject *)descr), 223 descr->d_type->tp_name); 224 return NULL; 225 } 226 self = PyTuple_GET_ITEM(args, 0); 227 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 228 (PyObject *)(descr->d_type))) { 229 PyErr_Format(PyExc_TypeError, 230 "descriptor '%.200s' " 231 "requires a '%.100s' object " 232 "but received a '%.100s'", 233 descr_name((PyDescrObject *)descr), 234 descr->d_type->tp_name, 235 self->ob_type->tp_name); 236 return NULL; 237 } 238 239 func = PyCFunction_New(descr->d_method, self); 240 if (func == NULL) 241 return NULL; 242 args = PyTuple_GetSlice(args, 1, argc); 243 if (args == NULL) { 244 Py_DECREF(func); 245 return NULL; 246 } 247 result = PyEval_CallObjectWithKeywords(func, args, kwds); 248 Py_DECREF(args); 249 Py_DECREF(func); 250 return result; 250 251 } 251 252 252 253 static PyObject * 253 254 classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, 254 PyObject *kwds) 255 { 256 PyObject *func, *result; 257 258 func = PyCFunction_New(descr->d_method, (PyObject *)descr->d_type); 259 if (func == NULL) 260 return NULL; 261 262 result = PyEval_CallObjectWithKeywords(func, args, kwds); 263 Py_DECREF(func); 264 return result; 255 PyObject *kwds) 256 { 257 Py_ssize_t argc; 258 PyObject *self, *func, *result; 259 260 /* Make sure that the first argument is acceptable as 'self' */ 261 assert(PyTuple_Check(args)); 262 argc = PyTuple_GET_SIZE(args); 263 if (argc < 1) { 264 PyErr_Format(PyExc_TypeError, 265 "descriptor '%s' of '%.100s' " 266 "object needs an argument", 267 descr_name((PyDescrObject *)descr), 268 descr->d_type->tp_name); 269 return NULL; 270 } 271 self = PyTuple_GET_ITEM(args, 0); 272 if (!PyType_Check(self)) { 273 PyErr_Format(PyExc_TypeError, 274 "descriptor '%s' requires a type " 275 "but received a '%.100s'", 276 descr_name((PyDescrObject *)descr), 277 self->ob_type->tp_name); 278 return NULL; 279 } 280 if (!PyType_IsSubtype((PyTypeObject *)self, descr->d_type)) { 281 PyErr_Format(PyExc_TypeError, 282 "descriptor '%s' " 283 "requires a subtype of '%.100s' " 284 "but received '%.100s", 285 descr_name((PyDescrObject *)descr), 286 descr->d_type->tp_name, 287 self->ob_type->tp_name); 288 return NULL; 289 } 290 291 func = PyCFunction_New(descr->d_method, self); 292 if (func == NULL) 293 return NULL; 294 args = PyTuple_GetSlice(args, 1, argc); 295 if (args == NULL) { 296 Py_DECREF(func); 297 return NULL; 298 } 299 result = PyEval_CallObjectWithKeywords(func, args, kwds); 300 Py_DECREF(func); 301 Py_DECREF(args); 302 return result; 265 303 } 266 304 … … 268 306 wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) 269 307 { 270 Py_ssize_t argc; 271 PyObject *self, *func, *result; 272 273 /* Make sure that the first argument is acceptable as 'self' */ 274 assert(PyTuple_Check(args)); 275 argc = PyTuple_GET_SIZE(args); 276 if (argc < 1) { 277 PyErr_Format(PyExc_TypeError, 278 "descriptor '%.300s' of '%.100s' " 279 "object needs an argument", 280 descr_name((PyDescrObject *)descr), 281 descr->d_type->tp_name); 282 return NULL; 283 } 284 self = PyTuple_GET_ITEM(args, 0); 285 if (!PyObject_IsInstance(self, (PyObject *)(descr->d_type))) { 286 PyErr_Format(PyExc_TypeError, 287 "descriptor '%.200s' " 288 "requires a '%.100s' object " 289 "but received a '%.100s'", 290 descr_name((PyDescrObject *)descr), 291 descr->d_type->tp_name, 292 self->ob_type->tp_name); 293 return NULL; 294 } 295 296 func = PyWrapper_New((PyObject *)descr, self); 297 if (func == NULL) 298 return NULL; 299 args = PyTuple_GetSlice(args, 1, argc); 300 if (args == NULL) { 301 Py_DECREF(func); 302 return NULL; 303 } 304 result = PyEval_CallObjectWithKeywords(func, args, kwds); 305 Py_DECREF(args); 306 Py_DECREF(func); 307 return result; 308 Py_ssize_t argc; 309 PyObject *self, *func, *result; 310 311 /* Make sure that the first argument is acceptable as 'self' */ 312 assert(PyTuple_Check(args)); 313 argc = PyTuple_GET_SIZE(args); 314 if (argc < 1) { 315 PyErr_Format(PyExc_TypeError, 316 "descriptor '%.300s' of '%.100s' " 317 "object needs an argument", 318 descr_name((PyDescrObject *)descr), 319 descr->d_type->tp_name); 320 return NULL; 321 } 322 self = PyTuple_GET_ITEM(args, 0); 323 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 324 (PyObject *)(descr->d_type))) { 325 PyErr_Format(PyExc_TypeError, 326 "descriptor '%.200s' " 327 "requires a '%.100s' object " 328 "but received a '%.100s'", 329 descr_name((PyDescrObject *)descr), 330 descr->d_type->tp_name, 331 self->ob_type->tp_name); 332 return NULL; 333 } 334 335 func = PyWrapper_New((PyObject *)descr, self); 336 if (func == NULL) 337 return NULL; 338 args = PyTuple_GetSlice(args, 1, argc); 339 if (args == NULL) { 340 Py_DECREF(func); 341 return NULL; 342 } 343 result = PyEval_CallObjectWithKeywords(func, args, kwds); 344 Py_DECREF(args); 345 Py_DECREF(func); 346 return result; 308 347 } 309 348 … … 311 350 method_get_doc(PyMethodDescrObject *descr, void *closure) 312 351 { 313 314 315 316 317 352 if (descr->d_method->ml_doc == NULL) { 353 Py_INCREF(Py_None); 354 return Py_None; 355 } 356 return PyString_FromString(descr->d_method->ml_doc); 318 357 } 319 358 320 359 static PyMemberDef descr_members[] = { 321 322 323 360 {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, 361 {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, 362 {0} 324 363 }; 325 364 326 365 static PyGetSetDef method_getset[] = { 327 328 366 {"__doc__", (getter)method_get_doc}, 367 {0} 329 368 }; 330 369 … … 332 371 member_get_doc(PyMemberDescrObject *descr, void *closure) 333 372 { 334 335 336 337 338 373 if (descr->d_member->doc == NULL) { 374 Py_INCREF(Py_None); 375 return Py_None; 376 } 377 return PyString_FromString(descr->d_member->doc); 339 378 } 340 379 341 380 static PyGetSetDef member_getset[] = { 342 343 381 {"__doc__", (getter)member_get_doc}, 382 {0} 344 383 }; 345 384 … … 347 386 getset_get_doc(PyGetSetDescrObject *descr, void *closure) 348 387 { 349 350 351 352 353 388 if (descr->d_getset->doc == NULL) { 389 Py_INCREF(Py_None); 390 return Py_None; 391 } 392 return PyString_FromString(descr->d_getset->doc); 354 393 } 355 394 356 395 static PyGetSetDef getset_getset[] = { 357 358 396 {"__doc__", (getter)getset_get_doc}, 397 {0} 359 398 }; 360 399 … … 362 401 wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) 363 402 { 364 365 366 367 368 403 if (descr->d_base->doc == NULL) { 404 Py_INCREF(Py_None); 405 return Py_None; 406 } 407 return PyString_FromString(descr->d_base->doc); 369 408 } 370 409 371 410 static PyGetSetDef wrapperdescr_getset[] = { 372 373 411 {"__doc__", (getter)wrapperdescr_get_doc}, 412 {0} 374 413 }; 375 414 … … 377 416 descr_traverse(PyObject *self, visitproc visit, void *arg) 378 417 { 379 380 381 418 PyDescrObject *descr = (PyDescrObject *)self; 419 Py_VISIT(descr->d_type); 420 return 0; 382 421 } 383 422 384 423 static PyTypeObject PyMethodDescr_Type = { 385 386 387 388 389 (destructor)descr_dealloc,/* tp_dealloc */390 0,/* tp_print */391 0,/* tp_getattr */392 0,/* tp_setattr */393 0,/* tp_compare */394 (reprfunc)method_repr,/* tp_repr */395 0,/* tp_as_number */396 0,/* tp_as_sequence */397 0,/* tp_as_mapping */398 0,/* tp_hash */399 (ternaryfunc)methoddescr_call,/* tp_call */400 0,/* tp_str */401 PyObject_GenericGetAttr,/* tp_getattro */402 0,/* tp_setattro */403 0,/* tp_as_buffer */404 405 0,/* tp_doc */406 descr_traverse,/* tp_traverse */407 0,/* tp_clear */408 0,/* tp_richcompare */409 0,/* tp_weaklistoffset */410 0,/* tp_iter */411 0,/* tp_iternext */412 0,/* tp_methods */413 descr_members,/* tp_members */414 method_getset,/* tp_getset */415 0,/* tp_base */416 0,/* tp_dict */417 (descrgetfunc)method_get,/* tp_descr_get */418 0,/* tp_descr_set */424 PyVarObject_HEAD_INIT(&PyType_Type, 0) 425 "method_descriptor", 426 sizeof(PyMethodDescrObject), 427 0, 428 (destructor)descr_dealloc, /* tp_dealloc */ 429 0, /* tp_print */ 430 0, /* tp_getattr */ 431 0, /* tp_setattr */ 432 0, /* tp_compare */ 433 (reprfunc)method_repr, /* tp_repr */ 434 0, /* tp_as_number */ 435 0, /* tp_as_sequence */ 436 0, /* tp_as_mapping */ 437 0, /* tp_hash */ 438 (ternaryfunc)methoddescr_call, /* tp_call */ 439 0, /* tp_str */ 440 PyObject_GenericGetAttr, /* tp_getattro */ 441 0, /* tp_setattro */ 442 0, /* tp_as_buffer */ 443 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 444 0, /* tp_doc */ 445 descr_traverse, /* tp_traverse */ 446 0, /* tp_clear */ 447 0, /* tp_richcompare */ 448 0, /* tp_weaklistoffset */ 449 0, /* tp_iter */ 450 0, /* tp_iternext */ 451 0, /* tp_methods */ 452 descr_members, /* tp_members */ 453 method_getset, /* tp_getset */ 454 0, /* tp_base */ 455 0, /* tp_dict */ 456 (descrgetfunc)method_get, /* tp_descr_get */ 457 0, /* tp_descr_set */ 419 458 }; 420 459 421 460 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ 422 461 static PyTypeObject PyClassMethodDescr_Type = { 423 424 425 426 427 (destructor)descr_dealloc,/* tp_dealloc */428 0,/* tp_print */429 0,/* tp_getattr */430 0,/* tp_setattr */431 0,/* tp_compare */432 (reprfunc)method_repr,/* tp_repr */433 0,/* tp_as_number */434 0,/* tp_as_sequence */435 0,/* tp_as_mapping */436 0,/* tp_hash */437 (ternaryfunc)classmethoddescr_call,/* tp_call */438 0,/* tp_str */439 PyObject_GenericGetAttr,/* tp_getattro */440 0,/* tp_setattro */441 0,/* tp_as_buffer */442 443 0,/* tp_doc */444 descr_traverse,/* tp_traverse */445 0,/* tp_clear */446 0,/* tp_richcompare */447 0,/* tp_weaklistoffset */448 0,/* tp_iter */449 0,/* tp_iternext */450 0,/* tp_methods */451 descr_members,/* tp_members */452 method_getset,/* tp_getset */453 0,/* tp_base */454 0,/* tp_dict */455 (descrgetfunc)classmethod_get,/* tp_descr_get */456 0,/* tp_descr_set */462 PyVarObject_HEAD_INIT(&PyType_Type, 0) 463 "classmethod_descriptor", 464 sizeof(PyMethodDescrObject), 465 0, 466 (destructor)descr_dealloc, /* tp_dealloc */ 467 0, /* tp_print */ 468 0, /* tp_getattr */ 469 0, /* tp_setattr */ 470 0, /* tp_compare */ 471 (reprfunc)method_repr, /* tp_repr */ 472 0, /* tp_as_number */ 473 0, /* tp_as_sequence */ 474 0, /* tp_as_mapping */ 475 0, /* tp_hash */ 476 (ternaryfunc)classmethoddescr_call, /* tp_call */ 477 0, /* tp_str */ 478 PyObject_GenericGetAttr, /* tp_getattro */ 479 0, /* tp_setattro */ 480 0, /* tp_as_buffer */ 481 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 482 0, /* tp_doc */ 483 descr_traverse, /* tp_traverse */ 484 0, /* tp_clear */ 485 0, /* tp_richcompare */ 486 0, /* tp_weaklistoffset */ 487 0, /* tp_iter */ 488 0, /* tp_iternext */ 489 0, /* tp_methods */ 490 descr_members, /* tp_members */ 491 method_getset, /* tp_getset */ 492 0, /* tp_base */ 493 0, /* tp_dict */ 494 (descrgetfunc)classmethod_get, /* tp_descr_get */ 495 0, /* tp_descr_set */ 457 496 }; 458 497 459 498 PyTypeObject PyMemberDescr_Type = { 460 461 462 463 464 (destructor)descr_dealloc,/* tp_dealloc */465 0,/* tp_print */466 0,/* tp_getattr */467 0,/* tp_setattr */468 0,/* tp_compare */469 (reprfunc)member_repr,/* tp_repr */470 0,/* tp_as_number */471 0,/* tp_as_sequence */472 0,/* tp_as_mapping */473 0,/* tp_hash */474 0,/* tp_call */475 0,/* tp_str */476 PyObject_GenericGetAttr,/* tp_getattro */477 0,/* tp_setattro */478 0,/* tp_as_buffer */479 480 0,/* tp_doc */481 descr_traverse,/* tp_traverse */482 0,/* tp_clear */483 0,/* tp_richcompare */484 0,/* tp_weaklistoffset */485 0,/* tp_iter */486 0,/* tp_iternext */487 0,/* tp_methods */488 descr_members,/* tp_members */489 member_getset,/* tp_getset */490 0,/* tp_base */491 0,/* tp_dict */492 (descrgetfunc)member_get,/* tp_descr_get */493 (descrsetfunc)member_set,/* tp_descr_set */499 PyVarObject_HEAD_INIT(&PyType_Type, 0) 500 "member_descriptor", 501 sizeof(PyMemberDescrObject), 502 0, 503 (destructor)descr_dealloc, /* tp_dealloc */ 504 0, /* tp_print */ 505 0, /* tp_getattr */ 506 0, /* tp_setattr */ 507 0, /* tp_compare */ 508 (reprfunc)member_repr, /* tp_repr */ 509 0, /* tp_as_number */ 510 0, /* tp_as_sequence */ 511 0, /* tp_as_mapping */ 512 0, /* tp_hash */ 513 0, /* tp_call */ 514 0, /* tp_str */ 515 PyObject_GenericGetAttr, /* tp_getattro */ 516 0, /* tp_setattro */ 517 0, /* tp_as_buffer */ 518 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 519 0, /* tp_doc */ 520 descr_traverse, /* tp_traverse */ 521 0, /* tp_clear */ 522 0, /* tp_richcompare */ 523 0, /* tp_weaklistoffset */ 524 0, /* tp_iter */ 525 0, /* tp_iternext */ 526 0, /* tp_methods */ 527 descr_members, /* tp_members */ 528 member_getset, /* tp_getset */ 529 0, /* tp_base */ 530 0, /* tp_dict */ 531 (descrgetfunc)member_get, /* tp_descr_get */ 532 (descrsetfunc)member_set, /* tp_descr_set */ 494 533 }; 495 534 496 535 PyTypeObject PyGetSetDescr_Type = { 497 498 499 500 501 (destructor)descr_dealloc,/* tp_dealloc */502 0,/* tp_print */503 0,/* tp_getattr */504 0,/* tp_setattr */505 0,/* tp_compare */506 (reprfunc)getset_repr,/* tp_repr */507 0,/* tp_as_number */508 0,/* tp_as_sequence */509 0,/* tp_as_mapping */510 0,/* tp_hash */511 0,/* tp_call */512 0,/* tp_str */513 PyObject_GenericGetAttr,/* tp_getattro */514 0,/* tp_setattro */515 0,/* tp_as_buffer */516 517 0,/* tp_doc */518 descr_traverse,/* tp_traverse */519 0,/* tp_clear */520 0,/* tp_richcompare */521 0,/* tp_weaklistoffset */522 0,/* tp_iter */523 0,/* tp_iternext */524 0,/* tp_methods */525 descr_members,/* tp_members */526 getset_getset,/* tp_getset */527 0,/* tp_base */528 0,/* tp_dict */529 (descrgetfunc)getset_get,/* tp_descr_get */530 (descrsetfunc)getset_set,/* tp_descr_set */536 PyVarObject_HEAD_INIT(&PyType_Type, 0) 537 "getset_descriptor", 538 sizeof(PyGetSetDescrObject), 539 0, 540 (destructor)descr_dealloc, /* tp_dealloc */ 541 0, /* tp_print */ 542 0, /* tp_getattr */ 543 0, /* tp_setattr */ 544 0, /* tp_compare */ 545 (reprfunc)getset_repr, /* tp_repr */ 546 0, /* tp_as_number */ 547 0, /* tp_as_sequence */ 548 0, /* tp_as_mapping */ 549 0, /* tp_hash */ 550 0, /* tp_call */ 551 0, /* tp_str */ 552 PyObject_GenericGetAttr, /* tp_getattro */ 553 0, /* tp_setattro */ 554 0, /* tp_as_buffer */ 555 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 556 0, /* tp_doc */ 557 descr_traverse, /* tp_traverse */ 558 0, /* tp_clear */ 559 0, /* tp_richcompare */ 560 0, /* tp_weaklistoffset */ 561 0, /* tp_iter */ 562 0, /* tp_iternext */ 563 0, /* tp_methods */ 564 descr_members, /* tp_members */ 565 getset_getset, /* tp_getset */ 566 0, /* tp_base */ 567 0, /* tp_dict */ 568 (descrgetfunc)getset_get, /* tp_descr_get */ 569 (descrsetfunc)getset_set, /* tp_descr_set */ 531 570 }; 532 571 533 572 PyTypeObject PyWrapperDescr_Type = { 534 535 536 537 538 (destructor)descr_dealloc,/* tp_dealloc */539 0,/* tp_print */540 0,/* tp_getattr */541 0,/* tp_setattr */542 0,/* tp_compare */543 (reprfunc)wrapperdescr_repr,/* tp_repr */544 0,/* tp_as_number */545 0,/* tp_as_sequence */546 0,/* tp_as_mapping */547 0,/* tp_hash */548 (ternaryfunc)wrapperdescr_call,/* tp_call */549 0,/* tp_str */550 PyObject_GenericGetAttr,/* tp_getattro */551 0,/* tp_setattro */552 0,/* tp_as_buffer */553 554 0,/* tp_doc */555 descr_traverse,/* tp_traverse */556 0,/* tp_clear */557 0,/* tp_richcompare */558 0,/* tp_weaklistoffset */559 0,/* tp_iter */560 0,/* tp_iternext */561 0,/* tp_methods */562 descr_members,/* tp_members */563 wrapperdescr_getset,/* tp_getset */564 0,/* tp_base */565 0,/* tp_dict */566 (descrgetfunc)wrapperdescr_get,/* tp_descr_get */567 0,/* tp_descr_set */573 PyVarObject_HEAD_INIT(&PyType_Type, 0) 574 "wrapper_descriptor", 575 sizeof(PyWrapperDescrObject), 576 0, 577 (destructor)descr_dealloc, /* tp_dealloc */ 578 0, /* tp_print */ 579 0, /* tp_getattr */ 580 0, /* tp_setattr */ 581 0, /* tp_compare */ 582 (reprfunc)wrapperdescr_repr, /* tp_repr */ 583 0, /* tp_as_number */ 584 0, /* tp_as_sequence */ 585 0, /* tp_as_mapping */ 586 0, /* tp_hash */ 587 (ternaryfunc)wrapperdescr_call, /* tp_call */ 588 0, /* tp_str */ 589 PyObject_GenericGetAttr, /* tp_getattro */ 590 0, /* tp_setattro */ 591 0, /* tp_as_buffer */ 592 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 593 0, /* tp_doc */ 594 descr_traverse, /* tp_traverse */ 595 0, /* tp_clear */ 596 0, /* tp_richcompare */ 597 0, /* tp_weaklistoffset */ 598 0, /* tp_iter */ 599 0, /* tp_iternext */ 600 0, /* tp_methods */ 601 descr_members, /* tp_members */ 602 wrapperdescr_getset, /* tp_getset */ 603 0, /* tp_base */ 604 0, /* tp_dict */ 605 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 606 0, /* tp_descr_set */ 568 607 }; 569 608 … … 571 610 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 572 611 { 573 574 575 576 577 578 579 580 581 582 583 584 585 612 PyDescrObject *descr; 613 614 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 615 if (descr != NULL) { 616 Py_XINCREF(type); 617 descr->d_type = type; 618 descr->d_name = PyString_InternFromString(name); 619 if (descr->d_name == NULL) { 620 Py_DECREF(descr); 621 descr = NULL; 622 } 623 } 624 return descr; 586 625 } 587 626 … … 589 628 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 590 629 { 591 592 593 594 595 596 597 630 PyMethodDescrObject *descr; 631 632 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, 633 type, method->ml_name); 634 if (descr != NULL) 635 descr->d_method = method; 636 return (PyObject *)descr; 598 637 } 599 638 … … 601 640 PyDescr_NewClassMethod(PyTypeObject *type, PyMethodDef *method) 602 641 { 603 604 605 606 607 608 609 642 PyMethodDescrObject *descr; 643 644 descr = (PyMethodDescrObject *)descr_new(&PyClassMethodDescr_Type, 645 type, method->ml_name); 646 if (descr != NULL) 647 descr->d_method = method; 648 return (PyObject *)descr; 610 649 } 611 650 … … 613 652 PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) 614 653 { 615 616 617 618 619 620 621 654 PyMemberDescrObject *descr; 655 656 descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, 657 type, member->name); 658 if (descr != NULL) 659 descr->d_member = member; 660 return (PyObject *)descr; 622 661 } 623 662 … … 625 664 PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) 626 665 { 627 628 629 630 631 632 633 666 PyGetSetDescrObject *descr; 667 668 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 669 type, getset->name); 670 if (descr != NULL) 671 descr->d_getset = getset; 672 return (PyObject *)descr; 634 673 } 635 674 … … 637 676 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) 638 677 { 639 640 641 642 643 644 645 646 647 678 PyWrapperDescrObject *descr; 679 680 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, 681 type, base->name); 682 if (descr != NULL) { 683 descr->d_base = base; 684 descr->d_wrapped = wrapped; 685 } 686 return (PyObject *)descr; 648 687 } 649 688 … … 655 694 656 695 typedef struct { 657 658 696 PyObject_HEAD 697 PyObject *dict; 659 698 } proxyobject; 660 699 … … 662 701 proxy_len(proxyobject *pp) 663 702 { 664 703 return PyObject_Size(pp->dict); 665 704 } 666 705 … … 668 707 proxy_getitem(proxyobject *pp, PyObject *key) 669 708 { 670 709 return PyObject_GetItem(pp->dict, key); 671 710 } 672 711 673 712 static PyMappingMethods proxy_as_mapping = { 674 (lenfunc)proxy_len,/* mp_length */675 (binaryfunc)proxy_getitem,/* mp_subscript */676 0,/* mp_ass_subscript */713 (lenfunc)proxy_len, /* mp_length */ 714 (binaryfunc)proxy_getitem, /* mp_subscript */ 715 0, /* mp_ass_subscript */ 677 716 }; 678 717 … … 680 719 proxy_contains(proxyobject *pp, PyObject *key) 681 720 { 682 721 return PyDict_Contains(pp->dict, key); 683 722 } 684 723 685 724 static PySequenceMethods proxy_as_sequence = { 686 0,/* sq_length */687 0,/* sq_concat */688 0,/* sq_repeat */689 0,/* sq_item */690 0,/* sq_slice */691 0,/* sq_ass_item */692 0,/* sq_ass_slice */693 (objobjproc)proxy_contains,/* sq_contains */694 0,/* sq_inplace_concat */695 0,/* sq_inplace_repeat */725 0, /* sq_length */ 726 0, /* sq_concat */ 727 0, /* sq_repeat */ 728 0, /* sq_item */ 729 0, /* sq_slice */ 730 0, /* sq_ass_item */ 731 0, /* sq_ass_slice */ 732 (objobjproc)proxy_contains, /* sq_contains */ 733 0, /* sq_inplace_concat */ 734 0, /* sq_inplace_repeat */ 696 735 }; 697 736 … … 699 738 proxy_has_key(proxyobject *pp, PyObject *key) 700 739 { 701 702 703 704 740 int res = PyDict_Contains(pp->dict, key); 741 if (res < 0) 742 return NULL; 743 return PyBool_FromLong(res); 705 744 } 706 745 … … 708 747 proxy_get(proxyobject *pp, PyObject *args) 709 748 { 710 711 712 713 714 749 PyObject *key, *def = Py_None; 750 751 if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) 752 return NULL; 753 return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def); 715 754 } 716 755 … … 718 757 proxy_keys(proxyobject *pp) 719 758 { 720 759 return PyMapping_Keys(pp->dict); 721 760 } 722 761 … … 724 763 proxy_values(proxyobject *pp) 725 764 { 726 765 return PyMapping_Values(pp->dict); 727 766 } 728 767 … … 730 769 proxy_items(proxyobject *pp) 731 770 { 732 771 return PyMapping_Items(pp->dict); 733 772 } 734 773 … … 736 775 proxy_iterkeys(proxyobject *pp) 737 776 { 738 777 return PyObject_CallMethod(pp->dict, "iterkeys", NULL); 739 778 } 740 779 … … 742 781 proxy_itervalues(proxyobject *pp) 743 782 { 744 783 return PyObject_CallMethod(pp->dict, "itervalues", NULL); 745 784 } 746 785 … … 748 787 proxy_iteritems(proxyobject *pp) 749 788 { 750 789 return PyObject_CallMethod(pp->dict, "iteritems", NULL); 751 790 } 752 791 static PyObject * 753 792 proxy_copy(proxyobject *pp) 754 793 { 755 794 return PyObject_CallMethod(pp->dict, "copy", NULL); 756 795 } 757 796 758 797 static PyMethodDef proxy_methods[] = { 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 798 {"has_key", (PyCFunction)proxy_has_key, METH_O, 799 PyDoc_STR("D.has_key(k) -> True if D has a key k, else False")}, 800 {"get", (PyCFunction)proxy_get, METH_VARARGS, 801 PyDoc_STR("D.get(k[,d]) -> D[k] if D.has_key(k), else d." 802 " d defaults to None.")}, 803 {"keys", (PyCFunction)proxy_keys, METH_NOARGS, 804 PyDoc_STR("D.keys() -> list of D's keys")}, 805 {"values", (PyCFunction)proxy_values, METH_NOARGS, 806 PyDoc_STR("D.values() -> list of D's values")}, 807 {"items", (PyCFunction)proxy_items, METH_NOARGS, 808 PyDoc_STR("D.items() -> list of D's (key, value) pairs, as 2-tuples")}, 809 {"iterkeys", (PyCFunction)proxy_iterkeys, METH_NOARGS, 810 PyDoc_STR("D.iterkeys() -> an iterator over the keys of D")}, 811 {"itervalues",(PyCFunction)proxy_itervalues, METH_NOARGS, 812 PyDoc_STR("D.itervalues() -> an iterator over the values of D")}, 813 {"iteritems", (PyCFunction)proxy_iteritems, METH_NOARGS, 814 PyDoc_STR("D.iteritems() ->" 815 " an iterator over the (key, value) items of D")}, 816 {"copy", (PyCFunction)proxy_copy, METH_NOARGS, 817 PyDoc_STR("D.copy() -> a shallow copy of D")}, 818 {0} 780 819 }; 781 820 … … 783 822 proxy_dealloc(proxyobject *pp) 784 823 { 785 786 787 824 _PyObject_GC_UNTRACK(pp); 825 Py_DECREF(pp->dict); 826 PyObject_GC_Del(pp); 788 827 } 789 828 … … 791 830 proxy_getiter(proxyobject *pp) 792 831 { 793 832 return PyObject_GetIter(pp->dict); 794 833 } 795 834 … … 797 836 proxy_str(proxyobject *pp) 798 837 { 799 return PyObject_Str(pp->dict); 838 return PyObject_Str(pp->dict); 839 } 840 841 static PyObject * 842 proxy_repr(proxyobject *pp) 843 { 844 PyObject *dictrepr; 845 PyObject *result; 846 847 dictrepr = PyObject_Repr(pp->dict); 848 if (dictrepr == NULL) 849 return NULL; 850 result = PyString_FromFormat("dict_proxy(%s)", PyString_AS_STRING(dictrepr)); 851 Py_DECREF(dictrepr); 852 return result; 800 853 } 801 854 … … 803 856 proxy_traverse(PyObject *self, visitproc visit, void *arg) 804 857 { 805 806 807 858 proxyobject *pp = (proxyobject *)self; 859 Py_VISIT(pp->dict); 860 return 0; 808 861 } 809 862 … … 811 864 proxy_compare(proxyobject *v, PyObject *w) 812 865 { 813 866 return PyObject_Compare(v->dict, w); 814 867 } 815 868 … … 817 870 proxy_richcompare(proxyobject *v, PyObject *w, int op) 818 871 { 819 872 return PyObject_RichCompare(v->dict, w, op); 820 873 } 821 874 822 875 PyTypeObject PyDictProxy_Type = { 823 824 "dictproxy",/* tp_name */825 sizeof(proxyobject),/* tp_basicsize */826 0,/* tp_itemsize */827 828 (destructor)proxy_dealloc,/* tp_dealloc */829 0,/* tp_print */830 0,/* tp_getattr */831 0,/* tp_setattr */832 (cmpfunc)proxy_compare,/* tp_compare */833 0,/* tp_repr */834 0,/* tp_as_number */835 &proxy_as_sequence,/* tp_as_sequence */836 &proxy_as_mapping,/* tp_as_mapping */837 0,/* tp_hash */838 0,/* tp_call */839 (reprfunc)proxy_str,/* tp_str */840 PyObject_GenericGetAttr,/* tp_getattro */841 0,/* tp_setattro */842 0,/* tp_as_buffer */843 844 0,/* tp_doc */845 proxy_traverse,/* tp_traverse */846 0,/* tp_clear */847 (richcmpfunc)proxy_richcompare,/* tp_richcompare */848 0,/* tp_weaklistoffset */849 (getiterfunc)proxy_getiter,/* tp_iter */850 0,/* tp_iternext */851 proxy_methods,/* tp_methods */852 0,/* tp_members */853 0,/* tp_getset */854 0,/* tp_base */855 0,/* tp_dict */856 0,/* tp_descr_get */857 0,/* tp_descr_set */876 PyVarObject_HEAD_INIT(&PyType_Type, 0) 877 "dictproxy", /* tp_name */ 878 sizeof(proxyobject), /* tp_basicsize */ 879 0, /* tp_itemsize */ 880 /* methods */ 881 (destructor)proxy_dealloc, /* tp_dealloc */ 882 0, /* tp_print */ 883 0, /* tp_getattr */ 884 0, /* tp_setattr */ 885 (cmpfunc)proxy_compare, /* tp_compare */ 886 (reprfunc)proxy_repr, /* tp_repr */ 887 0, /* tp_as_number */ 888 &proxy_as_sequence, /* tp_as_sequence */ 889 &proxy_as_mapping, /* tp_as_mapping */ 890 0, /* tp_hash */ 891 0, /* tp_call */ 892 (reprfunc)proxy_str, /* tp_str */ 893 PyObject_GenericGetAttr, /* tp_getattro */ 894 0, /* tp_setattro */ 895 0, /* tp_as_buffer */ 896 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 897 0, /* tp_doc */ 898 proxy_traverse, /* tp_traverse */ 899 0, /* tp_clear */ 900 (richcmpfunc)proxy_richcompare, /* tp_richcompare */ 901 0, /* tp_weaklistoffset */ 902 (getiterfunc)proxy_getiter, /* tp_iter */ 903 0, /* tp_iternext */ 904 proxy_methods, /* tp_methods */ 905 0, /* tp_members */ 906 0, /* tp_getset */ 907 0, /* tp_base */ 908 0, /* tp_dict */ 909 0, /* tp_descr_get */ 910 0, /* tp_descr_set */ 858 911 }; 859 912 … … 861 914 PyDictProxy_New(PyObject *dict) 862 915 { 863 864 865 866 867 868 869 870 871 916 proxyobject *pp; 917 918 pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type); 919 if (pp != NULL) { 920 Py_INCREF(dict); 921 pp->dict = dict; 922 _PyObject_GC_TRACK(pp); 923 } 924 return (PyObject *)pp; 872 925 } 873 926 … … 879 932 880 933 typedef struct { 881 882 883 934 PyObject_HEAD 935 PyWrapperDescrObject *descr; 936 PyObject *self; 884 937 } wrapperobject; 885 938 … … 887 940 wrapper_dealloc(wrapperobject *wp) 888 941 { 889 890 891 892 893 894 942 PyObject_GC_UnTrack(wp); 943 Py_TRASHCAN_SAFE_BEGIN(wp) 944 Py_XDECREF(wp->descr); 945 Py_XDECREF(wp->self); 946 PyObject_GC_Del(wp); 947 Py_TRASHCAN_SAFE_END(wp) 895 948 } 896 949 … … 898 951 wrapper_compare(wrapperobject *a, wrapperobject *b) 899 952 { 900 901 902 903 953 if (a->descr == b->descr) 954 return PyObject_Compare(a->self, b->self); 955 else 956 return (a->descr < b->descr) ? -1 : 1; 904 957 } 905 958 … … 907 960 wrapper_hash(wrapperobject *wp) 908 961 { 909 910 911 912 913 914 915 916 917 918 919 962 int x, y; 963 x = _Py_HashPointer(wp->descr); 964 if (x == -1) 965 return -1; 966 y = PyObject_Hash(wp->self); 967 if (y == -1) 968 return -1; 969 x = x ^ y; 970 if (x == -1) 971 x = -2; 972 return x; 920 973 } 921 974 … … 923 976 wrapper_repr(wrapperobject *wp) 924 977 { 925 926 927 928 978 return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>", 979 wp->descr->d_base->name, 980 wp->self->ob_type->tp_name, 981 wp->self); 929 982 } 930 983 931 984 static PyMemberDef wrapper_members[] = { 932 933 985 {"__self__", T_OBJECT, offsetof(wrapperobject, self), READONLY}, 986 {0} 934 987 }; 935 988 … … 937 990 wrapper_objclass(wrapperobject *wp) 938 991 { 939 940 941 942 992 PyObject *c = (PyObject *)wp->descr->d_type; 993 994 Py_INCREF(c); 995 return c; 943 996 } 944 997 … … 946 999 wrapper_name(wrapperobject *wp) 947 1000 { 948 949 950 1001 char *s = wp->descr->d_base->name; 1002 1003 return PyString_FromString(s); 951 1004 } 952 1005 … … 954 1007 wrapper_doc(wrapperobject *wp) 955 1008 { 956 957 958 959 960 961 962 963 964 1009 char *s = wp->descr->d_base->doc; 1010 1011 if (s == NULL) { 1012 Py_INCREF(Py_None); 1013 return Py_None; 1014 } 1015 else { 1016 return PyString_FromString(s); 1017 } 965 1018 } 966 1019 967 1020 static PyGetSetDef wrapper_getsets[] = { 968 969 970 971 1021 {"__objclass__", (getter)wrapper_objclass}, 1022 {"__name__", (getter)wrapper_name}, 1023 {"__doc__", (getter)wrapper_doc}, 1024 {0} 972 1025 }; 973 1026 … … 975 1028 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 976 1029 { 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 1030 wrapperfunc wrapper = wp->descr->d_base->wrapper; 1031 PyObject *self = wp->self; 1032 1033 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 1034 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; 1035 return (*wk)(self, args, wp->descr->d_wrapped, kwds); 1036 } 1037 1038 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { 1039 PyErr_Format(PyExc_TypeError, 1040 "wrapper %s doesn't take keyword arguments", 1041 wp->descr->d_base->name); 1042 return NULL; 1043 } 1044 return (*wrapper)(self, args, wp->descr->d_wrapped); 992 1045 } 993 1046 … … 995 1048 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 996 1049 { 997 998 999 1000 1050 wrapperobject *wp = (wrapperobject *)self; 1051 Py_VISIT(wp->descr); 1052 Py_VISIT(wp->self); 1053 return 0; 1001 1054 } 1002 1055 1003 1056 static PyTypeObject wrappertype = { 1004 1005 "method-wrapper",/* tp_name */1006 sizeof(wrapperobject),/* tp_basicsize */1007 0,/* tp_itemsize */1008 1009 (destructor)wrapper_dealloc,/* tp_dealloc */1010 0,/* tp_print */1011 0,/* tp_getattr */1012 0,/* tp_setattr */1013 (cmpfunc)wrapper_compare,/* tp_compare */1014 (reprfunc)wrapper_repr,/* tp_repr */1015 0,/* tp_as_number */1016 0,/* tp_as_sequence */1017 0,/* tp_as_mapping */1018 (hashfunc)wrapper_hash,/* tp_hash */1019 (ternaryfunc)wrapper_call,/* tp_call */1020 0,/* tp_str */1021 PyObject_GenericGetAttr,/* tp_getattro */1022 0,/* tp_setattro */1023 0,/* tp_as_buffer */1024 1025 0,/* tp_doc */1026 wrapper_traverse,/* tp_traverse */1027 0,/* tp_clear */1028 0,/* tp_richcompare */1029 0,/* tp_weaklistoffset */1030 0,/* tp_iter */1031 0,/* tp_iternext */1032 0,/* tp_methods */1033 wrapper_members,/* tp_members */1034 wrapper_getsets,/* tp_getset */1035 0,/* tp_base */1036 0,/* tp_dict */1037 0,/* tp_descr_get */1038 0,/* tp_descr_set */1057 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1058 "method-wrapper", /* tp_name */ 1059 sizeof(wrapperobject), /* tp_basicsize */ 1060 0, /* tp_itemsize */ 1061 /* methods */ 1062 (destructor)wrapper_dealloc, /* tp_dealloc */ 1063 0, /* tp_print */ 1064 0, /* tp_getattr */ 1065 0, /* tp_setattr */ 1066 (cmpfunc)wrapper_compare, /* tp_compare */ 1067 (reprfunc)wrapper_repr, /* tp_repr */ 1068 0, /* tp_as_number */ 1069 0, /* tp_as_sequence */ 1070 0, /* tp_as_mapping */ 1071 (hashfunc)wrapper_hash, /* tp_hash */ 1072 (ternaryfunc)wrapper_call, /* tp_call */ 1073 0, /* tp_str */ 1074 PyObject_GenericGetAttr, /* tp_getattro */ 1075 0, /* tp_setattro */ 1076 0, /* tp_as_buffer */ 1077 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1078 0, /* tp_doc */ 1079 wrapper_traverse, /* tp_traverse */ 1080 0, /* tp_clear */ 1081 0, /* tp_richcompare */ 1082 0, /* tp_weaklistoffset */ 1083 0, /* tp_iter */ 1084 0, /* tp_iternext */ 1085 0, /* tp_methods */ 1086 wrapper_members, /* tp_members */ 1087 wrapper_getsets, /* tp_getset */ 1088 0, /* tp_base */ 1089 0, /* tp_dict */ 1090 0, /* tp_descr_get */ 1091 0, /* tp_descr_set */ 1039 1092 }; 1040 1093 … … 1042 1095 PyWrapper_New(PyObject *d, PyObject *self) 1043 1096 { 1044 wrapperobject *wp; 1045 PyWrapperDescrObject *descr; 1046 1047 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1048 descr = (PyWrapperDescrObject *)d; 1049 assert(PyObject_IsInstance(self, (PyObject *)(descr->d_type))); 1050 1051 wp = PyObject_GC_New(wrapperobject, &wrappertype); 1052 if (wp != NULL) { 1053 Py_INCREF(descr); 1054 wp->descr = descr; 1055 Py_INCREF(self); 1056 wp->self = self; 1057 _PyObject_GC_TRACK(wp); 1058 } 1059 return (PyObject *)wp; 1097 wrapperobject *wp; 1098 PyWrapperDescrObject *descr; 1099 1100 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1101 descr = (PyWrapperDescrObject *)d; 1102 assert(_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 1103 (PyObject *)(descr->d_type))); 1104 1105 wp = PyObject_GC_New(wrapperobject, &wrappertype); 1106 if (wp != NULL) { 1107 Py_INCREF(descr); 1108 wp->descr = descr; 1109 Py_INCREF(self); 1110 wp->self = self; 1111 _PyObject_GC_TRACK(wp); 1112 } 1113 return (PyObject *)wp; 1060 1114 } 1061 1115 … … 1066 1120 class property(object): 1067 1121 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1122 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 1123 if doc is None and fget is not None and hasattr(fget, "__doc__"): 1124 doc = fget.__doc__ 1125 self.__get = fget 1126 self.__set = fset 1127 self.__del = fdel 1128 self.__doc__ = doc 1129 1130 def __get__(self, inst, type=None): 1131 if inst is None: 1132 return self 1133 if self.__get is None: 1134 raise AttributeError, "unreadable attribute" 1135 return self.__get(inst) 1136 1137 def __set__(self, inst, value): 1138 if self.__set is None: 1139 raise AttributeError, "can't set attribute" 1140 return self.__set(inst, value) 1141 1142 def __delete__(self, inst): 1143 if self.__del is None: 1144 raise AttributeError, "can't delete attribute" 1145 return self.__del(inst) 1092 1146 1093 1147 */ 1094 1148 1095 1149 typedef struct { 1096 1097 1098 1099 1100 1101 1150 PyObject_HEAD 1151 PyObject *prop_get; 1152 PyObject *prop_set; 1153 PyObject *prop_del; 1154 PyObject *prop_doc; 1155 int getter_doc; 1102 1156 } propertyobject; 1103 1157 1104 1158 static PyObject * property_copy(PyObject *, PyObject *, PyObject *, 1105 PyObject *,PyObject *);1159 PyObject *); 1106 1160 1107 1161 static PyMemberDef property_members[] = { 1108 1109 1110 1111 1112 1162 {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, 1163 {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, 1164 {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, 1165 {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY}, 1166 {0} 1113 1167 }; 1114 1168 1115 1169 1116 1170 PyDoc_STRVAR(getter_doc, 1117 1171 "Descriptor to change the getter on a property."); 1118 1172 1119 1173 static PyObject * 1120 1174 property_getter(PyObject *self, PyObject *getter) 1121 1175 { 1122 return property_copy(self, getter, NULL, NULL, NULL);1176 return property_copy(self, getter, NULL, NULL); 1123 1177 } 1124 1178 1125 1179 1126 1180 PyDoc_STRVAR(setter_doc, 1127 1181 "Descriptor to change the setter on a property."); 1128 1182 1129 1183 static PyObject * 1130 1184 property_setter(PyObject *self, PyObject *setter) 1131 1185 { 1132 return property_copy(self, NULL, setter, NULL, NULL);1186 return property_copy(self, NULL, setter, NULL); 1133 1187 } 1134 1188 1135 1189 1136 1190 PyDoc_STRVAR(deleter_doc, 1137 1191 "Descriptor to change the deleter on a property."); 1138 1192 1139 1193 static PyObject * 1140 1194 property_deleter(PyObject *self, PyObject *deleter) 1141 1195 { 1142 return property_copy(self, NULL, NULL, deleter, NULL);1196 return property_copy(self, NULL, NULL, deleter); 1143 1197 } 1144 1198 1145 1199 1146 1200 static PyMethodDef property_methods[] = { 1147 1148 1149 1150 1201 {"getter", property_getter, METH_O, getter_doc}, 1202 {"setter", property_setter, METH_O, setter_doc}, 1203 {"deleter", property_deleter, METH_O, deleter_doc}, 1204 {0} 1151 1205 }; 1152 1206 … … 1155 1209 property_dealloc(PyObject *self) 1156 1210 { 1157 1158 1159 1160 1161 1162 1163 1164 1211 propertyobject *gs = (propertyobject *)self; 1212 1213 _PyObject_GC_UNTRACK(self); 1214 Py_XDECREF(gs->prop_get); 1215 Py_XDECREF(gs->prop_set); 1216 Py_XDECREF(gs->prop_del); 1217 Py_XDECREF(gs->prop_doc); 1218 self->ob_type->tp_free(self); 1165 1219 } 1166 1220 … … 1168 1222 property_descr_get(PyObject *self, PyObject *obj, PyObject *type) 1169 1223 { 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1224 propertyobject *gs = (propertyobject *)self; 1225 1226 if (obj == NULL || obj == Py_None) { 1227 Py_INCREF(self); 1228 return self; 1229 } 1230 if (gs->prop_get == NULL) { 1231 PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); 1232 return NULL; 1233 } 1234 return PyObject_CallFunction(gs->prop_get, "(O)", obj); 1181 1235 } 1182 1236 … … 1184 1238 property_descr_set(PyObject *self, PyObject *obj, PyObject *value) 1185 1239 { 1186 propertyobject *gs = (propertyobject *)self; 1187 PyObject *func, *res; 1188 1189 if (value == NULL) 1190 func = gs->prop_del; 1191 else 1192 func = gs->prop_set; 1193 if (func == NULL) { 1194 PyErr_SetString(PyExc_AttributeError, 1195 value == NULL ? 1196 "can't delete attribute" : 1197 "can't set attribute"); 1198 return -1; 1199 } 1200 if (value == NULL) 1201 res = PyObject_CallFunction(func, "(O)", obj); 1202 else 1203 res = PyObject_CallFunction(func, "(OO)", obj, value); 1204 if (res == NULL) 1205 return -1; 1206 Py_DECREF(res); 1207 return 0; 1208 } 1209 1210 static PyObject * 1211 property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del, 1212 PyObject *doc) 1213 { 1214 propertyobject *pold = (propertyobject *)old; 1215 PyObject *new, *type; 1216 1217 type = PyObject_Type(old); 1218 if (type == NULL) 1219 return NULL; 1220 1221 if (get == NULL || get == Py_None) { 1222 Py_XDECREF(get); 1223 get = pold->prop_get ? pold->prop_get : Py_None; 1224 } 1225 if (set == NULL || set == Py_None) { 1226 Py_XDECREF(set); 1227 set = pold->prop_set ? pold->prop_set : Py_None; 1228 } 1229 if (del == NULL || del == Py_None) { 1230 Py_XDECREF(del); 1231 del = pold->prop_del ? pold->prop_del : Py_None; 1232 } 1233 if (doc == NULL || doc == Py_None) { 1234 Py_XDECREF(doc); 1235 if (pold->getter_doc && get != Py_None) { 1236 /* make _init use __doc__ from getter */ 1237 doc = Py_None; 1238 } 1239 else { 1240 doc = pold->prop_doc ? pold->prop_doc : Py_None; 1241 } 1242 } 1243 1244 new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); 1245 Py_DECREF(type); 1246 if (new == NULL) 1247 return NULL; 1248 return new; 1240 propertyobject *gs = (propertyobject *)self; 1241 PyObject *func, *res; 1242 1243 if (value == NULL) 1244 func = gs->prop_del; 1245 else 1246 func = gs->prop_set; 1247 if (func == NULL) { 1248 PyErr_SetString(PyExc_AttributeError, 1249 value == NULL ? 1250 "can't delete attribute" : 1251 "can't set attribute"); 1252 return -1; 1253 } 1254 if (value == NULL) 1255 res = PyObject_CallFunction(func, "(O)", obj); 1256 else 1257 res = PyObject_CallFunction(func, "(OO)", obj, value); 1258 if (res == NULL) 1259 return -1; 1260 Py_DECREF(res); 1261 return 0; 1262 } 1263 1264 static PyObject * 1265 property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) 1266 { 1267 propertyobject *pold = (propertyobject *)old; 1268 PyObject *new, *type, *doc; 1269 1270 type = PyObject_Type(old); 1271 if (type == NULL) 1272 return NULL; 1273 1274 if (get == NULL || get == Py_None) { 1275 Py_XDECREF(get); 1276 get = pold->prop_get ? pold->prop_get : Py_None; 1277 } 1278 if (set == NULL || set == Py_None) { 1279 Py_XDECREF(set); 1280 set = pold->prop_set ? pold->prop_set : Py_None; 1281 } 1282 if (del == NULL || del == Py_None) { 1283 Py_XDECREF(del); 1284 del = pold->prop_del ? pold->prop_del : Py_None; 1285 } 1286 if (pold->getter_doc && get != Py_None) { 1287 /* make _init use __doc__ from getter */ 1288 doc = Py_None; 1289 } 1290 else { 1291 doc = pold->prop_doc ? pold->prop_doc : Py_None; 1292 } 1293 1294 new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); 1295 Py_DECREF(type); 1296 if (new == NULL) 1297 return NULL; 1298 return new; 1249 1299 } 1250 1300 … … 1252 1302 property_init(PyObject *self, PyObject *args, PyObject *kwds) 1253 1303 { 1254 PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL; 1255 static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0}; 1256 propertyobject *prop = (propertyobject *)self; 1257 1258 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property", 1259 kwlist, &get, &set, &del, &doc)) 1260 return -1; 1261 1262 if (get == Py_None) 1263 get = NULL; 1264 if (set == Py_None) 1265 set = NULL; 1266 if (del == Py_None) 1267 del = NULL; 1268 1269 Py_XINCREF(get); 1270 Py_XINCREF(set); 1271 Py_XINCREF(del); 1272 Py_XINCREF(doc); 1273 1274 prop->prop_get = get; 1275 prop->prop_set = set; 1276 prop->prop_del = del; 1277 prop->prop_doc = doc; 1278 prop->getter_doc = 0; 1279 1280 /* if no docstring given and the getter has one, use that one */ 1281 if ((doc == NULL || doc == Py_None) && get != NULL) { 1282 PyObject *get_doc = PyObject_GetAttrString(get, "__doc__"); 1283 if (get_doc != NULL) { 1284 /* get_doc already INCREF'd by GetAttr */ 1285 if (Py_TYPE(self)==&PyProperty_Type) { 1286 Py_XDECREF(prop->prop_doc); 1287 prop->prop_doc = get_doc; 1288 } else { 1289 /* Put __doc__ in dict of the subclass instance instead, 1290 otherwise it gets shadowed by class's __doc__. */ 1291 if (PyObject_SetAttrString(self, "__doc__", get_doc) != 0) 1292 { 1293 /* DECREF for props handled by _dealloc */ 1294 Py_DECREF(get_doc); 1295 return -1; 1296 } 1297 Py_DECREF(get_doc); 1298 } 1299 prop->getter_doc = 1; 1300 } else { 1301 PyErr_Clear(); 1302 } 1303 } 1304 1305 return 0; 1304 PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL; 1305 static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0}; 1306 propertyobject *prop = (propertyobject *)self; 1307 1308 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property", 1309 kwlist, &get, &set, &del, &doc)) 1310 return -1; 1311 1312 if (get == Py_None) 1313 get = NULL; 1314 if (set == Py_None) 1315 set = NULL; 1316 if (del == Py_None) 1317 del = NULL; 1318 1319 Py_XINCREF(get); 1320 Py_XINCREF(set); 1321 Py_XINCREF(del); 1322 Py_XINCREF(doc); 1323 1324 prop->prop_get = get; 1325 prop->prop_set = set; 1326 prop->prop_del = del; 1327 prop->prop_doc = doc; 1328 prop->getter_doc = 0; 1329 1330 /* if no docstring given and the getter has one, use that one */ 1331 if ((doc == NULL || doc == Py_None) && get != NULL) { 1332 PyObject *get_doc = PyObject_GetAttrString(get, "__doc__"); 1333 if (get_doc) { 1334 if (Py_TYPE(self) == &PyProperty_Type) { 1335 Py_XDECREF(prop->prop_doc); 1336 prop->prop_doc = get_doc; 1337 } 1338 else { 1339 /* If this is a property subclass, put __doc__ 1340 in dict of the subclass instance instead, 1341 otherwise it gets shadowed by __doc__ in the 1342 class's dict. */ 1343 int err = PyObject_SetAttrString(self, "__doc__", get_doc); 1344 Py_DECREF(get_doc); 1345 if (err < 0) 1346 return -1; 1347 } 1348 prop->getter_doc = 1; 1349 } 1350 else if (PyErr_ExceptionMatches(PyExc_Exception)) { 1351 PyErr_Clear(); 1352 } 1353 else { 1354 return -1; 1355 } 1356 } 1357 1358 return 0; 1306 1359 } 1307 1360 … … 1331 1384 property_traverse(PyObject *self, visitproc visit, void *arg) 1332 1385 { 1333 1334 1335 1336 1337 1338 1386 propertyobject *pp = (propertyobject *)self; 1387 Py_VISIT(pp->prop_get); 1388 Py_VISIT(pp->prop_set); 1389 Py_VISIT(pp->prop_del); 1390 Py_VISIT(pp->prop_doc); 1391 return 0; 1339 1392 } 1340 1393 1341 1394 PyTypeObject PyProperty_Type = { 1342 1343 "property",/* tp_name */1344 sizeof(propertyobject),/* tp_basicsize */1345 0,/* tp_itemsize */1346 1347 property_dealloc,/* tp_dealloc */1348 0,/* tp_print */1349 0,/* tp_getattr */1350 0,/* tp_setattr */1351 0,/* tp_compare */1352 0,/* tp_repr */1353 0,/* tp_as_number */1354 0,/* tp_as_sequence */1355 0,/* tp_as_mapping */1356 0,/* tp_hash */1357 0,/* tp_call */1358 0,/* tp_str */1359 PyObject_GenericGetAttr,/* tp_getattro */1360 0,/* tp_setattro */1361 0,/* tp_as_buffer */1362 1363 Py_TPFLAGS_BASETYPE,/* tp_flags */1364 property_doc,/* tp_doc */1365 property_traverse,/* tp_traverse */1366 0,/* tp_clear */1367 0,/* tp_richcompare */1368 0,/* tp_weaklistoffset */1369 0,/* tp_iter */1370 0,/* tp_iternext */1371 property_methods,/* tp_methods */1372 property_members,/* tp_members */1373 0,/* tp_getset */1374 0,/* tp_base */1375 0,/* tp_dict */1376 property_descr_get,/* tp_descr_get */1377 property_descr_set,/* tp_descr_set */1378 0,/* tp_dictoffset */1379 property_init,/* tp_init */1380 PyType_GenericAlloc,/* tp_alloc */1381 PyType_GenericNew,/* tp_new */1382 PyObject_GC_Del,/* tp_free */1383 }; 1395 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1396 "property", /* tp_name */ 1397 sizeof(propertyobject), /* tp_basicsize */ 1398 0, /* tp_itemsize */ 1399 /* methods */ 1400 property_dealloc, /* tp_dealloc */ 1401 0, /* tp_print */ 1402 0, /* tp_getattr */ 1403 0, /* tp_setattr */ 1404 0, /* tp_compare */ 1405 0, /* tp_repr */ 1406 0, /* tp_as_number */ 1407 0, /* tp_as_sequence */ 1408 0, /* tp_as_mapping */ 1409 0, /* tp_hash */ 1410 0, /* tp_call */ 1411 0, /* tp_str */ 1412 PyObject_GenericGetAttr, /* tp_getattro */ 1413 0, /* tp_setattro */ 1414 0, /* tp_as_buffer */ 1415 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 1416 Py_TPFLAGS_BASETYPE, /* tp_flags */ 1417 property_doc, /* tp_doc */ 1418 property_traverse, /* tp_traverse */ 1419 0, /* tp_clear */ 1420 0, /* tp_richcompare */ 1421 0, /* tp_weaklistoffset */ 1422 0, /* tp_iter */ 1423 0, /* tp_iternext */ 1424 property_methods, /* tp_methods */ 1425 property_members, /* tp_members */ 1426 0, /* tp_getset */ 1427 0, /* tp_base */ 1428 0, /* tp_dict */ 1429 property_descr_get, /* tp_descr_get */ 1430 property_descr_set, /* tp_descr_set */ 1431 0, /* tp_dictoffset */ 1432 property_init, /* tp_init */ 1433 PyType_GenericAlloc, /* tp_alloc */ 1434 PyType_GenericNew, /* tp_new */ 1435 PyObject_GC_Del, /* tp_free */ 1436 };
Note:
See TracChangeset
for help on using the changeset viewer.