Skip to content

Commit f96de99

Browse files
authored
Merge branch 'main' into emscripten-static-linking
2 parents 1eaadc6 + 77dd973 commit f96de99

35 files changed

Lines changed: 1414 additions & 237 deletions

Doc/library/colorsys.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ spaces, the coordinates are all between 0 and 1.
1919
.. seealso::
2020

2121
More information about color spaces can be found at
22-
https://poynton.ca/ColorFAQ.html and
22+
https://www.poynton.ca/pdf/ColourFAQ.pdf and
2323
https://www.cambridgeincolour.com/tutorials/color-spaces.htm.
2424

2525
The :mod:`!colorsys` module defines the following functions:

Doc/library/ctypes.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ Specifying function pointers using type annotations
708708

709709
@wrap_dll_function(dll_to_wrap)
710710
def function_ptr_name(arg_name: ctypes_type, ...) -> ctypes_type:
711-
"""Optional docstring. There should be no function body."""
711+
"""Optional docstring. There should be no function body."""
712712

713713
The body of the decorated function is ignored, and any parameters that are
714714
missing type annotations are skipped. The names of the parameters are ignored
@@ -728,7 +728,7 @@ Specifying function pointers using type annotations
728728

729729
@wrap_dll_function(ctypes.pythonapi)
730730
def PyObject_GetAttrString(op: ctypes.py_object, attr: ctypes.c_char_p) -> ctypes.py_object:
731-
pass
731+
pass
732732

733733
PyObject_GetAttrString(42, b"real")
734734

@@ -3207,7 +3207,7 @@ fields, or any other data types containing pointer type fields.
32073207
that should be merged into a containing structure or union.
32083208

32093209

3210-
.. decorator:: struct(*, align=None, layout, endian='native', pack=None)
3210+
.. decorator:: struct(*, align=None, layout=None, endian='native', pack=None)
32113211
:module: ctypes.util
32123212

32133213
A :term:`decorator` that allows generating structure types using an
@@ -3244,14 +3244,18 @@ fields, or any other data types containing pointer type fields.
32443244

32453245
.. code-block:: python
32463246
3247+
from typing import Annotated
3248+
from ctypes import c_ssize_t, c_void_p
3249+
from ctypes.util import struct, CFieldInfo
3250+
32473251
@struct
32483252
class PyObject:
3249-
ob_refcnt: c_ssize_t
3250-
ob_type: c_void_p
3253+
ob_refcnt: c_ssize_t
3254+
ob_type: c_void_p
32513255
32523256
@struct
32533257
class PyHovercraftObject:
3254-
ob_base: Annotated[PyObject, CFieldInfo(anonymous=True)]
3258+
ob_base: Annotated[PyObject, CFieldInfo(anonymous=True)]
32553259
32563260
.. versionadded:: next
32573261

Doc/library/importlib.metadata.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ collection of :ref:`EntryPoint <entry-points>` objects.
9090

9191
You can get the :ref:`metadata for a distribution <metadata>`::
9292

93+
>>> from importlib.metadata import metadata # doctest: +SKIP
9394
>>> list(metadata('wheel')) # doctest: +SKIP
9495
['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist']
9596

Doc/library/multiprocessing.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2538,7 +2538,7 @@ with the :class:`Pool` class.
25382538

25392539
.. method:: imap(func, iterable, chunksize=1, *, buffersize=None)
25402540

2541-
A lazier version of :meth:`.map`.
2541+
An iterator-based version of :meth:`.map`.
25422542

25432543
The *chunksize* argument is the same as the one used by the :meth:`.map`
25442544
method. For very long iterables using a large value for *chunksize* can

Doc/using/windows.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,37 @@ checking for that feed.
943943
}
944944
945945
946+
Proxy Settings
947+
--------------
948+
949+
.. versionadded:: 26.4
950+
951+
By default, the Python install manager will use your system-wide proxy settings,
952+
including automatic authentication. For most users, this behaves the same as
953+
your browser and other applications.
954+
955+
To override the settings, use the ``NO_PROXY``, ``HTTP_PROXY`` and
956+
``HTTPS_PROXY`` environment variables. These should be set in the terminal
957+
session before using the Python install manager. Other applications may also
958+
use the variables, so use caution before setting them globally for your entire
959+
machine.
960+
961+
Setting ``NO_PROXY`` to any non-empty value will disable the use of any proxy.
962+
Use this to bypass your system's default proxy setting and attempt to access the
963+
index server directly.
964+
965+
Setting ``HTTPS_PROXY`` to a string like ``example.com:8080`` will connect to
966+
that proxy server for all HTTPS connections. For the default index, all
967+
connections will be using HTTPS, and so this is the usual setting to override.
968+
969+
The ``HTTP_PROXY`` variable may be needed if you are using a private index
970+
server that does not use encrypted connections, but does require the default
971+
proxy server to be overridden. It follows the same format as ``HTTPS_PROXY``.
972+
973+
Credentials may be embedded in either setting, however, when ``HTTPS_PROXY`` has
974+
credentials embedded they will be used in preference to other credentials. Only
975+
one set of credentials will be used for both types of proxy.
976+
946977
.. _pymanager-troubleshoot:
947978

948979
Troubleshooting

Include/cpython/object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
352352
#ifdef _Py_TYPEOF
353353
#define Py_SETREF(dst, src) \
354354
do { \
355-
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
355+
_Py_TYPEOF(&(dst)) _tmp_dst_ptr = &(dst); \
356356
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
357357
*_tmp_dst_ptr = (src); \
358358
Py_DECREF(_tmp_old_dst); \
@@ -374,7 +374,7 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
374374
#ifdef _Py_TYPEOF
375375
#define Py_XSETREF(dst, src) \
376376
do { \
377-
_Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
377+
_Py_TYPEOF(&(dst)) _tmp_dst_ptr = &(dst); \
378378
_Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
379379
*_tmp_dst_ptr = (src); \
380380
Py_XDECREF(_tmp_old_dst); \

Include/pyport.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,15 +538,18 @@ extern "C" {
538538
//
539539
// Example: _Py_TYPEOF(x) x_copy = (x);
540540
//
541-
// On C23, use typeof(). Otherwise __typeof__() if on GCC, clang or
542-
// MSVC 17.9 and newer. Else if on C++11 or newer, decltype() is used.
541+
// On C23, use typeof(). On C++11, use decltype(). Otherwise, use __typeof__()
542+
// if on GCC, clang or MSVC 17.9 and newer.
543+
//
544+
// On MSVC, check also _MSVC_LANG since __cplusplus is 199711L unless
545+
// the /Zc:__cplusplus flag is used.
543546
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
544547
# define _Py_TYPEOF(expr) typeof(expr)
548+
#elif defined(__cplusplus) && (__cplusplus >= 201103L || _MSVC_LANG >= 201103L)
549+
# define _Py_TYPEOF(expr) decltype(expr)
545550
#elif defined(__GNUC__) || defined(__clang__) || \
546551
(defined(_MSC_VER) && _MSC_VER >= 1939)
547552
# define _Py_TYPEOF(expr) __typeof__(expr)
548-
#elif defined(__cplusplus) && __cplusplus >= 201103L
549-
# define _Py_TYPEOF(expr) decltype(expr)
550553
#endif
551554

552555

Include/refcount.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op)
482482
#ifdef _Py_TYPEOF
483483
#define Py_CLEAR(op) \
484484
do { \
485-
_Py_TYPEOF(op)* _tmp_op_ptr = &(op); \
485+
_Py_TYPEOF(&(op)) _tmp_op_ptr = &(op); \
486486
_Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \
487487
if (_tmp_old_op != _Py_NULL) { \
488488
*_tmp_op_ptr = _Py_NULL; \

Lib/test/test_clinic.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,9 @@ def test_directive_output_invalid_command(self):
644644
- 'methoddef_define'
645645
- 'impl_prototype'
646646
- 'parser_prototype'
647+
- 'parser_helper'
647648
- 'parser_definition'
649+
- 'vectorcall_definition'
648650
- 'cpp_endif'
649651
- 'methoddef_ifndef'
650652
- 'impl_definition'
@@ -2887,6 +2889,112 @@ def test_duplicate_coexist(self):
28872889
"""
28882890
self.expect_failure(block, err, lineno=2)
28892891

2892+
def test_duplicate_vectorcall(self):
2893+
err = "Called @vectorcall twice"
2894+
block = """
2895+
module m
2896+
class Foo "FooObject *" ""
2897+
@vectorcall
2898+
@vectorcall
2899+
Foo.__init__
2900+
"""
2901+
self.expect_failure(block, err, lineno=3)
2902+
2903+
def test_vectorcall_on_regular_method(self):
2904+
err = "@vectorcall can only be used with __init__ and __new__ methods"
2905+
block = """
2906+
module m
2907+
class Foo "FooObject *" ""
2908+
@vectorcall
2909+
Foo.some_method
2910+
"""
2911+
self.expect_failure(block, err, lineno=3)
2912+
2913+
def test_vectorcall_on_module_function(self):
2914+
err = "@vectorcall can only be used with __init__ and __new__ methods"
2915+
block = """
2916+
module m
2917+
@vectorcall
2918+
m.fn
2919+
"""
2920+
self.expect_failure(block, err, lineno=2)
2921+
2922+
def test_vectorcall_on_init(self):
2923+
block = """
2924+
module m
2925+
class Foo "FooObject *" "Foo_Type"
2926+
@vectorcall
2927+
Foo.__init__
2928+
iterable: object = NULL
2929+
/
2930+
"""
2931+
func = self.parse_function(block, signatures_in_block=3,
2932+
function_index=2)
2933+
self.assertTrue(func.vectorcall)
2934+
2935+
def test_vectorcall_on_new(self):
2936+
block = """
2937+
module m
2938+
class Foo "FooObject *" "Foo_Type"
2939+
@classmethod
2940+
@vectorcall
2941+
Foo.__new__
2942+
x: object = NULL
2943+
/
2944+
"""
2945+
func = self.parse_function(block, signatures_in_block=3,
2946+
function_index=2)
2947+
self.assertTrue(func.vectorcall)
2948+
2949+
def test_vectorcall_takes_no_arguments(self):
2950+
err = "at_vectorcall() takes 1 positional argument but 2 were given"
2951+
block = """
2952+
module m
2953+
class Foo "FooObject *" "Foo_Type"
2954+
@vectorcall bogus=True
2955+
Foo.__init__
2956+
"""
2957+
self.expect_failure(block, err, lineno=2)
2958+
2959+
def test_vectorcall_without_type_object(self):
2960+
err = "@vectorcall requires the type object of 'Foo'"
2961+
block = """
2962+
module m
2963+
class Foo "FooObject *" ""
2964+
@vectorcall
2965+
Foo.__init__
2966+
"""
2967+
self.expect_failure(block, err, lineno=3)
2968+
2969+
def test_vectorcall_unsupported_converter(self):
2970+
# str(encoding=...) has no parse_arg() implementation.
2971+
err = ("@vectorcall requires all converters to support "
2972+
"parse_arg(); parameter 's' does not")
2973+
block = """
2974+
module m
2975+
class Foo "FooObject *" "Foo_Type"
2976+
@classmethod
2977+
@vectorcall
2978+
Foo.__new__
2979+
s: str(encoding="utf-8")
2980+
/
2981+
"""
2982+
self.expect_failure(block, err, lineno=6)
2983+
2984+
def test_vectorcall_with_option_groups(self):
2985+
err = "@vectorcall does not support optional groups"
2986+
block = """
2987+
module m
2988+
class Foo "FooObject *" "Foo_Type"
2989+
@vectorcall
2990+
Foo.__init__
2991+
[
2992+
a: object
2993+
]
2994+
/
2995+
"""
2996+
self.expect_failure(block, err, lineno=7)
2997+
28902998
def test_unused_param(self):
28912999
block = self.parse("""
28923000
module foo
@@ -5020,6 +5128,105 @@ def test_kwds_with_pos_only_and_stararg(self):
50205128
self.assertEqual(ac_tester.kwds_with_pos_only_and_stararg(1, 2, *args, **kwds), (1, 2, args, kwds))
50215129

50225130

5131+
@unittest.skipIf(ac_tester is None, "_testclinic is missing")
5132+
class VectorcallFunctionalTest(unittest.TestCase):
5133+
"""Runtime tests for @vectorcall exemplar types."""
5134+
5135+
def test_vc_new(self):
5136+
self.assertIsInstance(ac_tester.VcNew(), ac_tester.VcNew)
5137+
self.assertIsInstance(ac_tester.VcNew(1), ac_tester.VcNew)
5138+
self.assertIsInstance(ac_tester.VcNew(a=1), ac_tester.VcNew)
5139+
5140+
def test_vc_new_rejects_extra_args(self):
5141+
with self.assertRaises(TypeError):
5142+
ac_tester.VcNew(1, 2)
5143+
5144+
def test_vc_init(self):
5145+
self.assertIsInstance(ac_tester.VcInit(1), ac_tester.VcInit)
5146+
self.assertIsInstance(ac_tester.VcInit(1, 2), ac_tester.VcInit)
5147+
self.assertIsInstance(ac_tester.VcInit(1, b=2), ac_tester.VcInit)
5148+
5149+
def test_vc_init_missing_required(self):
5150+
with self.assertRaises(TypeError):
5151+
ac_tester.VcInit()
5152+
5153+
def test_vc_init_rejects_a_as_keyword(self):
5154+
# 'a' is positional-only
5155+
with self.assertRaises(TypeError):
5156+
ac_tester.VcInit(a=1)
5157+
5158+
def test_vc_new_base(self):
5159+
self.assertIsInstance(ac_tester.VcNewBase(1), ac_tester.VcNewBase)
5160+
self.assertIsInstance(ac_tester.VcNewBase(1, 2), ac_tester.VcNewBase)
5161+
self.assertIsInstance(ac_tester.VcNewBase(1, b=2), ac_tester.VcNewBase)
5162+
5163+
def test_vc_new_base_missing_required(self):
5164+
with self.assertRaises(TypeError):
5165+
ac_tester.VcNewBase()
5166+
5167+
def test_vc_new_base_subclass(self):
5168+
# tp_vectorcall is not inherited, so the subclass is constructed
5169+
# through tp_new. The generated vectorcall asserts on that, so a
5170+
# debug build aborts here if that ever stops holding.
5171+
Sub = type('Sub', (ac_tester.VcNewBase,), {})
5172+
obj = Sub(1)
5173+
self.assertIsInstance(obj, Sub)
5174+
self.assertIsInstance(obj, ac_tester.VcNewBase)
5175+
5176+
def test_vc_kwonly(self):
5177+
# keyword-only 'b': vectorcall has no kwnames==NULL fast path,
5178+
# so every call goes through the helper.
5179+
self.assertIsInstance(ac_tester.VcKwOnly(1), ac_tester.VcKwOnly)
5180+
self.assertIsInstance(ac_tester.VcKwOnly(1, b=2), ac_tester.VcKwOnly)
5181+
self.assertIsInstance(ac_tester.VcKwOnly(a=1, b=2), ac_tester.VcKwOnly)
5182+
5183+
def test_vc_kwonly_b_as_positional(self):
5184+
with self.assertRaises(TypeError):
5185+
ac_tester.VcKwOnly(1, 2)
5186+
5187+
def test_vc_kwonly_missing_required(self):
5188+
with self.assertRaises(TypeError):
5189+
ac_tester.VcKwOnly()
5190+
5191+
def test_parse_errors_match_slot(self):
5192+
# tp_vectorcall and tp_new/tp_init slot should match in argument parsing
5193+
# error messages. Explicit calls to __new__ and __init__, as well as
5194+
# subtype calls, will not hit the vectorcall slot. Test errors match.
5195+
def error(func, args, kwargs):
5196+
try:
5197+
func(*args, **kwargs)
5198+
except TypeError as exc:
5199+
return str(exc)
5200+
return None
5201+
5202+
def through_new(cls):
5203+
return cls, partial(cls.__new__, cls)
5204+
5205+
def through_init(cls):
5206+
# Not subclassable, and tp_new is PyType_GenericNew, so reach
5207+
# tp_init through the __init__ slot wrapper on an instance.
5208+
return cls, partial(cls.__init__, cls(1))
5209+
5210+
entry_points = [
5211+
through_new(enumerate), # the only non-test @vectorcall function
5212+
through_new(ac_tester.VcNew),
5213+
through_new(ac_tester.VcNewBase),
5214+
through_new(ac_tester.VcKwOnly),
5215+
through_init(ac_tester.VcInit),
5216+
]
5217+
invalid_calls = [
5218+
((), {}), # too few positional arguments
5219+
((1, 2, 3), {}), # too many positional arguments
5220+
((), {'zz': 1}), # unknown keyword argument
5221+
]
5222+
5223+
for direct, slot in entry_points:
5224+
for args, kwargs in invalid_calls:
5225+
with self.subTest(cls=direct, args=args, kwargs=kwargs):
5226+
self.assertEqual(error(direct, args, kwargs),
5227+
error(slot, args, kwargs))
5228+
5229+
50235230
class LimitedCAPIOutputTests(unittest.TestCase):
50245231

50255232
def setUp(self):

0 commit comments

Comments
 (0)