Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-45019: Do some cleanup related to frozen modules. #28319

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
63cd6f6
Fix freeze_module() in freeze_modules.py.
ericsnowcurrently Sep 2, 2021
0223e32
Add FrozenSource and FrozenModule to freeze_modules.py.
ericsnowcurrently Sep 1, 2021
a2be976
Leave all non-required frozen modules uncommitted.
ericsnowcurrently Sep 2, 2021
7a9d113
Leave *all* frozen modules uncommitted.
ericsnowcurrently Sep 2, 2021
e0f264f
Generate the list of frozen modules used by test_ctypes.
ericsnowcurrently Sep 1, 2021
c4cea0f
Ignore frozen submodules in generate_stdlib_module_names.py.
ericsnowcurrently Sep 7, 2021
1336b4e
Add a comment to the frozen modules manifest file.
ericsnowcurrently Sep 7, 2021
122492a
Show how the frozen manifest changed.
ericsnowcurrently Sep 7, 2021
4c1bc81
Go back to keeping frozen modules in the repo.
ericsnowcurrently Sep 7, 2021
cd99280
Also stop tracking the frozen manifest.
ericsnowcurrently Sep 8, 2021
65a9562
Mark the frozen manifest as a generated file.
ericsnowcurrently Sep 8, 2021
122e642
Drop a superfluous prefix on makefile rule dependencies.
ericsnowcurrently Sep 8, 2021
0704664
Do not generate test code.
ericsnowcurrently Sep 8, 2021
81d70ea
Drop unused code from freeze_modules.py.
ericsnowcurrently Sep 8, 2021
a61afbd
Do not clear the frozen .h files with "make distclean", now that they…
ericsnowcurrently Sep 9, 2021
ca35ee8
Always flush the printed "title" when freezing modules.
ericsnowcurrently Sep 10, 2021
1bf4d2f
Add the frozen manifest back into the repo.
ericsnowcurrently Sep 10, 2021
bd129b5
On Windows, only freeze the essential modules for now.
ericsnowcurrently Sep 13, 2021
20d3b50
Drop an outdated call.
ericsnowcurrently Sep 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Expand Up @@ -47,6 +47,7 @@ Objects/clinic/*.h linguist-generated=true
PC/clinic/*.h linguist-generated=true
Python/clinic/*.h linguist-generated=true
Python/frozen_modules/*.h linguist-generated=true
Python/frozen_modules/MANIFEST linguist-generated=true
Include/internal/pycore_ast.h linguist-generated=true
Python/Python-ast.c linguist-generated=true
Include/opcode.h linguist-generated=true
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Expand Up @@ -121,6 +121,13 @@ Tools/msi/obj
Tools/ssl/amd64
Tools/ssl/win32

# TODO: Once we auto-regen frozem modules for Windows builds
# we can drop the .h files from the repo and ignore them here.
# At that point we will rely the frozen manifest file to identify
# changed generated files. We'll drop the entry for it then.
# See: Tools/scripts/freeze_modules.py.
#Python/frozen_modules/*.h

# Two-trick pony for OSX and other case insensitive file systems:
# Ignore ./python binary on Unix but still look into ./Python/ directory.
/python
Expand Down
48 changes: 21 additions & 27 deletions Lib/ctypes/test/test_values.py
Expand Up @@ -2,9 +2,12 @@
A testcase which accesses *values* in a dll.
"""

import imp
import importlib.util
import unittest
import sys
from ctypes import *
from test.support import import_helper, captured_stdout

import _ctypes_test

Expand Down Expand Up @@ -55,41 +58,32 @@ class struct_frozen(Structure):

ft = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
# ft is a pointer to the struct_frozen entries:
items = []
# _frozen_importlib changes size whenever importlib._bootstrap
# changes, so it gets a special case. We should make sure it's
# found, but don't worry about its size too much. The same
# applies to _frozen_importlib_external.
bootstrap_seen = []
bootstrap_expected = [
b'_frozen_importlib',
b'_frozen_importlib_external',
b'zipimport',
]
modules = []
for entry in ft:
# This is dangerous. We *can* iterate over a pointer, but
# the loop will not terminate (maybe with an access
# violation;-) because the pointer instance has no size.
if entry.name is None:
break

if entry.name in bootstrap_expected:
bootstrap_seen.append(entry.name)
self.assertTrue(entry.size,
"{!r} was reported as having no size".format(entry.name))
continue
items.append((entry.name.decode("ascii"), entry.size))

expected = [("__hello__", 164),
("__phello__", -164),
("__phello__.spam", 164),
]
self.assertEqual(items, expected, "PyImport_FrozenModules example "
modname = entry.name.decode("ascii")
modules.append(modname)
with self.subTest(modname):
# Do a sanity check on entry.size and entry.code.
self.assertGreater(abs(entry.size), 10)
self.assertTrue([entry.code[i] for i in range(abs(entry.size))])
# Check the module's package-ness.
spec = importlib.util.find_spec(modname)
if entry.size < 0:
# It's a package.
self.assertIsNotNone(spec.submodule_search_locations)
else:
self.assertIsNone(spec.submodule_search_locations)

expected = imp._frozen_module_names()
self.maxDiff = None
self.assertEqual(modules, expected, "PyImport_FrozenModules example "
"in Doc/library/ctypes.rst may be out of date")

self.assertEqual(sorted(bootstrap_seen), bootstrap_expected,
"frozen bootstrap modules did not match PyImport_FrozenModules")

from ctypes import _pointer_type_cache
del _pointer_type_cache[struct_frozen]

Expand Down
2 changes: 1 addition & 1 deletion Lib/imp.py
Expand Up @@ -9,7 +9,7 @@
from _imp import (lock_held, acquire_lock, release_lock,
get_frozen_object, is_frozen_package,
init_frozen, is_builtin, is_frozen,
_fix_co_filename)
_fix_co_filename, _frozen_module_names)
try:
from _imp import create_dynamic
except ImportError:
Expand Down
8 changes: 4 additions & 4 deletions Makefile.pre.in
Expand Up @@ -750,22 +750,22 @@ regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES)

# BEGIN: freezing modules

Python/frozen_modules/importlib__bootstrap.h: $(srcdir)/Programs/_freeze_module $(srcdir)/Lib/importlib/_bootstrap.py
Python/frozen_modules/importlib__bootstrap.h: Programs/_freeze_module Lib/importlib/_bootstrap.py
$(srcdir)/Programs/_freeze_module importlib._bootstrap \
$(srcdir)/Lib/importlib/_bootstrap.py \
$(srcdir)/Python/frozen_modules/importlib__bootstrap.h

Python/frozen_modules/importlib__bootstrap_external.h: $(srcdir)/Programs/_freeze_module $(srcdir)/Lib/importlib/_bootstrap_external.py
Python/frozen_modules/importlib__bootstrap_external.h: Programs/_freeze_module Lib/importlib/_bootstrap_external.py
$(srcdir)/Programs/_freeze_module importlib._bootstrap_external \
$(srcdir)/Lib/importlib/_bootstrap_external.py \
$(srcdir)/Python/frozen_modules/importlib__bootstrap_external.h

Python/frozen_modules/zipimport.h: $(srcdir)/Programs/_freeze_module $(srcdir)/Lib/zipimport.py
Python/frozen_modules/zipimport.h: Programs/_freeze_module Lib/zipimport.py
$(srcdir)/Programs/_freeze_module zipimport \
$(srcdir)/Lib/zipimport.py \
$(srcdir)/Python/frozen_modules/zipimport.h

Python/frozen_modules/hello.h: $(srcdir)/Programs/_freeze_module $(srcdir)/Tools/freeze/flag.py
Python/frozen_modules/hello.h: Programs/_freeze_module Tools/freeze/flag.py
$(srcdir)/Programs/_freeze_module hello \
$(srcdir)/Tools/freeze/flag.py \
$(srcdir)/Python/frozen_modules/hello.h
Expand Down
20 changes: 19 additions & 1 deletion Python/clinic/import.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Python/frozen.c
Expand Up @@ -47,7 +47,7 @@
/* Note that a negative size indicates a package. */

static const struct _frozen _PyImport_FrozenModules[] = {
/* importlib */
/* import system */
{"_frozen_importlib", _Py_M__importlib__bootstrap,
(int)sizeof(_Py_M__importlib__bootstrap)},
{"_frozen_importlib_external", _Py_M__importlib__bootstrap_external,
Expand Down
12 changes: 12 additions & 0 deletions Python/frozen_modules/MANIFEST

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Python/frozen_modules/README.txt
@@ -0,0 +1,7 @@
This directory contains the generated .h files for all the frozen
modules. Python/frozen.c depends on these files.

Note that, other than the required frozen modules, none of these files
are committed into the repo.

See Tools/scripts/freeze_modules.py for more info.
41 changes: 41 additions & 0 deletions Python/import.c
Expand Up @@ -16,6 +16,7 @@
#include "code.h"
#include "importdl.h"
#include "pydtrace.h"
#include <stdbool.h>

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
Expand Down Expand Up @@ -1049,6 +1050,32 @@ _imp_create_builtin(PyObject *module, PyObject *spec)

/* Frozen modules */

static PyObject *
list_frozen_module_names(bool force)
{
PyObject *names = PyList_New(0);
if (names == NULL) {
return NULL;
}
for (const struct _frozen *p = PyImport_FrozenModules; ; p++) {
if (p->name == NULL) {
break;
}
PyObject *name = PyUnicode_FromString(p->name);
if (name == NULL) {
Py_DECREF(names);
return NULL;
}
int res = PyList_Append(names, name);
Py_DECREF(name);
if (res != 0) {
Py_DECREF(names);
return NULL;
}
}
return names;
}

static const struct _frozen *
find_frozen(PyObject *name)
{
Expand Down Expand Up @@ -1954,6 +1981,19 @@ _imp_is_frozen_impl(PyObject *module, PyObject *name)
return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
}

/*[clinic input]
_imp._frozen_module_names

Returns the list of available frozen modules.
[clinic start generated code]*/

static PyObject *
_imp__frozen_module_names_impl(PyObject *module)
/*[clinic end generated code: output=80609ef6256310a8 input=76237fbfa94460d2]*/
{
return list_frozen_module_names(true);
}

/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
static int
exec_builtin_or_dynamic(PyObject *mod) {
Expand Down Expand Up @@ -2114,6 +2154,7 @@ static PyMethodDef imp_methods[] = {
_IMP_INIT_FROZEN_METHODDEF
_IMP_IS_BUILTIN_METHODDEF
_IMP_IS_FROZEN_METHODDEF
_IMP__FROZEN_MODULE_NAMES_METHODDEF
_IMP_CREATE_DYNAMIC_METHODDEF
_IMP_EXEC_DYNAMIC_METHODDEF
_IMP_EXEC_BUILTIN_METHODDEF
Expand Down