diff options
author | Guido van Rossum <guido@python.org> | 2001-10-22 00:43:43 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-22 00:43:43 (GMT) |
commit | c8e5645f15054a87945d5f62dc23c6e49a394db5 (patch) | |
tree | 94172c8b5b197c564ba64789b81cd41334b996a9 /Objects | |
parent | d6bebce5e5a6e92b6949dd001d3d467a7aa1aaef (diff) | |
download | cpython-c8e5645f15054a87945d5f62dc23c6e49a394db5.zip cpython-c8e5645f15054a87945d5f62dc23c6e49a394db5.tar.gz cpython-c8e5645f15054a87945d5f62dc23c6e49a394db5.tar.bz2 |
Methods of built-in types now properly check for keyword arguments
(formerly these were silently ignored). The only built-in methods
that take keyword arguments are __call__, __init__ and __new__.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/descrobject.c | 11 | ||||
-rw-r--r-- | Objects/typeobject.c | 26 |
2 files changed, 25 insertions, 12 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index e4d9f33..c5e793d 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -805,6 +805,17 @@ wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) wrapperfunc wrapper = wp->descr->d_base->wrapper; PyObject *self = wp->self; + if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { + wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; + return (*wk)(self, args, wp->descr->d_wrapped, kwds); + } + + if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_Size(kwds) != 0)) { + PyErr_Format(PyExc_TypeError, + "wrapper %s doesn't take keyword arguments", + wp->descr->d_base->name); + return NULL; + } return (*wrapper)(self, args, wp->descr->d_wrapped); } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4e8f967..5952b4e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2251,12 +2251,11 @@ wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) } static PyObject * -wrap_call(PyObject *self, PyObject *args, void *wrapped) +wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { ternaryfunc func = (ternaryfunc)wrapped; - /* XXX What about keyword arguments? */ - return (*func)(self, args, NULL); + return (*func)(self, args, kwds); } static PyObject * @@ -2328,12 +2327,11 @@ wrap_descr_set(PyObject *self, PyObject *args, void *wrapped) } static PyObject * -wrap_init(PyObject *self, PyObject *args, void *wrapped) +wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { initproc func = (initproc)wrapped; - /* XXX What about keyword arguments? */ - if (func(self, args, NULL) < 0) + if (func(self, args, kwds) < 0) return NULL; Py_INCREF(Py_None); return Py_None; @@ -3177,6 +3175,7 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) typedef struct wrapperbase slotdef; #undef TPSLOT +#undef FLSLOT #undef ETSLOT #undef SQSLOT #undef MPSLOT @@ -3188,6 +3187,9 @@ typedef struct wrapperbase slotdef; #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, DOC} +#define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ + {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + DOC, FLAGS} #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ {NAME, offsetof(etype, SLOT), (void *)(FUNCTION), WRAPPER, DOC} #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ @@ -3346,8 +3348,8 @@ static slotdef slotdefs[] = { "x.__cmp__(y) <==> cmp(x,y)"), TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, "x.__hash__() <==> hash(x)"), - TPSLOT("__call__", tp_call, slot_tp_call, wrap_call, - "x.__call__(...) <==> x(...)"), + FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, + "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), @@ -3379,11 +3381,11 @@ static slotdef slotdefs[] = { "descr.__get__(obj[, type]) -> value"), TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, "descr.__set__(obj, value)"), - TPSLOT("__init__", tp_init, slot_tp_init, wrap_init, + FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, "x.__init__(...) initializes x; " - "see x.__class__.__doc__ for signature"), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, - ""), + "see x.__class__.__doc__ for signature", + PyWrapperFlag_KEYWORDS), + TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), {NULL} }; |