bpo-32030: Add _PyCoreConfig_Copy() (#4874) · python/cpython@da27341 (original) (raw)

`@@ -1914,6 +1914,154 @@ pymain_parse_cmdline_envvars(_PyMain *pymain)

`

1914

1914

`}

`

1915

1915

``

1916

1916

``

``

1917

`+

/* Read configuration settings from standard locations

`

``

1918

`+

`

``

1919

`+

`

``

1920

`+

`

``

1921

`+

`

``

1922

`+

`

``

1923

`+

`

``

1924

`+

`

``

1925

`+

`

``

1926

`+

`

``

1927

`+

*/

`

``

1928

+

``

1929

`+

_PyInitError

`

``

1930

`+

_PyCoreConfig_Read(_PyCoreConfig *config)

`

``

1931

`+

{

`

``

1932

`+

if (config->program_name == NULL) {

`

``

1933

`+

#ifdef MS_WINDOWS

`

``

1934

`+

const wchar_t *program_name = L"python";

`

``

1935

`+

#else

`

``

1936

`+

const wchar_t *program_name = L"python3";

`

``

1937

`+

#endif

`

``

1938

`+

config->program_name = _PyMem_RawWcsdup(program_name);

`

``

1939

`+

if (config->program_name == NULL) {

`

``

1940

`+

return _Py_INIT_NO_MEMORY();

`

``

1941

`+

}

`

``

1942

`+

}

`

``

1943

+

``

1944

`+

return _Py_INIT_OK();

`

``

1945

`+

}

`

``

1946

+

``

1947

+

``

1948

`+

void

`

``

1949

`+

_PyCoreConfig_Clear(_PyCoreConfig *config)

`

``

1950

`+

{

`

``

1951

`+

#define CLEAR(ATTR) \

`

``

1952

`+

do { \

`

``

1953

`+

PyMem_RawFree(ATTR); \

`

``

1954

`+

ATTR = NULL; \

`

``

1955

`+

} while (0)

`

``

1956

+

``

1957

`+

CLEAR(config->module_search_path_env);

`

``

1958

`+

CLEAR(config->home);

`

``

1959

`+

CLEAR(config->program_name);

`

``

1960

`+

#undef CLEAR

`

``

1961

`+

}

`

``

1962

+

``

1963

+

``

1964

`+

int

`

``

1965

`+

_PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)

`

``

1966

`+

{

`

``

1967

`+

_PyCoreConfig_Clear(config);

`

``

1968

+

``

1969

`+

#define COPY_ATTR(ATTR) config->ATTR = config2->ATTR

`

``

1970

`+

COPY_ATTR(ignore_environment);

`

``

1971

`+

COPY_ATTR(use_hash_seed);

`

``

1972

`+

COPY_ATTR(hash_seed);

`

``

1973

`+

COPY_ATTR(_disable_importlib);

`

``

1974

`+

COPY_ATTR(allocator);

`

``

1975

`+

COPY_ATTR(dev_mode);

`

``

1976

`+

COPY_ATTR(faulthandler);

`

``

1977

`+

COPY_ATTR(tracemalloc);

`

``

1978

`+

COPY_ATTR(import_time);

`

``

1979

`+

COPY_ATTR(show_ref_count);

`

``

1980

`+

COPY_ATTR(show_alloc_count);

`

``

1981

`+

COPY_ATTR(dump_refs);

`

``

1982

`+

COPY_ATTR(malloc_stats);

`

``

1983

`+

COPY_ATTR(utf8_mode);

`

``

1984

`+

#undef COPY_ATTR

`

``

1985

+

``

1986

`+

#define COPY_STR_ATTR(ATTR) \

`

``

1987

`+

do { \

`

``

1988

`+

if (config2->ATTR != NULL) { \

`

``

1989

`+

config->ATTR = _PyMem_RawWcsdup(config2->ATTR); \

`

``

1990

`+

if (config->ATTR == NULL) { \

`

``

1991

`+

return -1; \

`

``

1992

`+

} \

`

``

1993

`+

} \

`

``

1994

`+

} while (0)

`

``

1995

+

``

1996

`+

COPY_STR_ATTR(module_search_path_env);

`

``

1997

`+

COPY_STR_ATTR(home);

`

``

1998

`+

COPY_STR_ATTR(program_name);

`

``

1999

`+

#undef COPY_STR_ATTR

`

``

2000

`+

return 0;

`

``

2001

`+

}

`

``

2002

+

``

2003

+

``

2004

`+

void

`

``

2005

`+

_PyMainInterpreterConfig_Clear(_PyMainInterpreterConfig *config)

`

``

2006

`+

{

`

``

2007

`+

Py_CLEAR(config->argv);

`

``

2008

`+

Py_CLEAR(config->module_search_path);

`

``

2009

`+

Py_CLEAR(config->warnoptions);

`

``

2010

`+

Py_CLEAR(config->xoptions);

`

``

2011

`+

}

`

``

2012

+

``

2013

+

``

2014

`+

static PyObject*

`

``

2015

`+

config_copy_attr(PyObject *obj)

`

``

2016

`+

{

`

``

2017

`+

if (PyUnicode_Check(obj)) {

`

``

2018

`+

Py_INCREF(obj);

`

``

2019

`+

return obj;

`

``

2020

`+

}

`

``

2021

`+

else if (PyList_Check(obj)) {

`

``

2022

`+

return PyList_GetSlice(obj, 0, Py_SIZE(obj));

`

``

2023

`+

}

`

``

2024

`+

else if (PyDict_Check(obj)) {

`

``

2025

`+

/* The dict type is used for xoptions. Make the assumption that keys

`

``

2026

`+

and values are immutables */

`

``

2027

`+

return PyDict_Copy(obj);

`

``

2028

`+

}

`

``

2029

`+

else {

`

``

2030

`+

PyErr_Format(PyExc_TypeError,

`

``

2031

`+

"cannot copy config attribute of type %.200s",

`

``

2032

`+

Py_TYPE(obj)->tp_name);

`

``

2033

`+

return NULL;

`

``

2034

`+

}

`

``

2035

`+

}

`

``

2036

+

``

2037

+

``

2038

`+

int

`

``

2039

`+

_PyMainInterpreterConfig_Copy(_PyMainInterpreterConfig *config,

`

``

2040

`+

const _PyMainInterpreterConfig *config2)

`

``

2041

`+

{

`

``

2042

`+

_PyMainInterpreterConfig_Clear(config);

`

``

2043

+

``

2044

`+

#define COPY_ATTR(ATTR) \

`

``

2045

`+

do { \

`

``

2046

`+

if (config2->ATTR != NULL) { \

`

``

2047

`+

config->ATTR = config_copy_attr(config2->ATTR); \

`

``

2048

`+

if (config->ATTR == NULL) { \

`

``

2049

`+

return -1; \

`

``

2050

`+

} \

`

``

2051

`+

} \

`

``

2052

`+

} while (0)

`

``

2053

+

``

2054

`+

COPY_ATTR(argv);

`

``

2055

`+

COPY_ATTR(module_search_path);

`

``

2056

`+

COPY_ATTR(warnoptions);

`

``

2057

`+

COPY_ATTR(xoptions);

`

``

2058

`+

#undef COPY_ATTR

`

``

2059

`+

return 0;

`

``

2060

`+

}

`

``

2061

+

``

2062

+

``

2063

+

``

2064

+

1917

2065

`static PyObject *

`

1918

2066

`config_create_path_list(const wchar_t *path, wchar_t delim)

`

1919

2067

`{

`