summaryrefslogtreecommitdiff
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-05-24 23:57:23 +0200
committerGitHub <noreply@github.com>2019-05-24 23:57:23 +0200
commita9f05d69ccbf3c75cdd604c25094282697789a62 (patch)
treeb26677a8437f12e011b3adb574f32aa0bbff8739 /Objects/codeobject.c
parent561612d8456cfab5672c9b445521113b847bd6b3 (diff)
downloadcpython-git-a9f05d69ccbf3c75cdd604c25094282697789a62.tar.gz
bpo-37032: Add CodeType.replace() method (GH-13542)
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c79
1 files changed, 75 insertions, 4 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index f4e48a9757..1e76f26d98 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -5,6 +5,7 @@
#include "structmember.h"
#include "pycore_pystate.h"
#include "pycore_tupleobject.h"
+#include "clinic/codeobject.c.h"
/* Holder for co_extra information */
typedef struct {
@@ -12,6 +13,11 @@ typedef struct {
void *ce_extras[1];
} _PyCodeObjectExtra;
+/*[clinic input]
+class code "PyCodeObject *" "&PyCode_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/
+
/* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */
static int
all_name_chars(PyObject *o)
@@ -109,7 +115,8 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount,
/* Check argument types */
if (argcount < 0 || posonlyargcount < 0 || kwonlyargcount < 0 ||
- nlocals < 0 || code == NULL || !PyBytes_Check(code) ||
+ nlocals < 0 || stacksize < 0 || flags < 0 ||
+ code == NULL || !PyBytes_Check(code) ||
consts == NULL || !PyTuple_Check(consts) ||
names == NULL || !PyTuple_Check(names) ||
varnames == NULL || !PyTuple_Check(varnames) ||
@@ -122,9 +129,13 @@ PyCode_New(int argcount, int posonlyargcount, int kwonlyargcount,
return NULL;
}
- /* Ensure that the filename is a ready Unicode string */
- if (PyUnicode_READY(filename) < 0)
+ /* Ensure that strings are ready Unicode string */
+ if (PyUnicode_READY(name) < 0) {
+ return NULL;
+ }
+ if (PyUnicode_READY(filename) < 0) {
return NULL;
+ }
intern_strings(names);
intern_strings(varnames);
@@ -482,7 +493,7 @@ code_dealloc(PyCodeObject *co)
}
static PyObject *
-code_sizeof(PyCodeObject *co, void *unused)
+code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
{
Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co));
_PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
@@ -497,6 +508,65 @@ code_sizeof(PyCodeObject *co, void *unused)
return PyLong_FromSsize_t(res);
}
+/*[clinic input]
+code.replace
+
+ *
+ co_argcount: int(c_default="self->co_argcount") = -1
+ co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
+ co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
+ co_nlocals: int(c_default="self->co_nlocals") = -1
+ co_stacksize: int(c_default="self->co_stacksize") = -1
+ co_flags: int(c_default="self->co_flags") = -1
+ co_firstlineno: int(c_default="self->co_firstlineno") = -1
+ co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None
+ co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
+ co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None
+ co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None
+ co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None
+ co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None
+ co_filename: unicode(c_default="self->co_filename") = None
+ co_name: unicode(c_default="self->co_name") = None
+ co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None
+
+Return a new code object with new specified fields.
+[clinic start generated code]*/
+
+static PyObject *
+code_replace_impl(PyCodeObject *self, int co_argcount,
+ int co_posonlyargcount, int co_kwonlyargcount,
+ int co_nlocals, int co_stacksize, int co_flags,
+ int co_firstlineno, PyBytesObject *co_code,
+ PyObject *co_consts, PyObject *co_names,
+ PyObject *co_varnames, PyObject *co_freevars,
+ PyObject *co_cellvars, PyObject *co_filename,
+ PyObject *co_name, PyBytesObject *co_lnotab)
+/*[clinic end generated code: output=25c8e303913bcace input=77189e46579ec426]*/
+{
+#define CHECK_INT_ARG(ARG) \
+ if (ARG < 0) { \
+ PyErr_SetString(PyExc_ValueError, \
+ #ARG " must be a positive integer"); \
+ return NULL; \
+ }
+
+ CHECK_INT_ARG(co_argcount);
+ CHECK_INT_ARG(co_posonlyargcount);
+ CHECK_INT_ARG(co_kwonlyargcount);
+ CHECK_INT_ARG(co_nlocals);
+ CHECK_INT_ARG(co_stacksize);
+ CHECK_INT_ARG(co_flags);
+ CHECK_INT_ARG(co_firstlineno);
+
+#undef CHECK_INT_ARG
+
+ return (PyObject *)PyCode_New(
+ co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
+ co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
+ co_varnames, co_freevars, co_cellvars, co_filename, co_name,
+ co_firstlineno, (PyObject*)co_lnotab);
+}
+
static PyObject *
code_repr(PyCodeObject *co)
{
@@ -751,6 +821,7 @@ code_hash(PyCodeObject *co)
static struct PyMethodDef code_methods[] = {
{"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
+ CODE_REPLACE_METHODDEF
{NULL, NULL} /* sentinel */
};