aboutsummaryrefslogtreecommitdiff
blob: 58e417441d1393871c3382ba40b68ad45c0109f4 (plain)
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
.. highlight:: c

.. _init-config:

***********************************
Python Initialization Configuration
***********************************

.. versionadded:: 3.8

Structures:

* :c:type:`PyConfig`
* :c:type:`PyPreConfig`
* :c:type:`PyStatus`
* :c:type:`PyWideStringList`

Functions:

* :c:func:`PyConfig_Clear`
* :c:func:`PyConfig_InitIsolatedConfig`
* :c:func:`PyConfig_InitPythonConfig`
* :c:func:`PyConfig_Read`
* :c:func:`PyConfig_SetArgv`
* :c:func:`PyConfig_SetBytesArgv`
* :c:func:`PyConfig_SetBytesString`
* :c:func:`PyConfig_SetString`
* :c:func:`PyConfig_SetWideStringList`
* :c:func:`PyPreConfig_InitIsolatedConfig`
* :c:func:`PyPreConfig_InitPythonConfig`
* :c:func:`PyStatus_Error`
* :c:func:`PyStatus_Exception`
* :c:func:`PyStatus_Exit`
* :c:func:`PyStatus_IsError`
* :c:func:`PyStatus_IsExit`
* :c:func:`PyStatus_NoMemory`
* :c:func:`PyStatus_Ok`
* :c:func:`PyWideStringList_Append`
* :c:func:`PyWideStringList_Insert`
* :c:func:`Py_ExitStatusException`
* :c:func:`Py_InitializeFromConfig`
* :c:func:`Py_PreInitialize`
* :c:func:`Py_PreInitializeFromArgs`
* :c:func:`Py_PreInitializeFromBytesArgs`
* :c:func:`Py_RunMain`

The preconfiguration (``PyPreConfig`` type) is stored in
``_PyRuntime.preconfig`` and the configuration (``PyConfig`` type) is stored in
``PyInterpreterState.config``.

See also :ref:`Initialization, Finalization, and Threads <initialization>`.

.. seealso::
   :pep:`587` "Python Initialization Configuration".


PyWideStringList
----------------

.. c:type:: PyWideStringList

   List of ``wchar_t*`` strings.

   If *length* is non-zero, *items* must be non-NULL and all strings must be
   non-NULL.

   Methods:

   .. c:function:: PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)

      Append *item* to *list*.

      Python must be preinitialized to call this function.

   .. c:function:: PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)

      Insert *item* into *list* at *index*.

      If *index* is greater than or equal to *list* length, append *item* to
      *list*.

      *index* must be greater than or equal to 0.

      Python must be preinitialized to call this function.

   Structure fields:

   .. c:member:: Py_ssize_t length

      List length.

   .. c:member:: wchar_t** items

      List items.

PyStatus
--------

.. c:type:: PyStatus

   Structure to store an initialization function status: success, error
   or exit.

   For an error, it can store the C function name which created the error.

   Structure fields:

   .. c:member:: int exitcode

      Exit code. Argument passed to ``exit()``.

   .. c:member:: const char *err_msg

      Error message.

   .. c:member:: const char *func

      Name of the function which created an error, can be ``NULL``.

   Functions to create a status:

   .. c:function:: PyStatus PyStatus_Ok(void)

      Success.

   .. c:function:: PyStatus PyStatus_Error(const char *err_msg)

      Initialization error with a message.

   .. c:function:: PyStatus PyStatus_NoMemory(void)

      Memory allocation failure (out of memory).

   .. c:function:: PyStatus PyStatus_Exit(int exitcode)

      Exit Python with the specified exit code.

   Functions to handle a status:

   .. c:function:: int PyStatus_Exception(PyStatus status)

      Is the status an error or an exit? If true, the exception must be
      handled; by calling :c:func:`Py_ExitStatusException` for example.

   .. c:function:: int PyStatus_IsError(PyStatus status)

      Is the result an error?

   .. c:function:: int PyStatus_IsExit(PyStatus status)

      Is the result an exit?

   .. c:function:: void Py_ExitStatusException(PyStatus status)

      Call ``exit(exitcode)`` if *status* is an exit. Print the error
      message and exit with a non-zero exit code if *status* is an error.  Must
      only be called if ``PyStatus_Exception(status)`` is non-zero.

.. note::
   Internally, Python uses macros which set ``PyStatus.func``,
   whereas functions to create a status set ``func`` to ``NULL``.

Example::

    PyStatus alloc(void **ptr, size_t size)
    {
        *ptr = PyMem_RawMalloc(size);
        if (*ptr == NULL) {
            return PyStatus_NoMemory();
        }
        return PyStatus_Ok();
    }

    int main(int argc, char **argv)
    {
        void *ptr;
        PyStatus status = alloc(&ptr, 16);
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }
        PyMem_Free(ptr);
        return 0;
    }


PyPreConfig
-----------

.. c:type:: PyPreConfig

   Structure used to preinitialize Python:

   * Set the Python memory allocator
   * Configure the LC_CTYPE locale
   * Set the UTF-8 mode

   The :c:member:`struct_size` field must be explicitly initialized to
   ``sizeof(PyPreConfig)``.

   Function to initialize a preconfiguration:

   .. c:function:: PyStatus PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)

      Initialize the preconfiguration with :ref:`Python Configuration
      <init-python-config>`.

   .. c:function:: PyStatus PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

      Initialize the preconfiguration with :ref:`Isolated Configuration
      <init-isolated-conf>`.

   The caller of these functions is responsible to handle exceptions (error or
   exit) using :c:func:`PyStatus_Exception` and
   :c:func:`Py_ExitStatusException`.

   Structure fields:

   .. c:member:: int allocator

      Name of the memory allocator:

      * ``PYMEM_ALLOCATOR_NOT_SET`` (``0``): don't change memory allocators
        (use defaults)
      * ``PYMEM_ALLOCATOR_DEFAULT`` (``1``): default memory allocators
      * ``PYMEM_ALLOCATOR_DEBUG`` (``2``): default memory allocators with
        debug hooks
      * ``PYMEM_ALLOCATOR_MALLOC`` (``3``): force usage of ``malloc()``
      * ``PYMEM_ALLOCATOR_MALLOC_DEBUG`` (``4``): force usage of
        ``malloc()`` with debug hooks
      * ``PYMEM_ALLOCATOR_PYMALLOC`` (``5``): :ref:`Python pymalloc memory
        allocator <pymalloc>`
      * ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG`` (``6``): :ref:`Python pymalloc
        memory allocator <pymalloc>` with debug hooks

      ``PYMEM_ALLOCATOR_PYMALLOC`` and ``PYMEM_ALLOCATOR_PYMALLOC_DEBUG``
      are not supported if Python is configured using ``--without-pymalloc``

      See :ref:`Memory Management <memory>`.

   .. c:member:: int configure_locale

      Set the LC_CTYPE locale to the user preferred locale? If equals to 0, set
      :c:member:`coerce_c_locale` and :c:member:`coerce_c_locale_warn` to 0.

   .. c:member:: int coerce_c_locale

      If equals to 2, coerce the C locale; if equals to 1, read the LC_CTYPE
      locale to decide if it should be coerced.

   .. c:member:: int coerce_c_locale_warn

      If non-zero, emit a warning if the C locale is coerced.

   .. c:member:: int dev_mode

      See :c:member:`PyConfig.dev_mode`.

   .. c:member:: int isolated

      See :c:member:`PyConfig.isolated`.

   .. c:member:: int legacy_windows_fs_encoding (Windows only)

      If non-zero, disable UTF-8 Mode, set the Python filesystem encoding to
      ``mbcs``, set the filesystem error handler to ``replace``.

      Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for
      Windows specific code.

   .. c:member:: int parse_argv

      If non-zero, :c:func:`Py_PreInitializeFromArgs` and
      :c:func:`Py_PreInitializeFromBytesArgs` parse their ``argv`` argument the
      same way the regular Python parses command line arguments: see
      :ref:`Command Line Arguments <using-on-cmdline>`.

   .. c:member:: size_t struct_size

      Size of the structure in bytes: must be initialized to
      ``sizeof(PyPreConfig)``.

      Field used for API and ABI compatibility.

   .. c:member:: int use_environment

      See :c:member:`PyConfig.use_environment`.

   .. c:member:: int utf8_mode

      If non-zero, enable the UTF-8 mode.

Preinitialization with PyPreConfig
----------------------------------

Functions to preinitialize Python:

.. c:function:: PyStatus Py_PreInitialize(const PyPreConfig *preconfig)

   Preinitialize Python from *preconfig* preconfiguration.

.. c:function:: PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv)

   Preinitialize Python from *preconfig* preconfiguration and command line
   arguments (bytes strings).

.. c:function:: PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)

   Preinitialize Python from *preconfig* preconfiguration and command line
   arguments (wide strings).

The caller is responsible to handle exceptions (error or exit) using
:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`.

For :ref:`Python Configuration <init-python-config>`
(:c:func:`PyPreConfig_InitPythonConfig`), if Python is initialized with
command line arguments, the command line arguments must also be passed to
preinitialize Python, since they have an effect on the pre-configuration
like encodings. For example, the :option:`-X utf8 <-X>` command line option
enables the UTF-8 Mode.

``PyMem_SetAllocator()`` can be called after :c:func:`Py_PreInitialize` and
before :c:func:`Py_InitializeFromConfig` to install a custom memory allocator.
It can be called before :c:func:`Py_PreInitialize` if
:c:member:`PyPreConfig.allocator` is set to ``PYMEM_ALLOCATOR_NOT_SET``.

Python memory allocation functions like :c:func:`PyMem_RawMalloc` must not be
used before Python preinitialization, whereas calling directly ``malloc()`` and
``free()`` is always safe. :c:func:`Py_DecodeLocale` must not be called before
the preinitialization.

Example using the preinitialization to enable the UTF-8 Mode::

    PyStatus status;
    PyPreConfig preconfig;
    preconfig.struct_size = sizeof(PyPreConfig);

    status = PyPreConfig_InitPythonConfig(&preconfig);
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }

    preconfig.utf8_mode = 1;

    status = Py_PreInitialize(&preconfig);
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }

    /* at this point, Python will speak UTF-8 */

    Py_Initialize();
    /* ... use Python API here ... */
    Py_Finalize();


PyConfig
--------

.. c:type:: PyConfig

   Structure containing most parameters to configure Python.

   The :c:member:`struct_size` field must be explicitly initialized to
   ``sizeof(PyConfig)``.

   Structure methods:

   .. c:function:: PyStatus PyConfig_InitPythonConfig(PyConfig *config)

      Initialize configuration with :ref:`Python Configuration
      <init-python-config>`.

   .. c:function:: PyStatus PyConfig_InitIsolatedConfig(PyConfig *config)

      Initialize configuration with :ref:`Isolated Configuration
      <init-isolated-conf>`.

   .. c:function:: PyStatus PyConfig_SetString(PyConfig *config, wchar_t * const *config_str, const wchar_t *str)

      Copy the wide character string *str* into ``*config_str``.

      Preinitialize Python if needed.

   .. c:function:: PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t * const *config_str, const char *str)

      Decode *str* using ``Py_DecodeLocale()`` and set the result into ``*config_str``.

      Preinitialize Python if needed.

   .. c:function:: PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t * const *argv)

      Set command line arguments from wide character strings.

      Preinitialize Python if needed.

   .. c:function:: PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char * const *argv)

      Set command line arguments: decode bytes using :c:func:`Py_DecodeLocale`.

      Preinitialize Python if needed.

   .. c:function:: PyStatus PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)

      Set the list of wide strings *list* to *length* and *items*.

      Preinitialize Python if needed.

   .. c:function:: PyStatus PyConfig_Read(PyConfig *config)

      Read all Python configuration.

      Fields which are already initialized are left unchanged.

      Preinitialize Python if needed.

   .. c:function:: void PyConfig_Clear(PyConfig *config)

      Release configuration memory.

   Most ``PyConfig`` methods preinitialize Python if needed. In that case, the
   Python preinitialization configuration in based on the :c:type:`PyConfig`.
   If configuration fields which are in common with :c:type:`PyPreConfig` are
   tuned, they must be set before calling a :c:type:`PyConfig` method:

   * :c:member:`~PyConfig.dev_mode`
   * :c:member:`~PyConfig.isolated`
   * :c:member:`~PyConfig.parse_argv`
   * :c:member:`~PyConfig.use_environment`

   Moreover, if :c:func:`PyConfig_SetArgv` or :c:func:`PyConfig_SetBytesArgv`
   is used, this method must be called first, before other methods, since the
   preinitialization configuration depends on command line arguments (if
   :c:member:`parse_argv` is non-zero).

   The caller of these methods is responsible to handle exceptions (error or
   exit) using ``PyStatus_Exception()`` and ``Py_ExitStatusException()``.

   Structure fields:

   .. c:member:: PyWideStringList argv

      Command line arguments, :data:`sys.argv`. See
      :c:member:`~PyConfig.parse_argv` to parse :c:member:`~PyConfig.argv` the
      same way the regular Python parses Python command line arguments. If
      :c:member:`~PyConfig.argv` is empty, an empty string is added to ensure
      that :data:`sys.argv` always exists and is never empty.

   .. c:member:: wchar_t* base_exec_prefix

      :data:`sys.base_exec_prefix`.

   .. c:member:: wchar_t* base_executable

      :data:`sys._base_executable`: ``__PYVENV_LAUNCHER__`` environment
      variable value, or copy of :c:member:`PyConfig.executable`.

   .. c:member:: wchar_t* base_prefix

      :data:`sys.base_prefix`.

   .. c:member:: int buffered_stdio

      If equals to 0, enable unbuffered mode, making the stdout and stderr
      streams unbuffered.

      stdin is always opened in buffered mode.

   .. c:member:: int bytes_warning

      If equals to 1, issue a warning when comparing :class:`bytes` or
      :class:`bytearray` with :class:`str`, or comparing :class:`bytes` with
      :class:`int`. If equal or greater to 2, raise a :exc:`BytesWarning`
      exception.

   .. c:member:: wchar_t* check_hash_pycs_mode

      Control the validation behavior of hash-based ``.pyc`` files (see
      :pep:`552`): :option:`--check-hash-based-pycs` command line option value.

      Valid values: ``always``, ``never`` and ``default``.

      The default value is: ``default``.

   .. c:member:: int configure_c_stdio

      If non-zero, configure C standard streams (``stdio``, ``stdout``,
      ``stdout``). For example, set their mode to ``O_BINARY`` on Windows.

   .. c:member:: int dev_mode

      Development mode: see :option:`-X dev <-X>`.

   .. c:member:: int dump_refs

      If non-zero, dump all objects which are still alive at exit.

      Require a debug build of Python (``Py_REF_DEBUG`` macro must be defined).

   .. c:member:: wchar_t* exec_prefix

      :data:`sys.exec_prefix`.

   .. c:member:: wchar_t* executable

      :data:`sys.executable`.

   .. c:member:: int faulthandler

      If non-zero, call :func:`faulthandler.enable` at startup.

   .. c:member:: wchar_t* filesystem_encoding

      Filesystem encoding, :func:`sys.getfilesystemencoding`.

   .. c:member:: wchar_t* filesystem_errors

      Filesystem encoding errors, :func:`sys.getfilesystemencodeerrors`.

   .. c:member:: unsigned long hash_seed
   .. c:member:: int use_hash_seed

      Randomized hash function seed.

      If :c:member:`~PyConfig.use_hash_seed` is zero, a seed is chosen randomly
      at Pythonstartup, and :c:member:`~PyConfig.hash_seed` is ignored.

   .. c:member:: wchar_t* home

      Python home directory.

      Initialized from :envvar:`PYTHONHOME` environment variable value by
      default.

   .. c:member:: int import_time

      If non-zero, profile import time.

   .. c:member:: int inspect

      Enter interactive mode after executing a script or a command.

   .. c:member:: int install_signal_handlers

      Install signal handlers?

   .. c:member:: int interactive

      Interactive mode.

   .. c:member:: int isolated

      If greater than 0, enable isolated mode:

      * :data:`sys.path` contains neither the script's directory (computed from
        ``argv[0]`` or the current directory) nor the user's site-packages
        directory.
      * Python REPL doesn't import :mod:`readline` nor enable default readline
        configuration on interactive prompts.
      * Set :c:member:`~PyConfig.use_environment` and
        :c:member:`~PyConfig.user_site_directory` to 0.

   .. c:member:: int legacy_windows_stdio

      If non-zero, use :class:`io.FileIO` instead of
      :class:`io.WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout`
      and :data:`sys.stderr`.

      Only available on Windows. ``#ifdef MS_WINDOWS`` macro can be used for
      Windows specific code.

   .. c:member:: int malloc_stats

      If non-zero, dump statistics on :ref:`Python pymalloc memory allocator
      <pymalloc>` at exit.

      The option is ignored if Python is built using ``--without-pymalloc``.

   .. c:member:: wchar_t* pythonpath_env

      Module search paths as a string separated by ``DELIM``
      (:data:`os.path.pathsep`).

      Initialized from :envvar:`PYTHONPATH` environment variable value by
      default.

   .. c:member:: PyWideStringList module_search_paths
   .. c:member:: int module_search_paths_set

      :data:`sys.path`. If :c:member:`~PyConfig.module_search_paths_set` is
      equal to 0, the :c:member:`~PyConfig.module_search_paths` is overridden
      by the function calculating the :ref:`Path Configuration
      <init-path-config>`.

   .. c:member:: int optimization_level

      Compilation optimization level:

      * 0: Peephole optimizer (and ``__debug__`` is set to ``True``)
      * 1: Remove assertions, set ``__debug__`` to ``False``
      * 2: Strip docstrings

   .. c:member:: int parse_argv

      If non-zero, parse :c:member:`~PyConfig.argv` the same way the regular
      Python command line arguments, and strip Python arguments from
      :c:member:`~PyConfig.argv`: see :ref:`Command Line Arguments
      <using-on-cmdline>`.

   .. c:member:: int parser_debug

      If non-zero, turn on parser debugging output (for expert only, depending
      on compilation options).

   .. c:member:: int pathconfig_warnings

      If equal to 0, suppress warnings when calculating the :ref:`Path
      Configuration <init-path-config>` (Unix only, Windows does not log any
      warning). Otherwise, warnings are written into ``stderr``.

   .. c:member:: wchar_t* prefix

      :data:`sys.prefix`.

   .. c:member:: wchar_t* program_name

      Program name. Used to initialize :c:member:`~PyConfig.executable`, and in
      early error messages.

   .. c:member:: wchar_t* pycache_prefix

      :data:`sys.pycache_prefix`: ``.pyc`` cache prefix.

      If NULL, :data:`sys.pycache_prefix` is set to ``None``.

   .. c:member:: int quiet

      Quiet mode. For example, don't display the copyright and version messages
      in interactive mode.

   .. c:member:: wchar_t* run_command

      ``python3 -c COMMAND`` argument. Used by :c:func:`Py_RunMain`.

   .. c:member:: wchar_t* run_filename

      ``python3 FILENAME`` argument. Used by :c:func:`Py_RunMain`.

   .. c:member:: wchar_t* run_module

      ``python3 -m MODULE`` argument. Used by :c:func:`Py_RunMain`.

   .. c:member:: int show_alloc_count

      Show allocation counts at exit?

      Set to 1 by :option:`-X showalloccount <-X>` command line option.

      Need a special Python build with ``COUNT_ALLOCS`` macro defined.

   .. c:member:: int show_ref_count

      Show total reference count at exit?

      Set to 1 by :option:`-X showrefcount <-X>` command line option.

      Need a debug build of Python (``Py_REF_DEBUG`` macro must be defined).

   .. c:member:: int site_import

      Import the :mod:`site` module at startup?

   .. c:member:: int skip_source_first_line

      Skip the first line of the source?

   .. c:member:: wchar_t* stdio_encoding
   .. c:member:: wchar_t* stdio_errors

      Encoding and encoding errors of :data:`sys.stdin`, :data:`sys.stdout` and
      :data:`sys.stderr`.

   .. c:member:: size_t struct_size

      Size of the structure in bytes: must be initialized to
      ``sizeof(PyConfig)``.

      Field used for API and ABI compatibility.

   .. c:member:: int tracemalloc

      If non-zero, call :func:`tracemalloc.start` at startup.

   .. c:member:: int use_environment

      If greater than 0, use :ref:`environment variables <using-on-envvars>`.

   .. c:member:: int user_site_directory

      If non-zero, add user site directory to :data:`sys.path`.

   .. c:member:: int verbose

      If non-zero, enable verbose mode.

   .. c:member:: PyWideStringList warnoptions

      Options of the :mod:`warnings` module to build warnings filters.

   .. c:member:: int write_bytecode

      If non-zero, write ``.pyc`` files.

      :data:`sys.dont_write_bytecode` is initialized to the inverted value of
      :c:member:`~PyConfig.write_bytecode`.

   .. c:member:: PyWideStringList xoptions

      :data:`sys._xoptions`.

If ``parse_argv`` is non-zero, ``argv`` arguments are parsed the same
way the regular Python parses command line arguments, and Python
arguments are stripped from ``argv``: see :ref:`Command Line Arguments
<using-on-cmdline>`.

The ``xoptions`` options are parsed to set other options: see :option:`-X`
option.


Initialization with PyConfig
----------------------------

Function to initialize Python:

.. c:function:: PyStatus Py_InitializeFromConfig(const PyConfig *config)

   Initialize Python from *config* configuration.

The caller is responsible to handle exceptions (error or exit) using
:c:func:`PyStatus_Exception` and :c:func:`Py_ExitStatusException`.

If ``PyImport_FrozenModules``, ``PyImport_AppendInittab()`` or
``PyImport_ExtendInittab()`` are used, they must be set or called after Python
preinitialization and before the Python initialization.

Example setting the program name::

    void init_python(void)
    {
        PyStatus status;
        PyConfig config;
        config.struct_size = sizeof(PyConfig);

        status = PyConfig_InitPythonConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        /* Set the program name. Implicitly preinitialize Python. */
        status = PyConfig_SetString(&config, &config.program_name,
                                    L"/path/to/my_program");
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        status = Py_InitializeFromConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        PyConfig_Clear(&config);
        return;

    fail:
        PyConfig_Clear(&config);
        Py_ExitStatusException(status);
    }

More complete example modifying the default configuration, read the
configuration, and then override some parameters::

    PyStatus init_python(const char *program_name)
    {
        PyStatus status;
        PyConfig config;
        config.struct_size = sizeof(PyConfig);

        status = PyConfig_InitPythonConfig(&config);
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Set the program name before reading the configuraton
           (decode byte string from the locale encoding).

           Implicitly preinitialize Python. */
        status = PyConfig_SetBytesString(&config, &config.program_name,
                                      program_name);
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Read all configuration at once */
        status = PyConfig_Read(&config);
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Append our custom search path to sys.path */
        status = PyWideStringList_Append(&config.module_search_paths,
                                         L"/path/to/more/modules");
        if (PyStatus_Exception(status)) {
            goto done;
        }

        /* Override executable computed by PyConfig_Read() */
        status = PyConfig_SetString(&config, &config.executable,
                                    L"/path/to/my_executable");
        if (PyStatus_Exception(status)) {
            goto done;
        }

        status = Py_InitializeFromConfig(&config);

    done:
        PyConfig_Clear(&config);
        return status;
    }


.. _init-isolated-conf:

Isolated Configuration
----------------------

:c:func:`PyPreConfig_InitIsolatedConfig` and
:c:func:`PyConfig_InitIsolatedConfig` functions create a configuration to
isolate Python from the system. For example, to embed Python into an
application.

This configuration ignores global configuration variables, environments
variables, command line arguments (:c:member:`PyConfig.argv` is not parsed)
and user site directory. The C standard streams (ex: ``stdout``) and the
LC_CTYPE locale are left unchanged. Signal handlers are not installed.

Configuration files are still used with this configuration. Set the
:ref:`Path Configuration <init-path-config>` ("output fields") to ignore these
configuration files and avoid the function computing the default path
configuration.


.. _init-python-config:

Python Configuration
--------------------

:c:func:`PyPreConfig_InitPythonConfig` and :c:func:`PyConfig_InitPythonConfig`
functions create a configuration to build a customized Python which behaves as
the regular Python.

Environments variables and command line arguments are used to configure
Python, whereas global configuration variables are ignored.

This function enables C locale coercion (:pep:`538`) and UTF-8 Mode
(:pep:`540`) depending on the LC_CTYPE locale, :envvar:`PYTHONUTF8` and
:envvar:`PYTHONCOERCECLOCALE` environment variables.

Example of customized Python always running in isolated mode::

    int main(int argc, char **argv)
    {
        PyStatus status;
        PyConfig config;
        config.struct_size = sizeof(PyConfig);

        status = PyConfig_InitPythonConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        config.isolated = 1;

        /* Decode command line arguments.
           Implicitly preinitialize Python (in isolated mode). */
        status = PyConfig_SetBytesArgv(&config, argc, argv);
        if (PyStatus_Exception(status)) {
            goto fail;
        }

        status = Py_InitializeFromConfig(&config);
        if (PyStatus_Exception(status)) {
            goto fail;
        }
        PyConfig_Clear(&config);

        return Py_RunMain();

    fail:
        PyConfig_Clear(&config);
        if (PyStatus_IsExit(status)) {
            return status.exitcode;
        }
        /* Display the error message and exit the process with
           non-zero exit code */
        Py_ExitStatusException(status);
    }


.. _init-path-config:

Path Configuration
------------------

:c:type:`PyConfig` contains multiple fields for the path configuration:

* Path configuration inputs:

  * :c:member:`PyConfig.home`
  * :c:member:`PyConfig.pathconfig_warnings`
  * :c:member:`PyConfig.program_name`
  * :c:member:`PyConfig.pythonpath_env`
  * current working directory: to get absolute paths
  * ``PATH`` environment variable to get the program full path
    (from :c:member:`PyConfig.program_name`)
  * ``__PYVENV_LAUNCHER__`` environment variable
  * (Windows only) Application paths in the registry under
    "Software\Python\PythonCore\X.Y\PythonPath" of HKEY_CURRENT_USER and
    HKEY_LOCAL_MACHINE (where X.Y is the Python version).

* Path configuration output fields:

  * :c:member:`PyConfig.base_exec_prefix`
  * :c:member:`PyConfig.base_executable`
  * :c:member:`PyConfig.base_prefix`
  * :c:member:`PyConfig.exec_prefix`
  * :c:member:`PyConfig.executable`
  * :c:member:`PyConfig.module_search_paths_set`,
    :c:member:`PyConfig.module_search_paths`
  * :c:member:`PyConfig.prefix`

If at least one "output field" is not set, Python calculates the path
configuration to fill unset fields. If
:c:member:`~PyConfig.module_search_paths_set` is equal to 0,
:c:member:`~PyConfig.module_search_paths` is overridden and
:c:member:`~PyConfig.module_search_paths_set` is set to 1.

It is possible to completely ignore the function calculating the default
path configuration by setting explicitly all path configuration output
fields listed above. A string is considered as set even if it is non-empty.
``module_search_paths`` is considered as set if
``module_search_paths_set`` is set to 1. In this case, path
configuration input fields are ignored as well.

Set :c:member:`~PyConfig.pathconfig_warnings` to 0 to suppress warnings when
calculating the path configuration (Unix only, Windows does not log any warning).

If :c:member:`~PyConfig.base_prefix` or :c:member:`~PyConfig.base_exec_prefix`
fields are not set, they inherit their value from :c:member:`~PyConfig.prefix`
and :c:member:`~PyConfig.exec_prefix` respectively.

:c:func:`Py_RunMain` and :c:func:`Py_Main` modify :data:`sys.path`:

* If :c:member:`~PyConfig.run_filename` is set and is a directory which contains a
  ``__main__.py`` script, prepend :c:member:`~PyConfig.run_filename` to
  :data:`sys.path`.
* If :c:member:`~PyConfig.isolated` is zero:

  * If :c:member:`~PyConfig.run_module` is set, prepend the current directory
    to :data:`sys.path`. Do nothing if the current directory cannot be read.
  * If :c:member:`~PyConfig.run_filename` is set, prepend the directory of the
    filename to :data:`sys.path`.
  * Otherwise, prepend an empty string to :data:`sys.path`.

If :c:member:`~PyConfig.site_import` is non-zero, :data:`sys.path` can be
modified by the :mod:`site` module. If
:c:member:`~PyConfig.user_site_directory` is non-zero and the user's
site-package directory exists, the :mod:`site` module appends the user's
site-package directory to :data:`sys.path`.

The following configuration files are used by the path configuration:

* ``pyvenv.cfg``
* ``python._pth`` (Windows only)
* ``pybuilddir.txt`` (Unix only)

The ``__PYVENV_LAUNCHER__`` environment variable is used to set
:c:member:`PyConfig.base_executable`


Py_RunMain()
------------

.. c:function:: int Py_RunMain(void)

   Execute the command (:c:member:`PyConfig.run_command`), the script
   (:c:member:`PyConfig.run_filename`) or the module
   (:c:member:`PyConfig.run_module`) specified on the command line or in the
   configuration.

   By default and when if :option:`-i` option is used, run the REPL.

   Finally, finalizes Python and returns an exit status that can be passed to
   the ``exit()`` function.

See :ref:`Python Configuration <init-python-config>` for an example of
customized Python always running in isolated mode using
:c:func:`Py_RunMain`.


Multi-Phase Initialization Private Provisional API
--------------------------------------------------

This section is a private provisional API introducing multi-phase
initialization, the core feature of the :pep:`432`:

* "Core" initialization phase, "bare minimum Python":

  * Builtin types;
  * Builtin exceptions;
  * Builtin and frozen modules;
  * The :mod:`sys` module is only partially initialized
    (ex: :data:`sys.path` doesn't exist yet).

* "Main" initialization phase, Python is fully initialized:

  * Install and configure :mod:`importlib`;
  * Apply the :ref:`Path Configuration <init-path-config>`;
  * Install signal handlers;
  * Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout`
    and :data:`sys.path`);
  * Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`;
  * Import the :mod:`site` module;
  * etc.

Private provisional API:

* :c:member:`PyConfig._init_main`: if set to 0,
  :c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase.

.. c:function:: PyStatus _Py_InitializeMain(void)

   Move to the "Main" initialization phase, finish the Python initialization.

No module is imported during the "Core" phase and the ``importlib`` module is
not configured: the :ref:`Path Configuration <init-path-config>` is only
applied during the "Main" phase. It may allow to customize Python in Python to
override or tune the :ref:`Path Configuration <init-path-config>`, maybe
install a custom :data:`sys.meta_path` importer or an import hook, etc.

It may become possible to calculatin the :ref:`Path Configuration
<init-path-config>` in Python, after the Core phase and before the Main phase,
which is one of the :pep:`432` motivation.

The "Core" phase is not properly defined: what should be and what should
not be available at this phase is not specified yet. The API is marked
as private and provisional: the API can be modified or even be removed
anytime until a proper public API is designed.

Example running Python code between "Core" and "Main" initialization
phases::

    void init_python(void)
    {
        PyStatus status;
        PyConfig config;
        config.struct_size = sizeof(PyConfig);

        status = PyConfig_InitPythonConfig(&config);
        if (PyStatus_Exception(status)) {
            PyConfig_Clear(&config);
            Py_ExitStatusException(status);
        }

        config._init_main = 0;

        /* ... customize 'config' configuration ... */

        status = Py_InitializeFromConfig(&config);
        PyConfig_Clear(&config);
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }

        /* Use sys.stderr because sys.stdout is only created
           by _Py_InitializeMain() */
        int res = PyRun_SimpleString(
            "import sys; "
            "print('Run Python code before _Py_InitializeMain', "
                   "file=sys.stderr)");
        if (res < 0) {
            exit(1);
        }

        /* ... put more configuration code here ... */

        status = _Py_InitializeMain();
        if (PyStatus_Exception(status)) {
            Py_ExitStatusException(status);
        }
    }