[3.9] bpo-46469: Make asyncio generic classes return GenericAlias (GH-30777) (GH-30785)

Automerge-Triggered-By: GH:asvetlov
This commit is contained in:
Kumar Aditya 2022-01-22 18:22:24 +05:30 committed by GitHub
parent 3c4a3745b9
commit 6ed874f8c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 29 additions and 24 deletions

View file

@ -8,6 +8,7 @@ import concurrent.futures
import contextvars
import logging
import sys
from types import GenericAlias
from . import base_futures
from . import events
@ -106,8 +107,7 @@ class Future:
context['source_traceback'] = self._source_traceback
self._loop.call_exception_handler(context)
def __class_getitem__(cls, type):
return cls
__class_getitem__ = classmethod(GenericAlias)
@property
def _log_traceback(self):

View file

@ -3,6 +3,7 @@ __all__ = ('Queue', 'PriorityQueue', 'LifoQueue', 'QueueFull', 'QueueEmpty')
import collections
import heapq
import warnings
from types import GenericAlias
from . import events
from . import locks
@ -76,8 +77,7 @@ class Queue:
def __str__(self):
return f'<{type(self).__name__} {self._format()}>'
def __class_getitem__(cls, type):
return cls
__class_getitem__ = classmethod(GenericAlias)
def _format(self):
result = f'maxsize={self._maxsize!r}'

View file

@ -17,6 +17,7 @@ import itertools
import types
import warnings
import weakref
from types import GenericAlias
from . import base_tasks
from . import coroutines
@ -147,8 +148,7 @@ class Task(futures._PyFuture): # Inherit Python Task implementation
self._loop.call_exception_handler(context)
super().__del__()
def __class_getitem__(cls, type):
return cls
__class_getitem__ = classmethod(GenericAlias)
def _repr_info(self):
return base_tasks._task_repr_info(self)

View file

@ -7,7 +7,7 @@ import sys
import threading
import unittest
from unittest import mock
from types import GenericAlias
import asyncio
from asyncio import futures
from test.test_asyncio import utils as test_utils
@ -109,6 +109,11 @@ class BaseFutureTests:
self.loop = self.new_test_loop()
self.addCleanup(self.loop.close)
def test_generic_alias(self):
future = self.cls[str]
self.assertEqual(future.__args__, (str,))
self.assertIsInstance(future, GenericAlias)
def test_isfuture(self):
class MyFuture:
_asyncio_future_blocking = None

View file

@ -4,6 +4,7 @@ import unittest
from unittest import mock
import asyncio
from types import GenericAlias
from test.test_asyncio import utils as test_utils
@ -92,6 +93,11 @@ class QueueBasicTests(_QueueTestBase):
def test_str(self):
self._test_repr_or_str(str, False)
def test_generic_alias(self):
q = asyncio.Queue[int]
self.assertEqual(q.__args__, (int,))
self.assertIsInstance(q, GenericAlias)
def test_empty(self):
with self.assertWarns(DeprecationWarning):
q = asyncio.Queue(loop=self.loop)

View file

@ -9,12 +9,13 @@ import io
import random
import re
import sys
import types
import textwrap
import traceback
import types
import unittest
import weakref
from unittest import mock
from types import GenericAlias
import asyncio
from asyncio import coroutines
@ -120,6 +121,12 @@ class BaseTaskTests:
self.loop.set_task_factory(self.new_task)
self.loop.create_future = lambda: self.new_future(self.loop)
def test_generic_alias(self):
task = self.__class__.Task[str]
self.assertEqual(task.__args__, (str,))
self.assertIsInstance(task, GenericAlias)
def test_task_cancel_message_getter(self):
async def coro():
pass

View file

@ -0,0 +1 @@
:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in ``__class_getitem__`` instead of the same class.

View file

@ -1474,13 +1474,6 @@ finally:
PyErr_Restore(error_type, error_value, error_traceback);
}
static PyObject *
future_cls_getitem(PyObject *cls, PyObject *type)
{
Py_INCREF(cls);
return cls;
}
static PyAsyncMethods FutureType_as_async = {
(unaryfunc)future_new_iter, /* am_await */
0, /* am_aiter */
@ -1500,7 +1493,7 @@ static PyMethodDef FutureType_methods[] = {
_ASYNCIO_FUTURE_GET_LOOP_METHODDEF
_ASYNCIO_FUTURE__MAKE_CANCELLED_ERROR_METHODDEF
_ASYNCIO_FUTURE__REPR_INFO_METHODDEF
{"__class_getitem__", future_cls_getitem, METH_O|METH_CLASS, NULL},
{"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
{NULL, NULL} /* Sentinel */
};
@ -2487,13 +2480,6 @@ done:
FutureObj_finalize((FutureObj*)task);
}
static PyObject *
task_cls_getitem(PyObject *cls, PyObject *type)
{
Py_INCREF(cls);
return cls;
}
static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */
static PyMethodDef TaskType_methods[] = {
@ -2513,7 +2499,7 @@ static PyMethodDef TaskType_methods[] = {
_ASYNCIO_TASK_GET_NAME_METHODDEF
_ASYNCIO_TASK_SET_NAME_METHODDEF
_ASYNCIO_TASK_GET_CORO_METHODDEF
{"__class_getitem__", task_cls_getitem, METH_O|METH_CLASS, NULL},
{"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
{NULL, NULL} /* Sentinel */
};