Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
6029e086
Kaydet (Commit)
6029e086
authored
Ock 25, 2014
tarafından
Eric Snow
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue 19944: Fix importlib.find_spec() so it imports parents as needed.
The function is also moved to importlib.util.
üst
128ee220
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
292 additions
and
230 deletions
+292
-230
importlib.rst
Doc/library/importlib.rst
+17
-17
EditorWindow.py
Lib/idlelib/EditorWindow.py
+2
-1
__init__.py
Lib/importlib/__init__.py
+9
-37
util.py
Lib/importlib/util.py
+72
-0
pkgutil.py
Lib/pkgutil.py
+1
-1
pyclbr.py
Lib/pyclbr.py
+2
-2
runpy.py
Lib/runpy.py
+4
-22
test_api.py
Lib/test/test_importlib/test_api.py
+2
-149
test_util.py
Lib/test/test_importlib/test_util.py
+147
-0
util.py
Lib/test/test_importlib/util.py
+33
-1
NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/importlib.rst
Dosyayı görüntüle @
6029e086
...
@@ -89,22 +89,6 @@ Functions
...
@@ -89,22 +89,6 @@ Functions
..
versionchanged
::
3.3
..
versionchanged
::
3.3
Parent
packages
are
automatically
imported
.
Parent
packages
are
automatically
imported
.
..
function
::
find_spec
(
name
,
path
=
None
)
Find
the
:
term
:`
spec
<
module
spec
>`
for
a
module
,
optionally
within
the
specified
*
path
*.
If
the
module
is
in
:
attr
:`
sys
.
modules
`,
then
``
sys
.
modules
[
name
].
__spec__
``
is
returned
(
unless
the
spec
would
be
``
None
``
or
is
not
set
,
in
which
case
:
exc
:`
ValueError
`
is
raised
).
Otherwise
a
search
using
:
attr
:`
sys
.
meta_path
`
is
done
.
``
None
``
is
returned
if
no
spec
is
found
.
A
dotted
name
does
not
have
its
parent
implicitly
imported
as
that
requires
loading
them
and
that
may
not
be
desired
.
To
properly
import
a
submodule
you
will
need
to
import
all
parent
packages
of
the
submodule
and
use
the
correct
argument
to
*
path
*.
..
versionadded
::
3.4
..
function
::
find_loader
(
name
,
path
=
None
)
..
function
::
find_loader
(
name
,
path
=
None
)
Find
the
loader
for
a
module
,
optionally
within
the
specified
*
path
*.
If
the
Find
the
loader
for
a
module
,
optionally
within
the
specified
*
path
*.
If
the
...
@@ -125,7 +109,7 @@ Functions
...
@@ -125,7 +109,7 @@ Functions
attribute is set to ``None``.
attribute is set to ``None``.
.. deprecated:: 3.4
.. deprecated:: 3.4
Use :func:`find_spec` instead.
Use :func:`
importlib.util.
find_spec` instead.
.. function:: invalidate_caches()
.. function:: invalidate_caches()
...
@@ -1111,6 +1095,22 @@ an :term:`importer`.
...
@@ -1111,6 +1095,22 @@ an :term:`importer`.
.. versionadded:: 3.3
.. versionadded:: 3.3
.. function:: find_spec(name, package=None)
Find the :term:`spec <module spec>` for a module, optionally relative to
the specified **package** name. If the module is in :attr:`sys.modules`,
then ``sys.modules[name].__spec__`` is returned (unless the spec would be
``None`` or is not set, in which case :exc:`ValueError` is raised).
Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is
returned if no spec is found.
If **name** is for a submodule (contains a dot), the parent module is
automatically imported.
**name** and **package** work the same as for :func:`import_module`.
.. versionadded:: 3.4
.. decorator:: module_for_loader
.. decorator:: module_for_loader
A :term:`decorator` for :meth:`importlib.abc.Loader.load_module`
A :term:`decorator` for :meth:`importlib.abc.Loader.load_module`
...
...
Lib/idlelib/EditorWindow.py
Dosyayı görüntüle @
6029e086
import
importlib
import
importlib
import
importlib.abc
import
importlib.abc
import
importlib.util
import
os
import
os
from
platform
import
python_version
from
platform
import
python_version
import
re
import
re
...
@@ -660,7 +661,7 @@ class EditorWindow(object):
...
@@ -660,7 +661,7 @@ class EditorWindow(object):
return
return
# XXX Ought to insert current file's directory in front of path
# XXX Ought to insert current file's directory in front of path
try
:
try
:
spec
=
importlib
.
find_spec
(
name
)
spec
=
importlib
.
util
.
find_spec
(
name
)
except
(
ValueError
,
ImportError
)
as
msg
:
except
(
ValueError
,
ImportError
)
as
msg
:
tkMessageBox
.
showerror
(
"Import error"
,
str
(
msg
),
parent
=
self
.
text
)
tkMessageBox
.
showerror
(
"Import error"
,
str
(
msg
),
parent
=
self
.
text
)
return
return
...
...
Lib/importlib/__init__.py
Dosyayı görüntüle @
6029e086
...
@@ -11,8 +11,6 @@ __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload']
...
@@ -11,8 +11,6 @@ __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload']
# initialised below if the frozen one is not available).
# initialised below if the frozen one is not available).
import
_imp
# Just the builtin component, NOT the full Python module
import
_imp
# Just the builtin component, NOT the full Python module
import
sys
import
sys
import
types
import
warnings
try
:
try
:
import
_frozen_importlib
as
_bootstrap
import
_frozen_importlib
as
_bootstrap
...
@@ -34,6 +32,10 @@ _r_long = _bootstrap._r_long
...
@@ -34,6 +32,10 @@ _r_long = _bootstrap._r_long
# Fully bootstrapped at this point, import whatever you like, circular
# Fully bootstrapped at this point, import whatever you like, circular
# dependencies and startup overhead minimisation permitting :)
# dependencies and startup overhead minimisation permitting :)
import
types
import
warnings
# Public API #########################################################
# Public API #########################################################
from
._bootstrap
import
__import__
from
._bootstrap
import
__import__
...
@@ -47,47 +49,16 @@ def invalidate_caches():
...
@@ -47,47 +49,16 @@ def invalidate_caches():
finder
.
invalidate_caches
()
finder
.
invalidate_caches
()
def
find_spec
(
name
,
path
=
None
):
"""Return the spec for the specified module.
First, sys.modules is checked to see if the module was already imported. If
so, then sys.modules[name].__spec__ is returned. If that happens to be
set to None, then ValueError is raised. If the module is not in
sys.modules, then sys.meta_path is searched for a suitable spec with the
value of 'path' given to the finders. None is returned if no spec could
be found.
Dotted names do not have their parent packages implicitly imported. You will
most likely need to explicitly import all parent packages in the proper
order for a submodule to get the correct spec.
"""
if
name
not
in
sys
.
modules
:
return
_bootstrap
.
_find_spec
(
name
,
path
)
else
:
module
=
sys
.
modules
[
name
]
if
module
is
None
:
return
None
try
:
spec
=
module
.
__spec__
except
AttributeError
:
raise
ValueError
(
'{}.__spec__ is not set'
.
format
(
name
))
else
:
if
spec
is
None
:
raise
ValueError
(
'{}.__spec__ is None'
.
format
(
name
))
return
spec
def
find_loader
(
name
,
path
=
None
):
def
find_loader
(
name
,
path
=
None
):
"""Return the loader for the specified module.
"""Return the loader for the specified module.
This is a backward-compatible wrapper around find_spec().
This is a backward-compatible wrapper around find_spec().
This function is deprecated in favor of importlib.find_spec().
This function is deprecated in favor of importlib.
util.
find_spec().
"""
"""
warnings
.
warn
(
'Use importlib.
find_spec() instead.'
,
DeprecationWarning
,
warnings
.
warn
(
'Use importlib.
util.find_spec() instead.'
,
stacklevel
=
2
)
DeprecationWarning
,
stacklevel
=
2
)
try
:
try
:
loader
=
sys
.
modules
[
name
]
.
__loader__
loader
=
sys
.
modules
[
name
]
.
__loader__
if
loader
is
None
:
if
loader
is
None
:
...
@@ -167,7 +138,8 @@ def reload(module):
...
@@ -167,7 +138,8 @@ def reload(module):
pkgpath
=
parent
.
__path__
pkgpath
=
parent
.
__path__
else
:
else
:
pkgpath
=
None
pkgpath
=
None
spec
=
module
.
__spec__
=
_bootstrap
.
_find_spec
(
name
,
pkgpath
,
module
)
target
=
module
spec
=
module
.
__spec__
=
_bootstrap
.
_find_spec
(
name
,
pkgpath
,
target
)
methods
=
_bootstrap
.
_SpecMethods
(
spec
)
methods
=
_bootstrap
.
_SpecMethods
(
spec
)
methods
.
exec
(
module
)
methods
.
exec
(
module
)
# The module may have replaced itself in sys.modules!
# The module may have replaced itself in sys.modules!
...
...
Lib/importlib/util.py
Dosyayı görüntüle @
6029e086
...
@@ -7,6 +7,7 @@ from ._bootstrap import source_from_cache
...
@@ -7,6 +7,7 @@ from ._bootstrap import source_from_cache
from
._bootstrap
import
spec_from_loader
from
._bootstrap
import
spec_from_loader
from
._bootstrap
import
spec_from_file_location
from
._bootstrap
import
spec_from_file_location
from
._bootstrap
import
_resolve_name
from
._bootstrap
import
_resolve_name
from
._bootstrap
import
_find_spec
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
import
functools
import
functools
...
@@ -29,6 +30,77 @@ def resolve_name(name, package):
...
@@ -29,6 +30,77 @@ def resolve_name(name, package):
return
_resolve_name
(
name
[
level
:],
package
,
level
)
return
_resolve_name
(
name
[
level
:],
package
,
level
)
def
_find_spec_from_path
(
name
,
path
=
None
):
"""Return the spec for the specified module.
First, sys.modules is checked to see if the module was already imported. If
so, then sys.modules[name].__spec__ is returned. If that happens to be
set to None, then ValueError is raised. If the module is not in
sys.modules, then sys.meta_path is searched for a suitable spec with the
value of 'path' given to the finders. None is returned if no spec could
be found.
Dotted names do not have their parent packages implicitly imported. You will
most likely need to explicitly import all parent packages in the proper
order for a submodule to get the correct spec.
"""
if
name
not
in
sys
.
modules
:
return
_find_spec
(
name
,
path
)
else
:
module
=
sys
.
modules
[
name
]
if
module
is
None
:
return
None
try
:
spec
=
module
.
__spec__
except
AttributeError
:
raise
ValueError
(
'{}.__spec__ is not set'
.
format
(
name
))
else
:
if
spec
is
None
:
raise
ValueError
(
'{}.__spec__ is None'
.
format
(
name
))
return
spec
def
find_spec
(
name
,
package
=
None
):
"""Return the spec for the specified module.
First, sys.modules is checked to see if the module was already imported. If
so, then sys.modules[name].__spec__ is returned. If that happens to be
set to None, then ValueError is raised. If the module is not in
sys.modules, then sys.meta_path is searched for a suitable spec with the
value of 'path' given to the finders. None is returned if no spec could
be found.
If the name is for submodule (contains a dot), the parent module is
automatically imported.
The name and package arguments work the same as importlib.import_module().
In other words, relative module names (with leading dots) work.
"""
fullname
=
resolve_name
(
name
,
package
)
if
name
.
startswith
(
'.'
)
else
name
if
fullname
not
in
sys
.
modules
:
parent_name
=
fullname
.
rpartition
(
'.'
)[
0
]
if
parent_name
:
# Use builtins.__import__() in case someone replaced it.
parent
=
__import__
(
parent_name
,
fromlist
=
[
'__path__'
])
return
_find_spec
(
fullname
,
parent
.
__path__
)
else
:
return
_find_spec
(
fullname
,
None
)
else
:
module
=
sys
.
modules
[
fullname
]
if
module
is
None
:
return
None
try
:
spec
=
module
.
__spec__
except
AttributeError
:
raise
ValueError
(
'{}.__spec__ is not set'
.
format
(
name
))
else
:
if
spec
is
None
:
raise
ValueError
(
'{}.__spec__ is None'
.
format
(
name
))
return
spec
@contextmanager
@contextmanager
def
_module_to_load
(
name
):
def
_module_to_load
(
name
):
is_reload
=
name
in
sys
.
modules
is_reload
=
name
in
sys
.
modules
...
...
Lib/pkgutil.py
Dosyayı görüntüle @
6029e086
...
@@ -611,7 +611,7 @@ def get_data(package, resource):
...
@@ -611,7 +611,7 @@ def get_data(package, resource):
which does not support get_data(), then None is returned.
which does not support get_data(), then None is returned.
"""
"""
spec
=
importlib
.
find_spec
(
package
)
spec
=
importlib
.
util
.
find_spec
(
package
)
if
spec
is
None
:
if
spec
is
None
:
return
None
return
None
loader
=
spec
.
loader
loader
=
spec
.
loader
...
...
Lib/pyclbr.py
Dosyayı görüntüle @
6029e086
...
@@ -42,7 +42,7 @@ Instances of this class have the following instance variables:
...
@@ -42,7 +42,7 @@ Instances of this class have the following instance variables:
import
io
import
io
import
os
import
os
import
sys
import
sys
import
importlib
import
importlib
.util
import
tokenize
import
tokenize
from
token
import
NAME
,
DEDENT
,
OP
from
token
import
NAME
,
DEDENT
,
OP
from
operator
import
itemgetter
from
operator
import
itemgetter
...
@@ -141,7 +141,7 @@ def _readmodule(module, path, inpackage=None):
...
@@ -141,7 +141,7 @@ def _readmodule(module, path, inpackage=None):
else
:
else
:
search_path
=
path
+
sys
.
path
search_path
=
path
+
sys
.
path
# XXX This will change once issue19944 lands.
# XXX This will change once issue19944 lands.
spec
=
importlib
.
find_spec
(
fullmodule
,
search_path
)
spec
=
importlib
.
util
.
_find_spec_from_path
(
fullmodule
,
search_path
)
fname
=
spec
.
loader
.
get_filename
(
fullmodule
)
fname
=
spec
.
loader
.
get_filename
(
fullmodule
)
_modules
[
fullmodule
]
=
dict
_modules
[
fullmodule
]
=
dict
if
spec
.
loader
.
is_package
(
fullmodule
):
if
spec
.
loader
.
is_package
(
fullmodule
):
...
...
Lib/runpy.py
Dosyayı görüntüle @
6029e086
...
@@ -13,9 +13,8 @@ importers when locating support scripts as well as when importing modules.
...
@@ -13,9 +13,8 @@ importers when locating support scripts as well as when importing modules.
import
os
import
os
import
sys
import
sys
import
importlib.machinery
# importlib first so we can test #15386 via -m
import
importlib.machinery
# importlib first so we can test #15386 via -m
import
importlib.util
import
types
import
types
from
importlib
import
find_spec
from
importlib.util
import
spec_from_loader
from
pkgutil
import
read_code
,
get_importer
from
pkgutil
import
read_code
,
get_importer
__all__
=
[
__all__
=
[
...
@@ -100,33 +99,16 @@ def _run_module_code(code, init_globals=None,
...
@@ -100,33 +99,16 @@ def _run_module_code(code, init_globals=None,
# may be cleared when the temporary module goes away
# may be cleared when the temporary module goes away
return
mod_globals
.
copy
()
return
mod_globals
.
copy
()
# Helper to get the loader, code and filename for a module
def
_fixed_find_spec
(
mod_name
):
def
_get_module_details
(
mod_name
):
# find_spec has the same annoying behaviour as find_loader did (it
# fails to work properly for dotted names), so this is a fixed version
# ala pkgutil.get_loader
if
mod_name
.
startswith
(
'.'
):
msg
=
"Relative module name {!r} not supported"
.
format
(
mod_name
)
raise
ImportError
(
msg
)
path
=
None
pkg_name
=
mod_name
.
rpartition
(
"."
)[
0
]
if
pkg_name
:
pkg
=
importlib
.
import_module
(
pkg_name
)
path
=
getattr
(
pkg
,
"__path__"
,
None
)
if
path
is
None
:
return
None
try
:
try
:
return
importlib
.
find_spec
(
mod_name
,
path
)
spec
=
importlib
.
util
.
find_spec
(
mod_name
)
except
(
ImportError
,
AttributeError
,
TypeError
,
ValueError
)
as
ex
:
except
(
ImportError
,
AttributeError
,
TypeError
,
ValueError
)
as
ex
:
# This hack fixes an impedance mismatch between pkgutil and
# This hack fixes an impedance mismatch between pkgutil and
# importlib, where the latter raises other errors for cases where
# importlib, where the latter raises other errors for cases where
# pkgutil previously raised ImportError
# pkgutil previously raised ImportError
msg
=
"Error while finding spec for {!r} ({}: {})"
msg
=
"Error while finding spec for {!r} ({}: {})"
raise
ImportError
(
msg
.
format
(
mod_name
,
type
(
ex
),
ex
))
from
ex
raise
ImportError
(
msg
.
format
(
mod_name
,
type
(
ex
),
ex
))
from
ex
# Helper to get the loader, code and filename for a module
def
_get_module_details
(
mod_name
):
spec
=
_fixed_find_spec
(
mod_name
)
if
spec
is
None
:
if
spec
is
None
:
raise
ImportError
(
"No module named
%
s"
%
mod_name
)
raise
ImportError
(
"No module named
%
s"
%
mod_name
)
if
spec
.
submodule_search_locations
is
not
None
:
if
spec
.
submodule_search_locations
is
not
None
:
...
...
Lib/test/test_importlib/test_api.py
Dosyayı görüntüle @
6029e086
...
@@ -4,7 +4,6 @@ frozen_init, source_init = util.import_importlib('importlib')
...
@@ -4,7 +4,6 @@ frozen_init, source_init = util.import_importlib('importlib')
frozen_util
,
source_util
=
util
.
import_importlib
(
'importlib.util'
)
frozen_util
,
source_util
=
util
.
import_importlib
(
'importlib.util'
)
frozen_machinery
,
source_machinery
=
util
.
import_importlib
(
'importlib.machinery'
)
frozen_machinery
,
source_machinery
=
util
.
import_importlib
(
'importlib.machinery'
)
from
contextlib
import
contextmanager
import
os.path
import
os.path
import
sys
import
sys
from
test
import
support
from
test
import
support
...
@@ -13,37 +12,6 @@ import unittest
...
@@ -13,37 +12,6 @@ import unittest
import
warnings
import
warnings
@contextmanager
def
temp_module
(
name
,
content
=
''
,
*
,
pkg
=
False
):
conflicts
=
[
n
for
n
in
sys
.
modules
if
n
.
partition
(
'.'
)[
0
]
==
name
]
with
support
.
temp_cwd
(
None
)
as
cwd
:
with
util
.
uncache
(
name
,
*
conflicts
):
with
support
.
DirsOnSysPath
(
cwd
):
frozen_init
.
invalidate_caches
()
location
=
os
.
path
.
join
(
cwd
,
name
)
if
pkg
:
modpath
=
os
.
path
.
join
(
location
,
'__init__.py'
)
os
.
mkdir
(
name
)
else
:
modpath
=
location
+
'.py'
if
content
is
None
:
# Make sure the module file gets created.
content
=
''
if
content
is
not
None
:
# not a namespace package
with
open
(
modpath
,
'w'
)
as
modfile
:
modfile
.
write
(
content
)
yield
location
def
submodule
(
parent
,
name
,
pkg_dir
,
content
=
''
):
path
=
os
.
path
.
join
(
pkg_dir
,
name
+
'.py'
)
with
open
(
path
,
'w'
)
as
subfile
:
subfile
.
write
(
content
)
return
'{}.{}'
.
format
(
parent
,
name
),
path
class
ImportModuleTests
:
class
ImportModuleTests
:
"""Test importlib.import_module."""
"""Test importlib.import_module."""
...
@@ -210,121 +178,6 @@ class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase):
...
@@ -210,121 +178,6 @@ class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase):
init
=
source_init
init
=
source_init
class
FindSpecTests
:
class
FakeMetaFinder
:
@staticmethod
def
find_spec
(
name
,
path
=
None
,
target
=
None
):
return
name
,
path
,
target
def
test_sys_modules
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
loader
=
'a loader!'
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
loader
)
module
.
__loader__
=
loader
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
init
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_without___loader__
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
del
module
.
__loader__
loader
=
'a loader!'
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
loader
)
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
init
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_spec_is_None
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
module
.
__spec__
=
None
sys
.
modules
[
name
]
=
module
with
self
.
assertRaises
(
ValueError
):
self
.
init
.
find_spec
(
name
)
def
test_sys_modules_loader_is_None
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
None
)
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
init
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_spec_is_not_set
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
try
:
del
module
.
__spec__
except
AttributeError
:
pass
sys
.
modules
[
name
]
=
module
with
self
.
assertRaises
(
ValueError
):
self
.
init
.
find_spec
(
name
)
def
test_success
(
self
):
name
=
'some_mod'
with
util
.
uncache
(
name
):
with
util
.
import_state
(
meta_path
=
[
self
.
FakeMetaFinder
]):
self
.
assertEqual
((
name
,
None
,
None
),
self
.
init
.
find_spec
(
name
))
def
test_success_path
(
self
):
# Searching on a path should work.
name
=
'some_mod'
path
=
'path to some place'
with
util
.
uncache
(
name
):
with
util
.
import_state
(
meta_path
=
[
self
.
FakeMetaFinder
]):
self
.
assertEqual
((
name
,
path
,
None
),
self
.
init
.
find_spec
(
name
,
path
))
def
test_nothing
(
self
):
# None is returned upon failure to find a loader.
self
.
assertIsNone
(
self
.
init
.
find_spec
(
'nevergoingtofindthismodule'
))
def
test_find_submodule
(
self
):
name
=
'spam'
subname
=
'ham'
with
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
submodule
(
name
,
subname
,
pkg_dir
)
spec
=
self
.
init
.
find_spec
(
fullname
,
[
pkg_dir
])
self
.
assertIsNot
(
spec
,
None
)
self
.
assertNotIn
(
name
,
sorted
(
sys
.
modules
))
# Ensure successive calls behave the same.
spec_again
=
self
.
init
.
find_spec
(
fullname
,
[
pkg_dir
])
self
.
assertEqual
(
spec_again
,
spec
)
def
test_find_submodule_missing_path
(
self
):
name
=
'spam'
subname
=
'ham'
with
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
submodule
(
name
,
subname
,
pkg_dir
)
spec
=
self
.
init
.
find_spec
(
fullname
)
self
.
assertIs
(
spec
,
None
)
self
.
assertNotIn
(
name
,
sorted
(
sys
.
modules
))
# Ensure successive calls behave the same.
spec
=
self
.
init
.
find_spec
(
fullname
)
self
.
assertIs
(
spec
,
None
)
class
Frozen_FindSpecTests
(
FindSpecTests
,
unittest
.
TestCase
):
init
=
frozen_init
machinery
=
frozen_machinery
class
Source_FindSpecTests
(
FindSpecTests
,
unittest
.
TestCase
):
init
=
source_init
machinery
=
source_machinery
class
ReloadTests
:
class
ReloadTests
:
"""Test module reloading for builtin and extension modules."""
"""Test module reloading for builtin and extension modules."""
...
@@ -484,8 +337,8 @@ class ReloadTests:
...
@@ -484,8 +337,8 @@ class ReloadTests:
# See #19851.
# See #19851.
name
=
'spam'
name
=
'spam'
subname
=
'ham'
subname
=
'ham'
with
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
with
util
.
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
submodule
(
name
,
subname
,
pkg_dir
)
fullname
,
_
=
util
.
submodule
(
name
,
subname
,
pkg_dir
)
ham
=
self
.
init
.
import_module
(
fullname
)
ham
=
self
.
init
.
import_module
(
fullname
)
reloaded
=
self
.
init
.
reload
(
ham
)
reloaded
=
self
.
init
.
reload
(
ham
)
self
.
assertIs
(
reloaded
,
ham
)
self
.
assertIs
(
reloaded
,
ham
)
...
...
Lib/test/test_importlib/test_util.py
Dosyayı görüntüle @
6029e086
from
importlib
import
util
from
importlib
import
util
from
.
import
util
as
test_util
from
.
import
util
as
test_util
frozen_init
,
source_init
=
test_util
.
import_importlib
(
'importlib'
)
frozen_machinery
,
source_machinery
=
test_util
.
import_importlib
(
'importlib.machinery'
)
frozen_util
,
source_util
=
test_util
.
import_importlib
(
'importlib.util'
)
frozen_util
,
source_util
=
test_util
.
import_importlib
(
'importlib.util'
)
import
os
import
os
...
@@ -310,6 +312,151 @@ Frozen_ResolveNameTests, Source_ResolveNameTests = test_util.test_both(
...
@@ -310,6 +312,151 @@ Frozen_ResolveNameTests, Source_ResolveNameTests = test_util.test_both(
util
=
[
frozen_util
,
source_util
])
util
=
[
frozen_util
,
source_util
])
class
FindSpecTests
:
class
FakeMetaFinder
:
@staticmethod
def
find_spec
(
name
,
path
=
None
,
target
=
None
):
return
name
,
path
,
target
def
test_sys_modules
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
loader
=
'a loader!'
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
loader
)
module
.
__loader__
=
loader
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
util
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_without___loader__
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
del
module
.
__loader__
loader
=
'a loader!'
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
loader
)
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
util
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_spec_is_None
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
module
.
__spec__
=
None
sys
.
modules
[
name
]
=
module
with
self
.
assertRaises
(
ValueError
):
self
.
util
.
find_spec
(
name
)
def
test_sys_modules_loader_is_None
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
spec
=
self
.
machinery
.
ModuleSpec
(
name
,
None
)
module
.
__spec__
=
spec
sys
.
modules
[
name
]
=
module
found
=
self
.
util
.
find_spec
(
name
)
self
.
assertEqual
(
found
,
spec
)
def
test_sys_modules_spec_is_not_set
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
module
=
types
.
ModuleType
(
name
)
try
:
del
module
.
__spec__
except
AttributeError
:
pass
sys
.
modules
[
name
]
=
module
with
self
.
assertRaises
(
ValueError
):
self
.
util
.
find_spec
(
name
)
def
test_success
(
self
):
name
=
'some_mod'
with
test_util
.
uncache
(
name
):
with
test_util
.
import_state
(
meta_path
=
[
self
.
FakeMetaFinder
]):
self
.
assertEqual
((
name
,
None
,
None
),
self
.
util
.
find_spec
(
name
))
# def test_success_path(self):
# # Searching on a path should work.
# name = 'some_mod'
# path = 'path to some place'
# with test_util.uncache(name):
# with test_util.import_state(meta_path=[self.FakeMetaFinder]):
# self.assertEqual((name, path, None),
# self.util.find_spec(name, path))
def
test_nothing
(
self
):
# None is returned upon failure to find a loader.
self
.
assertIsNone
(
self
.
util
.
find_spec
(
'nevergoingtofindthismodule'
))
def
test_find_submodule
(
self
):
name
=
'spam'
subname
=
'ham'
with
test_util
.
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
test_util
.
submodule
(
name
,
subname
,
pkg_dir
)
spec
=
self
.
util
.
find_spec
(
fullname
)
self
.
assertIsNot
(
spec
,
None
)
self
.
assertIn
(
name
,
sorted
(
sys
.
modules
))
self
.
assertNotIn
(
fullname
,
sorted
(
sys
.
modules
))
# Ensure successive calls behave the same.
spec_again
=
self
.
util
.
find_spec
(
fullname
)
self
.
assertEqual
(
spec_again
,
spec
)
def
test_find_submodule_parent_already_imported
(
self
):
name
=
'spam'
subname
=
'ham'
with
test_util
.
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
self
.
init
.
import_module
(
name
)
fullname
,
_
=
test_util
.
submodule
(
name
,
subname
,
pkg_dir
)
spec
=
self
.
util
.
find_spec
(
fullname
)
self
.
assertIsNot
(
spec
,
None
)
self
.
assertIn
(
name
,
sorted
(
sys
.
modules
))
self
.
assertNotIn
(
fullname
,
sorted
(
sys
.
modules
))
# Ensure successive calls behave the same.
spec_again
=
self
.
util
.
find_spec
(
fullname
)
self
.
assertEqual
(
spec_again
,
spec
)
def
test_find_relative_module
(
self
):
name
=
'spam'
subname
=
'ham'
with
test_util
.
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
test_util
.
submodule
(
name
,
subname
,
pkg_dir
)
relname
=
'.'
+
subname
spec
=
self
.
util
.
find_spec
(
relname
,
name
)
self
.
assertIsNot
(
spec
,
None
)
self
.
assertIn
(
name
,
sorted
(
sys
.
modules
))
self
.
assertNotIn
(
fullname
,
sorted
(
sys
.
modules
))
# Ensure successive calls behave the same.
spec_again
=
self
.
util
.
find_spec
(
fullname
)
self
.
assertEqual
(
spec_again
,
spec
)
def
test_find_relative_module_missing_package
(
self
):
name
=
'spam'
subname
=
'ham'
with
test_util
.
temp_module
(
name
,
pkg
=
True
)
as
pkg_dir
:
fullname
,
_
=
test_util
.
submodule
(
name
,
subname
,
pkg_dir
)
relname
=
'.'
+
subname
with
self
.
assertRaises
(
ValueError
):
self
.
util
.
find_spec
(
relname
)
self
.
assertNotIn
(
name
,
sorted
(
sys
.
modules
))
self
.
assertNotIn
(
fullname
,
sorted
(
sys
.
modules
))
class
Frozen_FindSpecTests
(
FindSpecTests
,
unittest
.
TestCase
):
init
=
frozen_init
machinery
=
frozen_machinery
util
=
frozen_util
class
Source_FindSpecTests
(
FindSpecTests
,
unittest
.
TestCase
):
init
=
source_init
machinery
=
source_machinery
util
=
source_util
class
MagicNumberTests
:
class
MagicNumberTests
:
def
test_length
(
self
):
def
test_length
(
self
):
...
...
Lib/test/test_importlib/util.py
Dosyayı görüntüle @
6029e086
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
importlib
import
util
from
importlib
import
util
,
invalidate_caches
import
os.path
import
os.path
from
test
import
support
from
test
import
support
import
unittest
import
unittest
...
@@ -46,6 +46,13 @@ def case_insensitive_tests(test):
...
@@ -46,6 +46,13 @@ def case_insensitive_tests(test):
"requires a case-insensitive filesystem"
)(
test
)
"requires a case-insensitive filesystem"
)(
test
)
def
submodule
(
parent
,
name
,
pkg_dir
,
content
=
''
):
path
=
os
.
path
.
join
(
pkg_dir
,
name
+
'.py'
)
with
open
(
path
,
'w'
)
as
subfile
:
subfile
.
write
(
content
)
return
'{}.{}'
.
format
(
parent
,
name
),
path
@contextmanager
@contextmanager
def
uncache
(
*
names
):
def
uncache
(
*
names
):
"""Uncache a module from sys.modules.
"""Uncache a module from sys.modules.
...
@@ -71,6 +78,31 @@ def uncache(*names):
...
@@ -71,6 +78,31 @@ def uncache(*names):
except
KeyError
:
except
KeyError
:
pass
pass
@contextmanager
def
temp_module
(
name
,
content
=
''
,
*
,
pkg
=
False
):
conflicts
=
[
n
for
n
in
sys
.
modules
if
n
.
partition
(
'.'
)[
0
]
==
name
]
with
support
.
temp_cwd
(
None
)
as
cwd
:
with
uncache
(
name
,
*
conflicts
):
with
support
.
DirsOnSysPath
(
cwd
):
invalidate_caches
()
location
=
os
.
path
.
join
(
cwd
,
name
)
if
pkg
:
modpath
=
os
.
path
.
join
(
location
,
'__init__.py'
)
os
.
mkdir
(
name
)
else
:
modpath
=
location
+
'.py'
if
content
is
None
:
# Make sure the module file gets created.
content
=
''
if
content
is
not
None
:
# not a namespace package
with
open
(
modpath
,
'w'
)
as
modfile
:
modfile
.
write
(
content
)
yield
location
@contextmanager
@contextmanager
def
import_state
(
**
kwargs
):
def
import_state
(
**
kwargs
):
"""Context manager to manage the various importers and stored state in the
"""Context manager to manage the various importers and stored state in the
...
...
Misc/NEWS
Dosyayı görüntüle @
6029e086
...
@@ -382,6 +382,9 @@ Library
...
@@ -382,6 +382,9 @@ Library
- Issue #15475: Add __sizeof__ implementations for itertools objects.
- Issue #15475: Add __sizeof__ implementations for itertools objects.
- Issue #19944: Fix importlib.find_spec() so it imports parents as needed
and move the function to importlib.util.
- Issue #19880: Fix a reference leak in unittest.TestCase. Explicitly break
- Issue #19880: Fix a reference leak in unittest.TestCase. Explicitly break
reference cycles between frames and the _Outcome instance.
reference cycles between frames and the _Outcome instance.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment