diff options
author | Pablo Galindo <Pablogsal@gmail.com> | 2019-04-29 12:36:57 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-29 12:36:57 (GMT) |
commit | 8c77b8cb9188165a123f2512026e3629bf03dc9b (patch) | |
tree | 863ea19f5f2c8ec179c32b3d06dc8366859ae26e /Objects | |
parent | 99fcc616d400cd31af0733c3f8cc93bcc1d32a44 (diff) | |
download | cpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.zip cpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.tar.gz cpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.tar.bz2 |
bpo-36540: PEP 570 -- Implementation (GH-12701)
This commit contains the implementation of PEP570: Python positional-only parameters.
* Update Grammar/Grammar with new typedarglist and varargslist
* Regenerate grammar files
* Update and regenerate AST related files
* Update code object
* Update marshal.c
* Update compiler and symtable
* Regenerate importlib files
* Update callable objects
* Implement positional-only args logic in ceval.c
* Regenerate frozen data
* Update standard library to account for positional-only args
* Add test file for positional-only args
* Update other test files to account for positional-only args
* Add News entry
* Update inspect module and related tests
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/call.c | 8 | ||||
-rw-r--r-- | Objects/codeobject.c | 73 |
2 files changed, 48 insertions, 33 deletions
diff --git a/Objects/call.c b/Objects/call.c index d52e7e2..68f9e87 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -320,11 +320,11 @@ _PyFunction_FastCallDict(PyObject *func, PyObject *const *args, Py_ssize_t nargs (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { /* Fast paths */ - if (argdefs == NULL && co->co_argcount == nargs) { + if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount == nargs) { return function_code_fastcall(co, args, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ args = _PyTuple_ITEMS(argdefs); @@ -406,11 +406,11 @@ _PyFunction_FastCallKeywords(PyObject *func, PyObject *const *stack, if (co->co_kwonlyargcount == 0 && nkwargs == 0 && (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { - if (argdefs == NULL && co->co_argcount == nargs) { + if (argdefs == NULL && co->co_argcount + co->co_posonlyargcount== nargs) { return function_code_fastcall(co, stack, nargs, globals); } else if (nargs == 0 && argdefs != NULL - && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { + && co->co_argcount + co->co_posonlyargcount == PyTuple_GET_SIZE(argdefs)) { /* function called with no arguments, but all parameters have a default value: use default values as arguments .*/ stack = _PyTuple_ITEMS(argdefs); diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 09182d6..62d7c5d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -96,7 +96,7 @@ intern_string_constants(PyObject *tuple) PyCodeObject * -PyCode_New(int argcount, int kwonlyargcount, +PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -108,8 +108,8 @@ PyCode_New(int argcount, int kwonlyargcount, Py_ssize_t i, n_cellvars, n_varnames, total_args; /* Check argument types */ - if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || - code == NULL || !PyBytes_Check(code) || + if (argcount < 0 || posonlyargcount < 0 || kwonlyargcount < 0 || + nlocals < 0 || code == NULL || !PyBytes_Check(code) || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || @@ -141,10 +141,12 @@ PyCode_New(int argcount, int kwonlyargcount, } n_varnames = PyTuple_GET_SIZE(varnames); - if (argcount <= n_varnames && kwonlyargcount <= n_varnames) { + if (posonlyargcount + argcount <= n_varnames + && kwonlyargcount <= n_varnames) { /* Never overflows. */ - total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount + - ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); + total_args = (Py_ssize_t)posonlyargcount + (Py_ssize_t)argcount + + (Py_ssize_t)kwonlyargcount + + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); } else { total_args = n_varnames + 1; @@ -193,6 +195,7 @@ PyCode_New(int argcount, int kwonlyargcount, return NULL; } co->co_argcount = argcount; + co->co_posonlyargcount = posonlyargcount; co->co_kwonlyargcount = kwonlyargcount; co->co_nlocals = nlocals; co->co_stacksize = stacksize; @@ -249,6 +252,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) goto failed; result = PyCode_New(0, /* argcount */ + 0, /* posonlyargcount */ 0, /* kwonlyargcount */ 0, /* nlocals */ 0, /* stacksize */ @@ -274,21 +278,22 @@ failed: #define OFF(x) offsetof(PyCodeObject, x) static PyMemberDef code_memberlist[] = { - {"co_argcount", T_INT, OFF(co_argcount), READONLY}, - {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, - {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, - {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, - {"co_flags", T_INT, OFF(co_flags), READONLY}, - {"co_code", T_OBJECT, OFF(co_code), READONLY}, - {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, - {"co_names", T_OBJECT, OFF(co_names), READONLY}, - {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, - {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, - {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, - {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, - {"co_name", T_OBJECT, OFF(co_name), READONLY}, - {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, - {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, + {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, + {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, + {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, + {"co_flags", T_INT, OFF(co_flags), READONLY}, + {"co_code", T_OBJECT, OFF(co_code), READONLY}, + {"co_consts", T_OBJECT, OFF(co_consts), READONLY}, + {"co_names", T_OBJECT, OFF(co_names), READONLY}, + {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY}, + {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY}, + {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY}, + {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, + {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, + {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY}, {NULL} /* Sentinel */ }; @@ -335,9 +340,9 @@ validate_and_copy_tuple(PyObject *tup) } PyDoc_STRVAR(code_doc, -"code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\ - constants, names, varnames, filename, name, firstlineno,\n\ - lnotab[, freevars[, cellvars]])\n\ +"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\ + flags, codestring, constants, names, varnames, filename, name,\n\ + firstlineno, lnotab[, freevars[, cellvars]])\n\ \n\ Create a code object. Not for the faint of heart."); @@ -345,6 +350,7 @@ static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kw) { int argcount; + int posonlyargcount; int kwonlyargcount; int nlocals; int stacksize; @@ -361,8 +367,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) int firstlineno; PyObject *lnotab; - if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code", - &argcount, &kwonlyargcount, + if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code", + &argcount, &posonlyargcount, &kwonlyargcount, &nlocals, &stacksize, &flags, &code, &PyTuple_Type, &consts, @@ -381,6 +387,13 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) goto cleanup; } + if (posonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: posonlyargcount must not be negative"); + goto cleanup; + } + if (kwonlyargcount < 0) { PyErr_SetString( PyExc_ValueError, @@ -413,7 +426,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (ourcellvars == NULL) goto cleanup; - co = (PyObject *)PyCode_New(argcount, kwonlyargcount, + co = (PyObject *)PyCode_New(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, ournames, ourvarnames, ourfreevars, ourcellvars, filename, @@ -645,9 +658,11 @@ code_richcompare(PyObject *self, PyObject *other, int op) cp = (PyCodeObject *)other; eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); - if (eq <= 0) goto unequal; + if (!eq) goto unequal; eq = co->co_argcount == cp->co_argcount; if (!eq) goto unequal; + eq = co->co_posonlyargcount == cp->co_posonlyargcount; + if (!eq) goto unequal; eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; if (!eq) goto unequal; eq = co->co_nlocals == cp->co_nlocals; @@ -720,7 +735,7 @@ code_hash(PyCodeObject *co) h6 = PyObject_Hash(co->co_cellvars); if (h6 == -1) return -1; h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ - co->co_argcount ^ co->co_kwonlyargcount ^ + co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ co->co_nlocals ^ co->co_flags; if (h == -1) h = -2; return h; |