Skip to content

Commit 2a5686c

Browse files
committed
Merge branch 'main' into task-concept
2 parents 7a9bded + 7e473e9 commit 2a5686c

15 files changed

+263
-118
lines changed

Doc/library/asyncio-stream.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ and work with streams:
5151
.. coroutinefunction:: open_connection(host=None, port=None, *, \
5252
limit=None, ssl=None, family=0, proto=0, \
5353
flags=0, sock=None, local_addr=None, \
54-
server_hostname=None, ssl_handshake_timeout=None)
54+
server_hostname=None, ssl_handshake_timeout=None, \
55+
happy_eyeballs_delay=None, interleave=None)
5556

5657
Establish a network connection and return a pair of
5758
``(reader, writer)`` objects.
@@ -69,6 +70,9 @@ and work with streams:
6970
.. versionchanged:: 3.7
7071
Added the *ssl_handshake_timeout* parameter.
7172

73+
.. versionadded:: 3.8
74+
Added *happy_eyeballs_delay* and *interleave* parameters.
75+
7276
.. versionchanged:: 3.10
7377
Removed the *loop* parameter.
7478

Include/cpython/code.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ typedef uint16_t _Py_CODEUNIT;
2323
# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8))
2424
#endif
2525

26+
// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing:
27+
#define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode))
28+
2629

2730
/* Bytecode object */
2831
struct PyCodeObject {

Lib/asyncio/tasks.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ def _set_task_name(task, name):
6767
try:
6868
set_name = task.set_name
6969
except AttributeError:
70-
pass
70+
warnings.warn("Task.set_name() was added in Python 3.8, "
71+
"the method support will be mandatory for third-party "
72+
"task implementations since 3.13.",
73+
DeprecationWarning, stacklevel=3)
7174
else:
7275
set_name(name)
7376

Lib/test/test_asyncio/test_tasks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import textwrap
1313
import traceback
1414
import unittest
15-
import weakref
1615
from unittest import mock
1716
from types import GenericAlias
1817

Lib/test/test_genericalias.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,24 @@ class MyList(list):
169169
self.assertEqual(repr(list[str]), 'list[str]')
170170
self.assertEqual(repr(list[()]), 'list[()]')
171171
self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]')
172+
x1 = tuple[
173+
tuple( # Effectively the same as starring; TODO
174+
tuple[int]
175+
)
176+
]
177+
self.assertEqual(repr(x1), 'tuple[*tuple[int]]')
178+
x2 = tuple[
179+
tuple( # Ditto TODO
180+
tuple[int, str]
181+
)
182+
]
183+
self.assertEqual(repr(x2), 'tuple[*tuple[int, str]]')
184+
x3 = tuple[
185+
tuple( # Ditto TODO
186+
tuple[int, ...]
187+
)
188+
]
189+
self.assertEqual(repr(x3), 'tuple[*tuple[int, ...]]')
172190
self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
173191
self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr
174192

@@ -182,6 +200,7 @@ def test_exposed_type(self):
182200

183201
def test_parameters(self):
184202
from typing import List, Dict, Callable
203+
185204
D0 = dict[str, int]
186205
self.assertEqual(D0.__args__, (str, int))
187206
self.assertEqual(D0.__parameters__, ())
@@ -197,6 +216,7 @@ def test_parameters(self):
197216
D2b = dict[T, T]
198217
self.assertEqual(D2b.__args__, (T, T))
199218
self.assertEqual(D2b.__parameters__, (T,))
219+
200220
L0 = list[str]
201221
self.assertEqual(L0.__args__, (str,))
202222
self.assertEqual(L0.__parameters__, ())
@@ -219,6 +239,45 @@ def test_parameters(self):
219239
self.assertEqual(L5.__args__, (Callable[[K, V], K],))
220240
self.assertEqual(L5.__parameters__, (K, V))
221241

242+
T1 = tuple[
243+
tuple( # Ditto TODO
244+
tuple[int]
245+
)
246+
]
247+
self.assertEqual(
248+
T1.__args__,
249+
tuple( # Ditto TODO
250+
tuple[int]
251+
)
252+
)
253+
self.assertEqual(T1.__parameters__, ())
254+
255+
T2 = tuple[
256+
tuple( # Ditto TODO
257+
tuple[T]
258+
)
259+
]
260+
self.assertEqual(
261+
T2.__args__,
262+
tuple( # Ditto TODO
263+
tuple[T]
264+
)
265+
)
266+
self.assertEqual(T2.__parameters__, (T,))
267+
268+
T4 = tuple[
269+
tuple( # Ditto TODO
270+
tuple[int, str]
271+
)
272+
]
273+
self.assertEqual(
274+
T4.__args__,
275+
tuple( # Ditto TODO
276+
tuple[int, str]
277+
)
278+
)
279+
self.assertEqual(T4.__parameters__, ())
280+
222281
def test_parameter_chaining(self):
223282
from typing import List, Dict, Union, Callable
224283
self.assertEqual(list[T][int], list[int])
@@ -249,6 +308,19 @@ def test_parameter_chaining(self):
249308
def test_equality(self):
250309
self.assertEqual(list[int], list[int])
251310
self.assertEqual(dict[str, int], dict[str, int])
311+
self.assertEqual((*tuple[int],)[0], (*tuple[int],)[0])
312+
self.assertEqual(
313+
tuple[
314+
tuple( # Effectively the same as starring; TODO
315+
tuple[int]
316+
)
317+
],
318+
tuple[
319+
tuple( # Ditto TODO
320+
tuple[int]
321+
)
322+
]
323+
)
252324
self.assertNotEqual(dict[str, int], dict[str, str])
253325
self.assertNotEqual(list, list[int])
254326
self.assertNotEqual(list[int], list)
@@ -346,6 +418,24 @@ def __new__(cls, *args, **kwargs):
346418
with self.assertRaises(TypeError):
347419
Bad(list, int, bad=int)
348420

421+
def test_iter_creates_starred_tuple(self):
422+
t = tuple[int, str]
423+
iter_t = iter(t)
424+
x = next(iter_t)
425+
self.assertEqual(repr(x), '*tuple[int, str]')
426+
427+
def test_calling_next_twice_raises_stopiteration(self):
428+
t = tuple[int, str]
429+
iter_t = iter(t)
430+
next(iter_t)
431+
with self.assertRaises(StopIteration):
432+
next(iter_t)
433+
434+
def test_del_iter(self):
435+
t = tuple[int, str]
436+
iter_x = iter(t)
437+
del iter_x
438+
349439

350440
if __name__ == "__main__":
351441
unittest.main()

Lib/test/test_mimetypes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ def test_init_reinitializes(self):
159159
# Poison should be gone.
160160
self.assertEqual(mimetypes.guess_extension('foo/bar'), None)
161161

162+
@unittest.skipIf(sys.platform.startswith("win"), "Non-Windows only")
163+
def test_guess_known_extensions(self):
164+
# Issue 37529
165+
# The test fails on Windows because Windows adds mime types from the Registry
166+
# and that creates some duplicates.
167+
from mimetypes import types_map
168+
for v in types_map.values():
169+
self.assertIsNotNone(mimetypes.guess_extension(v))
170+
162171
def test_preferred_extension(self):
163172
def check_extensions():
164173
self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin')

Lib/test/test_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ def test_union_parameter_substitution_errors(self):
875875
T = typing.TypeVar("T")
876876
x = int | T
877877
with self.assertRaises(TypeError):
878-
x[42]
878+
x[int, str]
879879

880880
def test_or_type_operator_with_forward(self):
881881
T = typing.TypeVar('T')

Lib/test/test_typing.py

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ def test_cannot_instantiate_vars(self):
345345

346346
def test_bound_errors(self):
347347
with self.assertRaises(TypeError):
348-
TypeVar('X', bound=42)
348+
TypeVar('X', bound=Union)
349349
with self.assertRaises(TypeError):
350350
TypeVar('X', str, float, bound=Employee)
351351

@@ -377,7 +377,7 @@ def test_bad_var_substitution(self):
377377
T = TypeVar('T')
378378
P = ParamSpec("P")
379379
bad_args = (
380-
42, ..., [int], (), (int, str), Union,
380+
(), (int, str), Union,
381381
Generic, Generic[T], Protocol, Protocol[T],
382382
Final, Final[int], ClassVar, ClassVar[int],
383383
)
@@ -2591,9 +2591,6 @@ def test_extended_generic_rules_eq(self):
25912591
class Base: ...
25922592
class Derived(Base): ...
25932593
self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived])
2594-
with self.assertRaises(TypeError):
2595-
Union[T, int][1]
2596-
25972594
self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT])
25982595
self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]])
25992596

@@ -3136,8 +3133,6 @@ class Foo(obj):
31363133
class ClassVarTests(BaseTestCase):
31373134

31383135
def test_basics(self):
3139-
with self.assertRaises(TypeError):
3140-
ClassVar[1]
31413136
with self.assertRaises(TypeError):
31423137
ClassVar[int, str]
31433138
with self.assertRaises(TypeError):
@@ -3176,8 +3171,6 @@ class FinalTests(BaseTestCase):
31763171

31773172
def test_basics(self):
31783173
Final[int] # OK
3179-
with self.assertRaises(TypeError):
3180-
Final[1]
31813174
with self.assertRaises(TypeError):
31823175
Final[int, str]
31833176
with self.assertRaises(TypeError):
@@ -3591,14 +3584,6 @@ def foo(a: 'Node[T'):
35913584
with self.assertRaises(SyntaxError):
35923585
get_type_hints(foo)
35933586

3594-
def test_type_error(self):
3595-
3596-
def foo(a: Tuple['42']):
3597-
pass
3598-
3599-
with self.assertRaises(TypeError):
3600-
get_type_hints(foo)
3601-
36023587
def test_name_error(self):
36033588

36043589
def foo(a: 'Noode[T]'):
@@ -5011,8 +4996,6 @@ def test_namedtuple_keyword_usage(self):
50114996
self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int))
50124997
with self.assertRaises(TypeError):
50134998
NamedTuple('Name', [('x', int)], y=str)
5014-
with self.assertRaises(TypeError):
5015-
NamedTuple('Name', x=1, y='a')
50164999

50175000
def test_namedtuple_special_keyword_names(self):
50185001
NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list)
@@ -5048,8 +5031,6 @@ def test_namedtuple_errors(self):
50485031
NamedTuple('Emp', [('_name', str)])
50495032
with self.assertRaises(TypeError):
50505033
NamedTuple(typename='Emp', name=str, id=int)
5051-
with self.assertRaises(TypeError):
5052-
NamedTuple('Emp', fields=[('name', str), ('id', int)])
50535034

50545035
def test_copy_and_pickle(self):
50555036
global Emp # pickle wants to reference the class by name
@@ -5124,7 +5105,6 @@ def test_typeddict_create_errors(self):
51245105
TypedDict()
51255106
with self.assertRaises(TypeError):
51265107
TypedDict('Emp', [('name', str)], None)
5127-
51285108
with self.assertRaises(TypeError):
51295109
TypedDict(_typename='Emp', name=str, id=int)
51305110

@@ -5138,13 +5118,6 @@ def test_typeddict_errors(self):
51385118
isinstance(jim, Emp)
51395119
with self.assertRaises(TypeError):
51405120
issubclass(dict, Emp)
5141-
# We raise a DeprecationWarning for the keyword syntax
5142-
# before the TypeError.
5143-
with self.assertWarns(DeprecationWarning):
5144-
with self.assertRaises(TypeError):
5145-
TypedDict('Hi', x=1)
5146-
with self.assertRaises(TypeError):
5147-
TypedDict('Hi', [('x', int), ('y', 1)])
51485121
with self.assertRaises(TypeError):
51495122
TypedDict('Hi', [('x', int)], y=int)
51505123

@@ -5916,6 +5889,9 @@ def test_basics(self):
59165889
def foo(arg) -> TypeGuard[int]: ...
59175890
self.assertEqual(gth(foo), {'return': TypeGuard[int]})
59185891

5892+
with self.assertRaises(TypeError):
5893+
TypeGuard[int, str]
5894+
59195895
def test_repr(self):
59205896
self.assertEqual(repr(TypeGuard), 'typing.TypeGuard')
59215897
cv = TypeGuard[int]

Lib/typing.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=
185185
return arg
186186
if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol):
187187
raise TypeError(f"Plain {arg} is not valid as type argument")
188-
if isinstance(arg, (type, TypeVar, ForwardRef, types.UnionType, ParamSpec,
189-
ParamSpecArgs, ParamSpecKwargs, TypeVarTuple)):
190-
return arg
191-
if not callable(arg):
188+
if type(arg) is tuple:
192189
raise TypeError(f"{msg} Got {arg!r:.100}.")
193190
return arg
194191

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow unpacking types.GenericAlias objects, e.g. ``*tuple[int, str]``.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No longer require valid typeforms to be callable. This allows :data:`typing.Annotated` to wrap :data:`typing.ParamSpecArgs` and :data:`dataclasses.InitVar`. Patch by Gregory Beauregard.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Deprecate missing :meth:`asyncio.Task.set_name` for third-party task
2+
implementations, schedule making it mandatory in Python 3.13.

0 commit comments

Comments
 (0)