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
90a654b1
Kaydet (Commit)
90a654b1
authored
Kas 05, 2012
tarafından
Andrew Svetlov
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #15641: Clean up deprecated classes from importlib
Patch by Taras Lyapun.
üst
bcbf4036
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
7 additions
and
834 deletions
+7
-834
importlib.rst
Doc/library/importlib.rst
+0
-138
abc.py
Lib/importlib/abc.py
+0
-177
test_abc_loader.py
Lib/test/test_importlib/source/test_abc_loader.py
+3
-502
test_abc.py
Lib/test/test_importlib/test_abc.py
+1
-17
NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/importlib.rst
Dosyayı görüntüle @
90a654b1
...
...
@@ -133,8 +133,6 @@ ABC hierarchy::
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
+-- PyLoader (deprecated)
+-- PyPycLoader (deprecated)
.. class:: Finder
...
...
@@ -431,142 +429,6 @@ ABC hierarchy::
itself does not end in ``__init__``.
.. class:: PyLoader
An abstract base class inheriting from
:class:`ExecutionLoader` and
:class:`ResourceLoader` designed to ease the loading of
Python source modules (bytecode is not handled; see
:class:`SourceLoader` for a source/bytecode ABC). A subclass
implementing this ABC will only need to worry about exposing how the source
code is stored; all other details for loading Python source code will be
handled by the concrete implementations of key methods.
.. deprecated:: 3.2
This class has been deprecated in favor of :class:`SourceLoader` and is
slated for removal in Python 3.4. See below for how to create a
subclass that is compatible with Python 3.1 onwards.
If compatibility with Python 3.1 is required, then use the following idiom
to implement a subclass that will work with Python 3.1 onwards (make sure
to implement :meth:`ExecutionLoader.get_filename`)::
try:
from importlib.abc import SourceLoader
except ImportError:
from importlib.abc import PyLoader as SourceLoader
class CustomLoader(SourceLoader):
def get_filename(self, fullname):
"""Return the path to the source file."""
# Implement ...
def source_path(self, fullname):
"""Implement source_path in terms of get_filename."""
try:
return self.get_filename(fullname)
except ImportError:
return None
def is_package(self, fullname):
"""Implement is_package by looking for an __init__ file
name as returned by get_filename."""
filename = os.path.basename(self.get_filename(fullname))
return os.path.splitext(filename)[0] == '
__init__
'
.. method:: source_path(fullname)
An abstract method that returns the path to the source code for a
module. Should return ``None`` if there is no source code.
Raises :exc:`ImportError` if the loader knows it cannot handle the
module.
.. method:: get_filename(fullname)
A concrete implementation of
:meth:`importlib.abc.ExecutionLoader.get_filename` that
relies on :meth:`source_path`. If :meth:`source_path` returns
``None``, then :exc:`ImportError` is raised.
.. method:: load_module(fullname)
A concrete implementation of :meth:`importlib.abc.Loader.load_module`
that loads Python source code. All needed information comes from the
abstract methods required by this ABC. The only pertinent assumption
made by this method is that when loading a package
:attr:`__path__` is set to ``[os.path.dirname(__file__)]``.
.. method:: get_code(fullname)
A concrete implementation of
:meth:`importlib.abc.InspectLoader.get_code` that creates code objects
from Python source code, by requesting the source code (using
:meth:`source_path` and :meth:`get_data`) and compiling it with the
built-in :func:`compile` function.
.. method:: get_source(fullname)
A concrete implementation of
:meth:`importlib.abc.InspectLoader.get_source`. Uses
:meth:`importlib.abc.ResourceLoader.get_data` and :meth:`source_path`
to get the source code. It tries to guess the source encoding using
:func:`tokenize.detect_encoding`.
.. class:: PyPycLoader
An abstract base class inheriting from :class:`PyLoader`.
This ABC is meant to help in creating loaders that support both Python
source and bytecode.
.. deprecated:: 3.2
This class has been deprecated in favor of :class:`SourceLoader` and to
properly support :pep:`3147`. If compatibility is required with
Python 3.1, implement both :class:`SourceLoader` and :class:`PyLoader`;
instructions on how to do so are included in the documentation for
:class:`PyLoader`. Do note that this solution will not support
sourceless/bytecode-only loading; only source *and* bytecode loading.
.. versionchanged:: 3.3
Updated to parse (but not use) the new source size field in bytecode
files when reading and to write out the field properly when writing.
.. method:: source_mtime(fullname)
An abstract method which returns the modification time for the source
code of the specified module. The modification time should be an
integer. If there is no source code, return ``None``. If the
module cannot be found then :exc:`ImportError` is raised.
.. method:: bytecode_path(fullname)
An abstract method which returns the path to the bytecode for the
specified module, if it exists. It returns ``None``
if no bytecode exists (yet).
Raises :exc:`ImportError` if the loader knows it cannot handle the
module.
.. method:: get_filename(fullname)
A concrete implementation of
:meth:`ExecutionLoader.get_filename` that relies on
:meth:`PyLoader.source_path` and :meth:`bytecode_path`.
If :meth:`source_path` returns a path, then that value is returned.
Else if :meth:`bytecode_path` returns a path, that path will be
returned. If a path is not available from both methods,
:exc:`ImportError` is raised.
.. method:: write_bytecode(fullname, bytecode)
An abstract method which has the loader write *bytecode* for future
use. If the bytecode is written, return ``True``. Return
``False`` if the bytecode could not be written. This method
should not be called if :data:`sys.dont_write_bytecode` is true.
The *bytecode* argument should be a bytes string or bytes array.
:mod:`importlib.machinery` -- Importers and path hooks
------------------------------------------------------
...
...
Lib/importlib/abc.py
Dosyayı görüntüle @
90a654b1
...
...
@@ -225,180 +225,3 @@ class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader):
raise
NotImplementedError
_register
(
SourceLoader
,
machinery
.
SourceFileLoader
)
class
PyLoader
(
SourceLoader
):
"""Implement the deprecated PyLoader ABC in terms of SourceLoader.
This class has been deprecated! It is slated for removal in Python 3.4.
If compatibility with Python 3.1 is not needed then implement the
SourceLoader ABC instead of this class. If Python 3.1 compatibility is
needed, then use the following idiom to have a single class that is
compatible with Python 3.1 onwards::
try:
from importlib.abc import SourceLoader
except ImportError:
from importlib.abc import PyLoader as SourceLoader
class CustomLoader(SourceLoader):
def get_filename(self, fullname):
# Implement ...
def source_path(self, fullname):
'''Implement source_path in terms of get_filename.'''
try:
return self.get_filename(fullname)
except ImportError:
return None
def is_package(self, fullname):
filename = os.path.basename(self.get_filename(fullname))
return os.path.splitext(filename)[0] == '__init__'
"""
@abc.abstractmethod
def
is_package
(
self
,
fullname
):
raise
NotImplementedError
@abc.abstractmethod
def
source_path
(
self
,
fullname
):
"""Abstract method. Accepts a str module name and returns the path to
the source code for the module."""
raise
NotImplementedError
def
get_filename
(
self
,
fullname
):
"""Implement get_filename in terms of source_path.
As get_filename should only return a source file path there is no
chance of the path not existing but loading still being possible, so
ImportError should propagate instead of being turned into returning
None.
"""
warnings
.
warn
(
"importlib.abc.PyLoader is deprecated and is "
"slated for removal in Python 3.4; "
"use SourceLoader instead. "
"See the importlib documentation on how to be "
"compatible with Python 3.1 onwards."
,
DeprecationWarning
)
path
=
self
.
source_path
(
fullname
)
if
path
is
None
:
raise
ImportError
(
name
=
fullname
)
else
:
return
path
class
PyPycLoader
(
PyLoader
):
"""Abstract base class to assist in loading source and bytecode by
requiring only back-end storage methods to be implemented.
This class has been deprecated! Removal is slated for Python 3.4. Implement
the SourceLoader ABC instead. If Python 3.1 compatibility is needed, see
PyLoader.
The methods get_code, get_source, and load_module are implemented for the
user.
"""
def
get_filename
(
self
,
fullname
):
"""Return the source or bytecode file path."""
path
=
self
.
source_path
(
fullname
)
if
path
is
not
None
:
return
path
path
=
self
.
bytecode_path
(
fullname
)
if
path
is
not
None
:
return
path
raise
ImportError
(
"no source or bytecode path available for "
"{0!r}"
.
format
(
fullname
),
name
=
fullname
)
def
get_code
(
self
,
fullname
):
"""Get a code object from source or bytecode."""
warnings
.
warn
(
"importlib.abc.PyPycLoader is deprecated and slated for "
"removal in Python 3.4; use SourceLoader instead. "
"If Python 3.1 compatibility is required, see the "
"latest documentation for PyLoader."
,
DeprecationWarning
)
source_timestamp
=
self
.
source_mtime
(
fullname
)
# Try to use bytecode if it is available.
bytecode_path
=
self
.
bytecode_path
(
fullname
)
if
bytecode_path
:
data
=
self
.
get_data
(
bytecode_path
)
try
:
magic
=
data
[:
4
]
if
len
(
magic
)
<
4
:
raise
ImportError
(
"bad magic number in {}"
.
format
(
fullname
),
name
=
fullname
,
path
=
bytecode_path
)
raw_timestamp
=
data
[
4
:
8
]
if
len
(
raw_timestamp
)
<
4
:
raise
EOFError
(
"bad timestamp in {}"
.
format
(
fullname
))
pyc_timestamp
=
_bootstrap
.
_r_long
(
raw_timestamp
)
raw_source_size
=
data
[
8
:
12
]
if
len
(
raw_source_size
)
!=
4
:
raise
EOFError
(
"bad file size in {}"
.
format
(
fullname
))
# Source size is unused as the ABC does not provide a way to
# get the size of the source ahead of reading it.
bytecode
=
data
[
12
:]
# Verify that the magic number is valid.
if
imp
.
get_magic
()
!=
magic
:
raise
ImportError
(
"bad magic number in {}"
.
format
(
fullname
),
name
=
fullname
,
path
=
bytecode_path
)
# Verify that the bytecode is not stale (only matters when
# there is source to fall back on.
if
source_timestamp
:
if
pyc_timestamp
<
source_timestamp
:
raise
ImportError
(
"bytecode is stale"
,
name
=
fullname
,
path
=
bytecode_path
)
except
(
ImportError
,
EOFError
):
# If source is available give it a shot.
if
source_timestamp
is
not
None
:
pass
else
:
raise
else
:
# Bytecode seems fine, so try to use it.
return
marshal
.
loads
(
bytecode
)
elif
source_timestamp
is
None
:
raise
ImportError
(
"no source or bytecode available to create code "
"object for {0!r}"
.
format
(
fullname
),
name
=
fullname
)
# Use the source.
source_path
=
self
.
source_path
(
fullname
)
if
source_path
is
None
:
message
=
"a source path must exist to load {0}"
.
format
(
fullname
)
raise
ImportError
(
message
,
name
=
fullname
)
source
=
self
.
get_data
(
source_path
)
code_object
=
compile
(
source
,
source_path
,
'exec'
,
dont_inherit
=
True
)
# Generate bytecode and write it out.
if
not
sys
.
dont_write_bytecode
:
data
=
bytearray
(
imp
.
get_magic
())
data
.
extend
(
_bootstrap
.
_w_long
(
source_timestamp
))
data
.
extend
(
_bootstrap
.
_w_long
(
len
(
source
)
&
0xFFFFFFFF
))
data
.
extend
(
marshal
.
dumps
(
code_object
))
self
.
write_bytecode
(
fullname
,
data
)
return
code_object
@abc.abstractmethod
def
source_mtime
(
self
,
fullname
):
"""Abstract method. Accepts a str filename and returns an int
modification time for the source of the module."""
raise
NotImplementedError
@abc.abstractmethod
def
bytecode_path
(
self
,
fullname
):
"""Abstract method. Accepts a str filename and returns the str pathname
to the bytecode for the module."""
raise
NotImplementedError
@abc.abstractmethod
def
write_bytecode
(
self
,
fullname
,
bytecode
):
"""Abstract method. Accepts a str filename and bytes object
representing the bytecode for the module. Returns a boolean
representing whether the bytecode was written or not."""
raise
NotImplementedError
Lib/test/test_importlib/source/test_abc_loader.py
Dosyayı görüntüle @
90a654b1
...
...
@@ -70,483 +70,9 @@ class SourceLoaderMock(SourceOnlyLoaderMock):
return
path
==
self
.
bytecode_path
class
PyLoaderMock
(
abc
.
PyLoader
):
# Globals that should be defined for all modules.
source
=
(
b
"_ = '::'.join([__name__, __file__, __package__, "
b
"repr(__loader__)])"
)
def
__init__
(
self
,
data
):
"""Take a dict of 'module_name: path' pairings.
Paths should have no file extension, allowing packages to be denoted by
ending in '__init__'.
"""
self
.
module_paths
=
data
self
.
path_to_module
=
{
val
:
key
for
key
,
val
in
data
.
items
()}
def
get_data
(
self
,
path
):
if
path
not
in
self
.
path_to_module
:
raise
IOError
return
self
.
source
def
is_package
(
self
,
name
):
filename
=
os
.
path
.
basename
(
self
.
get_filename
(
name
))
return
os
.
path
.
splitext
(
filename
)[
0
]
==
'__init__'
def
source_path
(
self
,
name
):
try
:
return
self
.
module_paths
[
name
]
except
KeyError
:
raise
ImportError
def
get_filename
(
self
,
name
):
"""Silence deprecation warning."""
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
warnings
.
simplefilter
(
"always"
)
path
=
super
()
.
get_filename
(
name
)
assert
len
(
w
)
==
1
assert
issubclass
(
w
[
0
]
.
category
,
DeprecationWarning
)
return
path
def
module_repr
(
self
):
return
'<module>'
class
PyLoaderCompatMock
(
PyLoaderMock
):
"""Mock that matches what is suggested to have a loader that is compatible
from Python 3.1 onwards."""
def
get_filename
(
self
,
fullname
):
try
:
return
self
.
module_paths
[
fullname
]
except
KeyError
:
raise
ImportError
def
source_path
(
self
,
fullname
):
try
:
return
self
.
get_filename
(
fullname
)
except
ImportError
:
return
None
class
PyPycLoaderMock
(
abc
.
PyPycLoader
,
PyLoaderMock
):
default_mtime
=
1
def
__init__
(
self
,
source
,
bc
=
{}):
"""Initialize mock.
'bc' is a dict keyed on a module's name. The value is dict with
possible keys of 'path', 'mtime', 'magic', and 'bc'. Except for 'path',
each of those keys control if any part of created bytecode is to
deviate from default values.
"""
super
()
.
__init__
(
source
)
self
.
module_bytecode
=
{}
self
.
path_to_bytecode
=
{}
self
.
bytecode_to_path
=
{}
for
name
,
data
in
bc
.
items
():
self
.
path_to_bytecode
[
data
[
'path'
]]
=
name
self
.
bytecode_to_path
[
name
]
=
data
[
'path'
]
magic
=
data
.
get
(
'magic'
,
imp
.
get_magic
())
mtime
=
importlib
.
_w_long
(
data
.
get
(
'mtime'
,
self
.
default_mtime
))
source_size
=
importlib
.
_w_long
(
len
(
self
.
source
)
&
0xFFFFFFFF
)
if
'bc'
in
data
:
bc
=
data
[
'bc'
]
else
:
bc
=
self
.
compile_bc
(
name
)
self
.
module_bytecode
[
name
]
=
magic
+
mtime
+
source_size
+
bc
def
compile_bc
(
self
,
name
):
source_path
=
self
.
module_paths
.
get
(
name
,
'<test>'
)
or
'<test>'
code
=
compile
(
self
.
source
,
source_path
,
'exec'
)
return
marshal
.
dumps
(
code
)
def
source_mtime
(
self
,
name
):
if
name
in
self
.
module_paths
:
return
self
.
default_mtime
elif
name
in
self
.
module_bytecode
:
return
None
else
:
raise
ImportError
def
bytecode_path
(
self
,
name
):
try
:
return
self
.
bytecode_to_path
[
name
]
except
KeyError
:
if
name
in
self
.
module_paths
:
return
None
else
:
raise
ImportError
def
write_bytecode
(
self
,
name
,
bytecode
):
self
.
module_bytecode
[
name
]
=
bytecode
return
True
def
get_data
(
self
,
path
):
if
path
in
self
.
path_to_module
:
return
super
()
.
get_data
(
path
)
elif
path
in
self
.
path_to_bytecode
:
name
=
self
.
path_to_bytecode
[
path
]
return
self
.
module_bytecode
[
name
]
else
:
raise
IOError
def
is_package
(
self
,
name
):
try
:
return
super
()
.
is_package
(
name
)
except
TypeError
:
return
'__init__'
in
self
.
bytecode_to_path
[
name
]
def
get_code
(
self
,
name
):
with
warnings
.
catch_warnings
(
record
=
True
)
as
w
:
warnings
.
simplefilter
(
"always"
)
code_object
=
super
()
.
get_code
(
name
)
assert
len
(
w
)
==
1
assert
issubclass
(
w
[
0
]
.
category
,
DeprecationWarning
)
return
code_object
class
PyLoaderTests
(
testing_abc
.
LoaderTests
):
"""Tests for importlib.abc.PyLoader."""
mocker
=
PyLoaderMock
def
eq_attrs
(
self
,
ob
,
**
kwargs
):
for
attr
,
val
in
kwargs
.
items
():
found
=
getattr
(
ob
,
attr
)
self
.
assertEqual
(
found
,
val
,
"{} attribute: {} != {}"
.
format
(
attr
,
found
,
val
))
def
test_module
(
self
):
name
=
'<module>'
path
=
os
.
path
.
join
(
''
,
'path'
,
'to'
,
'module'
)
mock
=
self
.
mocker
({
name
:
path
})
with
util
.
uncache
(
name
):
module
=
mock
.
load_module
(
name
)
self
.
assertIn
(
name
,
sys
.
modules
)
self
.
eq_attrs
(
module
,
__name__
=
name
,
__file__
=
path
,
__package__
=
''
,
__loader__
=
mock
)
self
.
assertTrue
(
not
hasattr
(
module
,
'__path__'
))
return
mock
,
name
def
test_package
(
self
):
name
=
'<pkg>'
path
=
os
.
path
.
join
(
'path'
,
'to'
,
name
,
'__init__'
)
mock
=
self
.
mocker
({
name
:
path
})
with
util
.
uncache
(
name
):
module
=
mock
.
load_module
(
name
)
self
.
assertIn
(
name
,
sys
.
modules
)
self
.
eq_attrs
(
module
,
__name__
=
name
,
__file__
=
path
,
__path__
=
[
os
.
path
.
dirname
(
path
)],
__package__
=
name
,
__loader__
=
mock
)
return
mock
,
name
def
test_lacking_parent
(
self
):
name
=
'pkg.mod'
path
=
os
.
path
.
join
(
'path'
,
'to'
,
'pkg'
,
'mod'
)
mock
=
self
.
mocker
({
name
:
path
})
with
util
.
uncache
(
name
):
module
=
mock
.
load_module
(
name
)
self
.
assertIn
(
name
,
sys
.
modules
)
self
.
eq_attrs
(
module
,
__name__
=
name
,
__file__
=
path
,
__package__
=
'pkg'
,
__loader__
=
mock
)
self
.
assertFalse
(
hasattr
(
module
,
'__path__'
))
return
mock
,
name
def
test_module_reuse
(
self
):
name
=
'mod'
path
=
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)
module
=
imp
.
new_module
(
name
)
mock
=
self
.
mocker
({
name
:
path
})
with
util
.
uncache
(
name
):
sys
.
modules
[
name
]
=
module
loaded_module
=
mock
.
load_module
(
name
)
self
.
assertIs
(
loaded_module
,
module
)
self
.
assertIs
(
sys
.
modules
[
name
],
module
)
return
mock
,
name
def
test_state_after_failure
(
self
):
name
=
"mod"
module
=
imp
.
new_module
(
name
)
module
.
blah
=
None
mock
=
self
.
mocker
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)})
mock
.
source
=
b
"1/0"
with
util
.
uncache
(
name
):
sys
.
modules
[
name
]
=
module
with
self
.
assertRaises
(
ZeroDivisionError
):
mock
.
load_module
(
name
)
self
.
assertIs
(
sys
.
modules
[
name
],
module
)
self
.
assertTrue
(
hasattr
(
module
,
'blah'
))
return
mock
def
test_unloadable
(
self
):
name
=
"mod"
mock
=
self
.
mocker
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)})
mock
.
source
=
b
"1/0"
with
util
.
uncache
(
name
):
with
self
.
assertRaises
(
ZeroDivisionError
):
mock
.
load_module
(
name
)
self
.
assertNotIn
(
name
,
sys
.
modules
)
return
mock
class
PyLoaderCompatTests
(
PyLoaderTests
):
"""Test that the suggested code to make a loader that is compatible from
Python 3.1 forward works."""
mocker
=
PyLoaderCompatMock
class
PyLoaderInterfaceTests
(
unittest
.
TestCase
):
"""Tests for importlib.abc.PyLoader to make sure that when source_path()
doesn't return a path everything works as expected."""
def
test_no_source_path
(
self
):
# No source path should lead to ImportError.
name
=
'mod'
mock
=
PyLoaderMock
({})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
):
mock
.
load_module
(
name
)
def
test_source_path_is_None
(
self
):
name
=
'mod'
mock
=
PyLoaderMock
({
name
:
None
})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
):
mock
.
load_module
(
name
)
def
test_get_filename_with_source_path
(
self
):
# get_filename() should return what source_path() returns.
name
=
'mod'
path
=
os
.
path
.
join
(
'path'
,
'to'
,
'source'
)
mock
=
PyLoaderMock
({
name
:
path
})
with
util
.
uncache
(
name
):
self
.
assertEqual
(
mock
.
get_filename
(
name
),
path
)
def
test_get_filename_no_source_path
(
self
):
# get_filename() should raise ImportError if source_path returns None.
name
=
'mod'
mock
=
PyLoaderMock
({
name
:
None
})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
):
mock
.
get_filename
(
name
)
class
PyPycLoaderTests
(
PyLoaderTests
):
"""Tests for importlib.abc.PyPycLoader."""
mocker
=
PyPycLoaderMock
@source_util.writes_bytecode_files
def
verify_bytecode
(
self
,
mock
,
name
):
assert
name
in
mock
.
module_paths
self
.
assertIn
(
name
,
mock
.
module_bytecode
)
magic
=
mock
.
module_bytecode
[
name
][:
4
]
self
.
assertEqual
(
magic
,
imp
.
get_magic
())
mtime
=
importlib
.
_r_long
(
mock
.
module_bytecode
[
name
][
4
:
8
])
self
.
assertEqual
(
mtime
,
1
)
source_size
=
mock
.
module_bytecode
[
name
][
8
:
12
]
self
.
assertEqual
(
len
(
mock
.
source
)
&
0xFFFFFFFF
,
importlib
.
_r_long
(
source_size
))
bc
=
mock
.
module_bytecode
[
name
][
12
:]
self
.
assertEqual
(
bc
,
mock
.
compile_bc
(
name
))
def
test_module
(
self
):
mock
,
name
=
super
()
.
test_module
()
self
.
verify_bytecode
(
mock
,
name
)
def
test_package
(
self
):
mock
,
name
=
super
()
.
test_package
()
self
.
verify_bytecode
(
mock
,
name
)
def
test_lacking_parent
(
self
):
mock
,
name
=
super
()
.
test_lacking_parent
()
self
.
verify_bytecode
(
mock
,
name
)
def
test_module_reuse
(
self
):
mock
,
name
=
super
()
.
test_module_reuse
()
self
.
verify_bytecode
(
mock
,
name
)
def
test_state_after_failure
(
self
):
super
()
.
test_state_after_failure
()
def
test_unloadable
(
self
):
super
()
.
test_unloadable
()
class
PyPycLoaderInterfaceTests
(
unittest
.
TestCase
):
"""Test for the interface of importlib.abc.PyPycLoader."""
def
get_filename_check
(
self
,
src_path
,
bc_path
,
expect
):
name
=
'mod'
mock
=
PyPycLoaderMock
({
name
:
src_path
},
{
name
:
{
'path'
:
bc_path
}})
with
util
.
uncache
(
name
):
assert
mock
.
source_path
(
name
)
==
src_path
assert
mock
.
bytecode_path
(
name
)
==
bc_path
self
.
assertEqual
(
mock
.
get_filename
(
name
),
expect
)
def
test_filename_with_source_bc
(
self
):
# When source and bytecode paths present, return the source path.
self
.
get_filename_check
(
'source_path'
,
'bc_path'
,
'source_path'
)
def
test_filename_with_source_no_bc
(
self
):
# With source but no bc, return source path.
self
.
get_filename_check
(
'source_path'
,
None
,
'source_path'
)
def
test_filename_with_no_source_bc
(
self
):
# With not source but bc, return the bc path.
self
.
get_filename_check
(
None
,
'bc_path'
,
'bc_path'
)
def
test_filename_with_no_source_or_bc
(
self
):
# With no source or bc, raise ImportError.
name
=
'mod'
mock
=
PyPycLoaderMock
({
name
:
None
},
{
name
:
{
'path'
:
None
}})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
):
mock
.
get_filename
(
name
)
class
SkipWritingBytecodeTests
(
unittest
.
TestCase
):
"""Test that bytecode is properly handled based on
sys.dont_write_bytecode."""
@source_util.writes_bytecode_files
def
run_test
(
self
,
dont_write_bytecode
):
name
=
'mod'
mock
=
PyPycLoaderMock
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)})
sys
.
dont_write_bytecode
=
dont_write_bytecode
with
util
.
uncache
(
name
):
mock
.
load_module
(
name
)
self
.
assertIsNot
(
name
in
mock
.
module_bytecode
,
dont_write_bytecode
)
def
test_no_bytecode_written
(
self
):
self
.
run_test
(
True
)
def
test_bytecode_written
(
self
):
self
.
run_test
(
False
)
class
RegeneratedBytecodeTests
(
unittest
.
TestCase
):
"""Test that bytecode is regenerated as expected."""
@source_util.writes_bytecode_files
def
test_different_magic
(
self
):
# A different magic number should lead to new bytecode.
name
=
'mod'
bad_magic
=
b
'
\x00\x00\x00\x00
'
assert
bad_magic
!=
imp
.
get_magic
()
mock
=
PyPycLoaderMock
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)},
{
name
:
{
'path'
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod.bytecode'
),
'magic'
:
bad_magic
}})
with
util
.
uncache
(
name
):
mock
.
load_module
(
name
)
self
.
assertIn
(
name
,
mock
.
module_bytecode
)
magic
=
mock
.
module_bytecode
[
name
][:
4
]
self
.
assertEqual
(
magic
,
imp
.
get_magic
())
@source_util.writes_bytecode_files
def
test_old_mtime
(
self
):
# Bytecode with an older mtime should be regenerated.
name
=
'mod'
old_mtime
=
PyPycLoaderMock
.
default_mtime
-
1
mock
=
PyPycLoaderMock
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)},
{
name
:
{
'path'
:
'path/to/mod.bytecode'
,
'mtime'
:
old_mtime
}})
with
util
.
uncache
(
name
):
mock
.
load_module
(
name
)
self
.
assertIn
(
name
,
mock
.
module_bytecode
)
mtime
=
importlib
.
_r_long
(
mock
.
module_bytecode
[
name
][
4
:
8
])
self
.
assertEqual
(
mtime
,
PyPycLoaderMock
.
default_mtime
)
class
BadBytecodeFailureTests
(
unittest
.
TestCase
):
"""Test import failures when there is no source and parts of the bytecode
is bad."""
def
test_bad_magic
(
self
):
# A bad magic number should lead to an ImportError.
name
=
'mod'
bad_magic
=
b
'
\x00\x00\x00\x00
'
bc
=
{
name
:
{
'path'
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
),
'magic'
:
bad_magic
}}
mock
=
PyPycLoaderMock
({
name
:
None
},
bc
)
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
)
as
cm
:
mock
.
load_module
(
name
)
self
.
assertEqual
(
cm
.
exception
.
name
,
name
)
def
test_no_bytecode
(
self
):
# Missing code object bytecode should lead to an EOFError.
name
=
'mod'
bc
=
{
name
:
{
'path'
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
),
'bc'
:
b
''
}}
mock
=
PyPycLoaderMock
({
name
:
None
},
bc
)
with
util
.
uncache
(
name
),
self
.
assertRaises
(
EOFError
):
mock
.
load_module
(
name
)
def
test_bad_bytecode
(
self
):
# Malformed code object bytecode should lead to a ValueError.
name
=
'mod'
bc
=
{
name
:
{
'path'
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
),
'bc'
:
b
'1234'
}}
mock
=
PyPycLoaderMock
({
name
:
None
},
bc
)
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ValueError
):
mock
.
load_module
(
name
)
def
raise_ImportError
(
*
args
,
**
kwargs
):
raise
ImportError
class
MissingPathsTests
(
unittest
.
TestCase
):
"""Test what happens when a source or bytecode path does not exist (either
from *_path returning None or raising ImportError)."""
def
test_source_path_None
(
self
):
# Bytecode should be used when source_path returns None, along with
# __file__ being set to the bytecode path.
name
=
'mod'
bytecode_path
=
'path/to/mod'
mock
=
PyPycLoaderMock
({
name
:
None
},
{
name
:
{
'path'
:
bytecode_path
}})
with
util
.
uncache
(
name
):
module
=
mock
.
load_module
(
name
)
self
.
assertEqual
(
module
.
__file__
,
bytecode_path
)
# Testing for bytecode_path returning None handled by all tests where no
# bytecode initially exists.
def
test_all_paths_None
(
self
):
# If all *_path methods return None, raise ImportError.
name
=
'mod'
mock
=
PyPycLoaderMock
({
name
:
None
})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
)
as
cm
:
mock
.
load_module
(
name
)
self
.
assertEqual
(
cm
.
exception
.
name
,
name
)
def
test_source_path_ImportError
(
self
):
# An ImportError from source_path should trigger an ImportError.
name
=
'mod'
mock
=
PyPycLoaderMock
({},
{
name
:
{
'path'
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)}})
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
):
mock
.
load_module
(
name
)
def
test_bytecode_path_ImportError
(
self
):
# An ImportError from bytecode_path should trigger an ImportError.
name
=
'mod'
mock
=
PyPycLoaderMock
({
name
:
os
.
path
.
join
(
'path'
,
'to'
,
'mod'
)})
bad_meth
=
types
.
MethodType
(
raise_ImportError
,
mock
)
mock
.
bytecode_path
=
bad_meth
with
util
.
uncache
(
name
),
self
.
assertRaises
(
ImportError
)
as
cm
:
mock
.
load_module
(
name
)
class
SourceLoaderTestHarness
(
unittest
.
TestCase
):
...
...
@@ -801,6 +327,7 @@ class AbstractMethodImplTests(unittest.TestCase):
class
Loader
(
abc
.
Loader
):
def
load_module
(
self
,
fullname
):
super
()
.
load_module
(
fullname
)
def
module_repr
(
self
,
module
):
super
()
.
module_repr
(
module
)
...
...
@@ -825,20 +352,6 @@ class AbstractMethodImplTests(unittest.TestCase):
class
SourceLoader
(
ResourceLoader
,
ExecutionLoader
,
abc
.
SourceLoader
):
pass
class
PyLoader
(
ResourceLoader
,
InspectLoader
,
abc
.
PyLoader
):
def
source_path
(
self
,
_
):
super
()
.
source_path
(
_
)
class
PyPycLoader
(
PyLoader
,
abc
.
PyPycLoader
):
def
bytecode_path
(
self
,
_
):
super
()
.
bytecode_path
(
_
)
def
source_mtime
(
self
,
_
):
super
()
.
source_mtime
(
_
)
def
write_bytecode
(
self
,
_
,
_2
):
super
()
.
write_bytecode
(
_
,
_2
)
def
raises_NotImplementedError
(
self
,
ins
,
*
args
):
for
method_name
in
args
:
method
=
getattr
(
ins
,
method_name
)
...
...
@@ -877,24 +390,12 @@ class AbstractMethodImplTests(unittest.TestCase):
# Required abstractmethods.
self
.
raises_NotImplementedError
(
ins
,
'get_filename'
,
'get_data'
)
# Optional abstractmethods.
self
.
raises_NotImplementedError
(
ins
,
'path_stats'
,
'set_data'
)
def
test_PyLoader
(
self
):
self
.
raises_NotImplementedError
(
self
.
PyLoader
(),
'source_path'
,
'get_data'
,
'is_package'
)
def
test_PyPycLoader
(
self
):
self
.
raises_NotImplementedError
(
self
.
PyPycLoader
(),
'source_path'
,
'source_mtime'
,
'bytecode_path'
,
'write_bytecode'
)
self
.
raises_NotImplementedError
(
ins
,
'path_stats'
,
'set_data'
)
def
test_main
():
from
test.support
import
run_unittest
run_unittest
(
PyLoaderTests
,
PyLoaderCompatTests
,
PyLoaderInterfaceTests
,
PyPycLoaderTests
,
PyPycLoaderInterfaceTests
,
SkipWritingBytecodeTests
,
RegeneratedBytecodeTests
,
run_unittest
(
SkipWritingBytecodeTests
,
RegeneratedBytecodeTests
,
BadBytecodeFailureTests
,
MissingPathsTests
,
SourceOnlyLoaderTests
,
SourceLoaderBytecodeTests
,
...
...
Lib/test/test_importlib/test_abc.py
Dosyayı görüntüle @
90a654b1
...
...
@@ -43,11 +43,6 @@ class PathEntryFinder(InheritanceTests, unittest.TestCase):
subclasses
=
[
machinery
.
FileFinder
]
class
Loader
(
InheritanceTests
,
unittest
.
TestCase
):
subclasses
=
[
abc
.
PyLoader
]
class
ResourceLoader
(
InheritanceTests
,
unittest
.
TestCase
):
superclasses
=
[
abc
.
Loader
]
...
...
@@ -56,14 +51,13 @@ class ResourceLoader(InheritanceTests, unittest.TestCase):
class
InspectLoader
(
InheritanceTests
,
unittest
.
TestCase
):
superclasses
=
[
abc
.
Loader
]
subclasses
=
[
abc
.
PyLoader
,
machinery
.
BuiltinImporter
,
subclasses
=
[
machinery
.
BuiltinImporter
,
machinery
.
FrozenImporter
,
machinery
.
ExtensionFileLoader
]
class
ExecutionLoader
(
InheritanceTests
,
unittest
.
TestCase
):
superclasses
=
[
abc
.
InspectLoader
]
subclasses
=
[
abc
.
PyLoader
]
class
FileLoader
(
InheritanceTests
,
unittest
.
TestCase
):
...
...
@@ -78,16 +72,6 @@ class SourceLoader(InheritanceTests, unittest.TestCase):
subclasses
=
[
machinery
.
SourceFileLoader
]
class
PyLoader
(
InheritanceTests
,
unittest
.
TestCase
):
superclasses
=
[
abc
.
Loader
,
abc
.
ResourceLoader
,
abc
.
ExecutionLoader
]
class
PyPycLoader
(
InheritanceTests
,
unittest
.
TestCase
):
superclasses
=
[
abc
.
PyLoader
]
def
test_main
():
from
test.support
import
run_unittest
classes
=
[]
...
...
Misc/NEWS
Dosyayı görüntüle @
90a654b1
...
...
@@ -107,6 +107,9 @@ Core and Builtins
Library
-------
- Issue #15641: Clean up deprecated classes from importlib
Patch by Taras Lyapun.
- Issue #16350: zlib.Decompress.decompress() now accumulates data from
successive calls after EOF in unused_data, instead of only saving the argument
to the last call. Patch by Serhiy Storchaka.
...
...
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