Skip to content

GH-120507: Lower the BEFORE_WITH and BEFORE_ASYNC_WITH instructions. #120640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 18, 2024
Merged
Prev Previous commit
Next Next commit
Don't store special method names in co_consts and fix error messages
  • Loading branch information
markshannon committed Jun 17, 2024
commit 69db48b6f684968dcebc2af1a76625973a9625ab
7 changes: 7 additions & 0 deletions Include/ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
#define FVS_MASK 0x4
#define FVS_HAVE_SPEC 0x4

/* Special methods used by LOAD_SPECIAL */
#define SPECIAL___ENTER__ 0
#define SPECIAL___EXIT__ 1
#define SPECIAL___AENTER__ 2
#define SPECIAL___AEXIT__ 3
#define SPECIAL_MAX 3

#ifndef Py_LIMITED_API
# define Py_CPYTHON_CEVAL_H
# include "cpython/ceval.h"
Expand Down
7 changes: 7 additions & 0 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,13 @@ typedef PyObject *(*conversion_func)(PyObject *);
PyAPI_DATA(const binaryfunc) _PyEval_BinaryOps[];
PyAPI_DATA(const conversion_func) _PyEval_ConversionFuncs[];

typedef struct _special_method {
PyObject *name;
const char *error;
} _Py_SpecialMethod;

PyAPI_DATA(const _Py_SpecialMethod) _Py_SpecialMethods[];

PyAPI_FUNC(int) _PyEval_CheckExceptStarTypeValid(PyThreadState *tstate, PyObject* right);
PyAPI_FUNC(int) _PyEval_CheckExceptTypeValid(PyThreadState *tstate, PyObject* right);
PyAPI_FUNC(int) _PyEval_ExceptionGroupMatch(PyObject* exc_value, PyObject *match_type, PyObject **match, PyObject **rest);
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Include/internal/pycore_uop_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2818,15 +2818,14 @@ dummy_func(
_PUSH_FRAME;

inst(LOAD_SPECIAL, (owner -- attr, self_or_null)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
assert(oparg <= SPECIAL_MAX);
PyObject *name = _Py_SpecialMethods[oparg].name;
attr = _PyObject_LookupSpecialMethod(owner, name, &self_or_null);
if (attr == NULL) {
if (!_PyErr_Occurred(tstate)) {
_PyErr_Format(tstate, PyExc_TypeError,
"'%.200s' object does not support the "
"context manager protocol "
"(missed %U method)",
Py_TYPE(owner)->tp_name, name);
_Py_SpecialMethods[oparg].error,
Py_TYPE(owner)->tp_name);
}
}
ERROR_IF(attr == NULL, error);
Expand Down
23 changes: 23 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,29 @@ const conversion_func _PyEval_ConversionFuncs[4] = {
[FVC_ASCII] = PyObject_ASCII
};

const _Py_SpecialMethod _Py_SpecialMethods[] = {
[SPECIAL___ENTER__] = {
.name = &_Py_ID(__enter__),
.error = "'%.200s' object does not support the "
"context manager protocol (missed __enter__ method)",
},
[SPECIAL___EXIT__] = {
.name = &_Py_ID(__exit__),
.error = "'%.200s' object does not support the "
"context manager protocol (missed __exit__ method)",
},
[SPECIAL___AENTER__] = {
.name = &_Py_ID(__aenter__),
.error = "'%.200s' object does not support the asynchronous "
"context manager protocol (missed __aenter__ method)",
},
[SPECIAL___AEXIT__] = {
.name = &_Py_ID(__aexit__),
.error = "'%.200s' object does not support the asynchronous "
"context manager protocol (missed __aexit__ method)",
}
};


// PEP 634: Structural Pattern Matching

Expand Down
8 changes: 4 additions & 4 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5955,10 +5955,10 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
VISIT(c, expr, item->context_expr);
loc = LOC(item->context_expr);
ADDOP_I(c, loc, COPY, 1);
ADDOP_NAME(c, loc, LOAD_SPECIAL, &_Py_ID(__aexit__), names);
ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__);
ADDOP_I(c, loc, SWAP, 2);
ADDOP_I(c, loc, SWAP, 3);
ADDOP_NAME(c, loc, LOAD_SPECIAL, &_Py_ID(__aenter__), names);
ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
ADDOP_I(c, loc, CALL, 0);
ADDOP_I(c, loc, GET_AWAITABLE, 1);
ADDOP_LOAD_CONST(c, loc, Py_None);
Expand Down Expand Up @@ -6058,10 +6058,10 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
/* Will push bound __exit__ */
location loc = LOC(item->context_expr);
ADDOP_I(c, loc, COPY, 1);
ADDOP_NAME(c, loc, LOAD_SPECIAL, &_Py_ID(__exit__), names);
ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
ADDOP_I(c, loc, SWAP, 2);
ADDOP_I(c, loc, SWAP, 3);
ADDOP_NAME(c, loc, LOAD_SPECIAL, &_Py_ID(__enter__), names);
ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
ADDOP_I(c, loc, CALL, 0);
ADDOP_JUMP(c, loc, SETUP_WITH, final);

Expand Down
9 changes: 4 additions & 5 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy