Skip to content

Commit 5224098

Browse files
committed
Support dots in the function name
Add presite_resolve_name()
1 parent f724aec commit 5224098

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

Python/pylifecycle.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,54 @@ pyinit_main_reconfigure(PyThreadState *tstate)
12181218

12191219

12201220
#ifdef Py_DEBUG
1221+
// Equivalent to the Python code:
1222+
//
1223+
// for part in attr.split('.'):
1224+
// obj = getattr(obj, part)
1225+
static PyObject*
1226+
presite_resolve_name(PyObject *obj, PyObject *attr)
1227+
{
1228+
obj = Py_NewRef(obj);
1229+
attr = Py_NewRef(attr);
1230+
PyObject *res;
1231+
1232+
while (1) {
1233+
Py_ssize_t len = PyUnicode_GET_LENGTH(attr);
1234+
Py_ssize_t pos = PyUnicode_FindChar(attr, '.', 0, len, 1);
1235+
if (pos < 0) {
1236+
break;
1237+
}
1238+
1239+
PyObject *name = PyUnicode_Substring(attr, 0, pos);
1240+
if (name == NULL) {
1241+
goto error;
1242+
}
1243+
res = PyObject_GetAttr(obj, name);
1244+
Py_DECREF(name);
1245+
if (res == NULL) {
1246+
goto error;
1247+
}
1248+
Py_SETREF(obj, res);
1249+
1250+
PyObject *suffix = PyUnicode_Substring(attr, pos + 1, len);
1251+
if (suffix == NULL) {
1252+
goto error;
1253+
}
1254+
Py_SETREF(attr, suffix);
1255+
}
1256+
1257+
res = PyObject_GetAttr(obj, attr);
1258+
Py_DECREF(obj);
1259+
Py_DECREF(attr);
1260+
return res;
1261+
1262+
error:
1263+
Py_XDECREF(obj);
1264+
Py_DECREF(attr);
1265+
return NULL;
1266+
}
1267+
1268+
12211269
static void
12221270
run_presite(PyThreadState *tstate)
12231271
{
@@ -1256,13 +1304,14 @@ run_presite(PyThreadState *tstate)
12561304
mod_name = Py_NewRef(presite);
12571305
}
12581306

1307+
// mod_name can contain dots (ex: "math.integer")
12591308
module = PyImport_Import(mod_name);
12601309
if (module == NULL) {
12611310
goto error;
12621311
}
12631312

12641313
if (func_name != NULL) {
1265-
PyObject *func = PyObject_GetAttr(module, func_name);
1314+
PyObject *func = presite_resolve_name(module, func_name);
12661315
if (func == NULL) {
12671316
goto error;
12681317
}

0 commit comments

Comments
 (0)