@@ -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+
22982427static PyObject *
22992428imp_get_frozen_object (PyObject * self , PyObject * args )
23002429{
@@ -2521,13 +2650,31 @@ PyDoc_STRVAR(doc_lock_held,
25212650Return 1 if the import lock is currently held.\n\
25222651On 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+
25242667static 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