Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 587 – Python Initialisierungskonfiguration

Autor:
Victor Stinner <vstinner at python.org>, Alyssa Coghlan <ncoghlan at gmail.com>
BDFL-Delegate:
Thomas Wouters <thomas at python.org>
Discussions-To:
Python-Dev Liste
Status:
Final
Typ:
Standards Track
Erstellt:
27. Mrz. 2019
Python-Version:
3.8

Inhaltsverzeichnis

Zusammenfassung

Fügen Sie eine neue C-API hinzu, um die Python-Initialisierung zu konfigurieren, die eine feinere Kontrolle über die gesamte Konfiguration und eine bessere Fehlerberichterstattung bietet.

Es wird möglich, die Konfiguration zu lesen und dann einige berechnete Parameter zu überschreiben, bevor sie angewendet werden. Es wird auch möglich, die Art und Weise, wie Python die Modulsuchpfade (sys.path) berechnet, vollständig zu überschreiben.

Die neue isolierte Konfiguration bietet vernünftige Standardwerte, um Python vom System zu isolieren. Zum Beispiel, um Python in eine Anwendung einzubetten. Die Nutzung der Umgebung sind nun explizite Optionen statt impliziter Optionen. Zum Beispiel werden Umgebungsvariablen, Befehlszeilenargumente und globale Konfigurationsvariablen standardmäßig ignoriert.

Das Erstellen eines angepassten Python, das sich wie das reguläre Python verhält, wird durch die neue Funktion Py_RunMain() einfacher. Darüber hinaus werden mithilfe der Python-Konfiguration die Argumente von PyConfig.argv nun auf die gleiche Weise geparst wie die reguläre Python-Befehlszeilenargumente, und PyConfig.xoptions werden als -X opt-Befehlszeilenoptionen behandelt.

Dies extrahiert eine Teilmenge des API-Designs aus dem PEP 432-Entwicklungs- und Refactoring-Arbeiten, die nun als ausreichend stabil gelten, um öffentlich gemacht zu werden (wodurch Drittanbieter-Einbettungsanwendungen Zugang zu denselben Konfigurations-APIs erhalten, die die native CPython-CLI nun verwendet).

Begründung

Python ist hochgradig konfigurierbar, aber seine Konfiguration hat sich organisch entwickelt. Die Initialisierungskonfiguration ist über den gesamten Code verstreut und verwendet unterschiedliche Methoden zur Einstellung: globale Konfigurationsvariablen (z. B. Py_IsolatedFlag), Umgebungsvariablen (z. B. PYTHONPATH), Befehlszeilenargumente (z. B. -b), Konfigurationsdateien (z. B. pyvenv.cfg), Funktionsaufrufe (z. B. Py_SetProgramName()). Eine unkomplizierte und zuverlässige Methode zur Konfiguration von Python wird benötigt.

Einige Konfigurationsparameter sind über die C-API nicht oder nicht einfach zugänglich. Zum Beispiel gibt es keine API, um die Standardwerte von sys.executable zu überschreiben.

Einige Optionen wie PYTHONPATH können nur über eine Umgebungsvariable gesetzt werden, was sich auf Python-Kindprozesse auswirkt, wenn sie nicht richtig unsetzt wird.

Einige Optionen hängen auch von anderen Optionen ab: siehe Priorität und Regeln. Die Python 3.7 API bietet keine konsistente Sicht auf die Gesamtkonfiguration.

Die C-API der Python 3.7-Initialisierung verwendet wchar_t*-Strings als Eingabe, während die Dateisystemkodierung von Python während der Initialisierung festgelegt wird, was zu Mojibake führen kann.

Python 3.7-APIs wie Py_Initialize() brechen den Prozess bei einem Speicherallokationsfehler ab, was bei der Einbettung von Python nicht praktisch ist. Darüber hinaus konnte Py_Main() den Prozess direkt beenden, anstatt einen Exit-Code zurückzugeben. Die vorgeschlagene neue API meldet den Fehler oder den Exit-Code an den Aufrufer, der entscheiden kann, wie er damit umgeht.

Die Implementierung von PEP 540 (UTF-8-Modus) und des neuen -X dev war in Python 3.6 fast unmöglich richtig umzusetzen. Die Codebasis wurde in Python 3.7 und dann in Python 3.8 tiefgreifend überarbeitet, um die Konfiguration in eine Struktur ohne Seiteneffekte zu lesen. Es wird möglich, die Konfiguration zu löschen (Speicher freizugeben) und die Konfiguration erneut zu lesen, wenn sich die Kodierung geändert hat. Dies ist erforderlich, um UTF-8 richtig zu implementieren, was die Kodierung mit der Befehlszeilenoption -X utf8 ändert. Intern werden Bytes argv-Strings aus der Dateisystemkodierung dekodiert. -X dev ändert den Speicherallokator (verhält sich wie PYTHONMALLOC=debug), obwohl es nicht möglich war, die Speicherallokation *während* des Parsens der Befehlszeilenargumente zu ändern. Das neue Design der internen Implementierung hat nicht nur die ordnungsgemäße Implementierung von -X utf8 und -X dev ermöglicht, sondern auch die Änderung des Python-Verhaltens auf viel einfachere Weise, insbesondere für Eckfälle wie diesen, und stellt sicher, dass die Konfiguration konsistent bleibt: siehe Priorität und Regeln.

Dieser PEP ist eine Teilimplementierung von PEP 432, der das Gesamtdesign darstellt. Neue Felder können später zur PyConfig-Struktur hinzugefügt werden, um die Implementierung von PEP 432 abzuschließen (z. B. durch Hinzufügen einer neuen partiellen Initialisierungs-API, die die Konfiguration von Python mit Python-Objekten ermöglicht, um die vollständige Initialisierung abzuschließen). Diese Funktionen sind jedoch von diesem PEP ausgeschlossen, da selbst die native CPython-CLI nicht so funktioniert – die öffentliche API-Vorschlag in diesem PEP ist auf Funktionen beschränkt, die bereits als private APIs für uns in der nativen CPython-CLI implementiert und übernommen wurden.

Python Initialisierungs-C-API

Dieser PEP schlägt die folgenden neuen Strukturen und Funktionen vor.

Neue Strukturen

  • PyConfig
  • PyPreConfig
  • PyStatus
  • PyWideStringList

Neue Funktionen

  • PyConfig_Clear(config)
  • PyConfig_InitIsolatedConfig()
  • PyConfig_InitPythonConfig()
  • PyConfig_Read(config)
  • PyConfig_SetArgv(config, argc, argv)
  • PyConfig_SetBytesArgv(config, argc, argv)
  • PyConfig_SetBytesString(config, config_str, str)
  • PyConfig_SetString(config, config_str, str)
  • PyPreConfig_InitIsolatedConfig(preconfig)
  • PyPreConfig_InitPythonConfig(preconfig)
  • PyStatus_Error(err_msg)
  • PyStatus_Exception(status)
  • PyStatus_Exit(exitcode)
  • PyStatus_IsError(status)
  • PyStatus_IsExit(status)
  • PyStatus_NoMemory()
  • PyStatus_Ok()
  • PyWideStringList_Append(list, item)
  • PyWideStringList_Insert(list, index, item)
  • Py_BytesMain(argc, argv)
  • Py_ExitStatusException(status)
  • Py_InitializeFromConfig(config)
  • Py_PreInitialize(preconfig)
  • Py_PreInitializeFromArgs(preconfig, argc, argv)
  • Py_PreInitializeFromBytesArgs(preconfig, argc, argv)
  • Py_RunMain()

Dieser PEP fügt auch die Felder _PyRuntimeState.preconfig (PyPreConfig-Typ) und PyInterpreterState.config (PyConfig-Typ) zu diesen internen Strukturen hinzu. PyInterpreterState.config wird zur neuen Referenzkonfiguration und ersetzt globale Konfigurationsvariablen und andere private Variablen.

PyWideStringList

PyWideStringList ist eine Liste von wchar_t*-Strings.

PyWideStringList-Strukturfelder

  • length (Py_ssize_t)
  • items (wchar_t**)

Methoden

  • PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item): Fügt item an list an.
  • PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item): Fügt item an index in list ein. Wenn index größer als die Länge von list ist, wird item einfach an list angehängt.

Wenn length ungleich Null ist, muss items nicht NULL sein und alle Strings dürfen nicht NULL sein.

PyStatus

PyStatus ist eine Struktur zur Speicherung des Status einer Initialisierungsfunktion: Erfolg, Fehler oder Beendigung. Bei einem Fehler kann sie den C-Funktionsnamen speichern, der den Fehler verursacht hat.

Beispiel

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;
}

PyStatus-Felder

  • exitcode (int): An exit() übergebener Argument.
  • err_msg (const char*): Fehlermeldung.
  • func (const char *): Name der Funktion, die einen Fehler verursacht hat, kann NULL sein.
  • privates _type-Feld: nur für interne Nutzung.

Funktionen zum Erstellen eines Status

  • PyStatus_Ok(): Erfolg.
  • PyStatus_Error(err_msg): Initialisierungsfehler mit einer Meldung.
  • PyStatus_NoMemory(): Speicherallokationsfehler (nicht genügend Speicher).
  • PyStatus_Exit(exitcode): Beendet Python mit dem angegebenen Exit-Code.

Funktionen zur Handhabung eines Status

  • PyStatus_Exception(status): Ist das Ergebnis ein Fehler oder eine Beendigung? Wenn wahr, muss die Ausnahme behandelt werden; zum Beispiel durch Aufruf von Py_ExitStatusException(status).
  • PyStatus_IsError(status): Ist das Ergebnis ein Fehler?
  • PyStatus_IsExit(status): Ist das Ergebnis eine Beendigung?
  • Py_ExitStatusException(status): Ruft exit(exitcode) auf, wenn status eine Beendigung ist. Gibt die Fehlermeldung aus und beendet mit einem nicht-null Exit-Code, wenn status ein Fehler ist. Darf nur aufgerufen werden, wenn PyStatus_Exception(status) wahr ist.

Hinweis

Intern verwendet Python Makros, die PyStatus.func setzen, während Funktionen zum Erstellen eines Status func auf NULL setzen.

Vorinitialisierung mit PyPreConfig

Die PyPreConfig-Struktur wird zur Vorinitialisierung von Python verwendet

  • Festlegen des Python-Speicherallokators
  • Konfigurieren des LC_CTYPE-Locales
  • Festlegen des UTF-8-Modus

Beispiel für die Verwendung der Vorinitialisierung zur Aktivierung des UTF-8-Modus

PyStatus status;
PyPreConfig preconfig;

PyPreConfig_InitPythonConfig(&preconfig);

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();

Funktionen zur Initialisierung einer Vor-Konfiguration

  • PyStatus PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
  • PyStatus PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

Funktionen zur Vorinitialisierung von Python

  • PyStatus Py_PreInitialize(const PyPreConfig *preconfig)
  • PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv)
  • PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)

Der Aufrufer ist für die Handhabung von Ausnahmen (Fehler oder Beendigung) unter Verwendung von PyStatus_Exception() und Py_ExitStatusException() verantwortlich.

Für die Python-Konfiguration (PyPreConfig_InitPythonConfig()) müssen, wenn Python mit Befehlszeilenargumenten initialisiert wird, die Befehlszeilenargumente auch zur Vorinitialisierung von Python übergeben werden, da sie Auswirkungen auf die Vor-Konfiguration haben, wie z. B. Kodierungen. Die Befehlszeilenoption -X utf8 aktiviert beispielsweise den UTF-8-Modus.

PyPreConfig-Felder

  • allocator (int): Name des Speicherallokators (z. B. PYMEM_ALLOCATOR_MALLOC). Gültige Werte
    • PYMEM_ALLOCATOR_NOT_SET (0): Speicherallokatoren nicht ändern (Standard verwenden)
    • PYMEM_ALLOCATOR_DEFAULT (1): Standard-Speicherallokatoren
    • PYMEM_ALLOCATOR_DEBUG (2): Standard-Speicherallokatoren mit Debug-Hooks
    • PYMEM_ALLOCATOR_MALLOC (3): Erzwinge die Verwendung von malloc()
    • PYMEM_ALLOCATOR_MALLOC_DEBUG (4): Erzwinge die Verwendung von malloc() mit Debug-Hooks
    • PYMEM_ALLOCATOR_PYMALLOC (5): Python "pymalloc"-Allokator
    • PYMEM_ALLOCATOR_PYMALLOC_DEBUG (6): Python "pymalloc"-Allokator mit Debug-Hooks
    • Hinweis: PYMEM_ALLOCATOR_PYMALLOC und PYMEM_ALLOCATOR_PYMALLOC_DEBUG werden nicht unterstützt, wenn Python mit --without-pymalloc konfiguriert wurde.
  • configure_locale (int): Setzt das LC_CTYPE-Locale auf das bevorzugte Benutzer-Locale? Wenn gleich 0, wird coerce_c_locale und coerce_c_locale_warn auf 0 gesetzt.
  • coerce_c_locale (int): Wenn gleich 2, erzwinge das C-Locale; wenn gleich 1, lies das LC_CTYPE-Locale, um zu entscheiden, ob es erzwungen werden soll.
  • coerce_c_locale_warn (int): Wenn nicht-null, gibt eine Warnung aus, wenn das C-Locale erzwungen wird.
  • dev_mode (int): Siehe PyConfig.dev_mode.
  • isolated (int): Siehe PyConfig.isolated.
  • legacy_windows_fs_encoding (int, nur Windows): Wenn nicht-null, deaktiviere den UTF-8-Modus, setze die Python-Dateisystemkodierung auf mbcs, setze den Dateisystem-Fehlerhandler auf replace.
  • parse_argv (int): Wenn nicht-null, parsen Py_PreInitializeFromArgs() und Py_PreInitializeFromBytesArgs() ihr argv-Argument so, wie es das reguläre Python für Befehlszeilenargumente tut: siehe Befehlszeilenargumente.
  • use_environment (int): Siehe PyConfig.use_environment.
  • utf8_mode (int): Wenn nicht-null, aktiviere den UTF-8-Modus.

Das Feld legacy_windows_fs_encoding ist nur unter Windows verfügbar. Das Makro #ifdef MS_WINDOWS kann für Windows-spezifischen Code verwendet werden.

PyPreConfig private Felder, nur für interne Nutzung

  • _config_init (int): Funktion zur Initialisierung von PyConfig, verwendet für die Vorinitialisierung.

PyMem_SetAllocator() kann nach Py_PreInitialize() und vor Py_InitializeFromConfig() aufgerufen werden, um einen benutzerdefinierten Speicherallokator zu installieren. Es kann vor Py_PreInitialize() aufgerufen werden, wenn allocator auf PYMEM_ALLOCATOR_NOT_SET gesetzt ist (Standardwert).

Python-Speicherallokationsfunktionen wie PyMem_RawMalloc() dürfen nicht vor der Python-Vorinitialisierung verwendet werden, während der direkte Aufruf von malloc() und free() immer sicher ist. Py_DecodeLocale() darf nicht vor der Vorinitialisierung aufgerufen werden.

Initialisierung mit PyConfig

Die PyConfig-Struktur enthält die meisten Parameter zur Konfiguration von Python.

Beispiel für das Festlegen des Programmnamens

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* 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);
}

PyConfig-Methoden

  • void PyConfig_InitPythonConfig(PyConfig *config) Initialisiert die Konfiguration mit Python-Konfiguration.
  • void PyConfig_InitIsolatedConfig(PyConfig *config): Initialisiert die Konfiguration mit isolierter Konfiguration.
  • PyStatus PyConfig_SetString(PyConfig *config, wchar_t * const *config_str, const wchar_t *str): Kopiert den Wide-Character-String str in *config_str. Initialisiert Python bei Bedarf vor.
  • PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t * const *config_str, const char *str): Dekodiert str mit Py_DecodeLocale() und setzt das Ergebnis in *config_str. Initialisiert Python bei Bedarf vor.
  • PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t * const *argv): Setzt Befehlszeilenargumente aus Wide-Character-Strings. Initialisiert Python bei Bedarf vor.
  • PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char * const *argv): Setzt Befehlszeilenargumente: Dekodiert Bytes mit Py_DecodeLocale(). Initialisiert Python bei Bedarf vor.
  • PyStatus PyConfig_Read(PyConfig *config): Liest die gesamte Python-Konfiguration. Felder, die bereits initialisiert sind, bleiben unverändert. Initialisiert Python bei Bedarf vor.
  • void PyConfig_Clear(PyConfig *config): Gibt den Konfigurationsspeicher frei.

Die meisten PyConfig-Methoden initialisieren Python bei Bedarf vor. In diesem Fall basiert die Python-Vorinitialisierungskonfiguration auf der PyConfig. Wenn Konfigurationsfelder, die mit PyPreConfig gemeinsam sind, eingestellt werden, müssen sie vor dem Aufruf einer PyConfig-Methode gesetzt werden

  • dev_mode
  • isolated
  • parse_argv
  • use_environment

Darüber hinaus, wenn PyConfig_SetArgv() oder PyConfig_SetBytesArgv() verwendet wird, muss diese Methode zuerst und vor anderen Methoden aufgerufen werden, da die Vorinitialisierungskonfiguration von den Befehlszeilenargumenten abhängt (wenn parse_argv nicht-null ist).

Funktionen zur Initialisierung von Python

  • PyStatus Py_InitializeFromConfig(const PyConfig *config): Initialisiert Python aus der config-Konfiguration.

Der Aufrufer dieser Methoden und Funktionen ist für die Handhabung von Ausnahmen (Fehler oder Beendigung) unter Verwendung von PyStatus_Exception() und Py_ExitStatusException() verantwortlich.

PyConfig-Felder

  • argv (PyWideStringList): Befehlszeilenargumente, sys.argv. Siehe parse_argv, um argv so zu parsen, wie es das reguläre Python für Python-Befehlszeilenargumente tut. Wenn argv leer ist, wird ein leerer String hinzugefügt, um sicherzustellen, dass sys.argv immer existiert und nie leer ist.
  • base_exec_prefix (wchar_t*): sys.base_exec_prefix.
  • base_prefix (wchar_t*): sys.base_prefix.
  • buffered_stdio (int): Wenn gleich 0, aktiviere den unbuffered-Modus, wodurch die stdout- und stderr-Streams unbuffered werden.
  • bytes_warning (int): Wenn gleich 1, gib eine Warnung aus, wenn bytes oder bytearray mit str verglichen werden, oder wenn bytes mit int verglichen werden. Wenn gleich oder größer als 2, löse eine BytesWarning-Ausnahme aus.
  • check_hash_pycs_mode (wchar_t*): Wert der Befehlszeilenoption --check-hash-based-pycs (siehe PEP 552). Gültige Werte: always, never und default. Der Standardwert ist default.
  • configure_c_stdio (int): Wenn nicht-null, konfiguriere C-Standard-Streams (stdio, stdout, stdout). Setze beispielsweise ihren Modus auf O_BINARY unter Windows.
  • dev_mode (int): Entwicklungsmodus
  • dump_refs (int): Wenn nicht-null, gib alle Objekte aus, die beim Beenden noch leben. Erfordert einen speziellen Python-Build mit definiertem Makro Py_REF_DEBUG.
  • exec_prefix (wchar_t*): sys.exec_prefix.
  • executable (wchar_t*): sys.executable.
  • faulthandler (int): Wenn nicht-null, rufe faulthandler.enable() auf.
  • filesystem_encoding (wchar_t*): Dateisystemkodierung, sys.getfilesystemencoding().
  • filesystem_errors (wchar_t*): Dateisystemkodierungsfehler, sys.getfilesystemencodeerrors().
  • use_hash_seed (int), hash_seed (unsigned long): Zufälliger Hash-Funktions-Seed.
  • home (wchar_t*): Python-Home-Verzeichnis.
  • import_time (int): Wenn nicht-null, profiliere die Importzeit.
  • inspect (int): Geben Sie nach der Ausführung eines Skripts oder eines Befehls den interaktiven Modus ein.
  • install_signal_handlers (int): Signalhandler installieren?
  • interactive (int): Interaktiver Modus.
  • isolated (int): Wenn größer als 0, isolierten Modus aktivieren.
    • sys.path enthält weder das Verzeichnis des Skripts (berechnet aus argv[0] oder dem aktuellen Verzeichnis) noch das site-packages-Verzeichnis des Benutzers.
    • Die Python REPL importiert readline nicht und aktiviert auch keine standardmäßige Readline-Konfiguration bei interaktiven Eingabeaufforderungen.
    • Setzen Sie use_environment und user_site_directory auf 0.
  • legacy_windows_stdio (int, nur Windows): Wenn ungleich Null, verwenden Sie io.FileIO anstelle von WindowsConsoleIO für sys.stdin, sys.stdout und sys.stderr.
  • malloc_stats (int): Wenn ungleich Null, Statistiken über den pymalloc Speicherallokator beim Beenden ausgeben. Die Option wird ignoriert, wenn Python mit --without-pymalloc erstellt wurde.
  • pythonpath_env (wchar_t*): Modulsuchpfade als eine durch DELIM (normalerweise das Zeichen :) getrennte Zeichenkette. Standardmäßig aus dem Wert der Umgebungsvariable PYTHONPATH initialisiert.
  • module_search_paths_set (int), module_search_paths (PyWideStringList): sys.path. Wenn module_search_paths_set gleich 0 ist, wird module_search_paths durch die Funktion überschrieben, die die Pfadkonfiguration berechnet.
  • optimization_level (int): Kompilierungsoptimierungsstufe.
    • 0: Peephole-Optimierer (und __debug__ wird auf True gesetzt).
    • 1: Assertions entfernen, __debug__ auf False setzen.
    • 2: Docstrings entfernen.
  • parse_argv (int): Wenn ungleich Null, argv genauso parsen wie die regulären Python-Kommandozeilenargumente und Python-Argumente aus argv entfernen: siehe Kommandozeilenargumente.
  • parser_debug (int): Wenn ungleich Null, Parser-Debugging-Ausgabe einschalten (nur für Experten, abhängig von den Kompilierungsoptionen).
  • pathconfig_warnings (int): Wenn gleich 0, Warnungen bei der Berechnung der Pfadkonfiguration unterdrücken (nur Unix, Windows protokolliert keine Warnungen). Andernfalls werden Warnungen nach stderr geschrieben.
  • prefix (wchar_t*): sys.prefix.
  • program_name (wchar_t*): Programmname.
  • pycache_prefix (wchar_t*): .pyc Cache-Präfix.
  • quiet (int): Leiser Modus. Zeigt zum Beispiel die Copyright- und Versionshinweise auch im interaktiven Modus nicht an.
  • run_command (wchar_t*): python3 -c COMMAND Argument.
  • run_filename (wchar_t*): python3 FILENAME Argument.
  • run_module (wchar_t*): python3 -m MODULE Argument.
  • show_alloc_count (int): Allokationszähler beim Beenden anzeigen? Benötigt einen speziellen Python-Build mit definierter COUNT_ALLOCS Makro.
  • show_ref_count (int): Gesamten Referenzzähler beim Beenden anzeigen? Benötigt einen Debug-Build von Python (das Makro Py_REF_DEBUG sollte definiert sein).
  • site_import (int): Das Modul site beim Start importieren?
  • skip_source_first_line (int): Die erste Zeile der Quelle überspringen?
  • stdio_encoding (wchar_t*), stdio_errors (wchar_t*): Kodierung und Kodierungsfehler von sys.stdin, sys.stdout und sys.stderr.
  • tracemalloc (int): Wenn ungleich Null, tracemalloc.start(value) aufrufen.
  • user_site_directory (int): Wenn ungleich Null, das Benutzer-Site-Verzeichnis zu sys.path hinzufügen.
  • verbose (int): Wenn ungleich Null, den ausführlichen Modus aktivieren.
  • warnoptions (PyWideStringList): Optionen des Moduls warnings zum Erstellen von Warnfiltern.
  • write_bytecode (int): Wenn ungleich Null, .pyc Dateien schreiben.
  • xoptions (PyWideStringList): sys._xoptions.

Das Feld legacy_windows_stdio ist nur unter Windows verfügbar. Das Makro #ifdef MS_WINDOWS kann für Windows-spezifischen Code verwendet werden.

Wenn parse_argv ungleich Null ist, werden die argv-Argumente genauso geparst wie die regulären Python-Kommandozeilenargumente, und Python-Argumente werden aus argv entfernt: siehe Kommandozeilenargumente.

Die xoptions-Optionen werden geparst, um andere Optionen festzulegen: siehe -X Optionen.

PyConfig private Felder, nur für interne Verwendung.

  • _config_init (int): Funktion zur Initialisierung von PyConfig, verwendet für die Vorinitialisierung.
  • _install_importlib (int): Importlib installieren?
  • _init_main (int): Wenn gleich 0, die Python-Initialisierung vor der "main"-Phase stoppen (siehe PEP 432).

Ein vollständigeres Beispiel, das die Standardkonfiguration modifiziert, die Konfiguration liest und dann einige Parameter überschreibt.

PyStatus init_python(const char *program_name)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* Set the program name before reading the configuration
       (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;
}

Hinweis

PyImport_FrozenModules, PyImport_AppendInittab() und PyImport_ExtendInittab() Funktionen sind weiterhin relevant und funktionieren wie bisher. Sie sollten nach der Python-Vorinitialisierung und vor der Python-Initialisierung gesetzt oder aufgerufen werden.

Isolierte Konfiguration

PyPreConfig_InitIsolatedConfig() und PyConfig_InitIsolatedConfig() Funktionen erstellen eine Konfiguration, um Python vom System zu isolieren. Zum Beispiel, um Python in eine Anwendung einzubetten.

Diese Konfiguration ignoriert globale Konfigurationsvariablen, Umgebungsvariablen und Kommandozeilenargumente (argv wird nicht geparst). Die C-Standard-Streams (z.B. stdout) und das LC_CTYPE-Gebietsschema bleiben standardmäßig unverändert.

Konfigurationsdateien werden mit dieser Konfiguration weiterhin verwendet. Setzen Sie die Pfadkonfiguration ("Ausgabefelder"), um diese Konfigurationsdateien zu ignorieren und die Berechnung der Standard-Pfadkonfiguration zu vermeiden.

Python-Konfiguration

PyPreConfig_InitPythonConfig() und PyConfig_InitPythonConfig() Funktionen erstellen eine Konfiguration, um ein angepasstes Python zu erstellen, das sich wie das reguläre Python verhält.

Umgebungsvariablen und Kommandozeilenargumente werden zur Konfiguration von Python verwendet, während globale Konfigurationsvariablen ignoriert werden.

Diese Funktion aktiviert die C-Locale-Konvertierung (PEP 538) und den UTF-8-Modus (PEP 540) abhängig vom LC_CTYPE-Gebietsschema sowie den Umgebungsvariablen PYTHONUTF8 und PYTHONCOERCECLOCALE.

Beispiel für ein angepasstes Python, das immer im isolierten Modus läuft.

int main(int argc, char **argv)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    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);
}

Dieses Beispiel ist eine grundlegende Implementierung des "System Python Executable", wie in PEP 432 diskutiert.

Pfadkonfiguration

PyConfig enthält mehrere Felder für die Pfadkonfiguration.

  • Eingabefelder der Pfadkonfiguration.
    • home
    • pythonpath_env
    • pathconfig_warnings
  • Ausgabefelder der Pfadkonfiguration.
    • exec_prefix
    • executable
    • prefix
    • module_search_paths_set, module_search_paths

Wenn mindestens ein "Ausgabefeld" nicht gesetzt ist, berechnet Python die Pfadkonfiguration, um die nicht gesetzten Felder zu füllen. Wenn module_search_paths_set gleich 0 ist, wird module_search_paths überschrieben und module_search_paths_set auf 1 gesetzt.

Es ist möglich, die Berechnung der Standard-Pfadkonfiguration vollständig zu ignorieren, indem alle oben aufgeführten Ausgabefelder explizit gesetzt werden. Eine Zeichenkette gilt als gesetzt, auch wenn sie nicht leer ist. module_search_paths gilt als gesetzt, wenn module_search_paths_set auf 1 gesetzt ist. In diesem Fall werden auch die Eingabefelder der Pfadkonfiguration ignoriert.

Setzen Sie pathconfig_warnings auf 0, um Warnungen bei der Berechnung der Pfadkonfiguration zu unterdrücken (nur Unix, Windows protokolliert keine Warnungen).

Wenn die Felder base_prefix oder base_exec_prefix nicht gesetzt sind, erben sie ihren Wert von prefix bzw. exec_prefix.

Py_RunMain() und Py_Main() modifizieren sys.path.

  • Wenn run_filename gesetzt ist und ein Verzeichnis ist, das ein __main__.py Skript enthält, wird run_filename an den Anfang von sys.path gestellt.
  • Wenn isolated Null ist.
    • Wenn run_module gesetzt ist, wird das aktuelle Verzeichnis an den Anfang von sys.path gestellt. Es wird nichts unternommen, wenn das aktuelle Verzeichnis nicht gelesen werden kann.
    • Wenn run_filename gesetzt ist, wird das Verzeichnis der Datei an den Anfang von sys.path gestellt.
    • Andernfalls wird ein leerer String an den Anfang von sys.path gestellt.

Wenn site_import ungleich Null ist, kann sys.path durch das Modul site modifiziert werden. Wenn user_site_directory ungleich Null ist und das site-package-Verzeichnis des Benutzers existiert, hängt das Modul site das site-package-Verzeichnis des Benutzers an sys.path an.

Siehe auch Konfigurationsdateien, die von der Pfadkonfiguration verwendet werden.

Py_BytesMain()

Python 3.7 bietet eine High-Level-Funktion Py_Main(), die erfordert, Kommandozeilenargumente als wchar_t*-Strings zu übergeben. Es ist nicht trivial, die richtige Kodierung zum Dekodieren von Bytes zu verwenden. Python hat seine eigenen Probleme mit der C-Locale-Konvertierung und dem UTF-8-Modus.

Dieser PEP fügt eine neue Funktion Py_BytesMain() hinzu, die Kommandozeilenargumente als Bytes entgegennimmt.

int Py_BytesMain(int argc, char **argv)

Py_RunMain()

Die neue Funktion Py_RunMain() führt den Befehl (PyConfig.run_command), das Skript (PyConfig.run_filename) oder das Modul (PyConfig.run_module) aus, das auf der Kommandozeile oder in der Konfiguration angegeben ist, und finalisiert dann Python. Sie gibt einen Exit-Status zurück, der an die Funktion exit() übergeben werden kann.

int Py_RunMain(void);

Siehe Python-Konfiguration für ein Beispiel eines angepassten Pythons, das mit Py_RunMain() immer im isolierten Modus ausgeführt wird.

Multi-Phasen-Initialisierungs-Private-Vorläufige-API

Dieser Abschnitt ist eine private, vorläufige API, die eine mehrphasige Initialisierung einführt, das Kernmerkmal des PEP 432.

  • "Core"-Initialisierungsphase, "minimale Python"-Konfiguration.
    • Eingebaute Typen;
    • Eingebaute Ausnahmen;
    • Eingebaute und gefrorene Module;
    • Das Modul sys ist nur teilweise initialisiert (z.B. sys.path existiert noch nicht).
  • "Main"-Initialisierungsphase, Python ist vollständig initialisiert.
    • Installieren und Konfigurieren von importlib;
    • Anwenden der Pfadkonfiguration;
    • Installieren von Signalhandlern;
    • Fertigstellen der sys-Modul-Initialisierung (z.B. Erstellen von sys.stdout und sys.path);
    • Aktivieren optionaler Funktionen wie faulthandler und tracemalloc;
    • Importieren des Moduls site;
    • usw.

Private, vorläufige API.

  • PyConfig._init_main: Wenn auf 0 gesetzt, stoppt Py_InitializeFromConfig() in der "Core"-Initialisierungsphase.
  • PyStatus _Py_InitializeMain(void): Wechseln zur "Main"-Initialisierungsphase, Abschließen der Python-Initialisierung.

Kein Modul wird während der "Core"-Phase importiert und das Modul importlib ist nicht konfiguriert: Die Pfadkonfiguration wird nur während der "Main"-Phase angewendet. Dies kann die Anpassung von Python in Python ermöglichen, um die Pfadkonfiguration zu überschreiben oder abzustimmen, vielleicht einen benutzerdefinierten sys.meta_path-Importer oder einen Import-Hook zu installieren usw.

Es könnte möglich werden, die Pfadkonfiguration in Python zu berechnen, nach der Core-Phase und vor der Main-Phase, was eine der Motivationen von PEP 432 ist.

Die "Core"-Phase ist nicht richtig definiert: was in dieser Phase verfügbar sein sollte und was nicht, ist noch nicht spezifiziert. Die API ist als privat und vorläufig gekennzeichnet: die API kann jederzeit geändert oder sogar entfernt werden, bis eine ordnungsgemäße öffentliche API entworfen ist.

Beispiel für die Ausführung von Python-Code zwischen den Initialisierungsphasen "Core" und "Main".

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    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);
    }
}

Abwärtskompatibilität

Dieser PEP fügt lediglich eine neue API hinzu: die bestehende API bleibt unverändert und es gibt keine Auswirkungen auf die Abwärtskompatibilität.

Die Python 3.7 Py_Initialize() Funktion deaktiviert standardmäßig die C-Locale-Konvertierung (PEP 538) und den UTF-8-Modus (PEP 540), um Mojibake zu verhindern. Die neue API, die die Python-Konfiguration verwendet, wird benötigt, um diese automatisch zu aktivieren.

Anhänge

Vergleich von Python- und isolierter Konfiguration

Unterschiede zwischen PyPreConfig_InitPythonConfig() und PyPreConfig_InitIsolatedConfig().

PyPreConfig Python Isoliert
coerce_c_locale_warn -1 0
coerce_c_locale -1 0
configure_locale 1 0
dev_mode -1 0
isolated 0 1
legacy_windows_fs_encoding -1 0
use_environment 0 0
parse_argv 1 0
utf8_mode -1 0

Unterschiede zwischen PyConfig_InitPythonConfig() und PyConfig_InitIsolatedConfig().

PyConfig Python Isoliert
configure_c_stdio 1 0
install_signal_handlers 1 0
isolated 0 1
parse_argv 1 0
pathconfig_warnings 1 0
use_environment 1 0
user_site_directory 1 0

Priorität und Regeln

Priorität von Konfigurationsparametern, höchste bis niedrigste.

  • PyConfig
  • PyPreConfig
  • Konfigurationsdateien
  • Kommandozeilenoptionen
  • Umgebungsvariablen
  • Globale Konfigurationsvariablen

Priorität von Warnoptionen, höchste bis niedrigste.

  • PyConfig.warnoptions
  • PySys_AddWarnOption()
  • PyConfig.bytes_warning (fügt "error::BytesWarning" Filter hinzu, wenn größer als 1, fügt "default::BytesWarning Filter hinzu, wenn gleich 1).
  • Argument der Kommandozeile -W opt.
  • Umgebungsvariable PYTHONWARNINGS.
  • PyConfig.dev_mode (fügt "default" Filter hinzu).

Regeln für PyConfig-Parameter.

  • Wenn isolated ungleich Null ist, werden use_environment und user_site_directory auf 0 gesetzt.
  • Wenn dev_mode ungleich Null ist, wird allocator auf "debug" gesetzt, faulthandler auf 1 gesetzt und ein "default"-Filter zu warnoptions hinzugefügt. Die Umgebungsvariable PYTHONMALLOC hat jedoch Vorrang vor dev_mode bei der Festlegung des Speicherallokators.
  • Wenn base_prefix nicht gesetzt ist, erbt es den prefix-Wert.
  • Wenn base_exec_prefix nicht gesetzt ist, erbt es den exec_prefix-Wert.
  • Wenn die Konfigurationsdatei python._pth vorhanden ist, wird isolated auf 1 und site_import auf 0 gesetzt; site_import wird jedoch auf 1 gesetzt, wenn python._pth import site enthält.

Regeln für PyConfig und PyPreConfig Parameter.

  • Wenn PyPreConfig.legacy_windows_fs_encoding ungleich Null ist, wird PyPreConfig.utf8_mode auf 0 gesetzt, PyConfig.filesystem_encoding auf mbcs gesetzt und PyConfig.filesystem_errors auf replace gesetzt.

Konfigurationsdateien

Python-Konfigurationsdateien, die von der Pfadkonfiguration verwendet werden.

  • pyvenv.cfg
  • python._pth (nur Windows).
  • pybuilddir.txt (nur Unix).

Globale Konfigurationsvariablen

Globale Konfigurationsvariablen, die auf PyPreConfig-Felder abgebildet werden.

Variable. Feld.
Py_IgnoreEnvironmentFlag use_environment (NICHT).
Py_IsolatedFlag isolated
Py_LegacyWindowsFSEncodingFlag legacy_windows_fs_encoding
Py_UTF8Mode utf8_mode

(NICHT) bedeutet, dass der PyPreConfig-Wert das Gegenteil des Wertes der globalen Konfigurationsvariablen ist. Py_LegacyWindowsFSEncodingFlag ist nur unter Windows verfügbar.

Globale Konfigurationsvariablen, die auf PyConfig-Felder abgebildet werden.

Variable. Feld.
Py_BytesWarningFlag bytes_warning
Py_DebugFlag parser_debug
Py_DontWriteBytecodeFlag write_bytecode (NICHT).
Py_FileSystemDefaultEncodeErrors filesystem_errors
Py_FileSystemDefaultEncoding filesystem_encoding
Py_FrozenFlag pathconfig_warnings (NICHT).
Py_HasFileSystemDefaultEncoding filesystem_encoding
Py_HashRandomizationFlag use_hash_seed, hash_seed
Py_IgnoreEnvironmentFlag use_environment (NICHT).
Py_InspectFlag inspect
Py_InteractiveFlag interactive
Py_IsolatedFlag isolated
Py_LegacyWindowsStdioFlag legacy_windows_stdio
Py_NoSiteFlag site_import (NICHT).
Py_NoUserSiteDirectory user_site_directory (NICHT).
Py_OptimizeFlag optimization_level
Py_QuietFlag quiet
Py_UnbufferedStdioFlag buffered_stdio (NICHT).
Py_VerboseFlag verbose
_Py_HasFileSystemDefaultEncodeErrors filesystem_errors

(NICHT) bedeutet, dass der PyConfig-Wert das Gegenteil des Wertes der globalen Konfigurationsvariablen ist. Py_LegacyWindowsStdioFlag ist nur unter Windows verfügbar.

Befehlszeilenargumente

Verwendung.

python3 [options]
python3 [options] -c COMMAND
python3 [options] -m MODULE
python3 [options] SCRIPT

Kommandozeilenoptionen, die auf Pseudo-Aktionen für PyPreConfig-Felder abgebildet werden.

Option. PyConfig-Feld.
-E use_environment = 0
-I isolated = 1
-X dev dev_mode = 1
-X utf8 utf8_mode = 1
-X utf8=VALUE utf8_mode = VALUE

Kommandozeilenoptionen, die auf Pseudo-Aktionen für PyConfig-Felder abgebildet werden.

Option. PyConfig-Feld.
-b bytes_warning++
-B write_bytecode = 0
-c COMMAND run_command = COMMAND
--check-hash-based-pycs=MODE check_hash_pycs_mode = MODE
-d parser_debug++
-E use_environment = 0
-i inspect++ und interactive++.
-I isolated = 1
-m MODULE run_module = MODULE
-O optimization_level++
-q quiet++
-R use_hash_seed = 0
-s user_site_directory = 0
-S site_import
-t Ignoriert (aus Kompatibilitätsgründen beibehalten).
-u buffered_stdio = 0
-v verbose++
-W WARNING fügt WARNING zu warnoptions hinzu.
-x skip_source_first_line = 1
-X OPTION fügt OPTION zu xoptions hinzu.

-h, -? und -V Optionen werden ohne PyConfig behandelt.

-X-Optionen

-X Optionen, die auf Pseudo-Aktionen für PyConfig Felder abgebildet werden

Option. PyConfig-Feld.
-X dev dev_mode = 1
-X faulthandler faulthandler = 1
-X importtime import_time = 1
-X pycache_prefix=PREFIX pycache_prefix = PREFIX
-X showalloccount show_alloc_count = 1
-X showrefcount show_ref_count = 1
-X tracemalloc=N tracemalloc = N

Umgebungsvariablen

Umgebungsvariablen, die auf PyPreConfig Felder abgebildet werden

Variable. PyPreConfig Feld
PYTHONCOERCECLOCALE coerce_c_locale, coerce_c_locale_warn
PYTHONDEVMODE dev_mode
PYTHONLEGACYWINDOWSFSENCODING legacy_windows_fs_encoding
PYTHONMALLOC allocator
PYTHONUTF8 utf8_mode

Umgebungsvariablen, die auf PyConfig Felder abgebildet werden

Variable. PyConfig-Feld.
PYTHONDEBUG parser_debug
PYTHONDEVMODE dev_mode
PYTHONDONTWRITEBYTECODE write_bytecode
PYTHONDUMPREFS dump_refs
PYTHONEXECUTABLE program_name
PYTHONFAULTHANDLER faulthandler
PYTHONHASHSEED use_hash_seed, hash_seed
PYTHONHOME home
PYTHONINSPECT inspect
PYTHONIOENCODING stdio_encoding, stdio_errors
PYTHONLEGACYWINDOWSSTDIO legacy_windows_stdio
PYTHONMALLOCSTATS malloc_stats
PYTHONNOUSERSITE user_site_directory
PYTHONOPTIMIZE optimization_level
PYTHONPATH pythonpath_env
PYTHONPROFILEIMPORTTIME import_time
PYTHONPYCACHEPREFIX, pycache_prefix
PYTHONTRACEMALLOC tracemalloc
PYTHONUNBUFFERED buffered_stdio
PYTHONVERBOSE verbose
PYTHONWARNINGS warnoptions

PYTHONLEGACYWINDOWSFSENCODING und PYTHONLEGACYWINDOWSSTDIO sind spezifisch für Windows.

Standard-Python-Konfiguration

PyPreConfig_InitPythonConfig():

  • allocator = PYMEM_ALLOCATOR_NOT_SET
  • coerce_c_locale_warn = -1
  • coerce_c_locale = -1
  • configure_locale = 1
  • dev_mode = -1
  • isolated = 0
  • legacy_windows_fs_encoding = -1
  • use_environment = 1
  • utf8_mode = -1

PyConfig_InitPythonConfig():

  • argv = []
  • base_exec_prefix = NULL
  • base_prefix = NULL
  • buffered_stdio = 1
  • bytes_warning = 0
  • check_hash_pycs_mode = NULL
  • configure_c_stdio = 1
  • dev_mode = 0
  • dump_refs = 0
  • exec_prefix = NULL
  • executable = NULL
  • faulthandler = 0
  • filesystem_encoding = NULL
  • filesystem_errors = NULL
  • hash_seed = 0
  • home = NULL
  • import_time = 0
  • inspect = 0
  • install_signal_handlers = 1
  • interactive = 0
  • isolated = 0
  • malloc_stats = 0
  • module_search_path_env = NULL
  • module_search_paths = []
  • optimization_level = 0
  • parse_argv = 1
  • parser_debug = 0
  • pathconfig_warnings = 1
  • prefix = NULL
  • program_name = NULL
  • pycache_prefix = NULL
  • quiet = 0
  • run_command = NULL
  • run_filename = NULL
  • run_module = NULL
  • show_alloc_count = 0
  • show_ref_count = 0
  • site_import = 1
  • skip_source_first_line = 0
  • stdio_encoding = NULL
  • stdio_errors = NULL
  • tracemalloc = 0
  • use_environment = 1
  • use_hash_seed = 0
  • user_site_directory = 1
  • verbose = 0
  • warnoptions = []
  • write_bytecode = 1
  • xoptions = []
  • _init_main = 1
  • _install_importlib = 1

Standard-Isolierte-Konfiguration

PyPreConfig_InitIsolatedConfig():

  • allocator = PYMEM_ALLOCATOR_NOT_SET
  • coerce_c_locale_warn = 0
  • coerce_c_locale = 0
  • configure_locale = 0
  • dev_mode = 0
  • isolated = 1
  • legacy_windows_fs_encoding = 0
  • use_environment = 0
  • utf8_mode = 0

PyConfig_InitIsolatedConfig():

  • argv = []
  • base_exec_prefix = NULL
  • base_prefix = NULL
  • buffered_stdio = 1
  • bytes_warning = 0
  • check_hash_pycs_mode = NULL
  • configure_c_stdio = 0
  • dev_mode = 0
  • dump_refs = 0
  • exec_prefix = NULL
  • executable = NULL
  • faulthandler = 0
  • filesystem_encoding = NULL
  • filesystem_errors = NULL
  • hash_seed = 0
  • home = NULL
  • import_time = 0
  • inspect = 0
  • install_signal_handlers = 0
  • interactive = 0
  • isolated = 1
  • malloc_stats = 0
  • module_search_path_env = NULL
  • module_search_paths = []
  • optimization_level = 0
  • parse_argv = 0
  • parser_debug = 0
  • pathconfig_warnings = 0
  • prefix = NULL
  • program_name = NULL
  • pycache_prefix = NULL
  • quiet = 0
  • run_command = NULL
  • run_filename = NULL
  • run_module = NULL
  • show_alloc_count = 0
  • show_ref_count = 0
  • site_import = 1
  • skip_source_first_line = 0
  • stdio_encoding = NULL
  • stdio_errors = NULL
  • tracemalloc = 0
  • use_environment = 0
  • use_hash_seed = 0
  • user_site_directory = 0
  • verbose = 0
  • warnoptions = []
  • write_bytecode = 1
  • xoptions = []
  • _init_main = 1
  • _install_importlib = 1

Python 3.7 API

Python 3.7 hat 4 Funktionen in seiner C-API zur Initialisierung und Finalisierung von Python

  • Py_Initialize(), Py_InitializeEx(): Python initialisieren
  • Py_Finalize(), Py_FinalizeEx(): Python finalisieren

Python 3.7 kann konfiguriert werden über Globale Konfigurationsvariablen, Umgebungsvariablen und die folgenden Funktionen

  • PyImport_AppendInittab()
  • PyImport_ExtendInittab()
  • PyMem_SetAllocator()
  • PyMem_SetupDebugHooks()
  • PyObject_SetArenaAllocator()
  • Py_SetPath()
  • Py_SetProgramName()
  • Py_SetPythonHome()
  • Py_SetStandardStreamEncoding()
  • PySys_AddWarnOption()
  • PySys_AddXOption()
  • PySys_ResetWarnOptions()

Es gibt auch eine High-Level-Funktion Py_Main() und die Variable PyImport_FrozenModules, die überschrieben werden können.

Siehe Dokumentation zu Initialisierung, Finalisierung und Threads.

Python-Probleme

Probleme, die durch dieses PEP behoben werden, direkt oder indirekt

  • bpo-1195571: "Einfaches Callback-System für Py_FatalError"
  • bpo-11320: "Verwendung der API-Methode Py_SetPath verursacht Fehler in Py_Initialize() (nur Posix)"
  • bpo-13533: "Möchte, dass Py_Initialize mit der Host-Anwendung gut zurechtkommt"
  • bpo-14956: "Custom PYTHONPATH kann Python einbettende Apps kaputt machen"
  • bpo-19983: "Wenn während des Starts unterbrochen, sollte Python abort() nicht aufrufen, sondern exit() aufrufen"
  • bpo-22213: "Mache pyvenv-Style virtuelle Umgebungen einfacher zu konfigurieren, wenn Python eingebettet wird".
  • bpo-29778: "_Py_CheckPython3 verwendet uninitialisierten dllpath, wenn der Einbetter den Modulpfad mit Py_SetPath setzt"
  • bpo-30560: "Füge Py_SetFatalErrorAbortFunc hinzu: Ermöglicht einbettenden Programmen, fatale Fehler zu behandeln".
  • bpo-31745: "Überschreiben von "Py_GetPath" funktioniert nicht"
  • bpo-32573: "Alle sys-Attribute (.argv, …) sollten in eingebetteten Umgebungen existieren".
  • bpo-33135: "Definiere Feldpräfixe für die verschiedenen Konfigurationsstrukturen". Das PEP definiert nun klar, wie Warnoptionen behandelt werden.
  • bpo-34725: "Py_GetProgramFullPath() seltsames Verhalten unter Windows"
  • bpo-36204: "Aufruf von Py_Main() nach Py_Initialize() deprecaten? Py_InitializeFromArgv() hinzufügen?"

Probleme bei der PEP-Implementierung

  • bpo-16961: "Keine Regressionstests für -E und einzelne Umgebungsvariablen"
  • bpo-20361: "-W Kommandozeilenoptionen und die Umgebungsvariable PYTHONWARNINGS sollten -b / -bb Kommandozeilenoptionen nicht überschreiben"
  • bpo-26122: "Isolierter Modus ignoriert PYTHONHASHSEED nicht"
  • bpo-29818: "Py_SetStandardStreamEncoding führt zu einem Speicherfehler im Debug-Modus"
  • bpo-31845: "PYTHONDONTWRITEBYTECODE und PYTHONOPTIMIZE haben keine Wirkung"
  • bpo-32030: "PEP 432: Py_Main() neu schreiben"
  • bpo-32124: "Dokumentieren Sie Funktionen, die vor Py_Initialize() sicher aufgerufen werden können"
  • bpo-33042: "Neue 3.7 Startsequenz stürzt PyInstaller ab"
  • bpo-33932: "Aufruf von Py_Initialize() zweimal löst nun einen fatalen Fehler aus (Python 3.7)"
  • bpo-34008: "Unterstützen wir den Aufruf von Py_Main() nach Py_Initialize()?"
  • bpo-34170: "Py_Initialize(): Die Berechnung der Pfadkonfiguration darf keine Nebeneffekte haben (PEP 432)"
  • bpo-34589: "Py_Initialize() und Py_Main() sollten die C-Locale-Umwandlung nicht aktivieren"
  • bpo-34639: "PYTHONCOERCECLOCALE wird ignoriert, wenn die Option -E oder -I verwendet wird"
  • bpo-36142: "Füge einen neuen _PyPreConfig-Schritt zur Python-Initialisierung hinzu, um Speicherallokator und Kodierungen einzurichten"
  • bpo-36202: "Aufruf von Py_DecodeLocale() vor _PyPreConfig_Write() kann Mojibake erzeugen"
  • bpo-36301: "Füge die Funktion _Py_PreInitialize() hinzu"
  • bpo-36443: "coerce_c_locale und utf8_mode in _PyPreConfig standardmäßig deaktivieren?"
  • bpo-36444: "Python-Initialisierung: _PyMainInterpreterConfig entfernen"
  • bpo-36471: "PEP 432, PEP 587: _Py_RunMain() hinzufügen"
  • bpo-36763: "PEP 587: Initialisierungs-API überarbeiten, um die zweite Version des PEP vorzubereiten"
  • bpo-36775: "Dateisystem-Codec-Implementierung überarbeiten"
  • bpo-36900: "Verwende _PyCoreConfig anstelle von globalen Konfigurationsvariablen"

Probleme, die mit diesem PEP zusammenhängen

  • bpo-12598: "Systemvariableninitialisierung von import.c nach sysmodule.c verschieben"
  • bpo-15577: "Echte argc und argv im eingebetteten Interpreter"
  • bpo-16202: "Sicherheitsprobleme mit sys.path[0]"
  • bpo-18309: "Python etwas portabler machen"
  • bpo-22257: "PEP 432: Redesign der Interpreter-Startsequenz"
  • bpo-25631: "Segmentierungsfehler mit ungültigen Unicode-Kommandozeilenargumenten in eingebettetem Python"
  • bpo-26007: "Unterstütze das Einbetten der Standardbibliothek in eine ausführbare Datei"
  • bpo-31210: "Kann keine Module importieren, wenn sys.prefix DELIM enthält".
  • bpo-31349: "Eingebettete Initialisierung ignoriert Py_SetProgramName()"
  • bpo-33919: "Struktur _PyCoreConfig für Python bereitstellen"
  • bpo-35173: "Vorhandene Funktionalität wiederverwenden, um Python 2.7.x (sowohl eingebettet als auch eigenständig) zu ermöglichen, den Modulpfad gemäß der Shared Library zu lokalisieren"

Diskussionen

Versionshistorie

  • Version 5
    • Umbenennen von PyInitError in PyStatus
    • Umbenennen von PyInitError_Failed() in PyStatus_Exception()
    • Umbenennen von Py_ExitInitError() in Py_ExitStatusException()
    • Hinzufügen des privaten Feldes PyPreConfig._config_init.
    • Korrektur der Standardwerte der Python-Konfiguration: isolated=0 und use_environment=1, anstelle von -1.
    • Hinzufügen der Abschnitte "Multi-Phase Initialization Private Provisional API" und "Discussions"
  • Version 4
    • Einführung von "Python Configuration" und "Isolated Configuration", die besser definiert sind. Ersetzung aller Makros durch Funktionen.
    • Ersetzen der Makros PyPreConfig_INIT und PyConfig_INIT durch Funktionen
      • PyPreConfig_InitIsolatedConfig(), PyConfig_InitIsolatedConfig()
      • PyPreConfig_InitPythonConfig(), PyConfig_InitPythonConfig()
    • PyPreConfig verwendet kein dynamisches Gedächtnis mehr, der Feldtyp allocator wird zu einem Integer, Hinzufügen der Felder configure_locale und parse_argv.
    • PyConfig: Umbenennen von module_search_path_env in pythonpath_env, Umbenennen von use_module_search_paths in module_search_paths_set, Entfernen von program und dll_path.
    • Ersetzen der Makros Py_INIT_xxx() durch die Funktionen PyInitError_xxx().
    • Entfernen des Abschnitts "Constant PyConfig". Entfernen der Funktionen Py_InitializeFromArgs() und Py_InitializeFromBytesArgs().
  • Version 3
    • PyConfig: Hinzufügen von configure_c_stdio und parse_argv; Umbenennen von _frozen in pathconfig_warnings.
    • Umbenennen von Funktionen, die Byte-Strings und Wide-Character-Strings verwenden. Zum Beispiel wird Py_PreInitializeFromWideArgs() zu Py_PreInitializeFromArgs() und PyConfig_SetArgv() wird zu PyConfig_SetBytesArgv().
    • Hinzufügen der Funktion PyWideStringList_Insert().
    • Neue Abschnitte "Path Configuration", "Isolate Python", "Python Issues" und "Version History".
    • PyConfig_SetString() und PyConfig_SetBytesString() benötigen nun die Konfiguration als erstes Argument.
    • Umbenennen von Py_UnixMain() in Py_BytesMain()
  • Version 2: Hinzufügen von PyConfig-Methoden (z.B. PyConfig_Read()), Hinzufügen von PyWideStringList_Append(), Umbenennen von PyWideCharList in PyWideStringList.
  • Version 1: Erste Version.

Akzeptanz

PEP 587 wurde von Thomas Wouters am 26. Mai 2019 angenommen.


Quelle: https://github.com/python/peps/blob/main/peps/pep-0587.rst

Zuletzt geändert: 2025-02-01 08:55:40 GMT