Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3eb166b

Browse files
committed
Slightly improved version of patch #642578: "Expose PyImport_FrozenModules
in imp". This adds two functions to the imp module: get_frozenmodules() and set_frozenmodules().
1 parent 535ffa2 commit 3eb166b

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

Doc/lib/libimp.tex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,21 @@ \section{\module{imp} ---
106106
triggered by that).
107107
\end{funcdesc}
108108

109+
\begin{funcdesc}{set_frozenmodules}{seq_of_tuples}
110+
Set the global list of frozen modules. \var{seq_of_tuples} is a sequence
111+
of tuples of length 3: (\var{modulename}, \var{codedata}, \var{ispkg})
112+
\var{modulename} is the name of the frozen module (may contain dots).
113+
\var{codedata} is a marshalled code object. \var{ispkg} is a boolean
114+
indicating whether the module is a package.
115+
\versionadded{2.3}
116+
\end{funcdesc}
117+
118+
\begin{funcdesc}{get_frozenmodules}{}
119+
Return the global list of frozen modules as a tuple of tuples. See
120+
\function{set_frozenmodules()} for a description of its contents.
121+
\versionadded{2.3}
122+
\end{funcdesc}
123+
109124
The following constants with integer values, defined in this module,
110125
are used to indicate the search result of \function{find_module()}.
111126

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ What's New in Python 2.3 alpha 1?
1212
Type/class unification and new-style classes
1313
--------------------------------------------
1414

15+
- Exposed the PyImport_FrozenModules variable in import.c through
16+
imp.get_frozenmodules() and imp.set_frozenmodules(). This is
17+
useful for freezing tools written in Python that use Python for
18+
bootstrapping the frozen application.
19+
1520
- One can now assign to __bases__ and __name__ of new-style classes.
1621

1722
- dict() now accepts keyword arguments so that dict(one=1, two=2)

Python/import.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,135 @@ imp_init_frozen(PyObject *self, PyObject *args)
22952295
return m;
22962296
}
22972297

2298+
/* Keep a reference to the tuple used to build PyImport_FrozenModules,
2299+
as it points to the raw string data inside the tuple. */
2300+
static PyObject *frozenmodulestuple = NULL;
2301+
2302+
static PyObject *
2303+
imp_set_frozenmodules(PyObject *self, PyObject *args)
2304+
{
2305+
PyObject *t, *item, *name, *code, *ispkg;
2306+
struct _frozen *frozenmodules;
2307+
int n, i;
2308+
2309+
if (!PyArg_ParseTuple(args, "O:set_frozenmodules", &t))
2310+
return NULL;
2311+
2312+
/* turn the argument into a tuple so we're sure our list
2313+
isn't being tampered with behind our backs */
2314+
t = PySequence_Tuple(t);
2315+
if (t == NULL)
2316+
return NULL;
2317+
2318+
n = PyTuple_Size(t);
2319+
frozenmodules = PyMem_Malloc((n + 1)* sizeof(struct _frozen));
2320+
if (frozenmodules == NULL) {
2321+
PyErr_SetString(PyExc_MemoryError,
2322+
"no memory to allocate frozen array");
2323+
goto error;
2324+
}
2325+
for (i = 0; i < n; i++) {
2326+
item = PyTuple_GetItem(t, i);
2327+
if (item == NULL)
2328+
goto error;
2329+
if (!PyTuple_Check(item) || PyTuple_Size(item) != 3)
2330+
goto typeerror;
2331+
name = PyTuple_GetItem(item, 0);
2332+
code = PyTuple_GetItem(item, 1);
2333+
ispkg = PyTuple_GetItem(item, 2);
2334+
if (!PyString_Check(name) || (PyObject_IsTrue(code) &&
2335+
!PyString_Check(code)))
2336+
goto typeerror;
2337+
frozenmodules[i].name = PyString_AsString(name);
2338+
if (PyObject_IsTrue(code)) {
2339+
frozenmodules[i].code = PyString_AsString(code);
2340+
frozenmodules[i].size = PyString_Size(code);
2341+
} else {
2342+
frozenmodules[i].code = NULL;
2343+
frozenmodules[i].size = 0;
2344+
}
2345+
if (PyObject_IsTrue(ispkg))
2346+
frozenmodules[i].size = -frozenmodules[i].size;
2347+
}
2348+
frozenmodules[n].name = NULL; /* sentinel */
2349+
frozenmodules[n].code = NULL;
2350+
frozenmodules[n].size = 0;
2351+
2352+
if (frozenmodulestuple != NULL) {
2353+
Py_DECREF(frozenmodulestuple);
2354+
PyMem_Free(PyImport_FrozenModules);
2355+
} /* else we don't know how or if PyImport_FrozenModules were
2356+
allocated, so we can't do anything. */
2357+
2358+
frozenmodulestuple = t;
2359+
PyImport_FrozenModules = frozenmodules;
2360+
2361+
Py_INCREF(Py_None);
2362+
return Py_None;
2363+
2364+
typeerror:
2365+
PyErr_SetString(PyExc_TypeError,
2366+
"items must be tuples of length 3, "
2367+
"containing two strings and a bool");
2368+
error:
2369+
Py_DECREF(t);
2370+
PyMem_Free(frozenmodules);
2371+
return NULL;
2372+
}
2373+
2374+
static PyObject *
2375+
imp_get_frozenmodules(PyObject *self, PyObject *args)
2376+
{
2377+
PyObject *t, *item, *ob;
2378+
int i;
2379+
struct _frozen *p;
2380+
if (!PyArg_ParseTuple(args, ":get_frozenmodules"))
2381+
return NULL;
2382+
2383+
/* We could just return frozenmodulestuple if it isn't
2384+
NULL, but it's possible a C extension stepped on
2385+
PyImport_FrozenModules after us, so we always build
2386+
a new tuple. */
2387+
2388+
for (p = PyImport_FrozenModules, i = 0; ; p++, i++) {
2389+
if (p->name == NULL)
2390+
break;
2391+
}
2392+
t = PyTuple_New(i);
2393+
if (t == NULL)
2394+
return NULL;
2395+
for (p = PyImport_FrozenModules, i = 0; ; p++, i++) {
2396+
if (p->name == NULL)
2397+
break;
2398+
item = PyTuple_New(3);
2399+
if (item == NULL)
2400+
goto error;
2401+
ob = PyString_FromString(p->name);
2402+
if (ob == NULL)
2403+
goto error;
2404+
Py_INCREF(ob);
2405+
PyTuple_SET_ITEM(item, 0, ob);
2406+
if (p->code != NULL) {
2407+
ob = PyString_FromStringAndSize(p->code,
2408+
p->size >= 0 ? p->size : -(p->size));
2409+
if (ob == NULL)
2410+
goto error;
2411+
}
2412+
else
2413+
ob = Py_None;
2414+
Py_INCREF(ob);
2415+
PyTuple_SET_ITEM(item, 1, ob);
2416+
ob = p->size >= 0 ? Py_False : Py_True;
2417+
Py_INCREF(ob);
2418+
PyTuple_SET_ITEM(item, 2, ob);
2419+
PyTuple_SET_ITEM(t, i, item);
2420+
}
2421+
return t;
2422+
error:
2423+
Py_DECREF(t);
2424+
return NULL;
2425+
}
2426+
22982427
static PyObject *
22992428
imp_get_frozen_object(PyObject *self, PyObject *args)
23002429
{
@@ -2521,13 +2650,31 @@ PyDoc_STRVAR(doc_lock_held,
25212650
Return 1 if the import lock is currently held.\n\
25222651
On platforms without threads, return 0.");
25232652

2653+
PyDoc_STRVAR(doc_set_frozenmodules,
2654+
"set_frozenmodules(seq_of_tuples) -> None\n\
2655+
Set the global list of frozen modules.\n\
2656+
The single argument is a sequence of tuples of length 3:\n\
2657+
(modulename, codedata, ispkg)\n\
2658+
'modulename' is the name of the frozen module (may contain dots).\n\
2659+
'codedata' is a marshalled code object. 'ispkg' is a boolean\n\
2660+
indicating whether the module is a package.");
2661+
2662+
PyDoc_STRVAR(doc_get_frozenmodules,
2663+
"get_frozenmodules() -> tuple_of_tuples\n\
2664+
Return the global list of frozen modules as a tuple of tuples. See\n\
2665+
the set_frozenmodules() doc string for a description of its contents.");
2666+
25242667
static PyMethodDef imp_methods[] = {
25252668
{"find_module", imp_find_module, METH_VARARGS, doc_find_module},
25262669
{"get_magic", imp_get_magic, METH_VARARGS, doc_get_magic},
25272670
{"get_suffixes", imp_get_suffixes, METH_VARARGS, doc_get_suffixes},
25282671
{"load_module", imp_load_module, METH_VARARGS, doc_load_module},
25292672
{"new_module", imp_new_module, METH_VARARGS, doc_new_module},
25302673
{"lock_held", imp_lock_held, METH_VARARGS, doc_lock_held},
2674+
{"set_frozenmodules", imp_set_frozenmodules, METH_VARARGS,
2675+
doc_set_frozenmodules},
2676+
{"get_frozenmodules", imp_get_frozenmodules, METH_VARARGS,
2677+
doc_get_frozenmodules},
25312678
/* The rest are obsolete */
25322679
{"get_frozen_object", imp_get_frozen_object, METH_VARARGS},
25332680
{"init_builtin", imp_init_builtin, METH_VARARGS},

0 commit comments

Comments
 (0)