cpython/Python/initconfig.c

#include "Python.h"
#include "pycore_fileutils.h"     // _Py_HasFileSystemDefaultEncodeErrors
#include "pycore_getopt.h"        // _PyOS_GetOpt()
#include "pycore_initconfig.h"    // _PyStatus_OK()
#include "pycore_interp.h"        // _PyInterpreterState.runtime
#include "pycore_long.h"          // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
#include "pycore_pathconfig.h"    // _Py_path_config
#include "pycore_pyerrors.h"      // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h"   // _Py_PreInitializeFromConfig()
#include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h"       // _PyThreadState_GET()
#include "pycore_pystats.h"       // _Py_StatsOn()
#include "pycore_sysmodule.h"     // _PySys_SetIntMaxStrDigits()

#include "osdefs.h"               // DELIM

#include <locale.h>               // setlocale()
#include <stdlib.h>               // getenv()
#if defined(MS_WINDOWS) || defined(__CYGWIN__)
#  ifdef HAVE_IO_H
#    include <io.h>
#  endif
#  ifdef HAVE_FCNTL_H
#    include <fcntl.h>            // O_BINARY
#  endif
#endif

#include "config_common.h"

/* --- PyConfig setters ------------------------------------------- */

config_sys_flag_setter;

static PyObject*
config_sys_flag_long(int value)
{}

static PyObject*
config_sys_flag_not(int value)
{}

/* --- PyConfig spec ---------------------------------------------- */

PyConfigMemberType;

PyConfigMemberVisibility;

PyConfigSysSpec;

PyConfigSpec;

#define SPEC

#define SYS_ATTR
#define SYS_FLAG_SETTER
#define SYS_FLAG
#define NO_SYS

// Update _test_embed_set_config when adding new members
static const PyConfigSpec PYCONFIG_SPEC[] =;

#undef SPEC
#define SPEC

static const PyConfigSpec PYPRECONFIG_SPEC[] =;

#undef SPEC
#undef SYS_ATTR
#undef SYS_FLAG_SETTER
#undef SYS_FLAG
#undef NO_SYS


// Forward declarations
static PyObject*
config_get(const PyConfig *config, const PyConfigSpec *spec,
           int use_sys);


/* --- Command line options --------------------------------------- */

/* Short usage message (with %s for argv0) */
static const char usage_line[] =;

/* Long help message */
/* Lines sorted by option name; keep in sync with usage_envvars* below */
static const char usage_help[] =;

static const char usage_xoptions[] =;

/* Envvars that don't have equivalent command-line options are listed first */
static const char usage_envvars[] =
;

#if defined(MS_WINDOWS)
#define PYTHONHOMEHELP
#else
#define PYTHONHOMEHELP
#endif


/* --- Global configuration variables ----------------------------- */

/* UTF-8 mode (PEP 540): if equals to 1, use the UTF-8 encoding, and change
   stdin and stdout error handler to "surrogateescape". */
int Py_UTF8Mode =;
int Py_DebugFlag =; /* Needed by parser.c */
int Py_VerboseFlag =; /* Needed by import.c */
int Py_QuietFlag =; /* Needed by sysmodule.c */
int Py_InteractiveFlag =; /* Previously, was used by Py_FdIsInteractive() */
int Py_InspectFlag =; /* Needed to determine whether to exit at SystemExit */
int Py_OptimizeFlag =; /* Needed by compile.c */
int Py_NoSiteFlag =; /* Suppress 'import site' */
int Py_BytesWarningFlag =; /* Warn on str(bytes) and str(buffer) */
int Py_FrozenFlag =; /* Needed by getpath.c */
int Py_IgnoreEnvironmentFlag =; /* e.g. PYTHONPATH, PYTHONHOME */
int Py_DontWriteBytecodeFlag =; /* Suppress writing bytecode files (*.pyc) */
int Py_NoUserSiteDirectory =; /* for -s and site.py */
int Py_UnbufferedStdioFlag =; /* Unbuffered binary std{in,out,err} */
int Py_HashRandomizationFlag =; /* for -R and PYTHONHASHSEED */
int Py_IsolatedFlag =; /* for -I, isolate from user's env */
#ifdef MS_WINDOWS
int Py_LegacyWindowsFSEncodingFlag = 0; /* Uses mbcs instead of utf-8 */
int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */
#endif


static PyObject *
_Py_GetGlobalVariablesAsDict(void)
{}

char*
Py_GETENV(const char *name)
{}

/* --- PyStatus ----------------------------------------------- */

PyStatus PyStatus_Ok(void)
{}

PyStatus PyStatus_Error(const char *err_msg)
{}

PyStatus PyStatus_NoMemory(void)
{}

PyStatus PyStatus_Exit(int exitcode)
{}


int PyStatus_IsError(PyStatus status)
{}

int PyStatus_IsExit(PyStatus status)
{}

int PyStatus_Exception(PyStatus status)
{}

void
_PyErr_SetFromPyStatus(PyStatus status)
{}


/* --- PyWideStringList ------------------------------------------------ */

#ifndef NDEBUG
int
_PyWideStringList_CheckConsistency(const PyWideStringList *list)
{
    assert(list->length >= 0);
    if (list->length != 0) {
        assert(list->items != NULL);
    }
    for (Py_ssize_t i = 0; i < list->length; i++) {
        assert(list->items[i] != NULL);
    }
    return 1;
}
#endif   /* Py_DEBUG */


void
_PyWideStringList_Clear(PyWideStringList *list)
{}


int
_PyWideStringList_Copy(PyWideStringList *list, const PyWideStringList *list2)
{}


PyStatus
PyWideStringList_Insert(PyWideStringList *list,
                        Py_ssize_t index, const wchar_t *item)
{}


PyStatus
PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)
{}


PyStatus
_PyWideStringList_Extend(PyWideStringList *list, const PyWideStringList *list2)
{}


static int
_PyWideStringList_Find(PyWideStringList *list, const wchar_t *item)
{}


PyObject*
_PyWideStringList_AsList(const PyWideStringList *list)
{}


static PyObject*
_PyWideStringList_AsTuple(const PyWideStringList *list)
{}


/* --- Py_GetArgcArgv() ------------------------------------------- */

void
_Py_ClearArgcArgv(void)
{}


static int
_Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv)
{}


// _PyConfig_Write() calls _Py_SetArgcArgv() with PyConfig.orig_argv.
void
Py_GetArgcArgv(int *argc, wchar_t ***argv)
{}


/* --- PyConfig ---------------------------------------------- */

#define MAX_HASH_SEED


#ifndef NDEBUG
static int
config_check_consistency(const PyConfig *config)
{
    /* Check config consistency */
    assert(config->isolated >= 0);
    assert(config->use_environment >= 0);
    assert(config->dev_mode >= 0);
    assert(config->install_signal_handlers >= 0);
    assert(config->use_hash_seed >= 0);
    assert(config->hash_seed <= MAX_HASH_SEED);
    assert(config->faulthandler >= 0);
    assert(config->tracemalloc >= 0);
    assert(config->import_time >= 0);
    assert(config->code_debug_ranges >= 0);
    assert(config->show_ref_count >= 0);
    assert(config->dump_refs >= 0);
    assert(config->malloc_stats >= 0);
    assert(config->site_import >= 0);
    assert(config->bytes_warning >= 0);
    assert(config->warn_default_encoding >= 0);
    assert(config->inspect >= 0);
    assert(config->interactive >= 0);
    assert(config->optimization_level >= 0);
    assert(config->parser_debug >= 0);
    assert(config->write_bytecode >= 0);
    assert(config->verbose >= 0);
    assert(config->quiet >= 0);
    assert(config->user_site_directory >= 0);
    assert(config->parse_argv >= 0);
    assert(config->configure_c_stdio >= 0);
    assert(config->buffered_stdio >= 0);
    assert(_PyWideStringList_CheckConsistency(&config->orig_argv));
    assert(_PyWideStringList_CheckConsistency(&config->argv));
    /* sys.argv must be non-empty: empty argv is replaced with [''] */
    assert(config->argv.length >= 1);
    assert(_PyWideStringList_CheckConsistency(&config->xoptions));
    assert(_PyWideStringList_CheckConsistency(&config->warnoptions));
    assert(_PyWideStringList_CheckConsistency(&config->module_search_paths));
    assert(config->module_search_paths_set >= 0);
    assert(config->filesystem_encoding != NULL);
    assert(config->filesystem_errors != NULL);
    assert(config->stdio_encoding != NULL);
    assert(config->stdio_errors != NULL);
#ifdef MS_WINDOWS
    assert(config->legacy_windows_stdio >= 0);
#endif
    /* -c and -m options are exclusive */
    assert(!(config->run_command != NULL && config->run_module != NULL));
    assert(config->check_hash_pycs_mode != NULL);
    assert(config->_install_importlib >= 0);
    assert(config->pathconfig_warnings >= 0);
    assert(config->_is_python_build >= 0);
    assert(config->safe_path >= 0);
    assert(config->int_max_str_digits >= 0);
    // cpu_count can be -1 if the user doesn't override it.
    assert(config->cpu_count != 0);
    // config->use_frozen_modules is initialized later
    // by _PyConfig_InitImportConfig().
#ifdef Py_STATS
    assert(config->_pystats >= 0);
#endif
    return 1;
}
#endif


/* Free memory allocated in config, but don't clear all attributes */
void
PyConfig_Clear(PyConfig *config)
{}


void
_PyConfig_InitCompatConfig(PyConfig *config)
{}


static void
config_init_defaults(PyConfig *config)
{}


void
PyConfig_InitPythonConfig(PyConfig *config)
{}


void
PyConfig_InitIsolatedConfig(PyConfig *config)
{}


/* Copy str into *config_str (duplicate the string) */
PyStatus
PyConfig_SetString(PyConfig *config, wchar_t **config_str, const wchar_t *str)
{}


static PyStatus
config_set_bytes_string(PyConfig *config, wchar_t **config_str,
                        const char *str, const char *decode_err_msg)
{}


#define CONFIG_SET_BYTES_STR(config, config_str, str, NAME)


/* Decode str using Py_DecodeLocale() and set the result into *config_str.
   Pre-initialize Python if needed to ensure that encodings are properly
   configured. */
PyStatus
PyConfig_SetBytesString(PyConfig *config, wchar_t **config_str,
                        const char *str)
{}


static inline void*
config_get_spec_member(const PyConfig *config, const PyConfigSpec *spec)
{}


static inline void*
preconfig_get_spec_member(const PyPreConfig *preconfig, const PyConfigSpec *spec)
{}


PyStatus
_PyConfig_Copy(PyConfig *config, const PyConfig *config2)
{}


PyObject *
_PyConfig_AsDict(const PyConfig *config)
{}


static void
config_dict_invalid_value(const char *name)
{}


static int
config_dict_get_int(PyObject *dict, const char *name, int *result)
{}


static int
config_dict_get_ulong(PyObject *dict, const char *name, unsigned long *result)
{}


static int
config_dict_get_wstr(PyObject *dict, const char *name, PyConfig *config,
                     wchar_t **result)
{}


static int
config_dict_get_wstrlist(PyObject *dict, const char *name, PyConfig *config,
                         PyWideStringList *result)
{}


static int
config_dict_get_xoptions(PyObject *dict, const char *name, PyConfig *config,
                         PyWideStringList *result)
{}


int
_PyConfig_FromDict(PyConfig *config, PyObject *dict)
{}


static const char*
config_get_env(const PyConfig *config, const char *name)
{}


/* Get a copy of the environment variable as wchar_t*.
   Return 0 on success, but *dest can be NULL.
   Return -1 on memory allocation failure. Return -2 on decoding error. */
static PyStatus
config_get_env_dup(PyConfig *config,
                   wchar_t **dest,
                   wchar_t *wname, char *name,
                   const char *decode_err_msg)
{}


#define CONFIG_GET_ENV_DUP(CONFIG, DEST, WNAME, NAME)


static void
config_get_global_vars(PyConfig *config)
{}


/* Set Py_xxx global configuration variables from 'config' configuration. */
static void
config_set_global_vars(const PyConfig *config)
{}


static const wchar_t*
config_get_xoption(const PyConfig *config, wchar_t *name)
{}

static const wchar_t*
config_get_xoption_value(const PyConfig *config, wchar_t *name)
{}


static PyStatus
config_init_hash_seed(PyConfig *config)
{}


static int
config_wstr_to_int(const wchar_t *wstr, int *result)
{}

static PyStatus
config_read_gil(PyConfig *config, size_t len, wchar_t first_char)
{}

static PyStatus
config_read_env_vars(PyConfig *config)
{}

static PyStatus
config_init_cpu_count(PyConfig *config)
{}

static PyStatus
config_init_tlbc(PyConfig *config)
{}

static PyStatus
config_init_perf_profiling(PyConfig *config)
{}

static PyStatus
config_init_tracemalloc(PyConfig *config)
{}

static PyStatus
config_init_int_max_str_digits(PyConfig *config)
{}

static PyStatus
config_init_pycache_prefix(PyConfig *config)
{}


#ifdef Py_DEBUG
static PyStatus
config_init_run_presite(PyConfig *config)
{
    assert(config->run_presite == NULL);

    const wchar_t *xoption = config_get_xoption(config, L"presite");
    if (xoption) {
        const wchar_t *sep = wcschr(xoption, L'=');
        if (sep && wcslen(sep) > 1) {
            config->run_presite = _PyMem_RawWcsdup(sep + 1);
            if (config->run_presite == NULL) {
                return _PyStatus_NO_MEMORY();
            }
        }
        else {
            // PYTHON_PRESITE env var ignored
            // if "-X presite=" option is used
            config->run_presite = NULL;
        }
        return _PyStatus_OK();
    }

    return CONFIG_GET_ENV_DUP(config, &config->run_presite,
                              L"PYTHON_PRESITE",
                              "PYTHON_PRESITE");
}
#endif


static PyStatus
config_read_complex_options(PyConfig *config)
{}


static const wchar_t *
config_get_stdio_errors(const PyPreConfig *preconfig)
{}


// See also config_get_fs_encoding()
static PyStatus
config_get_locale_encoding(PyConfig *config, const PyPreConfig *preconfig,
                           wchar_t **locale_encoding)
{}


static PyStatus
config_init_stdio_encoding(PyConfig *config,
                           const PyPreConfig *preconfig)
{}


// See also config_get_locale_encoding()
static PyStatus
config_get_fs_encoding(PyConfig *config, const PyPreConfig *preconfig,
                       wchar_t **fs_encoding)
{}


static PyStatus
config_init_fs_encoding(PyConfig *config, const PyPreConfig *preconfig)
{}


static PyStatus
config_init_import(PyConfig *config, int compute_path_config)
{}

PyStatus
_PyConfig_InitImportConfig(PyConfig *config)
{}


static PyStatus
config_read(PyConfig *config, int compute_path_config)
{}


static void
config_init_stdio(const PyConfig *config)
{}


/* Write the configuration:

   - set Py_xxx global configuration variables
   - initialize C standard streams (stdin, stdout, stderr) */
PyStatus
_PyConfig_Write(const PyConfig *config, _PyRuntimeState *runtime)
{}


/* --- PyConfig command line parser -------------------------- */

static void
config_usage(int error, const wchar_t* program)
{}

static void
config_envvars_usage(void)
{}

static void
config_xoptions_usage(void)
{}

static void
config_complete_usage(const wchar_t* program)
{}


/* Parse the command line arguments */
static PyStatus
config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
                     Py_ssize_t *opt_index)
{}


#ifdef MS_WINDOWS
#define WCSTOK
#else
#define WCSTOK
#endif

/* Get warning options from PYTHONWARNINGS environment variable. */
static PyStatus
config_init_env_warnoptions(PyConfig *config, PyWideStringList *warnoptions)
{}


static PyStatus
warnoptions_append(PyConfig *config, PyWideStringList *options,
                   const wchar_t *option)
{}


static PyStatus
warnoptions_extend(PyConfig *config, PyWideStringList *options,
                   const PyWideStringList *options2)
{}


static PyStatus
config_init_warnoptions(PyConfig *config,
                        const PyWideStringList *cmdline_warnoptions,
                        const PyWideStringList *env_warnoptions,
                        const PyWideStringList *sys_warnoptions)
{}


static PyStatus
config_update_argv(PyConfig *config, Py_ssize_t opt_index)
{}


static PyStatus
core_read_precmdline(PyConfig *config, _PyPreCmdline *precmdline)
{}


/* Get run_filename absolute path */
static PyStatus
config_run_filename_abspath(PyConfig *config)
{}


static PyStatus
config_read_cmdline(PyConfig *config)
{}


PyStatus
_PyConfig_SetPyArgv(PyConfig *config, const _PyArgv *args)
{}


/* Set config.argv: decode argv using Py_DecodeLocale(). Pre-initialize Python
   if needed to ensure that encodings are properly configured. */
PyStatus
PyConfig_SetBytesArgv(PyConfig *config, Py_ssize_t argc, char * const *argv)
{}


PyStatus
PyConfig_SetArgv(PyConfig *config, Py_ssize_t argc, wchar_t * const *argv)
{}


PyStatus
PyConfig_SetWideStringList(PyConfig *config, PyWideStringList *list,
                           Py_ssize_t length, wchar_t **items)
{}


/* Read the configuration into PyConfig from:

   * Command line arguments
   * Environment variables
   * Py_xxx global configuration variables

   The only side effects are to modify config and to call _Py_SetArgcArgv(). */
PyStatus
_PyConfig_Read(PyConfig *config, int compute_path_config)
{}


PyStatus
PyConfig_Read(PyConfig *config)
{}


PyObject*
_Py_GetConfigsAsDict(void)
{}


static void
init_dump_ascii_wstr(const wchar_t *str)
{}


/* Dump the Python path configuration into sys.stderr */
void
_Py_DumpPathConfig(PyThreadState *tstate)
{}


// --- PyInitConfig API ---------------------------------------------------

struct PyInitConfig {};

static PyInitConfig*
initconfig_alloc(void)
{}


PyInitConfig*
PyInitConfig_Create(void)
{}


void
PyInitConfig_Free(PyInitConfig *config)
{}


int
PyInitConfig_GetError(PyInitConfig* config, const char **perr_msg)
{}


int
PyInitConfig_GetExitCode(PyInitConfig* config, int *exitcode)
{}


static void
initconfig_set_error(PyInitConfig *config, const char *err_msg)
{}


static const PyConfigSpec*
initconfig_find_spec(const PyConfigSpec *spec, const char *name)
{}


int
PyInitConfig_HasOption(PyInitConfig *config, const char *name)
{}


static const PyConfigSpec*
initconfig_prepare(PyInitConfig *config, const char *name, void **raw_member)
{}


int
PyInitConfig_GetInt(PyInitConfig *config, const char *name, int64_t *value)
{}


static char*
wstr_to_utf8(PyInitConfig *config, wchar_t *wstr)
{}


int
PyInitConfig_GetStr(PyInitConfig *config, const char *name, char **value)
{}


int
PyInitConfig_GetStrList(PyInitConfig *config, const char *name, size_t *length, char ***items)
{}


void
PyInitConfig_FreeStrList(size_t length, char **items)
{}


int
PyInitConfig_SetInt(PyInitConfig *config, const char *name, int64_t value)
{}


static wchar_t*
utf8_to_wstr(PyInitConfig *config, const char *str)
{}


int
PyInitConfig_SetStr(PyInitConfig *config, const char *name, const char* value)
{}


static int
_PyWideStringList_FromUTF8(PyInitConfig *config, PyWideStringList *list,
                           Py_ssize_t length, char * const *items)
{}


int
PyInitConfig_SetStrList(PyInitConfig *config, const char *name,
                        size_t length, char * const *items)
{}


int
PyInitConfig_AddModule(PyInitConfig *config, const char *name,
                       PyObject* (*initfunc)(void))
{}


int
Py_InitializeFromInitConfig(PyInitConfig *config)
{}


// --- PyConfig_Get() -------------------------------------------------------

static const PyConfigSpec*
config_generic_find_spec(const PyConfigSpec *spec, const char *name)
{}


static const PyConfigSpec*
config_find_spec(const char *name)
{}


static const PyConfigSpec*
preconfig_find_spec(const char *name)
{}


static int
config_add_xoption(PyObject *dict, const wchar_t *str)
{}


PyObject*
_PyConfig_CreateXOptionsDict(const PyConfig *config)
{}


static PyObject*
config_get_sys(const char *name)
{}


static int
config_get_sys_write_bytecode(const PyConfig *config, int *value)
{}


static PyObject*
config_get(const PyConfig *config, const PyConfigSpec *spec,
           int use_sys)
{}


static PyObject*
preconfig_get(const PyPreConfig *preconfig, const PyConfigSpec *spec)
{}


static void
config_unknown_name_error(const char *name)
{}


PyObject*
PyConfig_Get(const char *name)
{}


int
PyConfig_GetInt(const char *name, int *value)
{}


static int
config_names_add(PyObject *names, const PyConfigSpec *spec)
{}


PyObject*
PyConfig_Names(void)
{}


// --- PyConfig_Set() -------------------------------------------------------

static int
config_set_sys_flag(const PyConfigSpec *spec, int int_value)
{}


int
PyConfig_Set(const char *name, PyObject *value)
{}