Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 035a100

Browse files
committed
Issue #26667: Add path-like object support to importlib.util.
1 parent d5f9223 commit 035a100

7 files changed

Lines changed: 2219 additions & 2167 deletions

File tree

Doc/library/importlib.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,9 @@ an :term:`importer`.
11491149
The *optimization* parameter was added and the *debug_override* parameter
11501150
was deprecated.
11511151

1152+
.. versionchanged:: 3.6
1153+
Accepts a :term:`path-like object`.
1154+
11521155

11531156
.. function:: source_from_cache(path)
11541157

@@ -1162,6 +1165,9 @@ an :term:`importer`.
11621165

11631166
.. versionadded:: 3.4
11641167

1168+
.. versionchanged:: 3.6
1169+
Accepts a :term:`path-like object`.
1170+
11651171
.. function:: decode_source(source_bytes)
11661172

11671173
Decode the given bytes representing source code and return it as a string
@@ -1298,6 +1304,9 @@ an :term:`importer`.
12981304

12991305
.. versionadded:: 3.4
13001306

1307+
.. versionchanged:: 3.6
1308+
Accepts a :term:`path-like object`.
1309+
13011310
.. class:: LazyLoader(loader)
13021311

13031312
A class which postpones the execution of the loader of a module until the

Doc/whatsnew/3.6.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ New syntax features:
6868

6969
Standard library improvements:
7070

71-
* PEP 519: :ref:`Adding a file system path protocol <pep-519>`
72-
7371
Security improvements:
7472

7573
* On Linux, :func:`os.urandom` now blocks until the system urandom entropy pool
@@ -513,6 +511,11 @@ restriction that :class:`importlib.machinery.BuiltinImporter` and
513511
:class:`importlib.machinery.ExtensionFileLoader` couldn't be used with
514512
:class:`importlib.util.LazyLoader`.
515513

514+
:func:`importlib.util.cache_from_source`,
515+
:func:`importlib.util.source_from_cache`, and
516+
:func:`importlib.util.spec_from_file_location` now accept a
517+
:term:`path-like object`.
518+
516519

517520
os
518521
--
@@ -528,6 +531,11 @@ The Linux ``getrandom()`` syscall (get random bytes) is now exposed as the new
528531
:func:`os.getrandom` function.
529532
(Contributed by Victor Stinner, part of the :pep:`524`)
530533

534+
See the summary for :ref:`PEP 519 <pep-519>` for details on how the
535+
:mod:`os` and :mod:`os.path` modules now support
536+
:term:`path-like objects <path-like object>`.
537+
538+
531539
pickle
532540
------
533541

Lib/importlib/_bootstrap_external.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ def cache_from_source(path, debug_override=None, *, optimization=None):
279279
message = 'debug_override or optimization must be set to None'
280280
raise TypeError(message)
281281
optimization = '' if debug_override else 1
282+
path = _os.fspath(path)
282283
head, tail = _path_split(path)
283284
base, sep, rest = tail.rpartition('.')
284285
tag = sys.implementation.cache_tag
@@ -309,6 +310,7 @@ def source_from_cache(path):
309310
"""
310311
if sys.implementation.cache_tag is None:
311312
raise NotImplementedError('sys.implementation.cache_tag is None')
313+
path = _os.fspath(path)
312314
head, pycache_filename = _path_split(path)
313315
head, pycache = _path_split(head)
314316
if pycache != _PYCACHE:
@@ -536,6 +538,8 @@ def spec_from_file_location(name, location=None, *, loader=None,
536538
location = loader.get_filename(name)
537539
except ImportError:
538540
pass
541+
else:
542+
location = _os.fspath(location)
539543

540544
# If the location is on the filesystem, but doesn't actually exist,
541545
# we could return None here, indicating that the location is not

Lib/test/test_importlib/test_spec.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
util = test_util.import_importlib('importlib.util')
66

77
import os.path
8+
import pathlib
89
from test.support import CleanImport
910
import unittest
1011
import sys
@@ -659,6 +660,11 @@ def test_spec_from_file_location_default(self):
659660
self.assertEqual(spec.cached, self.cached)
660661
self.assertTrue(spec.has_location)
661662

663+
def test_spec_from_file_location_path_like_arg(self):
664+
spec = self.util.spec_from_file_location(self.name,
665+
pathlib.PurePath(self.path))
666+
self.assertEqual(spec.origin, self.path)
667+
662668
def test_spec_from_file_location_default_without_location(self):
663669
spec = self.util.spec_from_file_location(self.name)
664670

Lib/test/test_importlib/test_util.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
importlib_util = util.import_importlib('importlib.util')
66

77
import os
8+
import pathlib
89
import string
910
import sys
1011
from test import support
@@ -676,6 +677,15 @@ def test_sep_altsep_and_sep_cache_from_source(self):
676677
self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''),
677678
'\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag))
678679

680+
@unittest.skipUnless(sys.implementation.cache_tag is not None,
681+
'requires sys.implementation.cache_tag not be None')
682+
def test_source_from_cache_path_like_arg(self):
683+
path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py')
684+
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
685+
'qux.{}.pyc'.format(self.tag))
686+
self.assertEqual(self.util.cache_from_source(path, optimization=''),
687+
expect)
688+
679689
@unittest.skipUnless(sys.implementation.cache_tag is not None,
680690
'requires sys.implementation.cache_tag to not be '
681691
'None')
@@ -738,6 +748,15 @@ def test_source_from_cache_missing_optimization(self):
738748
with self.assertRaises(ValueError):
739749
self.util.source_from_cache(path)
740750

751+
@unittest.skipUnless(sys.implementation.cache_tag is not None,
752+
'requires sys.implementation.cache_tag to not be '
753+
'None')
754+
def test_source_from_cache_path_like_arg(self):
755+
path = pathlib.PurePath('foo', 'bar', 'baz', '__pycache__',
756+
'qux.{}.pyc'.format(self.tag))
757+
expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
758+
self.assertEqual(self.util.source_from_cache(path), expect)
759+
741760

742761
(Frozen_PEP3147Tests,
743762
Source_PEP3147Tests

Misc/NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ Library
108108

109109
- Issue #28005: Allow ImportErrors in encoding implementation to propagate.
110110

111+
- Issue #26667: Support path-like objects in importlib.util.
112+
111113
- Issue #27570: Avoid zero-length memcpy() etc calls with null source
112114
pointers in the "ctypes" and "array" modules.
113115

@@ -237,7 +239,7 @@ Library
237239
- Issue #27930: Improved behaviour of logging.handlers.QueueListener.
238240
Thanks to Paulo Andrade and Petr Viktorin for the analysis and patch.
239241

240-
- Issue #6766: Distributed reference counting added to multiprocessing
242+
- Issue #6766: Distributed reference counting added to multiprocessing
241243
to support nesting of shared values / proxy objects.
242244

243245
C API

0 commit comments

Comments
 (0)