Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
patch pkgutil and test_pkgutil
  • Loading branch information
arihant2math committed Apr 14, 2025
commit eca0b9e83996011be1d111438b18e98214edb27e
182 changes: 0 additions & 182 deletions Lib/pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,188 +184,6 @@ def _iter_file_finder_modules(importer, prefix=''):
iter_importer_modules.register(
importlib.machinery.FileFinder, _iter_file_finder_modules)


def _import_imp():
global imp
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
imp = importlib.import_module('imp')

class ImpImporter:
"""PEP 302 Finder that wraps Python's "classic" import algorithm

ImpImporter(dirname) produces a PEP 302 finder that searches that
directory. ImpImporter(None) produces a PEP 302 finder that searches
the current sys.path, plus any modules that are frozen or built-in.

Note that ImpImporter does not currently support being used by placement
on sys.meta_path.
"""

def __init__(self, path=None):
global imp
warnings.warn("This emulation is deprecated and slated for removal "
"in Python 3.12; use 'importlib' instead",
DeprecationWarning)
_import_imp()
self.path = path

def find_module(self, fullname, path=None):
# Note: we ignore 'path' argument since it is only used via meta_path
subname = fullname.split(".")[-1]
if subname != fullname and self.path is None:
return None
if self.path is None:
path = None
else:
path = [os.path.realpath(self.path)]
try:
file, filename, etc = imp.find_module(subname, path)
except ImportError:
return None
return ImpLoader(fullname, file, filename, etc)

def iter_modules(self, prefix=''):
if self.path is None or not os.path.isdir(self.path):
return

yielded = {}
import inspect
try:
filenames = os.listdir(self.path)
except OSError:
# ignore unreadable directories like import does
filenames = []
filenames.sort() # handle packages before same-named modules

for fn in filenames:
modname = inspect.getmodulename(fn)
if modname=='__init__' or modname in yielded:
continue

path = os.path.join(self.path, fn)
ispkg = False

if not modname and os.path.isdir(path) and '.' not in fn:
modname = fn
try:
dircontents = os.listdir(path)
except OSError:
# ignore unreadable directories like import does
dircontents = []
for fn in dircontents:
subname = inspect.getmodulename(fn)
if subname=='__init__':
ispkg = True
break
else:
continue # not a package

if modname and '.' not in modname:
yielded[modname] = 1
yield prefix + modname, ispkg


class ImpLoader:
"""PEP 302 Loader that wraps Python's "classic" import algorithm
"""
code = source = None

def __init__(self, fullname, file, filename, etc):
warnings.warn("This emulation is deprecated and slated for removal in "
"Python 3.12; use 'importlib' instead",
DeprecationWarning)
_import_imp()
self.file = file
self.filename = filename
self.fullname = fullname
self.etc = etc

def load_module(self, fullname):
self._reopen()
try:
mod = imp.load_module(fullname, self.file, self.filename, self.etc)
finally:
if self.file:
self.file.close()
# Note: we don't set __loader__ because we want the module to look
# normal; i.e. this is just a wrapper for standard import machinery
return mod

def get_data(self, pathname):
with open(pathname, "rb") as file:
return file.read()

def _reopen(self):
if self.file and self.file.closed:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
self.file = open(self.filename, 'r')
elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION):
self.file = open(self.filename, 'rb')

def _fix_name(self, fullname):
if fullname is None:
fullname = self.fullname
elif fullname != self.fullname:
raise ImportError("Loader for module %s cannot handle "
"module %s" % (self.fullname, fullname))
return fullname

def is_package(self, fullname):
fullname = self._fix_name(fullname)
return self.etc[2]==imp.PKG_DIRECTORY

def get_code(self, fullname=None):
fullname = self._fix_name(fullname)
if self.code is None:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
source = self.get_source(fullname)
self.code = compile(source, self.filename, 'exec')
elif mod_type==imp.PY_COMPILED:
self._reopen()
try:
self.code = read_code(self.file)
finally:
self.file.close()
elif mod_type==imp.PKG_DIRECTORY:
self.code = self._get_delegate().get_code()
return self.code

def get_source(self, fullname=None):
fullname = self._fix_name(fullname)
if self.source is None:
mod_type = self.etc[2]
if mod_type==imp.PY_SOURCE:
self._reopen()
try:
self.source = self.file.read()
finally:
self.file.close()
elif mod_type==imp.PY_COMPILED:
if os.path.exists(self.filename[:-1]):
with open(self.filename[:-1], 'r') as f:
self.source = f.read()
elif mod_type==imp.PKG_DIRECTORY:
self.source = self._get_delegate().get_source()
return self.source

def _get_delegate(self):
finder = ImpImporter(self.filename)
spec = _get_spec(finder, '__init__')
return spec.loader

def get_filename(self, fullname=None):
fullname = self._fix_name(fullname)
mod_type = self.etc[2]
if mod_type==imp.PKG_DIRECTORY:
return self._get_delegate().get_filename()
elif mod_type in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION):
return self.filename
return None


try:
import zipimport
from zipimport import zipimporter
Expand Down
27 changes: 0 additions & 27 deletions Lib/test/test_pkgutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,33 +491,6 @@ def test_nested(self):
self.assertEqual(c, 1)
self.assertEqual(d, 2)


class ImportlibMigrationTests(unittest.TestCase):
# With full PEP 302 support in the standard import machinery, the
# PEP 302 emulation in this module is in the process of being
# deprecated in favour of importlib proper

def check_deprecated(self):
return check_warnings(
("This emulation is deprecated and slated for removal in "
"Python 3.12; use 'importlib' instead",
DeprecationWarning))

def test_importer_deprecated(self):
with self.check_deprecated():
pkgutil.ImpImporter("")

def test_loader_deprecated(self):
with self.check_deprecated():
pkgutil.ImpLoader("", "", "", "")

def test_get_loader_avoids_emulation(self):
with check_warnings() as w:
self.assertIsNotNone(pkgutil.get_loader("sys"))
self.assertIsNotNone(pkgutil.get_loader("os"))
self.assertIsNotNone(pkgutil.get_loader("test.support"))
self.assertEqual(len(w.warnings), 0)

@unittest.skipIf(__name__ == '__main__', 'not compatible with __main__')
def test_get_loader_handles_missing_loader_attribute(self):
global __loader__
Expand Down