From 0361556537686f857f1025ead75e6af4ca7cc94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Batuhan=20Ta=C5=9Fkaya?= Date: Fri, 10 Apr 2020 17:46:36 +0300 Subject: [PATCH] bpo-39481: PEP 585 for a variety of modules (GH-19423) - concurrent.futures - ctypes - http.cookies - multiprocessing - queue - tempfile - unittest.case - urllib.parse --- Lib/concurrent/futures/_base.py | 3 +++ Lib/concurrent/futures/thread.py | 3 +++ Lib/ctypes/__init__.py | 3 +++ Lib/http/cookies.py | 3 +++ Lib/multiprocessing/managers.py | 3 +++ Lib/multiprocessing/pool.py | 3 +++ Lib/multiprocessing/queues.py | 3 +++ Lib/multiprocessing/shared_memory.py | 3 +++ Lib/queue.py | 5 +++++ Lib/tempfile.py | 2 ++ Lib/test/test_genericalias.py | 21 +++++++++++++++++++++ Lib/unittest/case.py | 2 ++ Lib/urllib/parse.py | 3 +++ Modules/_ctypes/_ctypes.c | 8 +++++++- Modules/_queuemodule.c | 2 ++ 15 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index fd0acec55d04..bf546f8ae1d1 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -7,6 +7,7 @@ import logging import threading import time +import types FIRST_COMPLETED = 'FIRST_COMPLETED' FIRST_EXCEPTION = 'FIRST_EXCEPTION' @@ -544,6 +545,8 @@ def set_exception(self, exception): self._condition.notify_all() self._invoke_callbacks() + __class_getitem__ = classmethod(types.GenericAlias) + class Executor(object): """This is an abstract base class for concrete asynchronous executors.""" diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 2aa4e17d47fa..2810b357bc1e 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -10,6 +10,7 @@ import itertools import queue import threading +import types import weakref import os @@ -57,6 +58,8 @@ def run(self): else: self.future.set_result(result) + __class_getitem__ = classmethod(types.GenericAlias) + def _worker(executor_reference, work_queue, initializer, initargs): if initializer is not None: diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 8f0991147d72..4afa4ebd4224 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -1,6 +1,7 @@ """create and manipulate C data types in Python""" import os as _os, sys as _sys +import types as _types __version__ = "1.1.0" @@ -450,6 +451,8 @@ def __getitem__(self, name): def LoadLibrary(self, name): return self._dlltype(name) + __class_getitem__ = classmethod(_types.GenericAlias) + cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 6694f5478bda..35ac2dc6ae28 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -131,6 +131,7 @@ # import re import string +import types __all__ = ["CookieError", "BaseCookie", "SimpleCookie"] @@ -419,6 +420,8 @@ def OutputString(self, attrs=None): # Return the result return _semispacejoin(result) + __class_getitem__ = classmethod(types.GenericAlias) + # # Pattern for finding cookie diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 1668220c0995..9d490a1d8b35 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -21,6 +21,7 @@ import array import queue import time +import types import os from os import getpid @@ -1129,6 +1130,8 @@ def set(self, value): return self._callmethod('set', (value,)) value = property(get, set) + __class_getitem__ = classmethod(types.GenericAlias) + BaseListProxy = MakeProxyType('BaseListProxy', ( '__add__', '__contains__', '__delitem__', '__getitem__', '__len__', diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 41dd923d4f97..b8a0b827635f 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -20,6 +20,7 @@ import threading import time import traceback +import types import warnings from queue import Empty @@ -780,6 +781,8 @@ def _set(self, i, obj): del self._cache[self._job] self._pool = None + __class_getitem__ = classmethod(types.GenericAlias) + AsyncResult = ApplyResult # create alias -- see #17805 # diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index d112db2cd981..835070118387 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -14,6 +14,7 @@ import threading import collections import time +import types import weakref import errno @@ -366,3 +367,5 @@ def put(self, obj): else: with self._wlock: self._writer.send_bytes(obj) + + __class_getitem__ = classmethod(types.GenericAlias) diff --git a/Lib/multiprocessing/shared_memory.py b/Lib/multiprocessing/shared_memory.py index 184e36704baa..9f954d9c38fe 100644 --- a/Lib/multiprocessing/shared_memory.py +++ b/Lib/multiprocessing/shared_memory.py @@ -14,6 +14,7 @@ import errno import struct import secrets +import types if os.name == "nt": import _winapi @@ -508,3 +509,5 @@ def index(self, value): return position else: raise ValueError(f"{value!r} not in this container") + + __class_getitem__ = classmethod(types.GenericAlias) diff --git a/Lib/queue.py b/Lib/queue.py index 5bb0431e9494..10dbcbc18ece 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -1,6 +1,7 @@ '''A multi-producer, multi-consumer queue.''' import threading +import types from collections import deque from heapq import heappush, heappop from time import monotonic as time @@ -216,6 +217,8 @@ def _put(self, item): def _get(self): return self.queue.popleft() + __class_getitem__ = classmethod(types.GenericAlias) + class PriorityQueue(Queue): '''Variant of Queue that retrieves open entries in priority order (lowest first). @@ -316,6 +319,8 @@ def qsize(self): '''Return the approximate size of the queue (not reliable!).''' return len(self._queue) + __class_getitem__ = classmethod(types.GenericAlias) + if SimpleQueue is None: SimpleQueue = _PySimpleQueue diff --git a/Lib/tempfile.py b/Lib/tempfile.py index a398345f108d..ed15c0fd1f8a 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -829,3 +829,5 @@ def __exit__(self, exc, value, tb): def cleanup(self): if self._finalizer.detach(): self._rmtree(self.name) + + __class_getitem__ = classmethod(_types.GenericAlias) diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index 4241eabed084..a00899f5267d 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -6,16 +6,28 @@ defaultdict, deque, OrderedDict, Counter, UserDict, UserList ) from collections.abc import * +from concurrent.futures import Future +from concurrent.futures.thread import _WorkItem from contextlib import AbstractContextManager, AbstractAsyncContextManager +from ctypes import Array, LibraryLoader from difflib import SequenceMatcher from filecmp import dircmp from fileinput import FileInput from mmap import mmap from ipaddress import IPv4Network, IPv4Interface, IPv6Network, IPv6Interface from itertools import chain +from http.cookies import Morsel +from multiprocessing.managers import ValueProxy +from multiprocessing.pool import ApplyResult +from multiprocessing.shared_memory import ShareableList +from multiprocessing.queues import SimpleQueue from os import DirEntry from re import Pattern, Match from types import GenericAlias, MappingProxyType, AsyncGeneratorType +from tempfile import TemporaryDirectory, SpooledTemporaryFile +from urllib.parse import SplitResult, ParseResult +from unittest.case import _AssertRaisesContext +from queue import Queue, SimpleQueue import typing from typing import TypeVar @@ -49,6 +61,15 @@ def test_subscriptable(self): DirEntry, IPv4Network, IPv4Interface, IPv6Network, IPv6Interface, chain, + TemporaryDirectory, SpooledTemporaryFile, + Queue, SimpleQueue, + _AssertRaisesContext, + Array, LibraryLoader, + SplitResult, ParseResult, + ValueProxy, ApplyResult, + ShareableList, SimpleQueue, + Future, _WorkItem, + Morsel, ): tname = t.__name__ with self.subTest(f"Testing {tname}"): diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 5e5d535dc693..d0ee561a3ae9 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -241,6 +241,8 @@ def __exit__(self, exc_type, exc_value, tb): expected_regex.pattern, str(exc_value))) return True + __class_getitem__ = classmethod(types.GenericAlias) + class _AssertWarnsContext(_AssertRaisesBaseContext): """A context manager used to implement TestCase.assertWarns* methods.""" diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 779278bac598..ea897c303225 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -29,6 +29,7 @@ import re import sys +import types import collections import warnings @@ -176,6 +177,8 @@ def port(self): raise ValueError("Port out of range 0-65535") return port + __class_getitem__ = classmethod(types.GenericAlias) + class _NetlocResultMixinStr(_NetlocResultMixinBase, _ResultMixinStr): __slots__ = () diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index dab39396476b..ba5ef397cf05 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4798,6 +4798,12 @@ Array_length(PyObject *myself) return self->b_length; } +static PyMethodDef Array_methods[] = { + {"__class_getitem__", (PyCFunction)Py_GenericAlias, + METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, + { NULL, NULL } +}; + static PySequenceMethods Array_as_sequence = { Array_length, /* sq_length; */ 0, /* sq_concat; */ @@ -4846,7 +4852,7 @@ PyTypeObject PyCArray_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + Array_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index 5eef06252cd3..28bf8991285d 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -302,6 +302,8 @@ static PyMethodDef simplequeue_methods[] = { _QUEUE_SIMPLEQUEUE_PUT_METHODDEF _QUEUE_SIMPLEQUEUE_PUT_NOWAIT_METHODDEF _QUEUE_SIMPLEQUEUE_QSIZE_METHODDEF + {"__class_getitem__", (PyCFunction)Py_GenericAlias, + METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ };