Skip to content

Commit f386307

Browse files
committed
Added frozen_utils module
frozen_utils is a module that exposes the modules (& submodules, essentially all frozen python files) that were freezed with the Python interpreter, including ones that have not been imported.
1 parent 74ab746 commit f386307

File tree

5 files changed

+109
-0
lines changed

5 files changed

+109
-0
lines changed

Modules/Setup.stdlib.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
@MODULE__XXSUBINTERPRETERS_TRUE@_xxsubinterpreters _xxsubinterpretersmodule.c
4545
@MODULE__XXINTERPCHANNELS_TRUE@_xxinterpchannels _xxinterpchannelsmodule.c
4646
@MODULE__ZONEINFO_TRUE@_zoneinfo _zoneinfo.c
47+
@MODULE_FROZEN_UTILS_TRUE@frozen_utils frozen_utils.c
4748

4849
# needs libm
4950
@MODULE_AUDIOOP_TRUE@audioop audioop.c

Modules/frozen_utils.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "Python.h"
2+
#include "pycore_import.h"
3+
4+
#include <string.h>
5+
6+
PyDoc_STRVAR(frozen_utils__doc__,
7+
"Expose the modules that were frozen together with the Python interpreter");
8+
9+
static int
10+
frozen_utils_exec(PyObject *module)
11+
{
12+
return 0;
13+
}
14+
15+
PyDoc_STRVAR(frozen_utils_get_frozen_modules__doc__,
16+
"get_frozen_modules() -> List[str]\n\nReturn all of the Python modules & submodules that have \
17+
been frozen with the Python interpreter.");
18+
19+
int
20+
is_frozen_modules_end(const struct _frozen* current_frozen)
21+
{
22+
// The array end in a _frozen instance that is completely zeroed out.
23+
struct _frozen empty_frozen;
24+
memset(&empty_frozen, 0, sizeof(struct _frozen));
25+
26+
return current_frozen == NULL || memcmp(&empty_frozen, current_frozen, sizeof(struct _frozen)) == 0;
27+
}
28+
29+
void
30+
add_modules(PyObject *frozen_list, const struct _frozen* frozen_modules_start)
31+
{
32+
const struct _frozen *current_frozen = NULL;
33+
for (current_frozen = frozen_modules_start; !is_frozen_modules_end(current_frozen); current_frozen++)
34+
{
35+
PyObject *name_str = PyUnicode_FromString(current_frozen->name);
36+
PyList_Append(frozen_list, name_str);
37+
}
38+
}
39+
40+
static PyObject *
41+
get_frozen_modules(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
42+
{
43+
PyObject *frozen_modules_list = PyList_New(0);
44+
45+
add_modules(frozen_modules_list, _PyImport_FrozenBootstrap);
46+
add_modules(frozen_modules_list, _PyImport_FrozenStdlib);
47+
add_modules(frozen_modules_list, PyImport_FrozenModules);
48+
add_modules(frozen_modules_list, _PyImport_FrozenTest);
49+
50+
return frozen_modules_list;
51+
}
52+
53+
static PyMethodDef frozen_utils_methods[] = {
54+
{"get_frozen_modules", _PyCFunction_CAST(get_frozen_modules), METH_FASTCALL, frozen_utils_get_frozen_modules__doc__},
55+
{NULL, NULL}
56+
};
57+
58+
static PyModuleDef_Slot frozen_utils_slots[] = {
59+
{Py_mod_exec, frozen_utils_exec},
60+
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
61+
{0, NULL}
62+
};
63+
64+
static struct PyModuleDef frozen_utils_module = {
65+
PyModuleDef_HEAD_INIT,
66+
.m_name = "frozen_utils",
67+
.m_doc = frozen_utils__doc__,
68+
.m_size = 0,
69+
.m_methods = frozen_utils_methods,
70+
.m_slots = frozen_utils_slots,
71+
};
72+
73+
PyMODINIT_FUNC
74+
PyInit_frozen_utils(void)
75+
{
76+
return PyModuleDef_Init(&frozen_utils_module);
77+
}

PC/config.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ extern PyObject* PyInit__stat(void);
7676
extern PyObject* PyInit__opcode(void);
7777
extern PyObject* PyInit__contextvars(void);
7878
extern PyObject* PyInit__tokenize(void);
79+
extern PyObject* PyInit_frozen_utils(void);
7980

8081
/* tools/freeze/makeconfig.py marker for additional "extern" */
8182
/* -- ADDMODULE MARKER 1 -- */
@@ -175,6 +176,7 @@ struct _inittab _PyImport_Inittab[] = {
175176
{"_opcode", PyInit__opcode},
176177

177178
{"_contextvars", PyInit__contextvars},
179+
{"frozen_utils", PyInit_frozen_utils},
178180

179181
/* Sentinel */
180182
{0, 0}

configure

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7410,6 +7410,7 @@ PY_STDLIB_MOD_SIMPLE([_typing])
74107410
PY_STDLIB_MOD_SIMPLE([_xxsubinterpreters])
74117411
PY_STDLIB_MOD_SIMPLE([_xxinterpchannels])
74127412
PY_STDLIB_MOD_SIMPLE([_zoneinfo])
7413+
PY_STDLIB_MOD_SIMPLE([frozen_utils])
74137414

74147415
dnl multiprocessing modules
74157416
PY_STDLIB_MOD([_multiprocessing],

0 commit comments

Comments
 (0)