Skip to content

Commit e8e1459

Browse files
committed
rather than passing locals to the class body, just execute the class body in the proper environment
1 parent e914123 commit e8e1459

File tree

10 files changed

+3134
-3166
lines changed

10 files changed

+3134
-3166
lines changed

Doc/library/dis.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,6 @@ the stack so that it is available for further iterations of the loop.
596596
.. XXX explain the WHY stuff!
597597
598598
599-
.. opcode:: STORE_LOCALS
600-
601-
Pops TOS from the stack and stores it as the current frame's ``f_locals``.
602-
This is used in class construction.
603-
604-
605599
All of the following opcodes expect arguments. An argument is two bytes, with
606600
the more significant byte last.
607601

Include/opcode.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ extern "C" {
4949
#define BINARY_OR 66
5050
#define INPLACE_POWER 67
5151
#define GET_ITER 68
52-
#define STORE_LOCALS 69
5352
#define PRINT_EXPR 70
5453
#define LOAD_BUILD_CLASS 71
5554
#define YIELD_FROM 72

Lib/importlib/_bootstrap.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,13 @@ def _call_with_frames_removed(f, *args, **kwds):
391391
# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override
392392
# free vars)
393393
# Python 3.4a1 3270 (various tweaks to the __class_ closure)
394+
# Python 3.4a1 3280 (remove implicit class argument)
394395
#
395396
# MAGIC must change whenever the bytecode emitted by the compiler may no
396397
# longer be understood by older implementations of the eval loop (usually
397398
# due to the addition of new opcodes).
398399

399-
_MAGIC_BYTES = (3270).to_bytes(2, 'little') + b'\r\n'
400+
_MAGIC_BYTES = (3280).to_bytes(2, 'little') + b'\r\n'
400401
_RAW_MAGIC_NUMBER = int.from_bytes(_MAGIC_BYTES, 'little')
401402

402403
_PYCACHE = '__pycache__'

Lib/opcode.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ def jabs_op(name, op):
8484
def_op('BINARY_OR', 66)
8585
def_op('INPLACE_POWER', 67)
8686
def_op('GET_ITER', 68)
87-
def_op('STORE_LOCALS', 69)
8887

8988
def_op('PRINT_EXPR', 70)
9089
def_op('LOAD_BUILD_CLASS', 71)

Python/bltinmodule.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
5757
return NULL;
5858
}
5959
func = PyTuple_GET_ITEM(args, 0); /* Better be callable */
60+
if (!PyFunction_Check(func)) {
61+
PyErr_SetString(PyExc_TypeError,
62+
"__build__class__: func must be a function");
63+
return NULL;
64+
}
6065
name = PyTuple_GET_ITEM(args, 1);
6166
if (!PyUnicode_Check(name)) {
6267
PyErr_SetString(PyExc_TypeError,
@@ -155,7 +160,9 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
155160
Py_DECREF(bases);
156161
return NULL;
157162
}
158-
cell = PyObject_CallFunctionObjArgs(func, ns, NULL);
163+
cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
164+
NULL, 0, NULL, 0, NULL, 0, NULL,
165+
PyFunction_GET_CLOSURE(func));
159166
if (cell != NULL) {
160167
PyObject *margs;
161168
margs = PyTuple_Pack(3, name, bases, ns);

Python/ceval.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,14 +1873,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
18731873
goto error;
18741874
}
18751875

1876-
TARGET(STORE_LOCALS) {
1877-
PyObject *locals = POP();
1878-
PyObject *old = f->f_locals;
1879-
Py_XDECREF(old);
1880-
f->f_locals = locals;
1881-
DISPATCH();
1882-
}
1883-
18841876
TARGET(RETURN_VALUE) {
18851877
retval = POP();
18861878
why = WHY_RETURN;

Python/compile.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -893,8 +893,6 @@ opcode_stack_effect(int opcode, int oparg)
893893
return 7;
894894
case WITH_CLEANUP:
895895
return -1; /* XXX Sometimes more */
896-
case STORE_LOCALS:
897-
return -1;
898896
case RETURN_VALUE:
899897
return -1;
900898
case IMPORT_STAR:
@@ -1696,12 +1694,6 @@ compiler_class(struct compiler *c, stmt_ty s)
16961694
Py_INCREF(s->v.ClassDef.name);
16971695
Py_XDECREF(c->u->u_private);
16981696
c->u->u_private = s->v.ClassDef.name;
1699-
/* force it to have one mandatory argument */
1700-
c->u->u_argcount = 1;
1701-
/* load the first argument (__locals__) ... */
1702-
ADDOP_I(c, LOAD_FAST, 0);
1703-
/* ... and store it into f_locals */
1704-
ADDOP_IN_SCOPE(c, STORE_LOCALS);
17051697
/* load (global) __name__ ... */
17061698
str = PyUnicode_InternFromString("__name__");
17071699
if (!str || !compiler_nameop(c, str, Load)) {
@@ -4110,9 +4102,8 @@ compute_code_flags(struct compiler *c)
41104102
{
41114103
PySTEntryObject *ste = c->u->u_ste;
41124104
int flags = 0, n;
4113-
if (ste->ste_type != ModuleBlock)
4114-
flags |= CO_NEWLOCALS;
41154105
if (ste->ste_type == FunctionBlock) {
4106+
flags |= CO_NEWLOCALS;
41164107
if (!ste->ste_unoptimized)
41174108
flags |= CO_OPTIMIZED;
41184109
if (ste->ste_nested)

0 commit comments

Comments
 (0)