Skip to content

Commit 71db5db

Browse files
authored
gh-102371: move _Py_Mangle from compile.c to symtable.c (#102372)
1 parent 7325000 commit 71db5db

File tree

5 files changed

+76
-76
lines changed

5 files changed

+76
-76
lines changed

Include/internal/pycore_compile.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
1919
int optimize,
2020
struct _arena *arena);
2121

22-
int _PyFuture_FromAST(
23-
struct _mod * mod,
24-
PyObject *filename,
25-
PyFutureFeatures* futures);
26-
27-
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
2822

2923
typedef struct {
3024
int optimize;

Include/internal/pycore_symtable.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
9090

9191
extern void _PySymtable_Free(struct symtable *);
9292

93+
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
94+
9395
/* Flags for def-use information */
9496

9597
#define DEF_GLOBAL 1 /* global stmt */
@@ -128,6 +130,11 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
128130
int start,
129131
PyCompilerFlags *flags);
130132

133+
int _PyFuture_FromAST(
134+
struct _mod * mod,
135+
PyObject *filename,
136+
PyFutureFeatures* futures);
137+
131138
#ifdef __cplusplus
132139
}
133140
#endif

Objects/typeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "Python.h"
44
#include "pycore_call.h"
55
#include "pycore_code.h" // CO_FAST_FREE
6-
#include "pycore_compile.h" // _Py_Mangle()
6+
#include "pycore_symtable.h" // _Py_Mangle()
77
#include "pycore_dict.h" // _PyDict_KeysSize()
88
#include "pycore_initconfig.h" // _PyStatus_OK()
99
#include "pycore_moduleobject.h" // _PyModule_GetDef()

Python/compile.c

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929
#include "Python.h"
3030
#include "pycore_ast.h" // _PyAST_GetDocString()
3131
#include "pycore_code.h" // _PyCode_New()
32-
#include "pycore_compile.h" // _PyFuture_FromAST()
32+
#include "pycore_compile.h"
3333
#include "pycore_intrinsics.h"
3434
#include "pycore_long.h" // _PyLong_GetZero()
3535
#include "pycore_opcode.h" // _PyOpcode_Caches
3636
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
37-
#include "pycore_symtable.h" // PySTEntryObject
37+
#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST()
3838

3939
#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
4040

@@ -569,72 +569,6 @@ static PyCodeObject *assemble(struct compiler *, int addNone);
569569

570570
#define CAPSULE_NAME "compile.c compiler unit"
571571

572-
PyObject *
573-
_Py_Mangle(PyObject *privateobj, PyObject *ident)
574-
{
575-
/* Name mangling: __private becomes _classname__private.
576-
This is independent from how the name is used. */
577-
PyObject *result;
578-
size_t nlen, plen, ipriv;
579-
Py_UCS4 maxchar;
580-
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
581-
PyUnicode_READ_CHAR(ident, 0) != '_' ||
582-
PyUnicode_READ_CHAR(ident, 1) != '_') {
583-
return Py_NewRef(ident);
584-
}
585-
nlen = PyUnicode_GET_LENGTH(ident);
586-
plen = PyUnicode_GET_LENGTH(privateobj);
587-
/* Don't mangle __id__ or names with dots.
588-
589-
The only time a name with a dot can occur is when
590-
we are compiling an import statement that has a
591-
package name.
592-
593-
TODO(jhylton): Decide whether we want to support
594-
mangling of the module name, e.g. __M.X.
595-
*/
596-
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
597-
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
598-
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
599-
return Py_NewRef(ident); /* Don't mangle __whatever__ */
600-
}
601-
/* Strip leading underscores from class name */
602-
ipriv = 0;
603-
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
604-
ipriv++;
605-
if (ipriv == plen) {
606-
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
607-
}
608-
plen -= ipriv;
609-
610-
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
611-
PyErr_SetString(PyExc_OverflowError,
612-
"private identifier too large to be mangled");
613-
return NULL;
614-
}
615-
616-
maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
617-
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar)
618-
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
619-
620-
result = PyUnicode_New(1 + nlen + plen, maxchar);
621-
if (!result) {
622-
return NULL;
623-
}
624-
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
625-
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
626-
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
627-
Py_DECREF(result);
628-
return NULL;
629-
}
630-
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
631-
Py_DECREF(result);
632-
return NULL;
633-
}
634-
assert(_PyUnicode_CheckConsistency(result, 1));
635-
return result;
636-
}
637-
638572

639573
static int
640574
compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,

Python/symtable.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "Python.h"
22
#include "pycore_ast.h" // identifier, stmt_ty
3-
#include "pycore_compile.h" // _Py_Mangle(), _PyFuture_FromAST()
43
#include "pycore_parser.h" // _PyParser_ASTFromString()
54
#include "pycore_pystate.h" // _PyThreadState_GET()
65
#include "pycore_symtable.h" // PySTEntryObject
@@ -2152,3 +2151,69 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
21522151
_PyArena_Free(arena);
21532152
return st;
21542153
}
2154+
2155+
PyObject *
2156+
_Py_Mangle(PyObject *privateobj, PyObject *ident)
2157+
{
2158+
/* Name mangling: __private becomes _classname__private.
2159+
This is independent from how the name is used. */
2160+
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
2161+
PyUnicode_READ_CHAR(ident, 0) != '_' ||
2162+
PyUnicode_READ_CHAR(ident, 1) != '_') {
2163+
return Py_NewRef(ident);
2164+
}
2165+
size_t nlen = PyUnicode_GET_LENGTH(ident);
2166+
size_t plen = PyUnicode_GET_LENGTH(privateobj);
2167+
/* Don't mangle __id__ or names with dots.
2168+
2169+
The only time a name with a dot can occur is when
2170+
we are compiling an import statement that has a
2171+
package name.
2172+
2173+
TODO(jhylton): Decide whether we want to support
2174+
mangling of the module name, e.g. __M.X.
2175+
*/
2176+
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
2177+
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
2178+
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
2179+
return Py_NewRef(ident); /* Don't mangle __whatever__ */
2180+
}
2181+
/* Strip leading underscores from class name */
2182+
size_t ipriv = 0;
2183+
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') {
2184+
ipriv++;
2185+
}
2186+
if (ipriv == plen) {
2187+
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
2188+
}
2189+
plen -= ipriv;
2190+
2191+
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
2192+
PyErr_SetString(PyExc_OverflowError,
2193+
"private identifier too large to be mangled");
2194+
return NULL;
2195+
}
2196+
2197+
Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
2198+
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) {
2199+
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
2200+
}
2201+
2202+
PyObject *result = PyUnicode_New(1 + nlen + plen, maxchar);
2203+
if (!result) {
2204+
return NULL;
2205+
}
2206+
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
2207+
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
2208+
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
2209+
Py_DECREF(result);
2210+
return NULL;
2211+
}
2212+
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
2213+
Py_DECREF(result);
2214+
return NULL;
2215+
}
2216+
assert(_PyUnicode_CheckConsistency(result, 1));
2217+
return result;
2218+
}
2219+

0 commit comments

Comments
 (0)