Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Side by Side Diff: Objects/descrobject.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Patch Set: Created 3 years, 2 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Objects/classobject.c ('k') | Objects/funcobject.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Descriptors -- a new, flexible way to describe attributes */ 1 /* Descriptors -- a new, flexible way to describe attributes */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "structmember.h" /* Why is this not included in Python.h? */ 4 #include "structmember.h" /* Why is this not included in Python.h? */
5 5
6 static void 6 static void
7 descr_dealloc(PyDescrObject *descr) 7 descr_dealloc(PyDescrObject *descr)
8 { 8 {
9 _PyObject_GC_UNTRACK(descr); 9 _PyObject_GC_UNTRACK(descr);
10 Py_XDECREF(descr->d_type); 10 Py_XDECREF(descr->d_type);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 return descr->d_getset->set(obj, value, 203 return descr->d_getset->set(obj, value,
204 descr->d_getset->closure); 204 descr->d_getset->closure);
205 PyErr_Format(PyExc_AttributeError, 205 PyErr_Format(PyExc_AttributeError,
206 "attribute '%V' of '%.100s' objects is not writable", 206 "attribute '%V' of '%.100s' objects is not writable",
207 descr_name((PyDescrObject *)descr), "?", 207 descr_name((PyDescrObject *)descr), "?",
208 PyDescr_TYPE(descr)->tp_name); 208 PyDescr_TYPE(descr)->tp_name);
209 return -1; 209 return -1;
210 } 210 }
211 211
212 static PyObject * 212 static PyObject *
213 methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) 213 methoddescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
214 PyObject *kwnames)
214 { 215 {
215 Py_ssize_t argc; 216 PyObject *self, *func, *result;
216 PyObject *self, *func, *result, **stack;
217 217
218 /* Make sure that the first argument is acceptable as 'self' */ 218 /* Make sure that the first argument is acceptable as 'self' */
219 assert(PyTuple_Check(args)); 219 if (nargs < 1) {
220 argc = PyTuple_GET_SIZE(args);
221 if (argc < 1) {
222 PyErr_Format(PyExc_TypeError, 220 PyErr_Format(PyExc_TypeError,
223 "descriptor '%V' of '%.100s' " 221 "descriptor '%V' of '%.100s' "
224 "object needs an argument", 222 "object needs an argument",
225 descr_name((PyDescrObject *)descr), "?", 223 descr_name((PyDescrObject *)descr), "?",
226 PyDescr_TYPE(descr)->tp_name); 224 PyDescr_TYPE(descr)->tp_name);
227 return NULL; 225 return NULL;
228 } 226 }
229 self = PyTuple_GET_ITEM(args, 0); 227 self = args[0];
230 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 228 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
231 (PyObject *)PyDescr_TYPE(descr))) { 229 (PyObject *)PyDescr_TYPE(descr))) {
232 PyErr_Format(PyExc_TypeError, 230 PyErr_Format(PyExc_TypeError,
233 "descriptor '%V' " 231 "descriptor '%V' "
234 "requires a '%.100s' object " 232 "requires a '%.100s' object "
235 "but received a '%.100s'", 233 "but received a '%.100s'",
236 descr_name((PyDescrObject *)descr), "?", 234 descr_name((PyDescrObject *)descr), "?",
237 PyDescr_TYPE(descr)->tp_name, 235 PyDescr_TYPE(descr)->tp_name,
238 self->ob_type->tp_name); 236 self->ob_type->tp_name);
239 return NULL; 237 return NULL;
240 } 238 }
241 239
242 func = PyCFunction_NewEx(descr->d_method, self, NULL); 240 func = PyCFunction_NewEx(descr->d_method, self, NULL);
243 if (func == NULL) 241 if (func == NULL)
244 return NULL; 242 return NULL;
245 stack = &PyTuple_GET_ITEM(args, 1); 243 result = _PyCFunction_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
246 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
247 Py_DECREF(func); 244 Py_DECREF(func);
248 return result; 245 return result;
249 } 246 }
250 247
251 static PyObject * 248 static PyObject *
252 classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, 249 classmethoddescr_call(PyMethodDescrObject *descr, PyObject **args,
253 PyObject *kwds) 250 Py_ssize_t nargs, PyObject *kwnames)
254 { 251 {
255 Py_ssize_t argc; 252 PyObject *self, *func, *result;
256 PyObject *self, *func, *result, **stack;
257 253
258 /* Make sure that the first argument is acceptable as 'self' */ 254 /* Make sure that the first argument is acceptable as 'self' */
259 assert(PyTuple_Check(args)); 255 if (nargs < 1) {
260 argc = PyTuple_GET_SIZE(args);
261 if (argc < 1) {
262 PyErr_Format(PyExc_TypeError, 256 PyErr_Format(PyExc_TypeError,
263 "descriptor '%V' of '%.100s' " 257 "descriptor '%V' of '%.100s' "
264 "object needs an argument", 258 "object needs an argument",
265 descr_name((PyDescrObject *)descr), "?", 259 descr_name((PyDescrObject *)descr), "?",
266 PyDescr_TYPE(descr)->tp_name); 260 PyDescr_TYPE(descr)->tp_name);
267 return NULL; 261 return NULL;
268 } 262 }
269 self = PyTuple_GET_ITEM(args, 0); 263 self = args[0];
270 if (!PyType_Check(self)) { 264 if (!PyType_Check(self)) {
271 PyErr_Format(PyExc_TypeError, 265 PyErr_Format(PyExc_TypeError,
272 "descriptor '%V' requires a type " 266 "descriptor '%V' requires a type "
273 "but received a '%.100s'", 267 "but received a '%.100s'",
274 descr_name((PyDescrObject *)descr), "?", 268 descr_name((PyDescrObject *)descr), "?",
275 PyDescr_TYPE(descr)->tp_name, 269 PyDescr_TYPE(descr)->tp_name,
276 self->ob_type->tp_name); 270 self->ob_type->tp_name);
277 return NULL; 271 return NULL;
278 } 272 }
279 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { 273 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
280 PyErr_Format(PyExc_TypeError, 274 PyErr_Format(PyExc_TypeError,
281 "descriptor '%V' " 275 "descriptor '%V' "
282 "requires a subtype of '%.100s' " 276 "requires a subtype of '%.100s' "
283 "but received '%.100s", 277 "but received '%.100s",
284 descr_name((PyDescrObject *)descr), "?", 278 descr_name((PyDescrObject *)descr), "?",
285 PyDescr_TYPE(descr)->tp_name, 279 PyDescr_TYPE(descr)->tp_name,
286 self->ob_type->tp_name); 280 self->ob_type->tp_name);
287 return NULL; 281 return NULL;
288 } 282 }
289 283
290 func = PyCFunction_NewEx(descr->d_method, self, NULL); 284 func = PyCFunction_NewEx(descr->d_method, self, NULL);
291 if (func == NULL) 285 if (func == NULL)
292 return NULL; 286 return NULL;
293 stack = &PyTuple_GET_ITEM(args, 1); 287 result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
294 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
295 Py_DECREF(func); 288 Py_DECREF(func);
296 return result; 289 return result;
297 } 290 }
298 291
299 static PyObject * 292 static PyObject *
300 wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) 293 wrapperdescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
294 PyObject *kwnames)
301 { 295 {
302 Py_ssize_t argc; 296 PyObject *self, *func, *result;
303 PyObject *self, *func, *result, **stack;
304 297
305 /* Make sure that the first argument is acceptable as 'self' */ 298 /* Make sure that the first argument is acceptable as 'self' */
306 assert(PyTuple_Check(args)); 299 if (nargs < 1) {
307 argc = PyTuple_GET_SIZE(args);
308 if (argc < 1) {
309 PyErr_Format(PyExc_TypeError, 300 PyErr_Format(PyExc_TypeError,
310 "descriptor '%V' of '%.100s' " 301 "descriptor '%V' of '%.100s' "
311 "object needs an argument", 302 "object needs an argument",
312 descr_name((PyDescrObject *)descr), "?", 303 descr_name((PyDescrObject *)descr), "?",
313 PyDescr_TYPE(descr)->tp_name); 304 PyDescr_TYPE(descr)->tp_name);
314 return NULL; 305 return NULL;
315 } 306 }
316 self = PyTuple_GET_ITEM(args, 0); 307 self = args[0];
317 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 308 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
318 (PyObject *)PyDescr_TYPE(descr))) { 309 (PyObject *)PyDescr_TYPE(descr))) {
319 PyErr_Format(PyExc_TypeError, 310 PyErr_Format(PyExc_TypeError,
320 "descriptor '%V' " 311 "descriptor '%V' "
321 "requires a '%.100s' object " 312 "requires a '%.100s' object "
322 "but received a '%.100s'", 313 "but received a '%.100s'",
323 descr_name((PyDescrObject *)descr), "?", 314 descr_name((PyDescrObject *)descr), "?",
324 PyDescr_TYPE(descr)->tp_name, 315 PyDescr_TYPE(descr)->tp_name,
325 self->ob_type->tp_name); 316 self->ob_type->tp_name);
326 return NULL; 317 return NULL;
327 } 318 }
328 319
329 func = PyWrapper_New((PyObject *)descr, self); 320 func = PyWrapper_New((PyObject *)descr, self);
330 if (func == NULL) 321 if (func == NULL)
331 return NULL; 322 return NULL;
332 323
333 stack = &PyTuple_GET_ITEM(args, 1); 324 result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
334 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
335 Py_DECREF(func); 325 Py_DECREF(func);
336 return result; 326 return result;
337 } 327 }
338 328
339 static PyObject * 329 static PyObject *
340 method_get_doc(PyMethodDescrObject *descr, void *closure) 330 method_get_doc(PyMethodDescrObject *descr, void *closure)
341 { 331 {
342 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_meth od->ml_doc); 332 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_meth od->ml_doc);
343 } 333 }
344 334
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 (destructor)descr_dealloc, /* tp_dealloc */ 474 (destructor)descr_dealloc, /* tp_dealloc */
485 0, /* tp_print */ 475 0, /* tp_print */
486 0, /* tp_getattr */ 476 0, /* tp_getattr */
487 0, /* tp_setattr */ 477 0, /* tp_setattr */
488 0, /* tp_reserved */ 478 0, /* tp_reserved */
489 (reprfunc)method_repr, /* tp_repr */ 479 (reprfunc)method_repr, /* tp_repr */
490 0, /* tp_as_number */ 480 0, /* tp_as_number */
491 0, /* tp_as_sequence */ 481 0, /* tp_as_sequence */
492 0, /* tp_as_mapping */ 482 0, /* tp_as_mapping */
493 0, /* tp_hash */ 483 0, /* tp_hash */
494 (ternaryfunc)methoddescr_call, /* tp_call */ 484 0, /* tp_call */
495 0, /* tp_str */ 485 0, /* tp_str */
496 PyObject_GenericGetAttr, /* tp_getattro */ 486 PyObject_GenericGetAttr, /* tp_getattro */
497 0, /* tp_setattro */ 487 0, /* tp_setattro */
498 0, /* tp_as_buffer */ 488 0, /* tp_as_buffer */
499 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 489 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
500 0, /* tp_doc */ 490 0, /* tp_doc */
501 descr_traverse, /* tp_traverse */ 491 descr_traverse, /* tp_traverse */
502 0, /* tp_clear */ 492 0, /* tp_clear */
503 0, /* tp_richcompare */ 493 0, /* tp_richcompare */
504 0, /* tp_weaklistoffset */ 494 0, /* tp_weaklistoffset */
505 0, /* tp_iter */ 495 0, /* tp_iter */
506 0, /* tp_iternext */ 496 0, /* tp_iternext */
507 descr_methods, /* tp_methods */ 497 descr_methods, /* tp_methods */
508 descr_members, /* tp_members */ 498 descr_members, /* tp_members */
509 method_getset, /* tp_getset */ 499 method_getset, /* tp_getset */
510 0, /* tp_base */ 500 0, /* tp_base */
511 0, /* tp_dict */ 501 0, /* tp_dict */
512 (descrgetfunc)method_get, /* tp_descr_get */ 502 (descrgetfunc)method_get, /* tp_descr_get */
513 0, /* tp_descr_set */ 503
504 .tp_fastcall = (fastternaryfunc)methoddescr_call,
514 }; 505 };
515 506
516 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ 507 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
517 PyTypeObject PyClassMethodDescr_Type = { 508 PyTypeObject PyClassMethodDescr_Type = {
518 PyVarObject_HEAD_INIT(&PyType_Type, 0) 509 PyVarObject_HEAD_INIT(&PyType_Type, 0)
519 "classmethod_descriptor", 510 "classmethod_descriptor",
520 sizeof(PyMethodDescrObject), 511 sizeof(PyMethodDescrObject),
521 0, 512 0,
522 (destructor)descr_dealloc, /* tp_dealloc */ 513 (destructor)descr_dealloc, /* tp_dealloc */
523 0, /* tp_print */ 514 0, /* tp_print */
524 0, /* tp_getattr */ 515 0, /* tp_getattr */
525 0, /* tp_setattr */ 516 0, /* tp_setattr */
526 0, /* tp_reserved */ 517 0, /* tp_reserved */
527 (reprfunc)method_repr, /* tp_repr */ 518 (reprfunc)method_repr, /* tp_repr */
528 0, /* tp_as_number */ 519 0, /* tp_as_number */
529 0, /* tp_as_sequence */ 520 0, /* tp_as_sequence */
530 0, /* tp_as_mapping */ 521 0, /* tp_as_mapping */
531 0, /* tp_hash */ 522 0, /* tp_hash */
532 (ternaryfunc)classmethoddescr_call, /* tp_call */ 523 0, /* tp_call */
533 0, /* tp_str */ 524 0, /* tp_str */
534 PyObject_GenericGetAttr, /* tp_getattro */ 525 PyObject_GenericGetAttr, /* tp_getattro */
535 0, /* tp_setattro */ 526 0, /* tp_setattro */
536 0, /* tp_as_buffer */ 527 0, /* tp_as_buffer */
537 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 528 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
538 0, /* tp_doc */ 529 0, /* tp_doc */
539 descr_traverse, /* tp_traverse */ 530 descr_traverse, /* tp_traverse */
540 0, /* tp_clear */ 531 0, /* tp_clear */
541 0, /* tp_richcompare */ 532 0, /* tp_richcompare */
542 0, /* tp_weaklistoffset */ 533 0, /* tp_weaklistoffset */
543 0, /* tp_iter */ 534 0, /* tp_iter */
544 0, /* tp_iternext */ 535 0, /* tp_iternext */
545 descr_methods, /* tp_methods */ 536 descr_methods, /* tp_methods */
546 descr_members, /* tp_members */ 537 descr_members, /* tp_members */
547 method_getset, /* tp_getset */ 538 method_getset, /* tp_getset */
548 0, /* tp_base */ 539 0, /* tp_base */
549 0, /* tp_dict */ 540 0, /* tp_dict */
550 (descrgetfunc)classmethod_get, /* tp_descr_get */ 541 (descrgetfunc)classmethod_get, /* tp_descr_get */
551 0, /* tp_descr_set */ 542
543 .tp_fastcall = (fastternaryfunc)classmethoddescr_call,
552 }; 544 };
553 545
554 PyTypeObject PyMemberDescr_Type = { 546 PyTypeObject PyMemberDescr_Type = {
555 PyVarObject_HEAD_INIT(&PyType_Type, 0) 547 PyVarObject_HEAD_INIT(&PyType_Type, 0)
556 "member_descriptor", 548 "member_descriptor",
557 sizeof(PyMemberDescrObject), 549 sizeof(PyMemberDescrObject),
558 0, 550 0,
559 (destructor)descr_dealloc, /* tp_dealloc */ 551 (destructor)descr_dealloc, /* tp_dealloc */
560 0, /* tp_print */ 552 0, /* tp_print */
561 0, /* tp_getattr */ 553 0, /* tp_getattr */
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 (destructor)descr_dealloc, /* tp_dealloc */ 625 (destructor)descr_dealloc, /* tp_dealloc */
634 0, /* tp_print */ 626 0, /* tp_print */
635 0, /* tp_getattr */ 627 0, /* tp_getattr */
636 0, /* tp_setattr */ 628 0, /* tp_setattr */
637 0, /* tp_reserved */ 629 0, /* tp_reserved */
638 (reprfunc)wrapperdescr_repr, /* tp_repr */ 630 (reprfunc)wrapperdescr_repr, /* tp_repr */
639 0, /* tp_as_number */ 631 0, /* tp_as_number */
640 0, /* tp_as_sequence */ 632 0, /* tp_as_sequence */
641 0, /* tp_as_mapping */ 633 0, /* tp_as_mapping */
642 0, /* tp_hash */ 634 0, /* tp_hash */
643 (ternaryfunc)wrapperdescr_call, /* tp_call */ 635 0, /* tp_call */
644 0, /* tp_str */ 636 0, /* tp_str */
645 PyObject_GenericGetAttr, /* tp_getattro */ 637 PyObject_GenericGetAttr, /* tp_getattro */
646 0, /* tp_setattro */ 638 0, /* tp_setattro */
647 0, /* tp_as_buffer */ 639 0, /* tp_as_buffer */
648 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 640 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
649 0, /* tp_doc */ 641 0, /* tp_doc */
650 descr_traverse, /* tp_traverse */ 642 descr_traverse, /* tp_traverse */
651 0, /* tp_clear */ 643 0, /* tp_clear */
652 0, /* tp_richcompare */ 644 0, /* tp_richcompare */
653 0, /* tp_weaklistoffset */ 645 0, /* tp_weaklistoffset */
654 0, /* tp_iter */ 646 0, /* tp_iter */
655 0, /* tp_iternext */ 647 0, /* tp_iternext */
656 descr_methods, /* tp_methods */ 648 descr_methods, /* tp_methods */
657 descr_members, /* tp_members */ 649 descr_members, /* tp_members */
658 wrapperdescr_getset, /* tp_getset */ 650 wrapperdescr_getset, /* tp_getset */
659 0, /* tp_base */ 651 0, /* tp_base */
660 0, /* tp_dict */ 652 0, /* tp_dict */
661 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 653 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
662 0, /* tp_descr_set */ 654
655 .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
663 }; 656 };
664 657
665 static PyDescrObject * 658 static PyDescrObject *
666 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 659 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
667 { 660 {
668 PyDescrObject *descr; 661 PyDescrObject *descr;
669 662
670 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 663 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
671 if (descr != NULL) { 664 if (descr != NULL) {
672 Py_XINCREF(type); 665 Py_XINCREF(type);
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 Py_XDECREF(gs->prop_get); 1345 Py_XDECREF(gs->prop_get);
1353 Py_XDECREF(gs->prop_set); 1346 Py_XDECREF(gs->prop_set);
1354 Py_XDECREF(gs->prop_del); 1347 Py_XDECREF(gs->prop_del);
1355 Py_XDECREF(gs->prop_doc); 1348 Py_XDECREF(gs->prop_doc);
1356 self->ob_type->tp_free(self); 1349 self->ob_type->tp_free(self);
1357 } 1350 }
1358 1351
1359 static PyObject * 1352 static PyObject *
1360 property_descr_get(PyObject *self, PyObject *obj, PyObject *type) 1353 property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1361 { 1354 {
1362 static PyObject * volatile cached_args = NULL;
1363 PyObject *args;
1364 PyObject *ret;
1365 propertyobject *gs = (propertyobject *)self; 1355 propertyobject *gs = (propertyobject *)self;
1356 PyObject *args[1];
1366 1357
1367 if (obj == NULL || obj == Py_None) { 1358 if (obj == NULL || obj == Py_None) {
1368 Py_INCREF(self); 1359 Py_INCREF(self);
1369 return self; 1360 return self;
1370 } 1361 }
1371 if (gs->prop_get == NULL) { 1362 if (gs->prop_get == NULL) {
1372 PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); 1363 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1373 return NULL; 1364 return NULL;
1374 } 1365 }
1375 args = cached_args; 1366
1376 cached_args = NULL; 1367 args[0] = obj;
1377 if (!args) { 1368 return _PyObject_FastCall(gs->prop_get, args, 1);
1378 args = PyTuple_New(1);
1379 if (!args)
1380 return NULL;
1381 _PyObject_GC_UNTRACK(args);
1382 }
1383 Py_INCREF(obj);
1384 PyTuple_SET_ITEM(args, 0, obj);
1385 ret = PyObject_Call(gs->prop_get, args, NULL);
1386 if (cached_args == NULL && Py_REFCNT(args) == 1) {
1387 assert(Py_SIZE(args) == 1);
1388 assert(PyTuple_GET_ITEM(args, 0) == obj);
1389 cached_args = args;
1390 Py_DECREF(obj);
1391 }
1392 else {
1393 assert(Py_REFCNT(args) >= 1);
1394 _PyObject_GC_TRACK(args);
1395 Py_DECREF(args);
1396 }
1397 return ret;
1398 } 1369 }
1399 1370
1400 static int 1371 static int
1401 property_descr_set(PyObject *self, PyObject *obj, PyObject *value) 1372 property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1402 { 1373 {
1403 propertyobject *gs = (propertyobject *)self; 1374 propertyobject *gs = (propertyobject *)self;
1404 PyObject *func, *res; 1375 PyObject *func, *res;
1405 1376
1406 if (value == NULL) 1377 if (value == NULL)
1407 func = gs->prop_del; 1378 func = gs->prop_del;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 0, /* tp_base */ 1610 0, /* tp_base */
1640 0, /* tp_dict */ 1611 0, /* tp_dict */
1641 property_descr_get, /* tp_descr_get */ 1612 property_descr_get, /* tp_descr_get */
1642 property_descr_set, /* tp_descr_set */ 1613 property_descr_set, /* tp_descr_set */
1643 0, /* tp_dictoffset */ 1614 0, /* tp_dictoffset */
1644 property_init, /* tp_init */ 1615 property_init, /* tp_init */
1645 PyType_GenericAlloc, /* tp_alloc */ 1616 PyType_GenericAlloc, /* tp_alloc */
1646 PyType_GenericNew, /* tp_new */ 1617 PyType_GenericNew, /* tp_new */
1647 PyObject_GC_Del, /* tp_free */ 1618 PyObject_GC_Del, /* tp_free */
1648 }; 1619 };
OLDNEW
« no previous file with comments | « Objects/classobject.c ('k') | Objects/funcobject.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+