|
19 | 19 | #include "pycore_pystate.h" // _PyThreadState_GET() |
20 | 20 | #include "pycore_runtime.h" // _Py_ID() |
21 | 21 | #include "pycore_setobject.h" // _PySet_NextEntry() |
| 22 | +#include "pycore_symtable.h" // _Py_Mangle() |
22 | 23 | #include "pycore_sysmodule.h" // _PySys_GetSizeOf() |
23 | 24 | #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString() |
24 | 25 |
|
@@ -1928,6 +1929,37 @@ get_dotted_path(PyObject *name) |
1928 | 1929 | return PyUnicode_Split(name, _Py_LATIN1_CHR('.'), -1); |
1929 | 1930 | } |
1930 | 1931 |
|
| 1932 | +static PyObject * |
| 1933 | +join_dotted_path(PyObject *dotted_path) |
| 1934 | +{ |
| 1935 | + return PyUnicode_Join(_Py_LATIN1_CHR('.'), dotted_path); |
| 1936 | +} |
| 1937 | + |
| 1938 | +/* Returns -1 (with an exception set) on error, 0 if there were no changes, |
| 1939 | + * 1 if some names were mangled. */ |
| 1940 | +static int |
| 1941 | +mangle_dotted_path(PyObject *dotted_path) |
| 1942 | +{ |
| 1943 | + int rc = 0; |
| 1944 | + Py_ssize_t n = PyList_GET_SIZE(dotted_path); |
| 1945 | + for (Py_ssize_t i = n-1; i > 0; i--) { |
| 1946 | + PyObject *subpath = PyList_GET_ITEM(dotted_path, i); |
| 1947 | + if (_Py_IsPrivateName(subpath)) { |
| 1948 | + PyObject *parent = PyList_GET_ITEM(dotted_path, i-1); |
| 1949 | + PyObject *mangled = _Py_Mangle(parent, subpath); |
| 1950 | + if (mangled == NULL) { |
| 1951 | + return -1; |
| 1952 | + } |
| 1953 | + if (mangled != subpath) { |
| 1954 | + rc = 1; |
| 1955 | + } |
| 1956 | + PyList_SET_ITEM(dotted_path, i, mangled); |
| 1957 | + Py_DECREF(subpath); |
| 1958 | + } |
| 1959 | + } |
| 1960 | + return rc; |
| 1961 | +} |
| 1962 | + |
1931 | 1963 | static int |
1932 | 1964 | check_dotted_path(PickleState *st, PyObject *obj, PyObject *dotted_path) |
1933 | 1965 | { |
@@ -3809,6 +3841,15 @@ save_global(PickleState *st, PicklerObject *self, PyObject *obj, |
3809 | 3841 | dotted_path = get_dotted_path(global_name); |
3810 | 3842 | if (dotted_path == NULL) |
3811 | 3843 | goto error; |
| 3844 | + switch (mangle_dotted_path(dotted_path)) { |
| 3845 | + case -1: |
| 3846 | + goto error; |
| 3847 | + case 1: |
| 3848 | + Py_SETREF(global_name, join_dotted_path(dotted_path)); |
| 3849 | + if (global_name == NULL) { |
| 3850 | + goto error; |
| 3851 | + } |
| 3852 | + } |
3812 | 3853 | module_name = whichmodule(st, obj, global_name, dotted_path); |
3813 | 3854 | if (module_name == NULL) |
3814 | 3855 | goto error; |
|
0 commit comments