File size: 105,863 Bytes
9273228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
# What\'s new in Python 3.15

Editor
:   Hugo van Kemenade

> \* Anyone can add text to this document. Do not spend very much time on the wording of your changes, because your text will probably get rewritten to some degree.
>
> \* The maintainer will go through Misc/NEWS periodically and add changes; it\'s therefore more important to add your changes to Misc/NEWS than to this file.
>
> \* This is not a complete list of every single change; completeness is the purpose of Misc/NEWS. Some changes I consider too small or esoteric to include. If such a change is added to the text, I\'ll just remove it. (This is another reason you shouldn\'t spend too much time on writing your addition.)
>
> \* If you want to draw your new text to the attention of the maintainer, add \'XXX\' to the beginning of the paragraph or section.
>
> \* It\'s OK to just add a fragmentary note about a change. For example: \"XXX Describe the transmogrify() function added to the socket module.\" The maintainer will research the change and write the necessary text.
>
> \* You can comment out your additions if you like, but it\'s not necessary (especially when a final release is some months away).
>
> \* Credit the author of a patch or bugfix. Just the name is sufficient; the e-mail address isn\'t necessary.
>
> - It\'s helpful to add the issue number as a comment:
>
> XXX Describe the transmogrify() function added to the socket module. (Contributed by P.Y. Developer in `12345`{.interpreted-text role="gh"}.)
>
> This saves the maintainer the effort of going through the VCS log when researching a change.

This article explains the new features in Python 3.15, compared to 3.14.

For full details, see the `changelog <changelog>`{.interpreted-text role="ref"}.

:::: note
::: title
Note
:::

Prerelease users should be aware that this document is currently in draft form. It will be updated substantially as Python 3.15 moves towards release, so it\'s worth checking back even after reading earlier versions.
::::

## Summary \-- Release highlights

- `810`{.interpreted-text role="pep"}: `Explicit lazy imports for faster startup times
  <whatsnew315-pep810>`{.interpreted-text role="ref"}
- `814`{.interpreted-text role="pep"}: `Add frozendict built-in type
  <whatsnew315-frozendict>`{.interpreted-text role="ref"}
- `799`{.interpreted-text role="pep"}: `A dedicated profiling package for organizing Python
  profiling tools <whatsnew315-profiling-package>`{.interpreted-text role="ref"}
- `799`{.interpreted-text role="pep"}: `Tachyon: High frequency statistical sampling profiler
  <whatsnew315-sampling-profiler>`{.interpreted-text role="ref"}
- `798`{.interpreted-text role="pep"}: `Unpacking in Comprehensions
  <whatsnew315-unpacking-in-comprehensions>`{.interpreted-text role="ref"}
- `686`{.interpreted-text role="pep"}: `Python now uses UTF-8 as the default encoding
  <whatsnew315-utf8-default>`{.interpreted-text role="ref"}
- `782`{.interpreted-text role="pep"}: `A new PyBytesWriter C API to create a Python bytes object
  <whatsnew315-pep782>`{.interpreted-text role="ref"}
- `The JIT compiler has been significantly upgraded <whatsnew315-jit>`{.interpreted-text role="ref"}
- `Improved error messages <whatsnew315-improved-error-messages>`{.interpreted-text role="ref"}

## New features

### `810`{.interpreted-text role="pep"}: Explicit lazy imports {#whatsnew315-pep810}

Large Python applications often suffer from slow startup times. A significant contributor to this problem is the import system: when a module is imported, Python must locate the file, read it from disk, compile it to bytecode, and execute all top-level code. For applications with deep dependency trees, this process can take seconds, even when most of the imported code is never actually used during a particular run.

Developers have worked around this by moving imports inside functions, using `importlib`{.interpreted-text role="mod"} to load modules on demand, or restructuring code to avoid unnecessary dependencies. These approaches work but make code harder to read and maintain, scatter import statements throughout the codebase, and require discipline to apply consistently.

Python now provides a cleaner solution through explicit `lazy`{.interpreted-text role="keyword"} imports using the new `lazy` soft keyword. When you mark an import as lazy, Python defers the actual module loading until the imported name is first used. This gives you the organizational benefits of declaring all imports at the top of the file while only paying the loading cost for modules you actually use.

The `lazy` keyword works with both `import` and `from ... import` statements. When you write `lazy import heavy_module`, Python does not immediately load the module. Instead, it creates a lightweight proxy object. The actual module loading happens transparently when you first access the name:

``` python
lazy import json
lazy from datetime import datetime

print("Starting up...")  # json and datetime not loaded yet

data = json.loads('{"key": "value"}')  # json gets loads here
now = datetime()  # datetime loads here
```

This mechanism is particularly useful for applications that import many modules at the top level but may only use a subset of them in any given run. The deferred loading reduces startup latency without requiring code restructuring or conditional imports scattered throughout the codebase.

In the case where loading a lazily imported module fails (for example, if the module does not exist), Python raises the exception at the point of first use rather than at import time. The associated traceback includes both the location where the name was accessed and the original import statement, making it straightforward to diagnose & debug the failure.

For cases where you want to enable lazy loading globally without modifying source code, Python provides the `-X lazy_imports <-X>`{.interpreted-text role="option"} command-line option and the `PYTHON_LAZY_IMPORTS`{.interpreted-text role="envvar"} environment variable. Both accept three values: `all` makes all imports lazy by default, `none` disables lazy imports entirely (even explicit `lazy` statements become eager), and `normal` (the default) respects the `lazy` keyword in source code. The `sys.set_lazy_imports`{.interpreted-text role="func"} and `sys.get_lazy_imports`{.interpreted-text role="func"} functions allow changing and querying this mode at runtime.

For more selective control, `sys.set_lazy_imports_filter`{.interpreted-text role="func"} accepts a callable that determines whether a specific module should be loaded lazily. The filter receives three arguments: the importing module\'s name (or `None`), the imported module\'s name, and the fromlist (or `None` for regular imports). It should return `True` to allow the import to be lazy, or `False` to force eager loading. This allows patterns like making only your own application\'s modules lazy while keeping third-party dependencies eager:

``` python
import sys

def myapp_filter(importing, imported, fromlist):
    return imported.startswith("myapp.")
sys.set_lazy_imports_filter(myapp_filter)
sys.set_lazy_imports("all")

import myapp.slow_module  # lazy (matches filter)
import json               # eager (does not match filter)
```

The proxy type itself is available as `types.LazyImportType`{.interpreted-text role="data"} for code that needs to detect lazy imports programmatically.

There are some restrictions on where the `lazy` keyword can be used. Lazy imports are only permitted at module scope; using `lazy` inside a function, class body, or `try`/`except`/`finally` block raises a `SyntaxError`{.interpreted-text role="exc"}. Neither star imports nor future imports can be lazy (`lazy from module import *` and `lazy from __future__ import ...` both raise `SyntaxError`{.interpreted-text role="exc"}).

::: seealso
`810`{.interpreted-text role="pep"} for the full specification and rationale.
:::

(Contributed by Pablo Galindo Salgado and Dino Viehland in `142349`{.interpreted-text role="gh"}.)

### `814`{.interpreted-text role="pep"}: Add frozendict built-in type {#whatsnew315-frozendict}

A new `immutable`{.interpreted-text role="term"} type, `frozendict`{.interpreted-text role="class"}, is added to the `builtins`{.interpreted-text role="mod"} module. It does not allow modification after creation. A `frozendict` is not a subclass of `dict`; it inherits directly from `object`. A `frozendict` is `hashable`{.interpreted-text role="term"} as long as all of its keys and values are hashable. A `frozendict` preserves insertion order, but comparison does not take order into account.

For example:

    >>> a = frozendict(x=1, y=2)
    >>> a
    frozendict({'x': 1, 'y': 2})
    >>> a['z'] = 3
    Traceback (most recent call last):
      File "<python-input-2>", line 1, in <module>
        a['z'] = 3
        ~^^^^^
    TypeError: 'frozendict' object does not support item assignment
    >>> b = frozendict(y=2, x=1)
    >>> hash(a) == hash(b)
    True
    >>> a == b
    True

::: seealso
`814`{.interpreted-text role="pep"} for the full specification and rationale.
:::

(Contributed by Victor Stinner and Donghee Na in `141510`{.interpreted-text role="gh"}.)

### `799`{.interpreted-text role="pep"}: A dedicated profiling package {#whatsnew315-profiling-package}

A new `profiling`{.interpreted-text role="mod"} module has been added to organize Python\'s built-in profiling tools under a single, coherent namespace. This module contains:

- `profiling.tracing`{.interpreted-text role="mod"}: deterministic function-call tracing (relocated from `cProfile`).
- `profiling.sampling`{.interpreted-text role="mod"}: a new statistical sampling profiler (named Tachyon).

The `cProfile` module remains as an alias for backwards compatibility. The `profile`{.interpreted-text role="mod"} module is deprecated and will be removed in Python 3.17.

::: seealso
`799`{.interpreted-text role="pep"} for further details.
:::

(Contributed by Pablo Galindo and László Kiss Kollár in `138122`{.interpreted-text role="gh"}.)

### Tachyon: High frequency statistical sampling profiler {#whatsnew315-sampling-profiler}

![Tachyon profiler logo](../library/tachyon-logo.png){.align-center width="200px"}

A new statistical sampling profiler (Tachyon) has been added as `profiling.sampling`{.interpreted-text role="mod"}. This profiler enables low-overhead performance analysis of running Python processes without requiring code modification or process restart.

Unlike deterministic profilers (such as `profiling.tracing`{.interpreted-text role="mod"}) that instrument every function call, the sampling profiler periodically captures stack traces from running processes. This approach provides virtually zero overhead while achieving sampling rates of **up to 1,000,000 Hz**, making it the fastest sampling profiler available for Python (at the time of its contribution) and ideal for debugging performance issues in production environments. This capability is particularly valuable for debugging performance issues in production systems where traditional profiling approaches would be too intrusive.

Key features include:

- **Zero-overhead profiling**: Attach to any running Python process without affecting its performance. Ideal for production debugging where you can\'t afford to restart or slow down your application.
- **No code modification required**: Profile existing applications without restart. Simply point the profiler at a running process by PID and start collecting data.
- **Flexible target modes**:
  - Profile running processes by PID (`attach`) - attach to already-running applications
  - Run and profile scripts directly (`run`) - profile from the very start of execution
  - Execute and profile modules (`run -m`) - profile packages run as `python -m module`
- **Multiple profiling modes**: Choose what to measure based on your performance investigation:
  - **Wall-clock time** (`--mode wall`, default): Measures real elapsed time including I/O, network waits, and blocking operations. Use this to understand where your program spends calendar time, including when waiting for external resources.
  - **CPU time** (`--mode cpu`): Measures only active CPU execution time, excluding I/O waits and blocking. Use this to identify CPU-bound bottlenecks and optimize computational work.
  - **GIL-holding time** (`--mode gil`): Measures time spent holding Python\'s Global Interpreter Lock. Use this to identify which threads dominate GIL usage in multi-threaded applications.
  - **Exception handling time** (`--mode exception`): Captures samples only from threads with an active exception. Use this to analyze exception handling overhead.
- **Thread-aware profiling**: Option to profile all threads (`-a`) or just the main thread, essential for understanding multi-threaded application behavior.
- **Multiple output formats**: Choose the visualization that best fits your workflow:
  - `--pstats`: Detailed tabular statistics compatible with `pstats`{.interpreted-text role="mod"}. Shows function-level timing with direct and cumulative samples. Best for detailed analysis and integration with existing Python profiling tools.
  - `--collapsed`: Generates collapsed stack traces (one line per stack). This format is specifically designed for creating flame graphs with external tools like Brendan Gregg\'s FlameGraph scripts or speedscope.
  - `--flamegraph`: Generates a self-contained interactive HTML flame graph using D3.js. Opens directly in your browser for immediate visual analysis. Flame graphs show the call hierarchy where width represents time spent, making it easy to spot bottlenecks at a glance.
  - `--gecko`: Generates Gecko Profiler format compatible with [Firefox Profiler](https://profiler.firefox.com). Upload the output to Firefox Profiler for advanced timeline-based analysis with features like stack charts, markers, and network activity.
  - `--heatmap`: Generates an interactive HTML heatmap visualization with line-level sample counts. Creates a directory with per-file heatmaps showing exactly where time is spent at the source code level.
- **Live interactive mode**: Real-time TUI profiler with a top-like interface (`--live`). Monitor performance as your application runs with interactive sorting and filtering.
- **Async-aware profiling**: Profile async/await code with task-based stack reconstruction (`--async-aware`). See which coroutines are consuming time, with options to show only running tasks or all tasks including those waiting.
- **Opcode-level profiling**: Gather bytecode opcode information for instruction-level profiling (`--opcodes`). Shows which bytecode instructions are executing, including specializations from the adaptive interpreter.

See `profiling.sampling`{.interpreted-text role="mod"} for the complete documentation, including all available output formats, profiling modes, and configuration options.

(Contributed by Pablo Galindo and László Kiss Kollár in `135953`{.interpreted-text role="gh"} and `138122`{.interpreted-text role="gh"}.)

### `798`{.interpreted-text role="pep"}: Unpacking in Comprehensions {#whatsnew315-unpacking-in-comprehensions}

List, set, and dictionary comprehensions, as well as generator expressions, now support unpacking with `*` and `**`. This extends the unpacking syntax from `448`{.interpreted-text role="pep"} to comprehensions, providing a new syntax for combining an arbitrary number of iterables or dictionaries into a single flat structure. This new syntax is a direct alternative to nested comprehensions, `itertools.chain`{.interpreted-text role="func"}, and `itertools.chain.from_iterable`{.interpreted-text role="meth"}. For example:

    >>> lists = [[1, 2], [3, 4], [5]]
    >>> [*L for L in lists]  # equivalent to [x for L in lists for x in L]
    [1, 2, 3, 4, 5]

    >>> sets = [{1, 2}, {2, 3}, {3, 4}]
    >>> {*s for s in sets}  # equivalent to {x for s in sets for x in s}
    {1, 2, 3, 4}

    >>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
    >>> {**d for d in dicts}  # equivalent to {k: v for d in dicts for k,v in d.items()}
    {'a': 3, 'b': 2}

Generator expressions can similarly use unpacking to yield values from multiple iterables:

    >>> gen = (*L for L in lists)  # equivalent to (x for L in lists for x in L)
    >>> list(gen)
    [1, 2, 3, 4, 5]

This change also extends to asynchronous generator expressions, such that, for example, `(*a async for a in agen())` is equivalent to `(x async for a in agen() for x in a)`.

::: seealso
`798`{.interpreted-text role="pep"} for further details.
:::

(Contributed by Adam Hartz in `143055`{.interpreted-text role="gh"}.)

### Improved error messages {#whatsnew315-improved-error-messages}

- The interpreter now provides more helpful suggestions in `AttributeError`{.interpreted-text role="exc"} exceptions when accessing an attribute on an object that does not exist, but a similar attribute is available through one of its members.

  For example, if the object has an attribute that itself exposes the requested name, the error message will suggest accessing it via that inner attribute:

  ``` python
  @dataclass
  class Circle:
     radius: float

     @property
     def area(self) -> float:
        return pi * self.radius**2

  class Container:
     def __init__(self, inner: Circle) -> None:
        self.inner = inner

  circle = Circle(radius=4.0)
  container = Container(circle)
  print(container.area)
  ```

  Running this code now produces a clearer suggestion:

  ``` pycon
  Traceback (most recent call last):
  File "/home/pablogsal/github/python/main/lel.py", line 42, in <module>
     print(container.area)
           ^^^^^^^^^^^^^^
  AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'?
  ```

## Other language changes

::: {#whatsnew315-utf8-default}
- Python now uses [UTF-8](https://en.wikipedia.org/wiki/UTF-8) as the default encoding, independent of the system\'s environment. This means that I/O operations without an explicit encoding, for example, `open('flying-circus.txt')`, will use UTF-8. UTF-8 is a widely-supported [Unicode](https://home.unicode.org/) character encoding that has become a *de facto* standard for representing text, including nearly every webpage on the internet, many common file formats, programming languages, and more.

  This only applies when no `encoding` argument is given. For best compatibility between versions of Python, ensure that an explicit `encoding` argument is always provided. The `opt-in encoding warning <io-encoding-warning>`{.interpreted-text role="ref"} can be used to identify code that may be affected by this change. The special `encoding='locale'` argument uses the current locale encoding, and has been supported since Python 3.10.

  To retain the previous behaviour, Python\'s UTF-8 mode may be disabled with the `PYTHONUTF8=0 <PYTHONUTF8>`{.interpreted-text role="envvar"} environment variable or the `-X utf8=0 <-X>`{.interpreted-text role="option"} command-line option.

  ::: seealso
  `686`{.interpreted-text role="pep"} for further details.
  :::

  (Contributed by Adam Turner in `133711`{.interpreted-text role="gh"}; PEP 686 written by Inada Naoki.)

- Several error messages incorrectly using the term \"argument\" have been corrected. (Contributed by Stan Ulbrych in `133382`{.interpreted-text role="gh"}.)

- The interpreter now tries to provide a suggestion when `delattr`{.interpreted-text role="func"} fails due to a missing attribute. When an attribute name that closely resembles an existing attribute is used, the interpreter will suggest the correct attribute name in the error message. For example:

  ::: doctest
  \>\>\> class A: \... pass \>\>\> a = A() \>\>\> a.abcde = 1 \>\>\> del a.abcdf \# doctest: +ELLIPSIS Traceback (most recent call last): \... AttributeError: \'A\' object has no attribute \'abcdf\'. Did you mean: \'abcde\'?
  :::

  (Contributed by Nikita Sobolev and Pranjal Prajapati in `136588`{.interpreted-text role="gh"}.)

- Unraisable exceptions are now highlighted with color by default. This can be controlled by `environment variables <using-on-controlling-color>`{.interpreted-text role="ref"}. (Contributed by Peter Bierma in `134170`{.interpreted-text role="gh"}.)

- The `~object.__repr__`{.interpreted-text role="meth"} of `ImportError`{.interpreted-text role="class"} and `ModuleNotFoundError`{.interpreted-text role="class"} now shows \"name\" and \"path\" as `name=<name>` and `path=<path>` if they were given as keyword arguments at construction time. (Contributed by Serhiy Storchaka, Oleg Iarygin, and Yoav Nir in `74185`{.interpreted-text role="gh"}.)

- The `~object.__dict__`{.interpreted-text role="attr"} and `!__weakref__`{.interpreted-text role="attr"} descriptors now use a single descriptor instance per interpreter, shared across all types that need them. This speeds up class creation, and helps avoid reference cycles. (Contributed by Petr Viktorin in `135228`{.interpreted-text role="gh"}.)

- The `-W`{.interpreted-text role="option"} option and the `PYTHONWARNINGS`{.interpreted-text role="envvar"} environment variable can now specify regular expressions instead of literal strings to match the warning message and the module name, if the corresponding field starts and ends with a forward slash (`/`). (Contributed by Serhiy Storchaka in `134716`{.interpreted-text role="gh"}.)

- Functions that take timestamp or timeout arguments now accept any real numbers (such as `~decimal.Decimal`{.interpreted-text role="class"} and `~fractions.Fraction`{.interpreted-text role="class"}), not only integers or floats, although this does not improve precision. (Contributed by Serhiy Storchaka in `67795`{.interpreted-text role="gh"}.)
:::

::: {#whatsnew315-bytearray-take-bytes}
- Added `bytearray.take_bytes(n=None, /) <bytearray.take_bytes>`{.interpreted-text role="meth"} to take bytes out of a `bytearray`{.interpreted-text role="class"} without copying. This enables optimizing code which must return `bytes`{.interpreted-text role="class"} after working with a mutable buffer of bytes such as data buffering, network protocol parsing, encoding, decoding, and compression. Common code patterns which can be optimized with `~bytearray.take_bytes`{.interpreted-text role="func"} are listed below.

  +---------------------------------------------------------------------------------------------------------------+------------------------------------+---------------------------------+
  | Description                                                                                                   | Old                                | New                             |
  +===============================================================================================================+====================================+=================================+
  | Return `bytes`{.interpreted-text role="class"} after working with `bytearray`{.interpreted-text role="class"} | ``` python                         | ``` python                      |
  |                                                                                                               | def read() -> bytes:               | def read() -> bytes:            |
  |                                                                                                               |     buffer = bytearray(1024)       |     buffer = bytearray(1024)    |
  |                                                                                                               |     ...                            |     ...                         |
  |                                                                                                               |     return bytes(buffer)           |     return buffer.take_bytes()  |
  |                                                                                                               | ```                                | ```                             |
  +---------------------------------------------------------------------------------------------------------------+------------------------------------+---------------------------------+
  | Empty a buffer getting the bytes                                                                              | ``` python                         | ``` python                      |
  |                                                                                                               | buffer = bytearray(1024)           | buffer = bytearray(1024)        |
  |                                                                                                               | ...                                | ...                             |
  |                                                                                                               | data = bytes(buffer)               | data = buffer.take_bytes()      |
  |                                                                                                               | buffer.clear()                     | ```                             |
  |                                                                                                               | ```                                |                                 |
  +---------------------------------------------------------------------------------------------------------------+------------------------------------+---------------------------------+
  | Split a buffer at a specific separator                                                                        | ``` python                         | ``` python                      |
  |                                                                                                               | buffer = bytearray(b'abc\ndef')    | buffer = bytearray(b'abc\ndef') |
  |                                                                                                               | n = buffer.find(b'\n')             | n = buffer.find(b'\n')          |
  |                                                                                                               | data = bytes(buffer[:n + 1])       | data = buffer.take_bytes(n + 1) |
  |                                                                                                               | del buffer[:n + 1]                 | ```                             |
  |                                                                                                               | assert data == b'abc'              |                                 |
  |                                                                                                               | assert buffer == bytearray(b'def') |                                 |
  |                                                                                                               | ```                                |                                 |
  +---------------------------------------------------------------------------------------------------------------+------------------------------------+---------------------------------+
  | Split a buffer at a specific separator; discard after the separator                                           | ``` python                         | ``` python                      |
  |                                                                                                               | buffer = bytearray(b'abc\ndef')    | buffer = bytearray(b'abc\ndef') |
  |                                                                                                               | n = buffer.find(b'\n')             | n = buffer.find(b'\n')          |
  |                                                                                                               | data = bytes(buffer[:n])           | buffer.resize(n)                |
  |                                                                                                               | buffer.clear()                     | data = buffer.take_bytes()      |
  |                                                                                                               | assert data == b'abc'              | ```                             |
  |                                                                                                               | assert len(buffer) == 0            |                                 |
  |                                                                                                               | ```                                |                                 |
  +---------------------------------------------------------------------------------------------------------------+------------------------------------+---------------------------------+

  : Suggested optimizing refactors

  (Contributed by Cody Maloney in `139871`{.interpreted-text role="gh"}.)

- Many functions related to compiling or parsing Python code, such as `compile`{.interpreted-text role="func"}, `ast.parse`{.interpreted-text role="func"}, `symtable.symtable`{.interpreted-text role="func"}, and `importlib.abc.InspectLoader.source_to_code`{.interpreted-text role="func"}, now allow the module name to be passed. It is needed to unambiguously `filter <warning-filter>`{.interpreted-text role="ref"} syntax warnings by module name. (Contributed by Serhiy Storchaka in `135801`{.interpreted-text role="gh"}.)

- Allowed defining the *\_\_dict\_\_* and *\_\_weakref\_\_* `__slots__ <slots>`{.interpreted-text role="ref"} for any class. (Contributed by Serhiy Storchaka in `41779`{.interpreted-text role="gh"}.)

- Allowed defining any `__slots__ <slots>`{.interpreted-text role="ref"} for a class derived from `tuple`{.interpreted-text role="class"} (including classes created by `collections.namedtuple`{.interpreted-text role="func"}). (Contributed by Serhiy Storchaka in `41779`{.interpreted-text role="gh"}.)

- The `slice`{.interpreted-text role="class"} type now supports subscription, making it a `generic type`{.interpreted-text role="term"}. (Contributed by James Hilton-Balfe in `128335`{.interpreted-text role="gh"}.)
:::

## New modules

### math.integer

This module provides access to the mathematical functions for integer arguments (`791`{.interpreted-text role="pep"}). (Contributed by Serhiy Storchaka in `81313`{.interpreted-text role="gh"}.)

## Improved modules

### argparse

- The `~argparse.BooleanOptionalAction`{.interpreted-text role="class"} action supports now single-dash long options and alternate prefix characters. (Contributed by Serhiy Storchaka in `138525`{.interpreted-text role="gh"}.)
- Changed the *suggest_on_error* parameter of `argparse.ArgumentParser`{.interpreted-text role="class"} to default to `True`. This enables suggestions for mistyped arguments by default. (Contributed by Jakob Schluse in `140450`{.interpreted-text role="gh"}.)
- Added backtick markup support in description and epilog text to highlight inline code when color output is enabled. (Contributed by Savannah Ostrowski in `142390`{.interpreted-text role="gh"}.)

### base64

- Added the *pad* parameter in `~base64.z85encode`{.interpreted-text role="func"}. (Contributed by Hauke Dämpfling in `143103`{.interpreted-text role="gh"}.)
- Added the *wrapcol* parameter in `~base64.b64encode`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `143214`{.interpreted-text role="gh"}.)
- Added the *ignorechars* parameter in `~base64.b64decode`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `144001`{.interpreted-text role="gh"}.)

### binascii

- Added functions for Ascii85, Base85, and Z85 encoding:

  - `~binascii.b2a_ascii85`{.interpreted-text role="func"} and `~binascii.a2b_ascii85`{.interpreted-text role="func"}
  - `~binascii.b2a_base85`{.interpreted-text role="func"} and `~binascii.a2b_base85`{.interpreted-text role="func"}
  - `~binascii.b2a_z85`{.interpreted-text role="func"} and `~binascii.a2b_z85`{.interpreted-text role="func"}

  (Contributed by James Seo and Serhiy Storchaka in `101178`{.interpreted-text role="gh"}.)

- Added the *wrapcol* parameter in `~binascii.b2a_base64`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `143214`{.interpreted-text role="gh"}.)

- Added the *ignorechars* parameter in `~binascii.a2b_base64`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `144001`{.interpreted-text role="gh"}.)

### calendar

- Calendar pages generated by the `calendar.HTMLCalendar`{.interpreted-text role="class"} class now support dark mode and have been migrated to the HTML5 standard for improved accessibility. (Contributed by Jiahao Li and Hugo van Kemenade in `137634`{.interpreted-text role="gh"}.)
- The `calendar`{.interpreted-text role="mod"}\'s `command-line <calendar-cli>`{.interpreted-text role="ref"} HTML output now accepts the year-month option: `python -m calendar -t html 2009 06`. (Contributed by Pål Grønås Drange in `140212`{.interpreted-text role="gh"}.)

### collections

- Added `!collections.Counter.__xor__`{.interpreted-text role="meth"} and `!collections.Counter.__ixor__`{.interpreted-text role="meth"} to compute the symmetric difference between `~collections.Counter`{.interpreted-text role="class"} objects. (Contributed by Raymond Hettinger in `138682`{.interpreted-text role="gh"}.)

### collections.abc

- `collections.abc.ByteString`{.interpreted-text role="class"} has been removed from `collections.abc.__all__`. `!collections.abc.ByteString`{.interpreted-text role="class"} has been deprecated since Python 3.12, and is scheduled for removal in Python 3.17.

- The following statements now cause `DeprecationWarning`s to be emitted at runtime:

  - `from collections.abc import ByteString`
  - `import collections.abc; collections.abc.ByteString`.

  `DeprecationWarning`s were already emitted if `collections.abc.ByteString`{.interpreted-text role="class"} was subclassed or used as the second argument to `isinstance`{.interpreted-text role="func"} or `issubclass`{.interpreted-text role="func"}, but warnings were not previously emitted if it was merely imported or accessed from the `!collections.abc`{.interpreted-text role="mod"} module.

### concurrent.futures

- Improved error reporting when a child process in a `concurrent.futures.ProcessPoolExecutor`{.interpreted-text role="class"} terminates abruptly. The resulting traceback will now tell you the PID and exit code of the terminated process. (Contributed by Jonathan Berg in `139486`{.interpreted-text role="gh"}.)

### contextlib

- Added support for arbitrary descriptors `!__enter__`{.interpreted-text role="meth"}, `!__exit__`{.interpreted-text role="meth"}, `!__aenter__`{.interpreted-text role="meth"}, and `!__aexit__`{.interpreted-text role="meth"} in `~contextlib.ExitStack`{.interpreted-text role="class"} and `contextlib.AsyncExitStack`{.interpreted-text role="class"}, for consistency with the `with`{.interpreted-text role="keyword"} and `async with`{.interpreted-text role="keyword"} statements. (Contributed by Serhiy Storchaka in `144386`{.interpreted-text role="gh"}.)

### dataclasses

- Annotations for generated `__init__` methods no longer include internal type names.

### dbm

- Added new `!reorganize`{.interpreted-text role="meth"} methods to `dbm.dumb`{.interpreted-text role="mod"} and `dbm.sqlite3`{.interpreted-text role="mod"} which allow to recover unused free space previously occupied by deleted entries. (Contributed by Andrea Oliveri in `134004`{.interpreted-text role="gh"}.)

### difflib

> 

- Introduced the optional *color* parameter to `difflib.unified_diff`{.interpreted-text role="func"}, enabling color output similar to `git diff`{.interpreted-text role="program"}. This can be controlled by `environment variables
  <using-on-controlling-color>`{.interpreted-text role="ref"}. (Contributed by Douglas Thor in `133725`{.interpreted-text role="gh"}.)
- Improved the styling of HTML diff pages generated by the `difflib.HtmlDiff`{.interpreted-text role="class"} class, and migrated the output to the HTML5 standard. (Contributed by Jiahao Li in `134580`{.interpreted-text role="gh"}.)

### functools

- `~functools.singledispatchmethod`{.interpreted-text role="func"} now supports non-`descriptor`{.interpreted-text role="term"} callables. (Contributed by Serhiy Storchaka in `140873`{.interpreted-text role="gh"}.)

### hashlib

- Ensure that hash functions guaranteed to be always *available* exist as attributes of `hashlib`{.interpreted-text role="mod"} even if they will not work at runtime due to missing backend implementations. For instance, `hashlib.md5` will no longer raise `AttributeError`{.interpreted-text role="exc"} if OpenSSL is not available and Python has been built without MD5 support. (Contributed by Bénédikt Tran in `136929`{.interpreted-text role="gh"}.)

### http.client

- A new *max_response_headers* keyword-only parameter has been added to `~http.client.HTTPConnection`{.interpreted-text role="class"} and `~http.client.HTTPSConnection`{.interpreted-text role="class"} constructors. This parameter overrides the default maximum number of allowed response headers. (Contributed by Alexander Enrique Urieles Nieto in `131724`{.interpreted-text role="gh"}.)

### http.cookies

- Allow \'`"`\' double quotes in cookie values. (Contributed by Nick Burns and Senthil Kumaran in `92936`{.interpreted-text role="gh"}.)

### inspect

- Add parameters *inherit_class_doc* and *fallback_to_class_doc* for `~inspect.getdoc`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `132686`{.interpreted-text role="gh"}.)

### locale

- `~locale.setlocale`{.interpreted-text role="func"} now supports language codes with `@`-modifiers. `@`-modifiers are no longer silently removed in `~locale.getlocale`{.interpreted-text role="func"}, but included in the language code. (Contributed by Serhiy Storchaka in `137729`{.interpreted-text role="gh"}.)
- Undeprecate the `locale.getdefaultlocale`{.interpreted-text role="func"} function. (Contributed by Victor Stinner in `130796`{.interpreted-text role="gh"}.)

### math

- Add `math.isnormal`{.interpreted-text role="func"} and `math.issubnormal`{.interpreted-text role="func"} functions. (Contributed by Sergey B Kirpichev in `132908`{.interpreted-text role="gh"}.)
- Add `math.fmax`{.interpreted-text role="func"}, `math.fmin`{.interpreted-text role="func"} and `math.signbit`{.interpreted-text role="func"} functions. (Contributed by Bénédikt Tran in `135853`{.interpreted-text role="gh"}.)

### mimetypes

- Add `application/dicom` MIME type for `.dcm` extension. (Contributed by Benedikt Johannes in `144217`{.interpreted-text role="gh"}.)
- Add `application/node` MIME type for `.cjs` extension. (Contributed by John Franey in `140937`{.interpreted-text role="gh"}.)
- Add `application/toml`. (Contributed by Gil Forcada in `139959`{.interpreted-text role="gh"}.)
- Add `image/jxl`. (Contributed by Foolbar in `144213`{.interpreted-text role="gh"}.)
- Rename `application/x-texinfo` to `application/texinfo`. (Contributed by Charlie Lin in `140165`{.interpreted-text role="gh"}.)
- Changed the MIME type for `.ai` files to `application/pdf`. (Contributed by Stan Ulbrych in `141239`{.interpreted-text role="gh"}.)

### mmap

- `mmap.mmap`{.interpreted-text role="class"} now has a *trackfd* parameter on Windows; if it is `False`, the file handle corresponding to *fileno* will not be duplicated. (Contributed by Serhiy Storchaka in `78502`{.interpreted-text role="gh"}.)
- Added the `mmap.mmap.set_name`{.interpreted-text role="meth"} method to annotate an anonymous memory mapping if Linux kernel supports `PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>`{.interpreted-text role="manpage"} (Linux 5.17 or newer). (Contributed by Donghee Na in `142419`{.interpreted-text role="gh"}.)

### os

- Add `os.statx`{.interpreted-text role="func"} on Linux kernel versions 4.11 and later with glibc versions 2.28 and later. (Contributed by Jeffrey Bosboom and Victor Stinner in `83714`{.interpreted-text role="gh"}.)

### os.path

- Add support of the all-but-last mode in `~os.path.realpath`{.interpreted-text role="func"}. (Contributed by Serhiy Storchaka in `71189`{.interpreted-text role="gh"}.)
- The *strict* parameter to `os.path.realpath`{.interpreted-text role="func"} accepts a new value, `os.path.ALLOW_MISSING`{.interpreted-text role="data"}. If used, errors other than `FileNotFoundError`{.interpreted-text role="exc"} will be re-raised; the resulting path can be missing but it will be free of symlinks. (Contributed by Petr Viktorin for `2025-4517`{.interpreted-text role="cve"}.)

### pickle

- Add support for pickling private methods and nested classes. (Contributed by Zackery Spytz and Serhiy Storchaka in `77188`{.interpreted-text role="gh"}.)

### re

- `re.prefixmatch`{.interpreted-text role="func"} and a corresponding `~re.Pattern.prefixmatch`{.interpreted-text role="meth"} have been added as alternate more explicit names for the existing `re.match`{.interpreted-text role="func"} and `~re.Pattern.match`{.interpreted-text role="meth"} APIs. These are intended to be used to alleviate confusion around what *match* means by following the Zen of Python\'s *\"Explicit is better than implicit\"* mantra. Most other language regular expression libraries use an API named *match* to mean what Python has always called *search*. (Contributed by Gregory P. Smith in `86519`{.interpreted-text role="gh"}.)

### resource

- Add new constants: `~resource.RLIMIT_NTHR`{.interpreted-text role="data"}, `~resource.RLIMIT_UMTXP`{.interpreted-text role="data"}, `~resource.RLIMIT_THREADS`{.interpreted-text role="data"}, `~resource.RLIM_SAVED_CUR`{.interpreted-text role="data"}, and `~resource.RLIM_SAVED_MAX`{.interpreted-text role="data"}. (Contributed by Serhiy Storchaka in `137512`{.interpreted-text role="gh"}.)

### shelve

- Added new `!reorganize`{.interpreted-text role="meth"} method to `shelve`{.interpreted-text role="mod"} used to recover unused free space previously occupied by deleted entries. (Contributed by Andrea Oliveri in `134004`{.interpreted-text role="gh"}.)

### socket

- Add constants for the ISO-TP CAN protocol. (Contributed by Patrick Menschel and Stefan Tatschner in `86819`{.interpreted-text role="gh"}.)

### sqlite3

- The `command-line interface <sqlite3-cli>`{.interpreted-text role="ref"} has several new features:
  - SQL keyword completion on \<tab\>. (Contributed by Long Tan in `133393`{.interpreted-text role="gh"}.)
  - Prompts, error messages, and help text are now colored. This is enabled by default, see `using-on-controlling-color`{.interpreted-text role="ref"} for details. (Contributed by Stan Ulbrych and Łukasz Langa in `133461`{.interpreted-text role="gh"}.)
  - Table, index, trigger, view, column, function, and schema completion on \<tab\>. (Contributed by Long Tan in `136101`{.interpreted-text role="gh"}.)

### ssl

- Indicate through `ssl.HAS_PSK_TLS13`{.interpreted-text role="data"} whether the `ssl`{.interpreted-text role="mod"} module supports \"External PSKs\" in TLSv1.3, as described in RFC 9258. (Contributed by Will Childs-Klein in `133624`{.interpreted-text role="gh"}.)

- Added new methods for managing groups used for SSL key agreement

  - `ssl.SSLContext.set_groups`{.interpreted-text role="meth"} sets the groups allowed for doing key agreement, extending the previous `ssl.SSLContext.set_ecdh_curve`{.interpreted-text role="meth"} method. This new API provides the ability to list multiple groups and supports fixed-field and post-quantum groups in addition to ECDH curves. This method can also be used to control what key shares are sent in the TLS handshake.
  - `ssl.SSLSocket.group`{.interpreted-text role="meth"} returns the group selected for doing key agreement on the current connection after the TLS handshake completes. This call requires OpenSSL 3.2 or later.
  - `ssl.SSLContext.get_groups`{.interpreted-text role="meth"} returns a list of all available key agreement groups compatible with the minimum and maximum TLS versions currently set in the context. This call requires OpenSSL 3.5 or later.

  (Contributed by Ron Frederick in `136306`{.interpreted-text role="gh"}.)

- Added a new method `ssl.SSLContext.set_ciphersuites`{.interpreted-text role="meth"} for setting TLS 1.3 ciphers. For TLS 1.2 or earlier, `ssl.SSLContext.set_ciphers`{.interpreted-text role="meth"} should continue to be used. Both calls can be made on the same context and the selected cipher suite will depend on the TLS version negotiated when a connection is made. (Contributed by Ron Frederick in `137197`{.interpreted-text role="gh"}.)

- Added new methods for managing signature algorithms:

  - `ssl.get_sigalgs`{.interpreted-text role="func"} returns a list of all available TLS signature algorithms. This call requires OpenSSL 3.4 or later.
  - `ssl.SSLContext.set_client_sigalgs`{.interpreted-text role="meth"} sets the signature algorithms allowed for certificate-based client authentication.
  - `ssl.SSLContext.set_server_sigalgs`{.interpreted-text role="meth"} sets the signature algorithms allowed for the server to complete the TLS handshake.
  - `ssl.SSLSocket.client_sigalg`{.interpreted-text role="meth"} returns the signature algorithm selected for client authentication on the current connection. This call requires OpenSSL 3.5 or later.
  - `ssl.SSLSocket.server_sigalg`{.interpreted-text role="meth"} returns the signature algorithm selected for the server to complete the TLS handshake on the current connection. This call requires OpenSSL 3.5 or later.

  (Contributed by Ron Frederick in `138252`{.interpreted-text role="gh"}.)

### subprocess

- `subprocess.Popen.wait`{.interpreted-text role="meth"}: when `timeout` is not `None` and the platform supports it, an efficient event-driven mechanism is used to wait for process termination:

  - Linux \>= 5.3 uses `os.pidfd_open`{.interpreted-text role="func"} + `select.poll`{.interpreted-text role="func"}.
  - macOS and other BSD variants use `select.kqueue`{.interpreted-text role="func"} + `KQ_FILTER_PROC` + `KQ_NOTE_EXIT`.
  - Windows keeps using `WaitForSingleObject` (unchanged).

  If none of these mechanisms are available, the function falls back to the traditional busy loop (non-blocking call and short sleeps). (Contributed by Giampaolo Rodola in `83069`{.interpreted-text role="gh"}).

### symtable

- Add `symtable.Function.get_cells`{.interpreted-text role="meth"} and `symtable.Symbol.is_cell`{.interpreted-text role="meth"} methods. (Contributed by Yashp002 in `143504`{.interpreted-text role="gh"}.)

### symtable

- Add `symtable.Function.get_cells`{.interpreted-text role="meth"} and `symtable.Symbol.is_cell`{.interpreted-text role="meth"} methods. (Contributed by Yashp002 in `143504`{.interpreted-text role="gh"}.)

### sys

- Add `sys.abi_info`{.interpreted-text role="data"} namespace to improve access to ABI information. (Contributed by Klaus Zimmermann in `137476`{.interpreted-text role="gh"}.)

### tarfile

- `~tarfile.data_filter`{.interpreted-text role="func"} now normalizes symbolic link targets in order to avoid path traversal attacks. (Contributed by Petr Viktorin in `127987`{.interpreted-text role="gh"} and `2025-4138`{.interpreted-text role="cve"}.)
- `~tarfile.TarFile.extractall`{.interpreted-text role="func"} now skips fixing up directory attributes when a directory was removed or replaced by another kind of file. (Contributed by Petr Viktorin in `127987`{.interpreted-text role="gh"} and `2024-12718`{.interpreted-text role="cve"}.)
- `~tarfile.TarFile.extract`{.interpreted-text role="func"} and `~tarfile.TarFile.extractall`{.interpreted-text role="func"} now (re-)apply the extraction filter when substituting a link (hard or symbolic) with a copy of another archive member, and when fixing up directory attributes. The former raises a new exception, `~tarfile.LinkFallbackError`{.interpreted-text role="exc"}. (Contributed by Petr Viktorin for `2025-4330`{.interpreted-text role="cve"} and `2024-12718`{.interpreted-text role="cve"}.)
- `~tarfile.TarFile.extract`{.interpreted-text role="func"} and `~tarfile.TarFile.extractall`{.interpreted-text role="func"} no longer extract rejected members when `~tarfile.TarFile.errorlevel`{.interpreted-text role="func"} is zero. (Contributed by Matt Prodani and Petr Viktorin in `112887`{.interpreted-text role="gh"} and `2025-4435`{.interpreted-text role="cve"}.)
- `~tarfile.TarFile.extract`{.interpreted-text role="func"} and `~tarfile.TarFile.extractall`{.interpreted-text role="func"} now replace slashes by backslashes in symlink targets on Windows to prevent creation of corrupted links. (Contributed by Christoph Walcher in `57911`{.interpreted-text role="gh"}.)

### timeit

- The command-line interface now colorizes error tracebacks by default. This can be controlled with `environment variables <using-on-controlling-color>`{.interpreted-text role="ref"}. (Contributed by Yi Hong in `139374`{.interpreted-text role="gh"}.)

### tkinter

- The `!tkinter.Text.search`{.interpreted-text role="meth"} method now supports two additional arguments: *nolinestop* which allows the search to continue across line boundaries; and *strictlimits* which restricts the search to within the specified range. (Contributed by Rihaan Meher in `130848`{.interpreted-text role="gh"}.)
- A new method `!tkinter.Text.search_all`{.interpreted-text role="meth"} has been introduced. This method allows for searching for all matches of a pattern using Tcl\'s `-all` and `-overlap` options. (Contributed by Rihaan Meher in `130848`{.interpreted-text role="gh"}.)
- Added new methods `!pack_content`{.interpreted-text role="meth"}, `!place_content`{.interpreted-text role="meth"} and `!grid_content`{.interpreted-text role="meth"} which use Tk commands with new names (introduced in Tk 8.6) instead of `!*_slaves`{.interpreted-text role="meth"} methods which use Tk commands with outdated names. (Contributed by Serhiy Storchaka in `143754`{.interpreted-text role="gh"}.)

### tomllib {#whatsnew315-tomllib-1-1-0}

- The `tomllib`{.interpreted-text role="mod"} module now supports TOML 1.1.0. This is a backwards compatible update, meaning that all valid TOML 1.0.0 documents are parsed the same way.

  The changes, according to the [official TOML changelog](https://github.com/toml-lang/toml/blob/main/CHANGELOG.md), are:

  - Allow newlines and trailing commas in inline tables.

    Previously an inline table had to be on a single line and couldn\'t end with a trailing comma. This is now relaxed so that the following is valid:

    ``` text
    tbl = {
       key      = "a string",
       moar-tbl =  {
          key = 1,
       },
    }
    ```

  - Add `\xHH` notation to basic strings for codepoints under 255, and the `\e` escape for the escape character:

    ``` text
    null = "null byte: \x00; letter a: \x61"
    csi = "\e["
    ```

  - Seconds in datetime and time values are now optional. The following are now valid:

    ``` text
    dt = 2010-02-03 14:15
    t  = 14:15
    ```

  (Contributed by Taneli Hukkinen in `142956`{.interpreted-text role="gh"}.)

### types

- Expose the write-through `locals`{.interpreted-text role="func"} proxy type as `types.FrameLocalsProxyType`{.interpreted-text role="data"}. This represents the type of the `frame.f_locals`{.interpreted-text role="attr"} attribute, as described in `667`{.interpreted-text role="pep"}.

### unicodedata

- The Unicode database has been updated to Unicode 17.0.0.
- Add `unicodedata.isxidstart`{.interpreted-text role="func"} and `unicodedata.isxidcontinue`{.interpreted-text role="func"} functions to check whether a character can start or continue a [Unicode Standard Annex #31](https://www.unicode.org/reports/tr31/) identifier. (Contributed by Stan Ulbrych in `129117`{.interpreted-text role="gh"}.)
- Add the `~unicodedata.iter_graphemes`{.interpreted-text role="func"} function to iterate over grapheme clusters according to rules defined in [Unicode Standard Annex #29, \"Unicode Text Segmentation\"](https://www.unicode.org/reports/tr29/). Add `~unicodedata.grapheme_cluster_break`{.interpreted-text role="func"}, `~unicodedata.indic_conjunct_break`{.interpreted-text role="func"} and `~unicodedata.extended_pictographic`{.interpreted-text role="func"} functions to get the properties of the character which are related to the above algorithm. (Contributed by Serhiy Storchaka and Guillaume Sanchez in `74902`{.interpreted-text role="gh"}.)
- Add `~unicodedata.block`{.interpreted-text role="func"} function to return the [Unicode block](https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G64189) assigned to a character. (Contributed by Stan Ulbrych in `66802`{.interpreted-text role="gh"}.)

### unittest

- `unittest.TestCase.assertLogs`{.interpreted-text role="func"} will now accept a formatter to control how messages are formatted. (Contributed by Garry Cairns in `134567`{.interpreted-text role="gh"}.)

### urllib.parse

- Add the *missing_as_none* parameter to `~urllib.parse.urlsplit`{.interpreted-text role="func"}, `~urllib.parse.urlparse`{.interpreted-text role="func"} and `~urllib.parse.urldefrag`{.interpreted-text role="func"} functions. Add the *keep_empty* parameter to `~urllib.parse.urlunsplit`{.interpreted-text role="func"} and `~urllib.parse.urlunparse`{.interpreted-text role="func"} functions. This allows to distinguish between empty and not defined URI components and preserve empty components. (Contributed by Serhiy Storchaka in `67041`{.interpreted-text role="gh"}.)

### venv

- On POSIX platforms, platlib directories will be created if needed when creating virtual environments, instead of using `lib64 -> lib` symlink. This means purelib and platlib of virtual environments no longer share the same `lib` directory on platforms where `sys.platlibdir`{.interpreted-text role="data"} is not equal to `lib`. (Contributed by Rui Xi in `133951`{.interpreted-text role="gh"}.)

### warnings

- Improve filtering by module in `warnings.warn_explicit`{.interpreted-text role="func"} if no *module* argument is passed. It now tests the module regular expression in the warnings filter not only against the filename with `.py` stripped, but also against module names constructed starting from different parent directories of the filename (with `/__init__.py`, `.py` and, on Windows, `.pyw` stripped). (Contributed by Serhiy Storchaka in `135801`{.interpreted-text role="gh"}.)

### xml.parsers.expat

- Add `~xml.parsers.expat.xmlparser.SetAllocTrackerActivationThreshold`{.interpreted-text role="meth"} and `~xml.parsers.expat.xmlparser.SetAllocTrackerMaximumAmplification`{.interpreted-text role="meth"} to `xmlparser <xmlparser-objects>`{.interpreted-text role="ref"} objects to tune protections against disproportional amounts of dynamic memory usage from within an Expat parser. (Contributed by Bénédikt Tran in `90949`{.interpreted-text role="gh"}.)
- Add `~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionActivationThreshold`{.interpreted-text role="meth"} and `~xml.parsers.expat.xmlparser.SetBillionLaughsAttackProtectionMaximumAmplification`{.interpreted-text role="meth"} to `xmlparser <xmlparser-objects>`{.interpreted-text role="ref"} objects to tune protections against [billion laughs](https://en.wikipedia.org/wiki/Billion_laughs_attack) attacks. (Contributed by Bénédikt Tran in `90949`{.interpreted-text role="gh"}.)

### zlib

- Allow combining two Adler-32 checksums via `~zlib.adler32_combine`{.interpreted-text role="func"}. (Contributed by Callum Attryde and Bénédikt Tran in `134635`{.interpreted-text role="gh"}.)
- Allow combining two CRC-32 checksums via `~zlib.crc32_combine`{.interpreted-text role="func"}. (Contributed by Bénédikt Tran in `134635`{.interpreted-text role="gh"}.)

## Optimizations

- Builds using Visual Studio 2026 (MSVC 18) may now use the new `tail-calling interpreter <whatsnew314-tail-call-interpreter>`{.interpreted-text role="ref"}. Results on Visual Studio 18.1.1 report between [15-20%](https://github.com/faster-cpython/ideas/blob/main/results/5800X-msvc.pgo2-vs-msvc.pgo.tc.svg) speedup on the geometric mean of pyperformance on Windows x86-64 over the switch-case interpreter on an AMD Ryzen 7 5800X. We have observed speedups ranging from 14% for large pure-Python libraries to 40% for long-running small pure-Python scripts on Windows. This was made possible by a new feature introduced in MSVC 18. (Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in `143068`{.interpreted-text role="gh"}. Special thanks to the MSVC team including Hulon Jenkins.)
- `mimalloc` is now used as the default allocator for for raw memory allocations such as via `PyMem_RawMalloc`{.interpreted-text role="c:func"} for better performance on `free-threaded builds <free-threaded build>`{.interpreted-text role="term"}. (Contributed by Kumar Aditya in `144914`{.interpreted-text role="gh"}.)

### base64 & binascii

- CPython\'s underlying base64 implementation now encodes 2x faster and decodes 3x faster thanks to simple CPU pipelining optimizations. (Contributed by Gregory P. Smith and Serhiy Storchaka in `143262`{.interpreted-text role="gh"}.)
- Implementation for Ascii85, Base85, and Z85 encoding has been rewritten in C. Encoding and decoding is now two orders of magnitude faster and consumes two orders of magnitude less memory. (Contributed by James Seo and Serhiy Storchaka in `101178`{.interpreted-text role="gh"}.)

### csv

- `csv.Sniffer.sniff`{.interpreted-text role="meth"} delimiter detection is now up to 1.6x faster. (Contributed by Maurycy Pawłowski-Wieroński in `137628`{.interpreted-text role="gh"}.)

## Upgraded JIT compiler {#whatsnew315-jit}

Results from the [pyperformance](https://github.com/python/pyperformance) benchmark suite report [4-5%](https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20260110-3.15.0a3%2B-aa8578d-JIT/bm-20260110-vultr-x86_64-python-aa8578dc54df2af9daa3-3.15.0a3%2B-aa8578d-vs-base.svg) geometric mean performance improvement for the JIT over the standard CPython interpreter built with all optimizations enabled on x86-64 Linux. On AArch64 macOS, the JIT has a [7-8%](https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20260110-3.15.0a3%2B-aa8578d-JIT/bm-20260110-macm4pro-arm64-python-aa8578dc54df2af9daa3-3.15.0a3%2B-aa8578d-vs-base.svg) speedup over the `tail calling interpreter <whatsnew314-tail-call-interpreter>`{.interpreted-text role="ref"} with all optimizations enabled. The speedups for JIT builds versus no JIT builds range from roughly 15% slowdown to over 100% speedup (ignoring the `unpack_sequence` microbenchmark) on x86-64 Linux and AArch64 macOS systems.

:::: attention
::: title
Attention
:::

These results are not yet final.
::::

The major upgrades to the JIT are:

- LLVM 21 build-time dependency
- New tracing frontend
- Basic register allocation in the JIT
- More JIT optimizations
- Better machine code generation

**LLVM 21 build-time dependency**

The JIT compiler now uses LLVM 21 for build-time stencil generation. As always, LLVM is only needed when building CPython with the JIT enabled; end users running Python do not need LLVM installed. Instructions for installing LLVM can be found in the [JIT compiler documentation](https://github.com/python/cpython/blob/main/Tools/jit/README.md) for all supported platforms.

(Contributed by Savannah Ostrowski in `140973`{.interpreted-text role="gh"}.)

**A new tracing frontend**

The JIT compiler now supports significantly more bytecode operations and control flow than in Python 3.14, enabling speedups on a wider variety of code. For example, simple Python object creation is now understood by the 3.15 JIT compiler. Overloaded operations and generators are also partially supported. This was made possible by an overhauled JIT tracing frontend that records actual execution paths through code, rather than estimating them as the previous implementation did.

(Contributed by Ken Jin in `139109`{.interpreted-text role="gh"}. Support for Windows added by Mark Shannon in `141703`{.interpreted-text role="gh"}.)

**Basic register allocation in the JIT**

A basic form of register allocation has been added to the JIT compiler\'s optimizer. This allows the JIT compiler to avoid certain stack operations altogether and instead operate on registers. This allows the JIT to produce more efficient traces by avoiding reads and writes to memory.

(Contributed by Mark Shannon in `135379`{.interpreted-text role="gh"}.)

**More JIT optimizations**

More [constant-propagation](https://en.wikipedia.org/wiki/Constant_folding) is now performed. This means when the JIT compiler detects that certain user code results in constants, the code can be simplified by the JIT.

(Contributed by Ken Jin and Savannah Ostrowski in `132732`{.interpreted-text role="gh"}.)

The JIT avoids `reference count`{.interpreted-text role="term"}s where possible. This generally reduces the cost of most operations in Python.

(Contributed by Ken Jin, Donghee Na, Zheao Li, Hai Zhu, Savannah Ostrowski, Reiden Ong, Noam Cohen, Tomas Roun, PuQing, and Cajetan Rodrigues in `134584`{.interpreted-text role="gh"}.)

**Better machine code generation**

The JIT compiler\'s machine code generator now produces better machine code for x86-64 and AArch64 macOS and Linux targets. In general, users should experience lower memory usage for generated machine code and more efficient machine code versus the old JIT.

(Contributed by Brandt Bucher in `136528`{.interpreted-text role="gh"} and `136528`{.interpreted-text role="gh"}. Implementation for AArch64 contributed by Mark Shannon in `139855`{.interpreted-text role="gh"}. Additional optimizations for AArch64 contributed by Mark Shannon and Diego Russo in `140683`{.interpreted-text role="gh"} and `142305`{.interpreted-text role="gh"}.)

## Removed

### ctypes

- Removed the undocumented function `!ctypes.SetPointerType`{.interpreted-text role="func"}, which has been deprecated since Python 3.13. (Contributed by Bénédikt Tran in `133866`{.interpreted-text role="gh"}.)

### glob

- Removed the undocumented `!glob.glob0`{.interpreted-text role="func"} and `!glob.glob1`{.interpreted-text role="func"} functions, which have been deprecated since Python 3.13. Use `glob.glob`{.interpreted-text role="func"} and pass a directory to its *root_dir* argument instead. (Contributed by Barney Gale in `137466`{.interpreted-text role="gh"}.)

### http.server

- Removed the `!CGIHTTPRequestHandler`{.interpreted-text role="class"} class and the `--cgi` flag from the `python -m http.server`{.interpreted-text role="program"} command-line interface. They were deprecated in Python 3.13. (Contributed by Bénédikt Tran in `133810`{.interpreted-text role="gh"}.)

### importlib.resources

- Removed deprecated `package` parameter from `importlib.resources.files`{.interpreted-text role="func"} function. (Contributed by Semyon Moroz in `138044`{.interpreted-text role="gh"}.)

### pathlib

- Removed deprecated `!pathlib.PurePath.is_reserved`{.interpreted-text role="meth"}. Use `os.path.isreserved`{.interpreted-text role="func"} to detect reserved paths on Windows. (Contributed by Nikita Sobolev in `133875`{.interpreted-text role="gh"}.)

### platform

- Removed the `!platform.java_ver`{.interpreted-text role="func"} function, which was deprecated since Python 3.13. (Contributed by Alexey Makridenko in `133604`{.interpreted-text role="gh"}.)

### [sre]()\*

- Removed `!sre_compile`{.interpreted-text role="mod"}, `!sre_constants`{.interpreted-text role="mod"} and `!sre_parse`{.interpreted-text role="mod"} modules. (Contributed by Stan Ulbrych in `135994`{.interpreted-text role="gh"}.)

### sysconfig

- Removed the *check_home* parameter of `sysconfig.is_python_build`{.interpreted-text role="func"}. (Contributed by Filipe Laíns in `92897`{.interpreted-text role="gh"}.)

### threading

- Remove support for arbitrary positional or keyword arguments in the C implementation of `~threading.RLock`{.interpreted-text role="class"} objects. This was deprecated in Python 3.14. (Contributed by Bénédikt Tran in `134087`{.interpreted-text role="gh"}.)

### typing

- The undocumented keyword argument syntax for creating `~typing.NamedTuple`{.interpreted-text role="class"} classes (for example, `Point = NamedTuple("Point", x=int, y=int)`) is no longer supported. Use the class-based syntax or the functional syntax instead. (Contributed by Bénédikt Tran in `133817`{.interpreted-text role="gh"}.)

- Using `TD = TypedDict("TD")` or `TD = TypedDict("TD", None)` to construct a `~typing.TypedDict`{.interpreted-text role="class"} type with zero fields is no longer supported. Use `class TD(TypedDict): pass` or `TD = TypedDict("TD", {})` instead. (Contributed by Bénédikt Tran in `133823`{.interpreted-text role="gh"}.)

- Code like `class ExtraTypeVars(P1[S], Protocol[T, T2]): ...` now raises a `TypeError`{.interpreted-text role="exc"}, because `S` is not listed in `Protocol` parameters. (Contributed by Nikita Sobolev in `137191`{.interpreted-text role="gh"}.)

- Code like `class B2(A[T2], Protocol[T1, T2]): ...` now correctly handles type parameters order: it is `(T1, T2)`, not `(T2, T1)` as it was incorrectly inferred in runtime before. (Contributed by Nikita Sobolev in `137191`{.interpreted-text role="gh"}.)

- `typing.ByteString`{.interpreted-text role="class"} has been removed from `typing.__all__`. `!typing.ByteString`{.interpreted-text role="class"} has been deprecated since Python 3.9, and is scheduled for removal in Python 3.17.

- The following statements now cause `DeprecationWarning`s to be emitted at runtime:

  - `from typing import ByteString`
  - `import typing; typing.ByteString`.

  `DeprecationWarning`s were already emitted if `typing.ByteString`{.interpreted-text role="class"} was subclassed or used as the second argument to `isinstance`{.interpreted-text role="func"} or `issubclass`{.interpreted-text role="func"}, but warnings were not previously emitted if it was merely imported or accessed from the `!typing`{.interpreted-text role="mod"} module.

- Deprecated `!typing.no_type_check_decorator`{.interpreted-text role="func"} has been removed. (Contributed by Nikita Sobolev in `133601`{.interpreted-text role="gh"}.)

### wave

- Removed the `getmark()`, `setmark()` and `getmarkers()` methods of the `~wave.Wave_read`{.interpreted-text role="class"} and `~wave.Wave_write`{.interpreted-text role="class"} classes, which were deprecated since Python 3.13. (Contributed by Bénédikt Tran in `133873`{.interpreted-text role="gh"}.)

### zipimport

- Remove deprecated `!zipimport.zipimporter.load_module`{.interpreted-text role="meth"}. Use `zipimport.zipimporter.exec_module`{.interpreted-text role="meth"} instead. (Contributed by Jiahao Li in `133656`{.interpreted-text role="gh"}.)

## Deprecated

### New deprecations

- `base64`{.interpreted-text role="mod"}:
  - Accepting the `+` and `/` characters with an alternative alphabet in `~base64.b64decode`{.interpreted-text role="func"} and `~base64.urlsafe_b64decode`{.interpreted-text role="func"} is now deprecated. In future Python versions they will be errors in the strict mode and discarded in the non-strict mode. (Contributed by Serhiy Storchaka in `125346`{.interpreted-text role="gh"}.)
- CLI:
  - Deprecate `-b`{.interpreted-text role="option"} and `!-bb`{.interpreted-text role="option"} command-line options and schedule them to become no-ops in Python 3.17. These were primarily helpers for the Python 2 -\> 3 transition. Starting with Python 3.17, no `BytesWarning`{.interpreted-text role="exc"} will be raised for these cases; use a type checker instead.

    (Contributed by Nikita Sobolev in `136355`{.interpreted-text role="gh"}.)
- `hashlib`{.interpreted-text role="mod"}:
  - In hash function constructors such as `~hashlib.new`{.interpreted-text role="func"} or the direct hash-named constructors such as `~hashlib.md5`{.interpreted-text role="func"} and `~hashlib.sha256`{.interpreted-text role="func"}, the optional initial data parameter could also be passed as a keyword argument named `data=` or `string=` in various `hashlib`{.interpreted-text role="mod"} implementations.

    Support for the `string` keyword argument name is now deprecated and is slated for removal in Python 3.19. Prefer passing the initial data as a positional argument for maximum backwards compatibility.

    (Contributed by Bénédikt Tran in `134978`{.interpreted-text role="gh"}.)
- `__version__`
  - The `__version__`, `version` and `VERSION` attributes have been deprecated in these standard library modules and will be removed in Python 3.20. Use `sys.version_info`{.interpreted-text role="py:data"} instead.

    - `argparse`{.interpreted-text role="mod"}
    - `csv`{.interpreted-text role="mod"}
    - `ctypes`{.interpreted-text role="mod"}
    - `!ctypes.macholib`{.interpreted-text role="mod"}
    - `decimal`{.interpreted-text role="mod"} (use `decimal.SPEC_VERSION`{.interpreted-text role="data"} instead)
    - `http.server`{.interpreted-text role="mod"}
    - `imaplib`{.interpreted-text role="mod"}
    - `ipaddress`{.interpreted-text role="mod"}
    - `json`{.interpreted-text role="mod"}
    - `logging`{.interpreted-text role="mod"} (`__date__` also deprecated)
    - `optparse`{.interpreted-text role="mod"}
    - `pickle`{.interpreted-text role="mod"}
    - `platform`{.interpreted-text role="mod"}
    - `re`{.interpreted-text role="mod"}
    - `socketserver`{.interpreted-text role="mod"}
    - `tabnanny`{.interpreted-text role="mod"}
    - `tkinter.font`{.interpreted-text role="mod"}
    - `tkinter.ttk`{.interpreted-text role="mod"}
    - `wsgiref.simple_server`{.interpreted-text role="mod"}
    - `xml.etree.ElementTree`{.interpreted-text role="mod"}
    - `!xml.sax.expatreader`{.interpreted-text role="mod"}
    - `xml.sax.handler`{.interpreted-text role="mod"}
    - `zlib`{.interpreted-text role="mod"}

    (Contributed by Hugo van Kemenade and Stan Ulbrych in `76007`{.interpreted-text role="gh"}.)

### Pending removal in Python 3.16

- The import system:
  - Setting `~module.__loader__`{.interpreted-text role="attr"} on a module while failing to set `__spec__.loader <importlib.machinery.ModuleSpec.loader>`{.interpreted-text role="attr"} is deprecated. In Python 3.16, `!__loader__`{.interpreted-text role="attr"} will cease to be set or taken into consideration by the import system or the standard library.
- `array`{.interpreted-text role="mod"}:
  - The `'u'` format code (`wchar_t`{.interpreted-text role="c:type"}) has been deprecated in documentation since Python 3.3 and at runtime since Python 3.13. Use the `'w'` format code (`Py_UCS4`{.interpreted-text role="c:type"}) for Unicode characters instead.
- `asyncio`{.interpreted-text role="mod"}:
  - `!asyncio.iscoroutinefunction`{.interpreted-text role="func"} is deprecated and will be removed in Python 3.16; use `inspect.iscoroutinefunction`{.interpreted-text role="func"} instead. (Contributed by Jiahao Li and Kumar Aditya in `122875`{.interpreted-text role="gh"}.)

  - `asyncio`{.interpreted-text role="mod"} policy system is deprecated and will be removed in Python 3.16. In particular, the following classes and functions are deprecated:

    - `asyncio.AbstractEventLoopPolicy`{.interpreted-text role="class"}
    - `asyncio.DefaultEventLoopPolicy`{.interpreted-text role="class"}
    - `asyncio.WindowsSelectorEventLoopPolicy`{.interpreted-text role="class"}
    - `asyncio.WindowsProactorEventLoopPolicy`{.interpreted-text role="class"}
    - `asyncio.get_event_loop_policy`{.interpreted-text role="func"}
    - `asyncio.set_event_loop_policy`{.interpreted-text role="func"}

    Users should use `asyncio.run`{.interpreted-text role="func"} or `asyncio.Runner`{.interpreted-text role="class"} with *loop_factory* to use the desired event loop implementation.

    For example, to use `asyncio.SelectorEventLoop`{.interpreted-text role="class"} on Windows:

        import asyncio

        async def main():
            ...

        asyncio.run(main(), loop_factory=asyncio.SelectorEventLoop)

    (Contributed by Kumar Aditya in `127949`{.interpreted-text role="gh"}.)
- `builtins`{.interpreted-text role="mod"}:
  - Bitwise inversion on boolean types, `~True` or `~False` has been deprecated since Python 3.12, as it produces surprising and unintuitive results (`-2` and `-1`). Use `not x` instead for the logical negation of a Boolean. In the rare case that you need the bitwise inversion of the underlying integer, convert to `int` explicitly (`~int(x)`).
- `functools`{.interpreted-text role="mod"}:
  - Calling the Python implementation of `functools.reduce`{.interpreted-text role="func"} with *function* or *sequence* as keyword arguments has been deprecated since Python 3.14.
- `logging`{.interpreted-text role="mod"}:
  - Support for custom logging handlers with the *strm* argument is deprecated and scheduled for removal in Python 3.16. Define handlers with the *stream* argument instead. (Contributed by Mariusz Felisiak in `115032`{.interpreted-text role="gh"}.)
- `mimetypes`{.interpreted-text role="mod"}:
  - Valid extensions start with a \'.\' or are empty for `mimetypes.MimeTypes.add_type`{.interpreted-text role="meth"}. Undotted extensions are deprecated and will raise a `ValueError`{.interpreted-text role="exc"} in Python 3.16. (Contributed by Hugo van Kemenade in `75223`{.interpreted-text role="gh"}.)
- `shutil`{.interpreted-text role="mod"}:
  - The `!ExecError`{.interpreted-text role="class"} exception has been deprecated since Python 3.14. It has not been used by any function in `!shutil`{.interpreted-text role="mod"} since Python 3.4, and is now an alias of `RuntimeError`{.interpreted-text role="exc"}.
- `symtable`{.interpreted-text role="mod"}:
  - The `Class.get_methods <symtable.Class.get_methods>`{.interpreted-text role="meth"} method has been deprecated since Python 3.14.
- `sys`{.interpreted-text role="mod"}:
  - The `~sys._enablelegacywindowsfsencoding`{.interpreted-text role="func"} function has been deprecated since Python 3.13. Use the `PYTHONLEGACYWINDOWSFSENCODING`{.interpreted-text role="envvar"} environment variable instead.
- `sysconfig`{.interpreted-text role="mod"}:
  - The `!sysconfig.expand_makefile_vars`{.interpreted-text role="func"} function has been deprecated since Python 3.14. Use the `vars` argument of `sysconfig.get_paths`{.interpreted-text role="func"} instead.
- `tarfile`{.interpreted-text role="mod"}:
  - The undocumented and unused `!TarFile.tarfile`{.interpreted-text role="attr"} attribute has been deprecated since Python 3.13.

### Pending removal in Python 3.17

- `collections.abc`{.interpreted-text role="mod"}:
  - `collections.abc.ByteString`{.interpreted-text role="class"} is scheduled for removal in Python 3.17.

    Use `isinstance(obj, collections.abc.Buffer)` to test if `obj` implements the `buffer protocol <bufferobjects>`{.interpreted-text role="ref"} at runtime. For use in type annotations, either use `~collections.abc.Buffer`{.interpreted-text role="class"} or a union that explicitly specifies the types your code supports (e.g., `bytes | bytearray | memoryview`).

    `!ByteString`{.interpreted-text role="class"} was originally intended to be an abstract class that would serve as a supertype of both `bytes`{.interpreted-text role="class"} and `bytearray`{.interpreted-text role="class"}. However, since the ABC never had any methods, knowing that an object was an instance of `!ByteString`{.interpreted-text role="class"} never actually told you anything useful about the object. Other common buffer types such as `memoryview`{.interpreted-text role="class"} were also never understood as subtypes of `!ByteString`{.interpreted-text role="class"} (either at runtime or by static type checkers).

    See `PEP 688 <688#current-options>`{.interpreted-text role="pep"} for more details. (Contributed by Shantanu Jain in `91896`{.interpreted-text role="gh"}.)
- `encodings`{.interpreted-text role="mod"}:
  - Passing non-ascii *encoding* names to `encodings.normalize_encoding`{.interpreted-text role="func"} is deprecated and scheduled for removal in Python 3.17. (Contributed by Stan Ulbrych in `136702`{.interpreted-text role="gh"})
- `typing`{.interpreted-text role="mod"}:
  - Before Python 3.14, old-style unions were implemented using the private class `typing._UnionGenericAlias`. This class is no longer needed for the implementation, but it has been retained for backward compatibility, with removal scheduled for Python 3.17. Users should use documented introspection helpers like `typing.get_origin`{.interpreted-text role="func"} and `typing.get_args`{.interpreted-text role="func"} instead of relying on private implementation details.

  - `typing.ByteString`{.interpreted-text role="class"}, deprecated since Python 3.9, is scheduled for removal in Python 3.17.

    Use `isinstance(obj, collections.abc.Buffer)` to test if `obj` implements the `buffer protocol <bufferobjects>`{.interpreted-text role="ref"} at runtime. For use in type annotations, either use `~collections.abc.Buffer`{.interpreted-text role="class"} or a union that explicitly specifies the types your code supports (e.g., `bytes | bytearray | memoryview`).

    `!ByteString`{.interpreted-text role="class"} was originally intended to be an abstract class that would serve as a supertype of both `bytes`{.interpreted-text role="class"} and `bytearray`{.interpreted-text role="class"}. However, since the ABC never had any methods, knowing that an object was an instance of `!ByteString`{.interpreted-text role="class"} never actually told you anything useful about the object. Other common buffer types such as `memoryview`{.interpreted-text role="class"} were also never understood as subtypes of `!ByteString`{.interpreted-text role="class"} (either at runtime or by static type checkers).

    See `PEP 688 <688#current-options>`{.interpreted-text role="pep"} for more details. (Contributed by Shantanu Jain in `91896`{.interpreted-text role="gh"}.)

### Pending removal in Python 3.18

- `decimal`{.interpreted-text role="mod"}:
  - The non-standard and undocumented `~decimal.Decimal`{.interpreted-text role="class"} format specifier `'N'`, which is only supported in the `!decimal`{.interpreted-text role="mod"} module\'s C implementation, has been deprecated since Python 3.13. (Contributed by Serhiy Storchaka in `89902`{.interpreted-text role="gh"}.)

### Pending removal in Python 3.19

- `ctypes`{.interpreted-text role="mod"}:
  - Implicitly switching to the MSVC-compatible struct layout by setting `~ctypes.Structure._pack_`{.interpreted-text role="attr"} but not `~ctypes.Structure._layout_`{.interpreted-text role="attr"} on non-Windows platforms.
- `hashlib`{.interpreted-text role="mod"}:
  - In hash function constructors such as `~hashlib.new`{.interpreted-text role="func"} or the direct hash-named constructors such as `~hashlib.md5`{.interpreted-text role="func"} and `~hashlib.sha256`{.interpreted-text role="func"}, their optional initial data parameter could also be passed a keyword argument named `data=` or `string=` in various `!hashlib`{.interpreted-text role="mod"} implementations.

    Support for the `string` keyword argument name is now deprecated and slated for removal in Python 3.19.

    Before Python 3.13, the `string` keyword parameter was not correctly supported depending on the backend implementation of hash functions. Prefer passing the initial data as a positional argument for maximum backwards compatibility.

### Pending removal in Python 3.20

- The `__version__`, `version` and `VERSION` attributes have been deprecated in these standard library modules and will be removed in Python 3.20. Use `sys.version_info`{.interpreted-text role="py:data"} instead.

  - `argparse`{.interpreted-text role="mod"}
  - `csv`{.interpreted-text role="mod"}
  - `ctypes`{.interpreted-text role="mod"}
  - `!ctypes.macholib`{.interpreted-text role="mod"}
  - `decimal`{.interpreted-text role="mod"} (use `decimal.SPEC_VERSION`{.interpreted-text role="data"} instead)
  - `http.server`{.interpreted-text role="mod"}
  - `imaplib`{.interpreted-text role="mod"}
  - `ipaddress`{.interpreted-text role="mod"}
  - `json`{.interpreted-text role="mod"}
  - `logging`{.interpreted-text role="mod"} (`__date__` also deprecated)
  - `optparse`{.interpreted-text role="mod"}
  - `pickle`{.interpreted-text role="mod"}
  - `platform`{.interpreted-text role="mod"}
  - `re`{.interpreted-text role="mod"}
  - `socketserver`{.interpreted-text role="mod"}
  - `tabnanny`{.interpreted-text role="mod"}
  - `tkinter.font`{.interpreted-text role="mod"}
  - `tkinter.ttk`{.interpreted-text role="mod"}
  - `wsgiref.simple_server`{.interpreted-text role="mod"}
  - `xml.etree.ElementTree`{.interpreted-text role="mod"}
  - `!xml.sax.expatreader`{.interpreted-text role="mod"}
  - `xml.sax.handler`{.interpreted-text role="mod"}
  - `zlib`{.interpreted-text role="mod"}

  (Contributed by Hugo van Kemenade and Stan Ulbrych in `76007`{.interpreted-text role="gh"}.)

### Pending removal in future versions

The following APIs will be removed in the future, although there is currently no date scheduled for their removal.

- `argparse`{.interpreted-text role="mod"}:
  - Nesting argument groups and nesting mutually exclusive groups are deprecated.
  - Passing the undocumented keyword argument *prefix_chars* to `~argparse.ArgumentParser.add_argument_group`{.interpreted-text role="meth"} is now deprecated.
  - The `argparse.FileType`{.interpreted-text role="class"} type converter is deprecated.
- `builtins`{.interpreted-text role="mod"}:
  - Generators: `throw(type, exc, tb)` and `athrow(type, exc, tb)` signature is deprecated: use `throw(exc)` and `athrow(exc)` instead, the single argument signature.
  - Currently Python accepts numeric literals immediately followed by keywords, for example `0in x`, `1or x`, `0if 1else 2`. It allows confusing and ambiguous expressions like `[0x1for x in y]` (which can be interpreted as `[0x1 for x in y]` or `[0x1f or x in y]`). A syntax warning is raised if the numeric literal is immediately followed by one of keywords `and`{.interpreted-text role="keyword"}, `else`{.interpreted-text role="keyword"}, `for`{.interpreted-text role="keyword"}, `if`{.interpreted-text role="keyword"}, `in`{.interpreted-text role="keyword"}, `is`{.interpreted-text role="keyword"} and `or`{.interpreted-text role="keyword"}. In a future release it will be changed to a syntax error. (`87999`{.interpreted-text role="gh"})
  - Support for `__index__()` and `__int__()` method returning non-int type: these methods will be required to return an instance of a strict subclass of `int`{.interpreted-text role="class"}.
  - Support for `__float__()` method returning a strict subclass of `float`{.interpreted-text role="class"}: these methods will be required to return an instance of `float`{.interpreted-text role="class"}.
  - Support for `__complex__()` method returning a strict subclass of `complex`{.interpreted-text role="class"}: these methods will be required to return an instance of `complex`{.interpreted-text role="class"}.
  - Passing a complex number as the *real* or *imag* argument in the `complex`{.interpreted-text role="func"} constructor is now deprecated; it should only be passed as a single positional argument. (Contributed by Serhiy Storchaka in `109218`{.interpreted-text role="gh"}.)
- `calendar`{.interpreted-text role="mod"}: `calendar.January` and `calendar.February` constants are deprecated and replaced by `calendar.JANUARY`{.interpreted-text role="data"} and `calendar.FEBRUARY`{.interpreted-text role="data"}. (Contributed by Prince Roshan in `103636`{.interpreted-text role="gh"}.)
- `codecs`{.interpreted-text role="mod"}: use `open`{.interpreted-text role="func"} instead of `codecs.open`{.interpreted-text role="func"}. (`133038`{.interpreted-text role="gh"})
- `codeobject.co_lnotab`{.interpreted-text role="attr"}: use the `codeobject.co_lines`{.interpreted-text role="meth"} method instead.
- `datetime`{.interpreted-text role="mod"}:
  - `~datetime.datetime.utcnow`{.interpreted-text role="meth"}: use `datetime.datetime.now(tz=datetime.UTC)`.
  - `~datetime.datetime.utcfromtimestamp`{.interpreted-text role="meth"}: use `datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)`.
- `gettext`{.interpreted-text role="mod"}: Plural value must be an integer.
- `importlib`{.interpreted-text role="mod"}:
  - `~importlib.util.cache_from_source`{.interpreted-text role="func"} *debug_override* parameter is deprecated: use the *optimization* parameter instead.
- `importlib.metadata`{.interpreted-text role="mod"}:
  - `EntryPoints` tuple interface.
  - Implicit `None` on return values.
- `logging`{.interpreted-text role="mod"}: the `warn()` method has been deprecated since Python 3.3, use `~logging.warning`{.interpreted-text role="meth"} instead.
- `mailbox`{.interpreted-text role="mod"}: Use of StringIO input and text mode is deprecated, use BytesIO and binary mode instead.
- `os`{.interpreted-text role="mod"}: Calling `os.register_at_fork`{.interpreted-text role="func"} in a multi-threaded process.
- `os.path`{.interpreted-text role="mod"}: `os.path.commonprefix`{.interpreted-text role="func"} is deprecated, use `os.path.commonpath`{.interpreted-text role="func"} for path prefixes. The `os.path.commonprefix`{.interpreted-text role="func"} function is being deprecated due to having a misleading name and module. The function is not safe to use for path prefixes despite being included in a module about path manipulation, meaning it is easy to accidentally introduce path traversal vulnerabilities into Python programs by using this function.
- `!pydoc.ErrorDuringImport`{.interpreted-text role="class"}: A tuple value for *exc_info* parameter is deprecated, use an exception instance.
- `re`{.interpreted-text role="mod"}: More strict rules are now applied for numerical group references and group names in regular expressions. Only sequence of ASCII digits is now accepted as a numerical reference. The group name in bytes patterns and replacement strings can now only contain ASCII letters and digits and underscore. (Contributed by Serhiy Storchaka in `91760`{.interpreted-text role="gh"}.)
- `shutil`{.interpreted-text role="mod"}: `~shutil.rmtree`{.interpreted-text role="func"}\'s *onerror* parameter is deprecated in Python 3.12; use the *onexc* parameter instead.
- `ssl`{.interpreted-text role="mod"} options and protocols:
  - `ssl.SSLContext`{.interpreted-text role="class"} without protocol argument is deprecated.
  - `ssl.SSLContext`{.interpreted-text role="class"}: `~ssl.SSLContext.set_npn_protocols`{.interpreted-text role="meth"} and `!selected_npn_protocol`{.interpreted-text role="meth"} are deprecated: use ALPN instead.
  - `ssl.OP_NO_SSL*` options
  - `ssl.OP_NO_TLS*` options
  - `ssl.PROTOCOL_SSLv3`
  - `ssl.PROTOCOL_TLS`
  - `ssl.PROTOCOL_TLSv1`
  - `ssl.PROTOCOL_TLSv1_1`
  - `ssl.PROTOCOL_TLSv1_2`
  - `ssl.TLSVersion.SSLv3`
  - `ssl.TLSVersion.TLSv1`
  - `ssl.TLSVersion.TLSv1_1`
- `threading`{.interpreted-text role="mod"} methods:
  - `!threading.Condition.notifyAll`{.interpreted-text role="meth"}: use `~threading.Condition.notify_all`{.interpreted-text role="meth"}.
  - `!threading.Event.isSet`{.interpreted-text role="meth"}: use `~threading.Event.is_set`{.interpreted-text role="meth"}.
  - `!threading.Thread.isDaemon`{.interpreted-text role="meth"}, `threading.Thread.setDaemon`{.interpreted-text role="meth"}: use `threading.Thread.daemon`{.interpreted-text role="attr"} attribute.
  - `!threading.Thread.getName`{.interpreted-text role="meth"}, `threading.Thread.setName`{.interpreted-text role="meth"}: use `threading.Thread.name`{.interpreted-text role="attr"} attribute.
  - `!threading.currentThread`{.interpreted-text role="meth"}: use `threading.current_thread`{.interpreted-text role="meth"}.
  - `!threading.activeCount`{.interpreted-text role="meth"}: use `threading.active_count`{.interpreted-text role="meth"}.
- `typing.Text`{.interpreted-text role="class"} (`92332`{.interpreted-text role="gh"}).
- The internal class `typing._UnionGenericAlias` is no longer used to implement `typing.Union`{.interpreted-text role="class"}. To preserve compatibility with users using this private class, a compatibility shim will be provided until at least Python 3.17. (Contributed by Jelle Zijlstra in `105499`{.interpreted-text role="gh"}.)
- `unittest.IsolatedAsyncioTestCase`{.interpreted-text role="class"}: it is deprecated to return a value that is not `None` from a test case.
- `urllib.parse`{.interpreted-text role="mod"} deprecated functions: `~urllib.parse.urlparse`{.interpreted-text role="func"} instead
  - `splitattr()`
  - `splithost()`
  - `splitnport()`
  - `splitpasswd()`
  - `splitport()`
  - `splitquery()`
  - `splittag()`
  - `splittype()`
  - `splituser()`
  - `splitvalue()`
  - `to_bytes()`
- `wsgiref`{.interpreted-text role="mod"}: `SimpleHandler.stdout.write()` should not do partial writes.
- `xml.etree.ElementTree`{.interpreted-text role="mod"}: Testing the truth value of an `~xml.etree.ElementTree.Element`{.interpreted-text role="class"} is deprecated. In a future release it will always return `True`. Prefer explicit `len(elem)` or `elem is not None` tests instead.
- `sys._clear_type_cache`{.interpreted-text role="func"} is deprecated: use `sys._clear_internal_caches`{.interpreted-text role="func"} instead.

## C API changes

### New features

- Add the following functions for the new `frozendict`{.interpreted-text role="class"} type:

  - `PyAnyDict_Check`{.interpreted-text role="c:func"}
  - `PyAnyDict_CheckExact`{.interpreted-text role="c:func"}
  - `PyFrozenDict_Check`{.interpreted-text role="c:func"}
  - `PyFrozenDict_CheckExact`{.interpreted-text role="c:func"}
  - `PyFrozenDict_New`{.interpreted-text role="c:func"}

  (Contributed by Victor Stinner in `141510`{.interpreted-text role="gh"}.)

- Add `PySys_GetAttr`{.interpreted-text role="c:func"}, `PySys_GetAttrString`{.interpreted-text role="c:func"}, `PySys_GetOptionalAttr`{.interpreted-text role="c:func"}, and `PySys_GetOptionalAttrString`{.interpreted-text role="c:func"} functions as replacements for `PySys_GetObject`{.interpreted-text role="c:func"}. (Contributed by Serhiy Storchaka in `108512`{.interpreted-text role="gh"}.)

- Add `PyUnstable_Unicode_GET_CACHED_HASH`{.interpreted-text role="c:type"} to get the cached hash of a string. See the documentation for caveats. (Contributed by Petr Viktorin in `131510`{.interpreted-text role="gh"}.)

- Add API for checking an extension module\'s ABI compatibility: `Py_mod_abi`{.interpreted-text role="c:data"}, `PyABIInfo_Check`{.interpreted-text role="c:func"}, `PyABIInfo_VAR`{.interpreted-text role="c:macro"} and `Py_mod_abi`{.interpreted-text role="c:data"}. (Contributed by Petr Viktorin in `137210`{.interpreted-text role="gh"}.)

::: {#whatsnew315-pep782}
- Implement `782`{.interpreted-text role="pep"}, the `PyBytesWriter API <pybyteswriter>`{.interpreted-text role="ref"}. Add functions:

  - `PyBytesWriter_Create`{.interpreted-text role="c:func"}
  - `PyBytesWriter_Discard`{.interpreted-text role="c:func"}
  - `PyBytesWriter_FinishWithPointer`{.interpreted-text role="c:func"}
  - `PyBytesWriter_FinishWithSize`{.interpreted-text role="c:func"}
  - `PyBytesWriter_Finish`{.interpreted-text role="c:func"}
  - `PyBytesWriter_Format`{.interpreted-text role="c:func"}
  - `PyBytesWriter_GetData`{.interpreted-text role="c:func"}
  - `PyBytesWriter_GetSize`{.interpreted-text role="c:func"}
  - `PyBytesWriter_GrowAndUpdatePointer`{.interpreted-text role="c:func"}
  - `PyBytesWriter_Grow`{.interpreted-text role="c:func"}
  - `PyBytesWriter_Resize`{.interpreted-text role="c:func"}
  - `PyBytesWriter_WriteBytes`{.interpreted-text role="c:func"}

  (Contributed by Victor Stinner in `129813`{.interpreted-text role="gh"}.)

- Add a new `PyImport_CreateModuleFromInitfunc`{.interpreted-text role="c:func"} C-API for creating a module from a *spec* and *initfunc*. (Contributed by Itamar Oren in `116146`{.interpreted-text role="gh"}.)

- Add `PyTuple_FromArray`{.interpreted-text role="c:func"} to create a `tuple`{.interpreted-text role="class"} from an array. (Contributed by Victor Stinner in `111489`{.interpreted-text role="gh"}.)

- Add `PyObject_Dump`{.interpreted-text role="c:func"} to dump an object to `stderr`. It should only be used for debugging. (Contributed by Victor Stinner in `141070`{.interpreted-text role="gh"}.)

- Add `PyUnstable_ThreadState_SetStackProtection`{.interpreted-text role="c:func"} and `PyUnstable_ThreadState_ResetStackProtection`{.interpreted-text role="c:func"} functions to set the stack protection base address and stack protection size of a Python thread state. (Contributed by Victor Stinner in `139653`{.interpreted-text role="gh"}.)

- Add `PyUnstable_SetImmortal`{.interpreted-text role="c:func"} C-API function to mark objects as `immortal`{.interpreted-text role="term"}. (Contributed by Kumar Aditya in `143300`{.interpreted-text role="gh"}.)
:::

### Changed C APIs

- If the `Py_TPFLAGS_MANAGED_DICT`{.interpreted-text role="c:macro"} or `Py_TPFLAGS_MANAGED_WEAKREF`{.interpreted-text role="c:macro"} flag is set then `Py_TPFLAGS_HAVE_GC`{.interpreted-text role="c:macro"} must be set too. (Contributed by Sergey Miryanov in `134786`{.interpreted-text role="gh"}.)
- `PyDateTime_IMPORT`{.interpreted-text role="c:macro"} is now thread safe. Code that directly checks `PyDateTimeAPI` for `NULL` should be updated to call `PyDateTime_IMPORT`{.interpreted-text role="c:macro"} instead. (Contributed by Kumar Aditya in `141563`{.interpreted-text role="gh"}.)

### Porting to Python 3.15

- Private functions promoted to public C APIs:

  The [[\|pythoncapi_compat_project_link\|](##SUBST##|pythoncapi_compat_project_link|)](##REF##pythoncapi_compat_project_link) can be used to get most of these new functions on Python 3.14 and older.

### Removed C APIs

- Remove deprecated `PyUnicode` functions:

  - `!PyUnicode_AsDecodedObject`{.interpreted-text role="c:func"}: Use `PyCodec_Decode`{.interpreted-text role="c:func"} instead.
  - `!PyUnicode_AsDecodedUnicode`{.interpreted-text role="c:func"}: Use `PyCodec_Decode`{.interpreted-text role="c:func"} instead; Note that some codecs (for example, \"base64\") may return a type other than `str`{.interpreted-text role="class"}, such as `bytes`{.interpreted-text role="class"}.
  - `!PyUnicode_AsEncodedObject`{.interpreted-text role="c:func"}: Use `PyCodec_Encode`{.interpreted-text role="c:func"} instead.
  - `!PyUnicode_AsEncodedUnicode`{.interpreted-text role="c:func"}: Use `PyCodec_Encode`{.interpreted-text role="c:func"} instead; Note that some codecs (for example, \"base64\") may return a type other than `bytes`{.interpreted-text role="class"}, such as `str`{.interpreted-text role="class"}.

  (Contributed by Stan Ulbrych in `133612`{.interpreted-text role="gh"}.)

- `!PyImport_ImportModuleNoBlock`{.interpreted-text role="c:func"}: deprecated alias of `PyImport_ImportModule`{.interpreted-text role="c:func"}. (Contributed by Bénédikt Tran in `133644`{.interpreted-text role="gh"}.)

- `!PyWeakref_GetObject`{.interpreted-text role="c:func"} and `!PyWeakref_GET_OBJECT`{.interpreted-text role="c:macro"}: use `PyWeakref_GetRef`{.interpreted-text role="c:func"} instead. The [[\|pythoncapi_compat_project_link\|](##SUBST##|pythoncapi_compat_project_link|)](##REF##pythoncapi_compat_project_link) can be used to get `!PyWeakref_GetRef`{.interpreted-text role="c:func"} on Python 3.12 and older. (Contributed by Bénédikt Tran in `133644`{.interpreted-text role="gh"}.)

- Remove deprecated `!PySys_ResetWarnOptions`{.interpreted-text role="c:func"}. Clear `sys.warnoptions`{.interpreted-text role="data"} and `!warnings.filters`{.interpreted-text role="data"} instead.

  (Contributed by Nikita Sobolev in `138886`{.interpreted-text role="gh"}.)

The following functions are removed in favor of `PyConfig_Get`{.interpreted-text role="c:func"}. The [[\|pythoncapi_compat_project_link\|](##SUBST##|pythoncapi_compat_project_link|)](##REF##pythoncapi_compat_project_link) can be used to get `!PyConfig_Get`{.interpreted-text role="c:func"} on Python 3.13 and older.

- Python initialization functions:

  - `!Py_GetExecPrefix`{.interpreted-text role="c:func"}: use `PyConfig_Get("base_exec_prefix") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.base_exec_prefix`{.interpreted-text role="data"}) instead. Use `PyConfig_Get("exec_prefix") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.exec_prefix`{.interpreted-text role="data"}) if `virtual environments <venv-def>`{.interpreted-text role="ref"} need to be handled.
  - `!Py_GetPath`{.interpreted-text role="c:func"}: use `PyConfig_Get("module_search_paths") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.path`{.interpreted-text role="data"}) instead.
  - `!Py_GetPrefix`{.interpreted-text role="c:func"}: use `PyConfig_Get("base_prefix") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.base_prefix`{.interpreted-text role="data"}) instead. Use `PyConfig_Get("prefix") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.prefix`{.interpreted-text role="data"}) if `virtual environments <venv-def>`{.interpreted-text role="ref"} need to be handled.
  - `!Py_GetProgramFullPath`{.interpreted-text role="c:func"}: use `PyConfig_Get("executable") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.executable`{.interpreted-text role="data"}) instead.
  - `!Py_GetProgramName`{.interpreted-text role="c:func"}: use `PyConfig_Get("executable") <PyConfig_Get>`{.interpreted-text role="c:func"} (`sys.executable`{.interpreted-text role="data"}) instead.
  - `!Py_GetPythonHome`{.interpreted-text role="c:func"}: use `PyConfig_Get("home") <PyConfig_Get>`{.interpreted-text role="c:func"} or the `PYTHONHOME`{.interpreted-text role="envvar"} environment variable instead.

  (Contributed by Bénédikt Tran in `133644`{.interpreted-text role="gh"}.)

### Deprecated C APIs

- Deprecate `456`{.interpreted-text role="pep"} support for providing an external definition of the string hashing scheme. Removal is scheduled for Python 3.19.

  Previously, embedders could define `Py_HASH_ALGORITHM`{.interpreted-text role="c:macro"} to be `Py_HASH_EXTERNAL` to indicate that the hashing scheme was provided externally but this feature was undocumented, untested and most likely unused.

  (Contributed by Bénédikt Tran in `141226`{.interpreted-text role="gh"}.)

- For unsigned integer formats in `PyArg_ParseTuple`{.interpreted-text role="c:func"}, accepting Python integers with value that is larger than the maximal value for the C type or less than the minimal value for the corresponding signed integer type of the same size is now deprecated. (Contributed by Serhiy Storchaka in `132629`{.interpreted-text role="gh"}.)

- `PyBytes_FromStringAndSize(NULL, len) <PyBytes_FromStringAndSize>`{.interpreted-text role="c:func"} and `_PyBytes_Resize`{.interpreted-text role="c:func"} are `soft deprecated`{.interpreted-text role="term"}, use the `PyBytesWriter`{.interpreted-text role="c:type"} API instead. (Contributed by Victor Stinner in `129813`{.interpreted-text role="gh"}.)

- `!_PyObject_CallMethodId`{.interpreted-text role="c:func"}, `!_PyObject_GetAttrId`{.interpreted-text role="c:func"} and `!_PyUnicode_FromId`{.interpreted-text role="c:func"} are deprecated since 3.15 and will be removed in 3.20. Instead, use `PyUnicode_InternFromString()`{.interpreted-text role="c:func"} and cache the result in the module state, then call `PyObject_CallMethod`{.interpreted-text role="c:func"} or `PyObject_GetAttr`{.interpreted-text role="c:func"}. (Contributed by Victor Stinner in `141049`{.interpreted-text role="gh"}.)

- Deprecate `~PyComplexObject.cval`{.interpreted-text role="c:member"} field of the `PyComplexObject`{.interpreted-text role="c:type"} type. Use `PyComplex_AsCComplex`{.interpreted-text role="c:func"} and `PyComplex_FromCComplex`{.interpreted-text role="c:func"} to convert a Python complex number to/from the C `Py_complex`{.interpreted-text role="c:type"} representation. (Contributed by Sergey B Kirpichev in `128813`{.interpreted-text role="gh"}.)

- Functions `_Py_c_sum`{.interpreted-text role="c:func"}, `_Py_c_diff`{.interpreted-text role="c:func"}, `_Py_c_neg`{.interpreted-text role="c:func"}, `_Py_c_prod`{.interpreted-text role="c:func"}, `_Py_c_quot`{.interpreted-text role="c:func"}, `_Py_c_pow`{.interpreted-text role="c:func"} and `_Py_c_abs`{.interpreted-text role="c:func"} are `soft deprecated`{.interpreted-text role="term"}. (Contributed by Sergey B Kirpichev in `128813`{.interpreted-text role="gh"}.)

- `~PyConfig.bytes_warning`{.interpreted-text role="c:member"} is deprecated since 3.15 and will be removed in 3.17. (Contributed by Nikita Sobolev in `136355`{.interpreted-text role="gh"}.)

- `!Py_INFINITY`{.interpreted-text role="c:macro"} macro is `soft deprecated`{.interpreted-text role="term"}, use the C11 standard `<math.h>` `!INFINITY`{.interpreted-text role="c:macro"} instead. (Contributed by Sergey B Kirpichev in `141004`{.interpreted-text role="gh"}.)

- `!Py_MATH_El`{.interpreted-text role="c:macro"} and `!Py_MATH_PIl`{.interpreted-text role="c:macro"} are deprecated since 3.15 and will be removed in 3.20. (Contributed by Sergey B Kirpichev in `141004`{.interpreted-text role="gh"}.)

## Build changes

- Removed implicit fallback to the bundled copy of the `libmpdec` library. Now this should be explicitly enabled with `--with-system-libmpdec`{.interpreted-text role="option"} set to `no` or with `!--without-system-libmpdec`{.interpreted-text role="option"}. (Contributed by Sergey B Kirpichev in `115119`{.interpreted-text role="gh"}.)
- The new configure option `--with-missing-stdlib-config=FILE`{.interpreted-text role="option"} allows distributors to pass a [JSON](https://www.json.org/json-en.html) configuration file containing custom error messages for `standard library`{.interpreted-text role="term"} modules that are missing or packaged separately. (Contributed by Stan Ulbrych and Petr Viktorin in `139707`{.interpreted-text role="gh"}.)
- The new configure option `--with-pymalloc-hugepages`{.interpreted-text role="option"} enables huge page support for `pymalloc <pymalloc>`{.interpreted-text role="ref"} arenas. When enabled, arena size increases to 2 MiB and allocation uses `MAP_HUGETLB` (Linux) or `MEM_LARGE_PAGES` (Windows) with automatic fallback to regular pages. On Windows, use `build.bat --pymalloc-hugepages`. At runtime, huge pages must be explicitly enabled by setting the `PYTHON_PYMALLOC_HUGEPAGES`{.interpreted-text role="envvar"} environment variable to `1`.
- Annotating anonymous mmap usage is now supported if Linux kernel supports `PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>`{.interpreted-text role="manpage"} (Linux 5.17 or newer). Annotations are visible in `/proc/<pid>/maps` if the kernel supports the feature and `-X dev <-X>`{.interpreted-text role="option"} is passed to the Python or Python is built in `debug mode <debug-build>`{.interpreted-text role="ref"}. (Contributed by Donghee Na in `141770`{.interpreted-text role="gh"}.)

## Porting to Python 3.15

This section lists previously described changes and other bugfixes that may require changes to your code.

- `sqlite3.Connection`{.interpreted-text role="class"} APIs have been cleaned up.

  - All parameters of `sqlite3.connect`{.interpreted-text role="func"} except *database* are now keyword-only.
  - The first three parameters of methods `~sqlite3.Connection.create_function`{.interpreted-text role="meth"} and `~sqlite3.Connection.create_aggregate`{.interpreted-text role="meth"} are now positional-only.
  - The first parameter of methods `~sqlite3.Connection.set_authorizer`{.interpreted-text role="meth"}, `~sqlite3.Connection.set_progress_handler`{.interpreted-text role="meth"} and `~sqlite3.Connection.set_trace_callback`{.interpreted-text role="meth"} is now positional-only.

  (Contributed by Serhiy Storchaka in `133595`{.interpreted-text role="gh"}.)

- `resource.RLIM_INFINITY`{.interpreted-text role="data"} is now always positive. Passing a negative integer value that corresponded to its old value (such as `-1` or `-3`, depending on platform) to `resource.setrlimit`{.interpreted-text role="func"} and `resource.prlimit`{.interpreted-text role="func"} is now deprecated. (Contributed by Serhiy Storchaka in `137044`{.interpreted-text role="gh"}.)

- `mmap.mmap.resize`{.interpreted-text role="meth"} has been removed on platforms that don\'t support the underlying syscall, instead of raising a `SystemError`{.interpreted-text role="exc"}.

- A resource warning is now emitted for an unclosed `xml.etree.ElementTree.iterparse`{.interpreted-text role="func"} iterator if it opened a file. Use its `!close`{.interpreted-text role="meth"} method or the `contextlib.closing`{.interpreted-text role="func"} context manager to close it. (Contributed by Osama Abdelkader and Serhiy Storchaka in `140601`{.interpreted-text role="gh"}.)

- If a short option and a single-dash long option are passed to `argparse.ArgumentParser.add_argument`{.interpreted-text role="meth"}, *dest* is now inferred from the single-dash long option. For example, in `add_argument('-f', '-foo')`, *dest* is now `'foo'` instead of `'f'`. Pass an explicit *dest* argument to preserve the old behavior. (Contributed by Serhiy Storchaka in `138697`{.interpreted-text role="gh"}.)