bpo-28411: Support other mappings in PyInterpreterState.modules. (#3593) · python/cpython@3f9eee6 (original) (raw)

`@@ -1649,13 +1649,40 @@ getattribute(PyObject *obj, PyObject *name, int allow_qualname)

`

1649

1649

`return attr;

`

1650

1650

`}

`

1651

1651

``

``

1652

`+

static int

`

``

1653

`+

_checkmodule(PyObject *module_name, PyObject *module,

`

``

1654

`+

PyObject *global, PyObject *dotted_path)

`

``

1655

`+

{

`

``

1656

`+

if (module == Py_None) {

`

``

1657

`+

return -1;

`

``

1658

`+

}

`

``

1659

`+

if (PyUnicode_Check(module_name) &&

`

``

1660

`+

_PyUnicode_EqualToASCIIString(module_name, "main")) {

`

``

1661

`+

return -1;

`

``

1662

`+

}

`

``

1663

+

``

1664

`+

PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);

`

``

1665

`+

if (candidate == NULL) {

`

``

1666

`+

if (PyErr_ExceptionMatches(PyExc_AttributeError)) {

`

``

1667

`+

PyErr_Clear();

`

``

1668

`+

}

`

``

1669

`+

return -1;

`

``

1670

`+

}

`

``

1671

`+

if (candidate != global) {

`

``

1672

`+

Py_DECREF(candidate);

`

``

1673

`+

return -1;

`

``

1674

`+

}

`

``

1675

`+

Py_DECREF(candidate);

`

``

1676

`+

return 0;

`

``

1677

`+

}

`

``

1678

+

1652

1679

`static PyObject *

`

1653

1680

`whichmodule(PyObject *global, PyObject *dotted_path)

`

1654

1681

`{

`

1655

1682

`PyObject *module_name;

`

1656

``

`-

PyObject *modules_dict;

`

1657

``

`-

PyObject *module;

`

``

1683

`+

PyObject *module = NULL;

`

1658

1684

`Py_ssize_t i;

`

``

1685

`+

PyObject *modules;

`

1659

1686

`_Py_IDENTIFIER(module);

`

1660

1687

`_Py_IDENTIFIER(modules);

`

1661

1688

`_Py_IDENTIFIER(main);

`

`@@ -1678,35 +1705,48 @@ whichmodule(PyObject *global, PyObject *dotted_path)

`

1678

1705

`assert(module_name == NULL);

`

1679

1706

``

1680

1707

`/* Fallback on walking sys.modules */

`

1681

``

`-

modules_dict = _PySys_GetObjectId(&PyId_modules);

`

1682

``

`-

if (modules_dict == NULL) {

`

``

1708

`+

modules = _PySys_GetObjectId(&PyId_modules);

`

``

1709

`+

if (modules == NULL) {

`

1683

1710

`PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");

`

1684

1711

`return NULL;

`

1685

1712

` }

`

1686

``

-

1687

``

`-

i = 0;

`

1688

``

`-

while (PyDict_Next(modules_dict, &i, &module_name, &module)) {

`

1689

``

`-

PyObject *candidate;

`

1690

``

`-

if (PyUnicode_Check(module_name) &&

`

1691

``

`-

_PyUnicode_EqualToASCIIString(module_name, "main"))

`

1692

``

`-

continue;

`

1693

``

`-

if (module == Py_None)

`

1694

``

`-

continue;

`

1695

``

-

1696

``

`-

candidate = get_deep_attribute(module, dotted_path, NULL);

`

1697

``

`-

if (candidate == NULL) {

`

1698

``

`-

if (!PyErr_ExceptionMatches(PyExc_AttributeError))

`

``

1713

`+

if (PyDict_CheckExact(modules)) {

`

``

1714

`+

i = 0;

`

``

1715

`+

while (PyDict_Next(modules, &i, &module_name, &module)) {

`

``

1716

`+

if (_checkmodule(module_name, module, global, dotted_path) == 0) {

`

``

1717

`+

Py_INCREF(module_name);

`

``

1718

`+

return module_name;

`

``

1719

`+

}

`

``

1720

`+

if (PyErr_Occurred()) {

`

1699

1721

`return NULL;

`

1700

``

`-

PyErr_Clear();

`

1701

``

`-

continue;

`

``

1722

`+

}

`

1702

1723

` }

`

1703

``

-

1704

``

`-

if (candidate == global) {

`

1705

``

`-

Py_INCREF(module_name);

`

1706

``

`-

Py_DECREF(candidate);

`

1707

``

`-

return module_name;

`

``

1724

`+

}

`

``

1725

`+

else {

`

``

1726

`+

PyObject *iterator = PyObject_GetIter(modules);

`

``

1727

`+

if (iterator == NULL) {

`

``

1728

`+

return NULL;

`

1708

1729

` }

`

1709

``

`-

Py_DECREF(candidate);

`

``

1730

`+

while ((module_name = PyIter_Next(iterator))) {

`

``

1731

`+

module = PyObject_GetItem(modules, module_name);

`

``

1732

`+

if (module == NULL) {

`

``

1733

`+

Py_DECREF(module_name);

`

``

1734

`+

Py_DECREF(iterator);

`

``

1735

`+

return NULL;

`

``

1736

`+

}

`

``

1737

`+

if (_checkmodule(module_name, module, global, dotted_path) == 0) {

`

``

1738

`+

Py_DECREF(module);

`

``

1739

`+

Py_DECREF(iterator);

`

``

1740

`+

return module_name;

`

``

1741

`+

}

`

``

1742

`+

Py_DECREF(module);

`

``

1743

`+

Py_DECREF(module_name);

`

``

1744

`+

if (PyErr_Occurred()) {

`

``

1745

`+

Py_DECREF(iterator);

`

``

1746

`+

return NULL;

`

``

1747

`+

}

`

``

1748

`+

}

`

``

1749

`+

Py_DECREF(iterator);

`

1710

1750

` }

`

1711

1751

``

1712

1752

`/* If no module is found, use main. */

`

`@@ -6424,9 +6464,7 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self,

`

6424

6464

`/[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]/

`

6425

6465

`{

`

6426

6466

`PyObject *global;

`

6427

``

`-

PyObject *modules_dict;

`

6428

6467

`PyObject *module;

`

6429

``

`-

_Py_IDENTIFIER(modules);

`

6430

6468

``

6431

6469

`/* Try to map the old names used in Python 2.x to the new ones used in

`

6432

6470

` Python 3.x. We do this only with old pickle protocols and when the

`

`@@ -6483,25 +6521,16 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self,

`

6483

6521

` }

`

6484

6522

` }

`

6485

6523

``

6486

``

`-

modules_dict = _PySys_GetObjectId(&PyId_modules);

`

6487

``

`-

if (modules_dict == NULL) {

`

6488

``

`-

PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");

`

6489

``

`-

return NULL;

`

6490

``

`-

}

`

6491

``

-

6492

``

`-

module = PyDict_GetItemWithError(modules_dict, module_name);

`

``

6524

`+

module = PyImport_GetModule(module_name);

`

6493

6525

`if (module == NULL) {

`

6494

6526

`if (PyErr_Occurred())

`

6495

6527

`return NULL;

`

6496

6528

`module = PyImport_Import(module_name);

`

6497

6529

`if (module == NULL)

`

6498

6530

`return NULL;

`

6499

``

`-

global = getattribute(module, global_name, self->proto >= 4);

`

6500

``

`-

Py_DECREF(module);

`

6501

``

`-

}

`

6502

``

`-

else {

`

6503

``

`-

global = getattribute(module, global_name, self->proto >= 4);

`

6504

6531

` }

`

``

6532

`+

global = getattribute(module, global_name, self->proto >= 4);

`

``

6533

`+

Py_DECREF(module);

`

6505

6534

`return global;

`

6506

6535

`}

`

6507

6536

``