FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python-docs-ru/howto/abi3t-migration.po at 3.15 · python/python-docs-ru · GitHub
python
python-docs-ru
Repository navigation
Code
Issues
Pull requests
Actions
Security and quality
Insights
Expand file tree
Breadcrumbs
python-docs-ru
/
howto
/
abi3t-migration.po
Copy path
More file actions
More file actions
Latest commit
History
History
History
943 lines (764 loc) · 26.5 KB
Breadcrumbs
python-docs-ru
/
howto
/
abi3t-migration.po
Copy path
File metadata and controls
943 lines (764 loc) · 26.5 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
#
SOME DESCRIPTIVE TITLE.
#
Copyright (C) 2001 Python Software Foundation
#
This file is distributed under the same license as the Python package.
#
FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#
Translators:
#
python-doc bot, 2026
#
#,
fuzzy
msgid ""
msgstr ""
"
Project-Id-Version
:
Python 3.15\n
"
"
Report-Msgid-Bugs-To
:
\n
"
"
POT-Creation-Date
:
2026-10-27 19:03+0000\n
"
"
PO-Revision-Date
:
2026-06-03 18:21+0000\n
"
"
Last-Translator
:
python-doc bot, 2026\n
"
"
Language-Team
:
Russian (https://app.transifex.com/python-doc/teams/5390/
"
"
ru/)\n
"
"
MIME-Version
:
1.0\n
"
"
Content-Type
:
text/plain; charset=UTF-8\n
"
"
Content-Transfer-Encoding
:
8bit\n
"
"
Language
:
ru\n
"
"
Plural-Forms
:
nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 &&
"
"
n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) ||
"
"
(n%100>=11 && n%100<=14)? 2 : 3);\n
"
msgid
"Migrating to Stable ABI for free threading (``abi3t``)"
msgstr
""
msgid
""
"Starting with the 3.15 release, CPython supports a variant of the Stable ABI "
"that supports :term:`free-threaded <free threading>` Python: the Stable ABI "
"for Free-Threaded Builds, or ``abi3t`` for short. This document describes "
"how to adapt C API extensions to support free threading."
msgstr
""
msgid
"Why do this"
msgstr
""
msgid
""
"The typical reason to use the Stable ABI is to reduce the number of "
"artifacts that you need to build and distribute for each version of your "
"library."
msgstr
""
msgid
""
"Without the Stable ABI, you must build a separate shared library, and "
"typically a *wheel* distribution, for each feature version of CPython you "
"wish to support. For example, each tag in the following table represents a "
"separate library/wheel:"
msgstr
""
msgid
"CPython version"
msgstr
""
msgid
"Non-free-threaded"
msgstr
""
msgid
"Free-threaded"
msgstr
""
msgid
"3.12"
msgstr
""
msgid
"``cpython-312``"
msgstr
""
msgid
"---"
msgstr
""
msgid
"3.13"
msgstr
""
msgid
"``cpython-313``"
msgstr
""
msgid
"``cpython-313t``"
msgstr
""
msgid
"3.14"
msgstr
""
msgid
"``cpython-314``"
msgstr
""
msgid
"``cpython-314t``"
msgstr
""
msgid
"3.15"
msgstr
""
msgid
"``cpython-315``"
msgstr
""
msgid
"``cpython-315t``"
msgstr
""
msgid
"3.16"
msgstr
""
msgid
"``cpython-316``"
msgstr
""
msgid
"``cpython-316t``"
msgstr
""
msgid
"Later versions"
msgstr
""
msgid
":samp:`cpython-3{XX}`"
msgstr
""
msgid
":samp:`cpython-3{XX}t`"
msgstr
""
msgid
""
"That's a lot of builds, especially when multiplied by the number of "
"supported platforms."
msgstr
""
msgid
""
"With the Stable ABI (``abi3``, introduced in CPython 3.2), a single "
"extension (per platform) can cover all *non-free-threaded* builds of CPython:"
msgstr
""
msgid
"``abi3``"
msgstr
""
msgid
""
"The Stable ABI for free-threaded builds (``abi3t``), introduced in CPython "
"3.15, does the same for free-threaded builds. And it's compatible with non-"
"free-threaded ones as well:"
msgstr
""
msgid
"``abi3`` *"
msgstr
""
msgid
"``abi3t``"
msgstr
""
msgid
""
"
\\
* (As above, the ``abi3`` extension is compatible with all non-free-"
"threaded builds; even the 3.15+ ones that this table
\"
attributes
\"
to "
"``abi3t``.)"
msgstr
""
msgid
"Why *not* do this"
msgstr
""
msgid
"There are two main downsides to the Stable ABI."
msgstr
""
msgid
""
"First, your extension may become slower, since the Stable ABI prioritizes "
"compatibility over performance. The difference is usually not noticeable, "
"and often can be mitigated by using the same source to build both a Stable "
"ABI build and a few version-specific ones for
\"
tier 1
\"
CPython versions."
msgstr
""
msgid
""
"Second, not all of the C API is available. Extensions need to be ported to "
"build for the Stable ABI, which may be difficult or, in rare cases, "
"impossible."
msgstr
""
msgid
""
"Specifically, ``abi3t`` requires APIs added in CPython 3.15. If you want to "
"build your extension for older versions of CPython from the same source, you "
"have two main options:"
msgstr
""
msgid
"Use preprocessor conditionals."
msgstr
""
msgid
""
"When following this guide, use ``#ifdef Py_TARGET_ABI3T`` blocks whenever "
"you are told to do a change that breaks the build on CPython versions you "
"care about. Keep the pre-existing code in ``#else`` blocks."
msgstr
""
msgid
""
"For hand-written C extensions, this approach is reasonable down to CPython "
"3.12, due to additions introduced in :pep:`697`. Keeping compatibility with "
"3.11 and below may be worth it for code generators (for example, Cython)."
msgstr
""
msgid
""
"Do not port to ``abi3t``, and continue building separate extensions for each "
"version of CPython, until you can drop support for the older versions."
msgstr
""
msgid
""
"This is a valid approach. Not all extensions need to switch to ``abi3t`` "
"right now."
msgstr
""
msgid
"Prerequisites"
msgstr
""
msgid
""
"This guide assumes that you have an extension written directly in C (or C+"
"+), which you want to port to ``abi3t``."
msgstr
""
msgid
""
"If your extension uses a code generator (like Cython) or language binding "
"(like PyO3), it's best to wait until that tool has support for ``abi3t``. If "
"you maintain such a tool, you might be able to adapt the instructions here "
"for your tool."
msgstr
""
msgid
"Non-free-threaded Stable ABI"
msgstr
""
msgid
""
"Your extension should support the non-free-threaded Stable ABI (``abi3``). "
"If not, either port it first, or follow this guide but be prepared to fix "
"issues it does not mention."
msgstr
""
msgid
"Free-threading support"
msgstr
""
msgid
""
"While it's technically not a hard prerequisite, you will most likely want to "
"prepare your extension for free threading before you port it to ``abi3t``. "
"See :ref:`freethreading-extensions-howto` for instructions."
msgstr
""
msgid
""
"`Porting Extension Modules to Support Free-Threading <https://py-free-"
"threading.github.io/porting/>`__: A community-maintained porting guide for "
"extension authors."
msgstr
""
msgid
"Isolating extension modules"
msgstr
""
msgid
""
"Your module should use :ref:`multi-phase initialization <multi-phase-"
"initialization>`, and it should either be isolated or limit itself to be "
"loaded at most once per process. If it is not your case, follow :ref:"
"`isolating-extensions-howto` first. (See the :ref:`opt-out section "
"<isolating-extensions-optout>` for a shortcut.)"
msgstr
""
msgid
"Avoiding variable-sized types"
msgstr
""
msgid
""
"If your extension defines variable-sized types (using :c:macro:"
"`Py_tp_itemsize` or :c:member:`PyTypeObject.tp_itemsize`), it cannot be "
"ported to ``abi3t`` 3.15."
msgstr
""
msgid
"Setting up the build"
msgstr
""
msgid
""
"If you use a build tool, search its documentation for
\"
``abi3t``
\"
, and "
"follow any instructions to select the ABI. For reference, here are direct "
"links for several popular build tools:"
msgstr
""
msgid
""
"`meson-python <https://mesonbuild.com/meson-python/how-to-guides/limited-api."
"html#the-abi3t-stable-abi>`__"
msgstr
""
msgid
""
"`scikit-build-core <https://scikit-build-core.readthedocs.io/en/stable/"
"configuration/#customizing-the-output-wheel>`__"
msgstr
""
msgid
"`Maturin <https://www.maturin.rs/bindings#py_limited_apiabi3>`__"
msgstr
""
msgid
""
"You may want to verify that the tool set the right flag by temporarily "
"adding the following just after ``#include <Python.h>``::"
msgstr
""
msgid
""
"#if Py_TARGET_ABI3T+0 <= 0x30f0000\n"
"#error
\"
abi3t define is not set!
\"
\n"
"#endif"
msgstr
""
msgid
""
"This should result in a different error than
\"
``abi3t`` define is not set
\"
."
msgstr
""
msgid
""
"`Building and distributing abi3t extensions <https://py-free-threading."
"github.io/abi3t/>`__: Build configuration and wheel testing examples in the "
"community-maintained Python Free-Threading Guide."
msgstr
""
msgid
""
"If your build tool doesn't support ``abi3t`` yet, set the following macro "
"before including ``Python.h``::"
msgstr
""
msgid
"#define Py_TARGET_ABI3T 0x30f0000"
msgstr
""
msgid
"or specify it as a compiler flag, for example::"
msgstr
""
msgid
"-DPy_TARGET_ABI3T=0x30f0000"
msgstr
""
msgid
""
"Once your extension builds with this setting, it will be compatible with "
"CPython 3.15 and above."
msgstr
""
msgid
""
"If you set this macro manually, you will later need to name and tag the "
"resulting extension manually as well. This is covered in :ref:`abi3t-"
"migration-tagging` below."
msgstr
""
msgid
""
"This guide will ask you to make a series of changes. After each one, verify "
"that your extension still builds in the original (non-``abi3t``) "
"configuration, and ideally run tests on all Python versions you support. "
"This will ensure that nothing breaks as you are porting."
msgstr
""
msgid
"Module export hook"
msgstr
""
msgid
""
"Unless you've done this step already, your extension module defines a :ref:"
"`module initialization function <extension-pyinit>` named :samp:"
"`PyInit_{<modname>}` (where ``modname`` is the name of your module). You "
"will need to port it to a :ref:`module export hook <extension-export-"
"hook>`, :samp:`PyModExport_{<modname>}`, a feature added in CPython 3.15 in :"
"pep:`793`."
msgstr
""
msgid
""
"Your existing init function should look like this (with your own names for "
"``<modname>`` and ``<moddef>``):"
msgstr
""
msgid
""
"PyMODINIT_FUNC\n"
"PyInit_<modname>(void)\n"
"{\n"
" return PyModuleDef_Init(&<moddef>);\n"
"}"
msgstr
""
msgid
""
"If there is some code before the ``return``, move it to a :c:macro:"
"`Py_mod_create` or :c:macro:`Py_mod_exec` slot function. See the :ref:"
"`PyInit documentation <extension-pyinit>` for related information."
msgstr
""
msgid
""
"The function references a ``PyModuleDef`` object (``<moddef>`` in the code "
"above). Its definition should be similar to the following, with different "
"values and perhaps some fields unnnamed or left out:"
msgstr
""
msgid
""
"static PyModuleDef <moddef> = {\n"
" PyModuleDef_HEAD_INIT,\n"
" .m_name =
\"
my_module
\"
,\n"
" .m_doc =
\"
my docstring
\"
,\n"
" .m_size = sizeof(my_state_struct),\n"
" .m_methods = my_methods,\n"
" .m_slots = my_slots,\n"
" .m_traverse = my_traverse,\n"
" .m_clear = my_clear,\n"
" .m_free = my_free,\n"
"};"
msgstr
""
msgid
""
"Remove this definition and the ``PyInit`` function (or put them in an "
"``#ifndef Py_TARGET_ABI3T`` block, to retain backwards compatibility), and "
"replace them with the following:"
msgstr
""
msgid
""
"PyABIInfo_VAR(abi_info);\n"
"\n"
"static PySlot my_slot_array[] = {\n"
" PySlot_STATIC_DATA(Py_mod_abi, &abi_info),\n"
" PySlot_STATIC_DATA(Py_mod_name,
\"
my_module
\"
),\n"
" PySlot_STATIC_DATA(Py_mod_doc,
\"
my docstring
\"
),\n"
" PySlot_SIZE(Py_mod_state_size, sizeof(my_state_struct)),\n"
" PySlot_STATIC_DATA(Py_mod_methods, my_methods),\n"
" PySlot_STATIC_DATA(Py_mod_slots, my_slots),\n"
" PySlot_FUNC(Py_mod_state_traverse, my_traverse),\n"
" PySlot_FUNC(Py_mod_state_clear, my_clear),\n"
" PySlot_FUNC(Py_mod_state_free, my_free),\n"
" PySlot_END\n"
"};\n"
"\n"
"PyMODEXPORT_FUNC\n"
"PyModExport_<modname>(void)\n"
"{\n"
" return my_slot_array;\n"
"}"
msgstr
""
msgid
""
"Leave out any fields that were missing (except the new :c:macro:"
"`Py_mod_abi`), and substitute your own values."
msgstr
""
msgid
""
"See the :c:type:`PySlot` and :c:ref:`export hook <extension-export-hook>` "
"documentation for details on this API."
msgstr
""
msgid
""
"As in the example, your ``PyModExport_`` function should *only* return a "
"pointer to static data. If you cannot avoid additional code, refer to the :"
"ref:`caveats in PyModExport documentation <pymodexport-api-caveats>`."
msgstr
""
msgid
""
"When building for Windows using the Setuptools_ build tool, removing the :"
"samp:`PyInit_{<modname>}` function may result in the linker error :samp:"
"`LINK : error LNK2001: unresolved external symbol PyInit_{<modname>}`. This "
"is caused by Setuptools passing an ``/EXPORT`` linker flag, which is "
"redundant since Python 3.15 (see :gh:`141671`). A workaround is to add a "
"dummy :samp:`PyInit_{<modname>}` function to your code. Python 3.15+ will "
"never call this function if :samp:`PyModExport_{<modname>}` is present, so "
"it can always fail:"
msgstr
""
msgid
""
"// Workaround for https://github.com/pypa/distutils/issues/387\n"
"PyMODINIT_FUNC\n"
"PyInit_<modname>(void)\n"
"{\n"
" PyErr_SetString(PyExc_SystemError,\n"
"
\"
PyInit_* called for module with PyModExport_*
\"
);\n"
" return NULL;\n"
"}"
msgstr
""
msgid
""
"(This issue is present in Setuptools 84.0.0; it might be fixed in newer "
"versions.)"
msgstr
""
msgid
"Existing slots"
msgstr
""
msgid
""
"If you have a ``Py_mod_slots`` slot, check the array it refers to. It should "
"be a :c:type:`PyModuleDef_Slot` array like the following:"
msgstr
""
msgid
""
"static PyObject *create_module(PyObject *spec, PyModuleDef *def) { ... }\n"
"static int my_first_module_exec(PyObject *module) { ... }\n"
"static int my_second_module_exec(PyObject *module) { ... }\n"
"\n"
"static PyModuleDef_Slot my_slots[] = {\n"
" {Py_mod_gil, Py_MOD_GIL_NOT_USED},\n"
" {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},\n"
" {Py_mod_create, my_module_create},\n"
" {Py_mod_exec, my_first_module_exec},\n"
" {Py_mod_exec, my_second_module_exec},\n"
" {0, NULL}\n"
"};"
msgstr
""
msgid
"``py_mod_create``"
msgstr
""
msgid
""
"If you have a :c:macro:`Py_mod_create` entry, make sure the function can be "
"called with ``NULL`` as its second argument (instead of the :c:type:"
"`PyModuleDef`, which you are removing). Often, this argument isn't used at "
"all; you can check by renaming it:"
msgstr
""
msgid
""
"static PyObject *create_module(PyObject *spec, PyModuleDef *_unused) { ... }"
msgstr
""
msgid
""
"If the argument is used, find a different way to pass in the data. Commonly, "
"the information is static and you can refer to it directly. (If you're "
"reusing a single function for several different modules, consider defining "
"several functions instead.)"
msgstr
""
msgid
"Multiple ``py_mod_exec``"
msgstr
""
msgid
""
"If you have *more than one* :c:macro:`Py_mod_exec` entry, consolidate them: "
"create a new function that calls the others, and replace existing slots with "
"it."
msgstr
""
msgid
""
"static int my_module_exec(PyObject *module) {\n"
" if (my_first_module_exec(module) < 0) return -1;\n"
" if (my_second_module_exec(module) < 0) return -1;\n"
"}\n"
"\n"
"static PyModuleDef_Slot my_slots[] = {\n"
" ...\n"
" /* (remove other Py_mod_exec slots) */\n"
" ...\n"
" {Py_mod_exec, my_module_exec},\n"
" {0, NULL}\n"
"};"
msgstr
""
msgid
""
"If the functions aren't used elsewhere, you can combine their bodies instead."
msgstr
""
msgid
"Merging slot arrays"
msgstr
""
msgid
""
"Optionally, when you break compatibility with Python 3.14, you may clean up "
"the code by moving slots into the :c:type:`PySlot` array, and converting the "
"definitions to :c:macro:`PySlot_DATA` and :c:macro:`PySlot_FUNC`:"
msgstr
""
msgid
""
"static PySlot my_slot_array[] = {\n"
" ...\n"
" PySlot_DATA(Py_mod_gil, Py_MOD_GIL_NOT_USED),\n"
" PySlot_DATA(Py_mod_multiple_interpreters,\n"
" Py_MOD_PER_INTERPRETER_GIL_SUPPORTED)\n"
" PySlot_FUNC(Py_mod_create, my_module_create),\n"
" PySlot_FUNC(Py_mod_exec, my_module_exec),\n"
" PySlot_END\n"
"};"
msgstr
""
msgid
""
"If you do this, delete the original :c:type:`PyModuleDef_Slot` array and its "
"``Py_mod_slots`` entry."
msgstr
""
msgid
"Associated ``PyModuleDef``"
msgstr
""
msgid
""
"Since the new API does not use a :c:type:`!PyModuleDef` structure, a "
"definition will not be associated with the resulting module. This changes "
"the behavior of the following functions:"
msgstr
""
msgid
":c:func:`PyModule_GetDef`"
msgstr
""
msgid
":c:func:`PyType_GetModuleByDef`"
msgstr
""
msgid
""
"Check your code for these. If you do not use them, you can skip this section."
msgstr
""
msgid
"These functions are typically used for two purposes:"
msgstr
""
msgid
""
"To get the definition the module was created with. This is no longer "
"possible using the new API. Modules no longer keep a reference to the "
"definition, so you will need to figure out a different way to pass the "
"relevant data around."
msgstr
""
msgid
""
"To check if a given module object is “yours”. This use case is now served "
"by :ref:`module tokens <ext-module-token>` -- opaque pointers that identify "
"a module. To use a token, declare (or reuse) a unique static variable, for "
"example:"
msgstr
""
msgid
"static char my_token;"
msgstr
""
msgid
""
"and add a pointer to it in a new entry to your module's ``PySlot`` array:"
msgstr
""
msgid
""
"static PySlot my_slot_array[] = {\n"
" ...\n"
" PySlot_STATIC_DATA(Py_mod_token, &my_token),\n"
" PySlot_END\n"
"}"
msgstr
""
msgid
"Then, switch from :c:func:`PyModule_GetDef` calls such as:"
msgstr
""
msgid
"PyModuleDef *def = PyModule_GetDef(module);"
msgstr
""
msgid
""
"to :c:func:`PyModule_GetToken` (which uses an output argument and may fail "
"with an exception):"
msgstr
""
msgid
""
"void *token;\n"
"if (PyModule_GetToken(module, &token) < 0) {\n"
" /* handle error */\n"
"}"
msgstr
""
msgid
"and from :c:func:`PyType_GetModuleByDef` calls such as:"
msgstr
""
msgid
""
"PyObject *module = PyType_GetModuleByDef(type, my_def);\n"
"/* handle error; use module */"
msgstr
""
msgid
""
"to :c:func:`PyType_GetModuleByToken` (which returns a strong reference):"
msgstr
""
msgid
""
"PyObject *module = PyType_GetModuleByToken(type, my_token);\n"
"/* handle error; use module */\n"
"Py_XDECREF(module);"
msgstr
""
msgid
"``PyObject`` opaqueness"
msgstr
""
msgid
""
"The :c:type:`PyObject` and :c:type:`PyVarObject` structures are opaque in "
"``abi3t``."
msgstr
""
msgid
""
"Accessing their members is prohibited. If you do this, switch to getter/"
"setter functions mentioned in their documentation:"
msgstr
""
msgid
":c:member:`PyObject.ob_type`"
msgstr
""
msgid
":c:member:`PyObject.ob_refcnt`"
msgstr
""
msgid
":c:member:`PyVarObject.ob_size`"
msgstr
""
msgid
""
"Also, the *size* of the :c:type:`PyObject` structures is unknown to the "
"compiler. It can -- and *does* -- change between different CPython builds."
msgstr
""
msgid
""
"While the size is available at runtime (for example as ``sys."
"getsizeof(object())`` in Python code), you should resist the temptation to "
"calculate pointer offsets from it. The object memory layout is subject to "
"change in future ``abi3t`` implementations."
msgstr
""
msgid
"Custom type definitions"
msgstr
""
msgid
""
"Since :c:type:`!PyObject` is opaque, the traditional way of defining custom "
"types no longer works:"
msgstr
""
msgid
""
"typedef struct {\n"
" PyObject_HEAD // expands to `PyObject ob_base;` which has unknown size\n"
"\n"
" int my_data;\n"
"} CustomObject;\n"
"\n"
"static PyType_Spec CustomType_spec = {\n"
" ...\n"
" .basicsize = sizeof(CustomObject),\n"
" ...\n"
"};"
msgstr
""
msgid
""
"Most likely, all your class definitions, *and* all code that accesses your "
"classes' data, will need to be rewritten. This will probably be the biggest "
"change you need to support ``abi3t``."
msgstr
""
msgid
""
"For each such type, instead of defining a ``struct`` for the entire "
"instance, define one with only the “additional” fields -- ones specific to "
"your class, not its superclasses:"
msgstr
""
msgid
""
"typedef struct {\n"
" int my_data;\n"
"} CustomObjectData;"
msgstr
""
msgid
""
"Change the name. Almost all code that uses the struct will need to change "
"(notably, pointers to the new structure cannot be cast to/from "
"``PyObject*``), and changing the name will highlight the usages as compiler "
"errors. (If you use ``typeof``, C++ ``auto``, or similar ways to avoid "
"typing the type name, this won't work. Be extra careful, and consider "
"running tools to detect undefined behavior.)"
msgstr
""
msgid
""
"Then, to create the class, use *negative* ``basicsize`` to indicate “extra” "
"storage space rather than *total* instance size:"
msgstr
""
msgid
""
"static PyType_Spec CustomType_spec = {\n"
" ...\n"
" .basicsize = -sizeof(CustomObjectData), /* note the minus sign */\n"
" ...\n"
"};"
msgstr
""
msgid
""
"If you use :c:macro:`Py_tp_members`, set the :c:macro:`Py_RELATIVE_OFFSET` "
"flag on each member and specify the :c:member:`~PyMemberDef.offset` relative "
"to your new struct."
msgstr
""
msgid
"Custom type data access"
msgstr
""
msgid
""
"Then comes the hard part: in all code that needs to access this struct, you "
"will need an additional :c:func:`PyObject_GetTypeData` call to retrieve a "
"``CustomObjectData *`` pointer from ``PyObject *``:"
msgstr
""
msgid
""
"PyObject *obj = ...;\n"
"CustomObjectData *data = PyObject_GetTypeData(obj, cls);"
msgstr
""
msgid
""
"Note that this call requires the *type object* for your class (``cls``)."
msgstr
""
msgid
""
"If your class is not subclassable (that is, it does not use the :c:macro:"
"`Py_TPFLAGS_BASETYPE` flag), ``cls`` will be ``Py_TYPE(obj)``. Otherwise, "
"**DO NOT USE** ``Py_TYPE`` with :c:func:`!PyObject_GetTypeData`: it might "
"return memory reserved to an unrelated subclass! For example, if a user "
"makes a subclass like this:"
msgstr
""
msgid
""
"class Sub(YourCustomClass):\n"
" __slots__ = ('a', 'b')"
msgstr
""
msgid
""
"then ``Py_TYPE(obj)`` is ``Sub``, and the underlying memory may look like "
"this:"
msgstr
""
msgid
""
"╭─ PyObject *obj\n"
"│ ╭─ the pointer you want\n"
"│ │ ╭─ PyObject_GetTypeData(obj, "
"Py_TYPE(obj))\n"
"▼ ▼ ▼\n"
"┌──────────┬───┬────────────────┬───┬─────────────┬───┬─────────────┐\n"
"│ PyObject │...│ CustomTypeData │...│ PyObject *a │...│ PyObject *b │\n"
"└──────────┴───┴────────────────┴───┴─────────────┴───┴─────────────┘"
msgstr
""
msgid
""
"(Ellipses indicate possible padding. Note that this memory layout is not "
"guaranteed: future versions of Python may add different padding or even "
"switch the order of the structures.)"
msgstr
""
msgid
"There are two main ways to get the right class:"
msgstr
""
msgid
""
"In instance methods, your implementation may use the :c:type:`PyCMethod` "
"signature (and the :c:macro:`METH_METHOD` bit in :c:member:`PyMethodDef."
"ml_flags`), and get the class as the ``defining_class`` argument."
msgstr
""
msgid
""
"Otherwise, give your class a unique static token using the :c:macro:"
"`Py_tp_token` slot, and use:"
msgstr
""
msgid
""
"PyTypeObject cls;\n"
"if (PyType_GetBaseByToken(Py_TYPE(obj), my_tp_token, &cls) < 0) {\n"
" /* handle error */\n"
"}\n"
"CustomObjectData *data = PyObject_GetTypeData(obj, cls);"
msgstr
""
msgid
""
"Type tokens work similarly to module tokens covered :ref:`earlier in this "
"guide <abi3t-migration-module-token>`."
msgstr
""
msgid
"Avoid build-time conditionals"
msgstr
""
msgid
""
"Check your code for API that identifies the version of Python used to "
"*build* your extension. This no longer corresponds to the Python your "
"extension runs on, so code that uses this information often needs changing. "
"The macros to check for are:"
msgstr
""
msgid
""
":c:macro:`PY_VERSION_HEX`, :c:macro:`PY_MAJOR_VERSION`, :c:macro:"
"`PY_MINOR_VERSION`:"
msgstr
""
msgid
"to get the run-time version, use :c:data:`Py_Version`;"
msgstr
""
msgid
""
"to determine what C API is available, use :c:macro:`Py_TARGET_ABI3T`. This "
"macro is set to the minimum supported version."
msgstr
""
msgid
""
":c:macro:`Py_GIL_DISABLED`: under ``abi3t``, this macro is always defined. "
"Code that works with free-threaded Python *should* also work with the GIL "
"enabled (since the GIL can be enabled at run time), and usually *does* "
"(unless it, for some reason, requires more than one :term:`attached thread "
"state <attached thread state>` at one time)."
msgstr
""
msgid
"Further code changes"
msgstr
""
msgid
""
"If you are still left with compiler errors or warnings, find a way to fix "
"them. Alas, this guide is limited, and cannot cover all possible code "
"changes extensions may need."
msgstr
""
msgid
""
"If you find a problem that other extension authors might run into, consider :"
"ref:`reporting an issue <reporting-documentation-bugs>` (or sending a pull "
"request) for this guide."
msgstr
""
msgid
""
"It is possible your issue cannot be fixed for the current version of "
"``abi3t``. In that case, reporting it may help it get prioritized for the "
"next version of CPython."
msgstr
""
msgid
"Tagging and distribution"
msgstr
""
msgid
""
"If you are using a build tool with ``abi3t`` support, your extension is "
"ready, but you might want to check that it was built correctly."
msgstr
""
msgid
"Extensions built with ``abi3t`` should have the following extension:"
msgstr
""
msgid
"On Windows: ``.pyd`` (like any other extension);"
msgstr
""
msgid
""
"Linux, macOS, and other systems that use the ``.so`` suffix: ``.abi3t.so`` "
"(**not** ``.cpython-315t.so`` or ``.abi3.so``). Note that both free-threaded "
"and non-free-threaded builds will load ``.abi3t.so`` extensions;"
msgstr
""
msgid
"Other systems: consult your distributor, and perhaps update this guide."
msgstr
""
msgid
"If you distribute the extension as a *wheel*, use the following tags:"
msgstr
""
msgid
""
"Python tag: :samp:`cp3{XX}`, where *XX* is the minimum Python version the "
"extension is built for. (For example, ``cp315`` if you set "
"``Py_TARGET_ABI3T`` to ``0x30f0000``. See :ref:`abi3-compiling` for more "
"values.)"
msgstr
""
msgid
""
"ABI tag: ``abi3.abi3t``. This is a *compressed tag set* that indicates "
"support for both non-free-threaded and free-threaded builds."
msgstr
""
msgid
"For example, the wheel filename may look like this:"
msgstr
""
msgid
"myproject-1.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl"
msgstr
""
msgid
""
"`Platform Compatibility Tags <https://packaging.python.org/en/latest/"
"specifications/platform-compatibility-tags/>`__ in the PyPA package "
"distribution metadata."
msgstr
""
msgid
"If the filename or tags are incorrect, fix them."
msgstr
""
msgid
"Testing"
msgstr
""
msgid
""
"Note that when you build an extension compatible with multiple versions of "
"CPython, you should always *test* it with each version it supports (for "
"example, 3.15, 3.16, and so on). The Stable ABI only guarantees *ABI* "
"compatibility; there may also be behavior changes -- both intentional ones "
"(covered by :pep:`387`) and bugs."
msgstr
""
msgid
""
"Be sure to run tests on both free-threaded and non-free-threaded builds of "
"CPython."
msgstr
""
msgid
"If they pass, congratulations! You have an ``abi3t`` extension."
msgstr
""
Back
|
FazBrowse Home
|
New Git URL