Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
22 changes: 13 additions & 9 deletions Doc/library/importlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,11 @@ ABC hierarchy::
See :pep:`302` for the exact definition for a loader.

Loaders that wish to support resource reading should implement a
:meth:`get_resource_reader` method as specified by
:meth:`!get_resource_reader` method as specified by
:class:`importlib.resources.abc.ResourceReader`.

.. versionchanged:: 3.7
Introduced the optional :meth:`get_resource_reader` method.
Introduced the optional :meth:`!get_resource_reader` method.

.. versionchanged:: 3.15
Removed the ``load_module()`` method.
Expand Down Expand Up @@ -717,7 +717,8 @@ find and load modules.

.. versionchanged:: 3.5
As part of :pep:`489`, the builtin importer now implements
:meth:`Loader.create_module` and :meth:`Loader.exec_module`
:meth:`Loader.create_module <importlib.abc.Loader.create_module>`
and :meth:`Loader.exec_module <importlib.abc.Loader.exec_module>`


.. class:: FrozenImporter
Expand All @@ -730,7 +731,8 @@ find and load modules.
instantiation.

.. versionchanged:: 3.4
Gained :meth:`~Loader.create_module` and :meth:`~Loader.exec_module`
Gained :meth:`~importlib.abc.Loader.create_module` and
:meth:`~importlib.abc.Loader.exec_module`
methods.


Expand Down Expand Up @@ -1180,8 +1182,8 @@ an :term:`importer`.
with the source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return
value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2.
The ``cpython-32`` string comes from the current magic tag (see
:func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then
:exc:`NotImplementedError` will be raised).
:attr:`sys.implementation.cache_tag <sys.implementation>`; if it is not
defined then :exc:`NotImplementedError` will be raised).

The *optimization* parameter is used to specify the optimization level of the
bytecode file. An empty string represents no optimization, so
Expand Down Expand Up @@ -1213,7 +1215,7 @@ an :term:`importer`.
``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be
``/foo/bar/baz.py``. *path* need not exist, however if it does not conform
to :pep:`3147` or :pep:`488` format, a :exc:`ValueError` is raised. If
:attr:`sys.implementation.cache_tag` is not defined,
:attr:`sys.implementation.cache_tag <sys.implementation>` is not defined,
:exc:`NotImplementedError` is raised.

.. versionadded:: 3.4
Expand Down Expand Up @@ -1263,7 +1265,8 @@ an :term:`importer`.
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`.
**name** and **package** work the same as for
:func:`importlib.import_module`.

.. versionadded:: 3.4

Expand Down Expand Up @@ -1293,7 +1296,8 @@ an :term:`importer`.
A factory function for creating a :class:`~importlib.machinery.ModuleSpec`
instance based on a loader. The parameters have the same meaning as they do
for ModuleSpec. The function uses available :term:`loader` APIs, such as
:meth:`InspectLoader.is_package`, to fill in any missing
:meth:`InspectLoader.is_package
<importlib.abc.InspectLoader.is_package>`, to fill in any missing
information on the spec.

.. versionadded:: 3.4
Expand Down
1 change: 0 additions & 1 deletion Doc/tools/.nitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Doc/library/ast.rst
Doc/library/asyncio-extending.rst
Doc/library/email.charset.rst
Doc/library/email.parser.rst
Doc/library/importlib.rst
Doc/library/logging.config.rst
Doc/library/logging.handlers.rst
Doc/library/mmap.rst
Expand Down
5 changes: 2 additions & 3 deletions Lib/copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,8 @@ def deepcopy(x, memo=None):
if memo is None:
memo = {}
else:
y = memo.get(d, None)
if y is not None:
return y
if d in memo:
return memo[d]

copier = _deepcopy_dispatch.get(cls)
if copier is not None:
Expand Down
11 changes: 11 additions & 0 deletions Lib/test/test_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,17 @@ def m(self):
self.assertIs(g.b.__self__, g)
g.b()

def test_deepcopy_memo_none_result(self):
# Objects whose deepcopy result is None must still be memoized.
class C:
call_count = 0
def __deepcopy__(self, memo):
C.call_count += 1
return None
obj = C()
copy.deepcopy([obj, obj, obj])
self.assertEqual(C.call_count, 1)


class TestReplace(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :func:`copy.deepcopy` so that an object whose deep copy is ``None`` is
still memoized. Patch by tonghuaroot.
15 changes: 15 additions & 0 deletions Modules/_ctypes/malloc_closure.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,25 @@ static void more_core(void)

/* allocate a memory block */
#ifdef MS_WIN32
#ifdef MS_WINDOWS_DESKTOP
item = (ITEM *)VirtualAlloc(NULL,
count * sizeof(ITEM),
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
#else // UWP
/* Due security restrictions, UWP not allows request Read-Write-Execute permissions at once.
The correct flow in UWP for execute dynamic code in memmory is:
1. Alloate as Read-Write (PAGE_READWRITE) and write dynamic code to memmory.
2. Change to Executable (PAGE_EXECUTE_READ) with 'VirtualProtectFromApp'.
3. Flush cache with 'FlushInstructionCache' to ensure CPU instruction cache coherency
before executing the generated code.
TODO: Implement 2 and 3 in the appropriate places. For now, this defers
the error from import time to time of use (or never, if an app avoids it). */
item = (ITEM*)VirtualAllocFromApp(NULL,
count * sizeof(ITEM),
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
#endif // !MS_WINDOWS_DESKTOP
if (item == NULL)
return;
#else
Expand Down
Loading