rather than passing locals to the class body, just execute the class body in the proper environment
This commit is contained in:
parent
e914123d1f
commit
e8e14591eb
|
@ -596,12 +596,6 @@ the stack so that it is available for further iterations of the loop.
|
|||
.. XXX explain the WHY stuff!
|
||||
|
||||
|
||||
.. opcode:: STORE_LOCALS
|
||||
|
||||
Pops TOS from the stack and stores it as the current frame's ``f_locals``.
|
||||
This is used in class construction.
|
||||
|
||||
|
||||
All of the following opcodes expect arguments. An argument is two bytes, with
|
||||
the more significant byte last.
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ extern "C" {
|
|||
#define BINARY_OR 66
|
||||
#define INPLACE_POWER 67
|
||||
#define GET_ITER 68
|
||||
#define STORE_LOCALS 69
|
||||
#define PRINT_EXPR 70
|
||||
#define LOAD_BUILD_CLASS 71
|
||||
#define YIELD_FROM 72
|
||||
|
|
|
@ -391,12 +391,13 @@ def _call_with_frames_removed(f, *args, **kwds):
|
|||
# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override
|
||||
# free vars)
|
||||
# Python 3.4a1 3270 (various tweaks to the __class_ closure)
|
||||
# Python 3.4a1 3280 (remove implicit class argument)
|
||||
#
|
||||
# MAGIC must change whenever the bytecode emitted by the compiler may no
|
||||
# longer be understood by older implementations of the eval loop (usually
|
||||
# due to the addition of new opcodes).
|
||||
|
||||
_MAGIC_BYTES = (3270).to_bytes(2, 'little') + b'\r\n'
|
||||
_MAGIC_BYTES = (3280).to_bytes(2, 'little') + b'\r\n'
|
||||
_RAW_MAGIC_NUMBER = int.from_bytes(_MAGIC_BYTES, 'little')
|
||||
|
||||
_PYCACHE = '__pycache__'
|
||||
|
|
|
@ -84,7 +84,6 @@ def_op('BINARY_XOR', 65)
|
|||
def_op('BINARY_OR', 66)
|
||||
def_op('INPLACE_POWER', 67)
|
||||
def_op('GET_ITER', 68)
|
||||
def_op('STORE_LOCALS', 69)
|
||||
|
||||
def_op('PRINT_EXPR', 70)
|
||||
def_op('LOAD_BUILD_CLASS', 71)
|
||||
|
|
|
@ -57,6 +57,11 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
}
|
||||
func = PyTuple_GET_ITEM(args, 0); /* Better be callable */
|
||||
if (!PyFunction_Check(func)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"__build__class__: func must be a function");
|
||||
return NULL;
|
||||
}
|
||||
name = PyTuple_GET_ITEM(args, 1);
|
||||
if (!PyUnicode_Check(name)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
|
@ -155,7 +160,9 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
Py_DECREF(bases);
|
||||
return NULL;
|
||||
}
|
||||
cell = PyObject_CallFunctionObjArgs(func, ns, NULL);
|
||||
cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
|
||||
NULL, 0, NULL, 0, NULL, 0, NULL,
|
||||
PyFunction_GET_CLOSURE(func));
|
||||
if (cell != NULL) {
|
||||
PyObject *margs;
|
||||
margs = PyTuple_Pack(3, name, bases, ns);
|
||||
|
|
|
@ -1873,14 +1873,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
goto error;
|
||||
}
|
||||
|
||||
TARGET(STORE_LOCALS) {
|
||||
PyObject *locals = POP();
|
||||
PyObject *old = f->f_locals;
|
||||
Py_XDECREF(old);
|
||||
f->f_locals = locals;
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(RETURN_VALUE) {
|
||||
retval = POP();
|
||||
why = WHY_RETURN;
|
||||
|
|
|
@ -893,8 +893,6 @@ opcode_stack_effect(int opcode, int oparg)
|
|||
return 7;
|
||||
case WITH_CLEANUP:
|
||||
return -1; /* XXX Sometimes more */
|
||||
case STORE_LOCALS:
|
||||
return -1;
|
||||
case RETURN_VALUE:
|
||||
return -1;
|
||||
case IMPORT_STAR:
|
||||
|
@ -1696,12 +1694,6 @@ compiler_class(struct compiler *c, stmt_ty s)
|
|||
Py_INCREF(s->v.ClassDef.name);
|
||||
Py_XDECREF(c->u->u_private);
|
||||
c->u->u_private = s->v.ClassDef.name;
|
||||
/* force it to have one mandatory argument */
|
||||
c->u->u_argcount = 1;
|
||||
/* load the first argument (__locals__) ... */
|
||||
ADDOP_I(c, LOAD_FAST, 0);
|
||||
/* ... and store it into f_locals */
|
||||
ADDOP_IN_SCOPE(c, STORE_LOCALS);
|
||||
/* load (global) __name__ ... */
|
||||
str = PyUnicode_InternFromString("__name__");
|
||||
if (!str || !compiler_nameop(c, str, Load)) {
|
||||
|
@ -4110,9 +4102,8 @@ compute_code_flags(struct compiler *c)
|
|||
{
|
||||
PySTEntryObject *ste = c->u->u_ste;
|
||||
int flags = 0, n;
|
||||
if (ste->ste_type != ModuleBlock)
|
||||
flags |= CO_NEWLOCALS;
|
||||
if (ste->ste_type == FunctionBlock) {
|
||||
flags |= CO_NEWLOCALS;
|
||||
if (!ste->ste_unoptimized)
|
||||
flags |= CO_OPTIMIZED;
|
||||
if (ste->ste_nested)
|
||||
|
|
6270
Python/importlib.h
6270
Python/importlib.h
File diff suppressed because it is too large
Load Diff
|
@ -68,7 +68,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_BINARY_OR,
|
||||
&&TARGET_INPLACE_POWER,
|
||||
&&TARGET_GET_ITER,
|
||||
&&TARGET_STORE_LOCALS,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_PRINT_EXPR,
|
||||
&&TARGET_LOAD_BUILD_CLASS,
|
||||
&&TARGET_YIELD_FROM,
|
||||
|
|
|
@ -192,7 +192,7 @@ static int symtable_visit_withitem(struct symtable *st, withitem_ty item);
|
|||
|
||||
static identifier top = NULL, lambda = NULL, genexpr = NULL,
|
||||
listcomp = NULL, setcomp = NULL, dictcomp = NULL,
|
||||
__class__ = NULL, __locals__ = NULL;
|
||||
__class__ = NULL;
|
||||
|
||||
#define GET_IDENTIFIER(VAR) \
|
||||
((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
|
||||
|
@ -1185,11 +1185,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
|
|||
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
|
||||
(void *)s, s->lineno, s->col_offset))
|
||||
VISIT_QUIT(st, 0);
|
||||
if (!GET_IDENTIFIER(__locals__) ||
|
||||
!symtable_add_def(st, __locals__, DEF_PARAM)) {
|
||||
symtable_exit_block(st, s);
|
||||
VISIT_QUIT(st, 0);
|
||||
}
|
||||
tmp = st->st_private;
|
||||
st->st_private = s->v.ClassDef.name;
|
||||
VISIT_SEQ(st, stmt, s->v.ClassDef.body);
|
||||
|
|
Loading…
Reference in New Issue