Skip to content

Commit

Permalink
Issue python#26667: Add path-like object support to importlib.util.
Browse files Browse the repository at this point in the history
  • Loading branch information
brettcannon committed Sep 8, 2016
1 parent d5f9223 commit 035a100
Show file tree
Hide file tree
Showing 7 changed files with 2,219 additions and 2,167 deletions.
9 changes: 9 additions & 0 deletions Doc/library/importlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,9 @@ an :term:`importer`.
The *optimization* parameter was added and the *debug_override* parameter
was deprecated.

.. versionchanged:: 3.6
Accepts a :term:`path-like object`.


.. function:: source_from_cache(path)

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

.. versionadded:: 3.4

.. versionchanged:: 3.6
Accepts a :term:`path-like object`.

.. function:: decode_source(source_bytes)

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

.. versionadded:: 3.4

.. versionchanged:: 3.6
Accepts a :term:`path-like object`.

.. class:: LazyLoader(loader)

A class which postpones the execution of the loader of a module until the
Expand Down
12 changes: 10 additions & 2 deletions Doc/whatsnew/3.6.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ New syntax features:

Standard library improvements:

* PEP 519: :ref:`Adding a file system path protocol <pep-519>`

Security improvements:

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

:func:`importlib.util.cache_from_source`,
:func:`importlib.util.source_from_cache`, and
:func:`importlib.util.spec_from_file_location` now accept a
:term:`path-like object`.


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

See the summary for :ref:`PEP 519 <pep-519>` for details on how the
:mod:`os` and :mod:`os.path` modules now support
:term:`path-like objects <path-like object>`.


pickle
------

Expand Down
4 changes: 4 additions & 0 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ def cache_from_source(path, debug_override=None, *, optimization=None):
message = 'debug_override or optimization must be set to None'
raise TypeError(message)
optimization = '' if debug_override else 1
path = _os.fspath(path)
head, tail = _path_split(path)
base, sep, rest = tail.rpartition('.')
tag = sys.implementation.cache_tag
Expand Down Expand Up @@ -309,6 +310,7 @@ def source_from_cache(path):
"""
if sys.implementation.cache_tag is None:
raise NotImplementedError('sys.implementation.cache_tag is None')
path = _os.fspath(path)
head, pycache_filename = _path_split(path)
head, pycache = _path_split(head)
if pycache != _PYCACHE:
Expand Down Expand Up @@ -536,6 +538,8 @@ def spec_from_file_location(name, location=None, *, loader=None,
location = loader.get_filename(name)
except ImportError:
pass
else:
location = _os.fspath(location)

# If the location is on the filesystem, but doesn't actually exist,
# we could return None here, indicating that the location is not
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_importlib/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
util = test_util.import_importlib('importlib.util')

import os.path
import pathlib
from test.support import CleanImport
import unittest
import sys
Expand Down Expand Up @@ -659,6 +660,11 @@ def test_spec_from_file_location_default(self):
self.assertEqual(spec.cached, self.cached)
self.assertTrue(spec.has_location)

def test_spec_from_file_location_path_like_arg(self):
spec = self.util.spec_from_file_location(self.name,
pathlib.PurePath(self.path))
self.assertEqual(spec.origin, self.path)

def test_spec_from_file_location_default_without_location(self):
spec = self.util.spec_from_file_location(self.name)

Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_importlib/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
importlib_util = util.import_importlib('importlib.util')

import os
import pathlib
import string
import sys
from test import support
Expand Down Expand Up @@ -676,6 +677,15 @@ def test_sep_altsep_and_sep_cache_from_source(self):
self.util.cache_from_source('\\foo\\bar\\baz/qux.py', optimization=''),
'\\foo\\bar\\baz\\__pycache__\\qux.{}.pyc'.format(self.tag))

@unittest.skipUnless(sys.implementation.cache_tag is not None,
'requires sys.implementation.cache_tag not be None')
def test_source_from_cache_path_like_arg(self):
path = pathlib.PurePath('foo', 'bar', 'baz', 'qux.py')
expect = os.path.join('foo', 'bar', 'baz', '__pycache__',
'qux.{}.pyc'.format(self.tag))
self.assertEqual(self.util.cache_from_source(path, optimization=''),
expect)

@unittest.skipUnless(sys.implementation.cache_tag is not None,
'requires sys.implementation.cache_tag to not be '
'None')
Expand Down Expand Up @@ -738,6 +748,15 @@ def test_source_from_cache_missing_optimization(self):
with self.assertRaises(ValueError):
self.util.source_from_cache(path)

@unittest.skipUnless(sys.implementation.cache_tag is not None,
'requires sys.implementation.cache_tag to not be '
'None')
def test_source_from_cache_path_like_arg(self):
path = pathlib.PurePath('foo', 'bar', 'baz', '__pycache__',
'qux.{}.pyc'.format(self.tag))
expect = os.path.join('foo', 'bar', 'baz', 'qux.py')
self.assertEqual(self.util.source_from_cache(path), expect)


(Frozen_PEP3147Tests,
Source_PEP3147Tests
Expand Down
4 changes: 3 additions & 1 deletion Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Library

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

- Issue #26667: Support path-like objects in importlib.util.

- Issue #27570: Avoid zero-length memcpy() etc calls with null source
pointers in the "ctypes" and "array" modules.

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

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

C API
Expand Down
Loading

0 comments on commit 035a100

Please sign in to comment.