summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2019-04-29 12:36:57 (GMT)
committerGitHub <noreply@github.com>2019-04-29 12:36:57 (GMT)
commit8c77b8cb9188165a123f2512026e3629bf03dc9b (patch)
tree863ea19f5f2c8ec179c32b3d06dc8366859ae26e /Objects
parent99fcc616d400cd31af0733c3f8cc93bcc1d32a44 (diff)
downloadcpython-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.c8
-rw-r--r--Objects/codeobject.c73
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;