@@ -19,6 +19,7 @@ extern "C" {
19
19
#endif
20
20
21
21
#include < Python.h>
22
+ #include < stddef.h> // offsetof()
22
23
23
24
// Python 3.11.0b4 added PyFrame_Back() to Python.h
24
25
#if PY_VERSION_HEX < 0x030b00B4 && !defined(PYPY_VERSION)
@@ -583,7 +584,7 @@ static inline int PyWeakref_GetRef(PyObject *ref, PyObject **pobj)
583
584
return 0 ;
584
585
}
585
586
*pobj = Py_NewRef (obj);
586
- return (*pobj != NULL ) ;
587
+ return 1 ;
587
588
}
588
589
#endif
589
590
@@ -1933,6 +1934,267 @@ PyLongWriter_Finish(PyLongWriter *writer)
1933
1934
#endif
1934
1935
1935
1936
1937
+ // gh-127350 added Py_fopen() and Py_fclose() to Python 3.14a4
1938
+ #if PY_VERSION_HEX < 0x030E00A4
1939
+ static inline FILE* Py_fopen (PyObject *path, const char *mode)
1940
+ {
1941
+ #if 0x030400A2 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
1942
+ extern FILE* _Py_fopen_obj (PyObject *path, const char *mode);
1943
+ return _Py_fopen_obj (path, mode);
1944
+ #else
1945
+ FILE *f;
1946
+ PyObject *bytes;
1947
+ #if PY_VERSION_HEX >= 0x03000000
1948
+ if (!PyUnicode_FSConverter (path, &bytes)) {
1949
+ return NULL ;
1950
+ }
1951
+ #else
1952
+ if (!PyString_Check (path)) {
1953
+ PyErr_SetString (PyExc_TypeError, " except str" );
1954
+ return NULL ;
1955
+ }
1956
+ bytes = Py_NewRef (path);
1957
+ #endif
1958
+ const char *path_bytes = PyBytes_AS_STRING (bytes);
1959
+
1960
+ f = fopen (path_bytes, mode);
1961
+ Py_DECREF (bytes);
1962
+
1963
+ if (f == NULL ) {
1964
+ PyErr_SetFromErrnoWithFilenameObject (PyExc_OSError, path);
1965
+ return NULL ;
1966
+ }
1967
+ return f;
1968
+ #endif
1969
+ }
1970
+
1971
+ static inline int Py_fclose (FILE *file)
1972
+ {
1973
+ return fclose (file);
1974
+ }
1975
+ #endif
1976
+
1977
+
1978
+ #if 0x03090000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030E0000 && !defined(PYPY_VERSION)
1979
+ static inline PyObject*
1980
+ PyConfig_Get (const char *name)
1981
+ {
1982
+ typedef enum {
1983
+ _PyConfig_MEMBER_INT,
1984
+ _PyConfig_MEMBER_UINT,
1985
+ _PyConfig_MEMBER_ULONG,
1986
+ _PyConfig_MEMBER_BOOL,
1987
+ _PyConfig_MEMBER_WSTR,
1988
+ _PyConfig_MEMBER_WSTR_OPT,
1989
+ _PyConfig_MEMBER_WSTR_LIST,
1990
+ } PyConfigMemberType;
1991
+
1992
+ typedef struct {
1993
+ const char *name;
1994
+ size_t offset;
1995
+ PyConfigMemberType type;
1996
+ const char *sys_attr;
1997
+ } PyConfigSpec;
1998
+
1999
+ #define PYTHONCAPI_COMPAT_SPEC (MEMBER, TYPE, sys_attr ) \
2000
+ {#MEMBER, offsetof (PyConfig, MEMBER), \
2001
+ _PyConfig_MEMBER_##TYPE, sys_attr}
2002
+
2003
+ static const PyConfigSpec config_spec[] = {
2004
+ PYTHONCAPI_COMPAT_SPEC (argv, WSTR_LIST, " argv" ),
2005
+ PYTHONCAPI_COMPAT_SPEC (base_exec_prefix, WSTR_OPT, " base_exec_prefix" ),
2006
+ PYTHONCAPI_COMPAT_SPEC (base_executable, WSTR_OPT, " _base_executable" ),
2007
+ PYTHONCAPI_COMPAT_SPEC (base_prefix, WSTR_OPT, " base_prefix" ),
2008
+ PYTHONCAPI_COMPAT_SPEC (bytes_warning, UINT, _Py_NULL),
2009
+ PYTHONCAPI_COMPAT_SPEC (exec_prefix, WSTR_OPT, " exec_prefix" ),
2010
+ PYTHONCAPI_COMPAT_SPEC (executable, WSTR_OPT, " executable" ),
2011
+ PYTHONCAPI_COMPAT_SPEC (inspect, BOOL, _Py_NULL),
2012
+ #if 0x030C0000 <= PY_VERSION_HEX
2013
+ PYTHONCAPI_COMPAT_SPEC (int_max_str_digits, UINT, _Py_NULL),
2014
+ #endif
2015
+ PYTHONCAPI_COMPAT_SPEC (interactive, BOOL, _Py_NULL),
2016
+ PYTHONCAPI_COMPAT_SPEC (module_search_paths, WSTR_LIST, " path" ),
2017
+ PYTHONCAPI_COMPAT_SPEC (optimization_level, UINT, _Py_NULL),
2018
+ PYTHONCAPI_COMPAT_SPEC (parser_debug, BOOL, _Py_NULL),
2019
+ PYTHONCAPI_COMPAT_SPEC (platlibdir, WSTR, " platlibdir" ),
2020
+ PYTHONCAPI_COMPAT_SPEC (prefix, WSTR_OPT, " prefix" ),
2021
+ PYTHONCAPI_COMPAT_SPEC (pycache_prefix, WSTR_OPT, " pycache_prefix" ),
2022
+ PYTHONCAPI_COMPAT_SPEC (quiet, BOOL, _Py_NULL),
2023
+ #if 0x030B0000 <= PY_VERSION_HEX
2024
+ PYTHONCAPI_COMPAT_SPEC (stdlib_dir, WSTR_OPT, " _stdlib_dir" ),
2025
+ #endif
2026
+ PYTHONCAPI_COMPAT_SPEC (use_environment, BOOL, _Py_NULL),
2027
+ PYTHONCAPI_COMPAT_SPEC (verbose, UINT, _Py_NULL),
2028
+ PYTHONCAPI_COMPAT_SPEC (warnoptions, WSTR_LIST, " warnoptions" ),
2029
+ PYTHONCAPI_COMPAT_SPEC (write_bytecode, BOOL, _Py_NULL),
2030
+ PYTHONCAPI_COMPAT_SPEC (xoptions, WSTR_LIST, " _xoptions" ),
2031
+ PYTHONCAPI_COMPAT_SPEC (buffered_stdio, BOOL, _Py_NULL),
2032
+ PYTHONCAPI_COMPAT_SPEC (check_hash_pycs_mode, WSTR, _Py_NULL),
2033
+ #if 0x030B0000 <= PY_VERSION_HEX
2034
+ PYTHONCAPI_COMPAT_SPEC (code_debug_ranges, BOOL, _Py_NULL),
2035
+ #endif
2036
+ PYTHONCAPI_COMPAT_SPEC (configure_c_stdio, BOOL, _Py_NULL),
2037
+ #if 0x030D0000 <= PY_VERSION_HEX
2038
+ PYTHONCAPI_COMPAT_SPEC (cpu_count, INT, _Py_NULL),
2039
+ #endif
2040
+ PYTHONCAPI_COMPAT_SPEC (dev_mode, BOOL, _Py_NULL),
2041
+ PYTHONCAPI_COMPAT_SPEC (dump_refs, BOOL, _Py_NULL),
2042
+ #if 0x030B0000 <= PY_VERSION_HEX
2043
+ PYTHONCAPI_COMPAT_SPEC (dump_refs_file, WSTR_OPT, _Py_NULL),
2044
+ #endif
2045
+ #ifdef Py_GIL_DISABLED
2046
+ PYTHONCAPI_COMPAT_SPEC (enable_gil, INT, _Py_NULL),
2047
+ #endif
2048
+ PYTHONCAPI_COMPAT_SPEC (faulthandler, BOOL, _Py_NULL),
2049
+ PYTHONCAPI_COMPAT_SPEC (filesystem_encoding, WSTR, _Py_NULL),
2050
+ PYTHONCAPI_COMPAT_SPEC (filesystem_errors, WSTR, _Py_NULL),
2051
+ PYTHONCAPI_COMPAT_SPEC (hash_seed, ULONG, _Py_NULL),
2052
+ PYTHONCAPI_COMPAT_SPEC (home, WSTR_OPT, _Py_NULL),
2053
+ PYTHONCAPI_COMPAT_SPEC (import_time, BOOL, _Py_NULL),
2054
+ PYTHONCAPI_COMPAT_SPEC (install_signal_handlers, BOOL, _Py_NULL),
2055
+ PYTHONCAPI_COMPAT_SPEC (isolated, BOOL, _Py_NULL),
2056
+ #ifdef MS_WINDOWS
2057
+ PYTHONCAPI_COMPAT_SPEC (legacy_windows_stdio, BOOL, _Py_NULL),
2058
+ #endif
2059
+ PYTHONCAPI_COMPAT_SPEC (malloc_stats, BOOL, _Py_NULL),
2060
+ #if 0x030A0000 <= PY_VERSION_HEX
2061
+ PYTHONCAPI_COMPAT_SPEC (orig_argv, WSTR_LIST, " orig_argv" ),
2062
+ #endif
2063
+ PYTHONCAPI_COMPAT_SPEC (parse_argv, BOOL, _Py_NULL),
2064
+ PYTHONCAPI_COMPAT_SPEC (pathconfig_warnings, BOOL, _Py_NULL),
2065
+ #if 0x030C0000 <= PY_VERSION_HEX
2066
+ PYTHONCAPI_COMPAT_SPEC (perf_profiling, UINT, _Py_NULL),
2067
+ #endif
2068
+ PYTHONCAPI_COMPAT_SPEC (program_name, WSTR, _Py_NULL),
2069
+ PYTHONCAPI_COMPAT_SPEC (run_command, WSTR_OPT, _Py_NULL),
2070
+ PYTHONCAPI_COMPAT_SPEC (run_filename, WSTR_OPT, _Py_NULL),
2071
+ PYTHONCAPI_COMPAT_SPEC (run_module, WSTR_OPT, _Py_NULL),
2072
+ #if 0x030B0000 <= PY_VERSION_HEX
2073
+ PYTHONCAPI_COMPAT_SPEC (safe_path, BOOL, _Py_NULL),
2074
+ #endif
2075
+ PYTHONCAPI_COMPAT_SPEC (show_ref_count, BOOL, _Py_NULL),
2076
+ PYTHONCAPI_COMPAT_SPEC (site_import, BOOL, _Py_NULL),
2077
+ PYTHONCAPI_COMPAT_SPEC (skip_source_first_line, BOOL, _Py_NULL),
2078
+ PYTHONCAPI_COMPAT_SPEC (stdio_encoding, WSTR, _Py_NULL),
2079
+ PYTHONCAPI_COMPAT_SPEC (stdio_errors, WSTR, _Py_NULL),
2080
+ PYTHONCAPI_COMPAT_SPEC (tracemalloc, UINT, _Py_NULL),
2081
+ #if 0x030B0000 <= PY_VERSION_HEX
2082
+ PYTHONCAPI_COMPAT_SPEC (use_frozen_modules, BOOL, _Py_NULL),
2083
+ #endif
2084
+ PYTHONCAPI_COMPAT_SPEC (use_hash_seed, BOOL, _Py_NULL),
2085
+ PYTHONCAPI_COMPAT_SPEC (user_site_directory, BOOL, _Py_NULL),
2086
+ #if 0x030A0000 <= PY_VERSION_HEX
2087
+ PYTHONCAPI_COMPAT_SPEC (warn_default_encoding, BOOL, _Py_NULL),
2088
+ #endif
2089
+ };
2090
+
2091
+ #undef PYTHONCAPI_COMPAT_SPEC
2092
+
2093
+ const PyConfigSpec *spec;
2094
+ int found = 0 ;
2095
+ for (size_t i=0 ; i < sizeof (config_spec) / sizeof (config_spec[0 ]); i++) {
2096
+ spec = &config_spec[i];
2097
+ if (strcmp (spec->name , name) == 0 ) {
2098
+ found = 1 ;
2099
+ break ;
2100
+ }
2101
+ }
2102
+ if (found) {
2103
+ if (spec->sys_attr != NULL ) {
2104
+ PyObject *value = PySys_GetObject (spec->sys_attr );
2105
+ if (value == NULL ) {
2106
+ PyErr_Format (PyExc_RuntimeError, " lost sys.%s" , spec->sys_attr );
2107
+ return NULL ;
2108
+ }
2109
+ return Py_NewRef (value);
2110
+ }
2111
+
2112
+ extern const PyConfig* _Py_GetConfig (void );
2113
+ const PyConfig *config = _Py_GetConfig ();
2114
+ void *member = (char *)config + spec->offset ;
2115
+ switch (spec->type ) {
2116
+ case _PyConfig_MEMBER_INT:
2117
+ case _PyConfig_MEMBER_UINT:
2118
+ {
2119
+ int value = *(int *)member;
2120
+ return PyLong_FromLong (value);
2121
+ }
2122
+ case _PyConfig_MEMBER_BOOL:
2123
+ {
2124
+ int value = *(int *)member;
2125
+ return PyBool_FromLong (value != 0 );
2126
+ }
2127
+ case _PyConfig_MEMBER_ULONG:
2128
+ {
2129
+ unsigned long value = *(unsigned long *)member;
2130
+ return PyLong_FromUnsignedLong (value);
2131
+ }
2132
+ case _PyConfig_MEMBER_WSTR:
2133
+ case _PyConfig_MEMBER_WSTR_OPT:
2134
+ {
2135
+ wchar_t *wstr = *(wchar_t **)member;
2136
+ if (wstr != NULL ) {
2137
+ return PyUnicode_FromWideChar (wstr, -1 );
2138
+ }
2139
+ else {
2140
+ return Py_NewRef (Py_None);
2141
+ }
2142
+ }
2143
+ case _PyConfig_MEMBER_WSTR_LIST:
2144
+ {
2145
+ const PyWideStringList *list = (const PyWideStringList *)member;
2146
+ PyObject *tuple = PyTuple_New (list->length );
2147
+ if (tuple == NULL ) {
2148
+ return NULL ;
2149
+ }
2150
+
2151
+ for (Py_ssize_t i = 0 ; i < list->length ; i++) {
2152
+ PyObject *item = PyUnicode_FromWideChar (list->items [i], -1 );
2153
+ if (item == NULL ) {
2154
+ Py_DECREF (tuple);
2155
+ return NULL ;
2156
+ }
2157
+ PyTuple_SET_ITEM (tuple, i, item);
2158
+ }
2159
+ return tuple;
2160
+ }
2161
+ default :
2162
+ Py_UNREACHABLE ();
2163
+ }
2164
+ }
2165
+
2166
+ PyErr_Format (PyExc_ValueError, " unknown config option name: %s" , name);
2167
+ return NULL ;
2168
+ }
2169
+
2170
+ static inline int
2171
+ PyConfig_GetInt (const char *name, int *value)
2172
+ {
2173
+ PyObject *obj = PyConfig_Get (name);
2174
+ if (obj == NULL ) {
2175
+ return -1 ;
2176
+ }
2177
+
2178
+ if (!PyLong_Check (obj)) {
2179
+ Py_DECREF (obj);
2180
+ PyErr_Format (PyExc_TypeError, " config option %s is not an int" , name);
2181
+ return -1 ;
2182
+ }
2183
+
2184
+ int as_int = PyLong_AsInt (obj);
2185
+ Py_DECREF (obj);
2186
+ if (as_int == -1 && PyErr_Occurred ()) {
2187
+ PyErr_Format (PyExc_OverflowError,
2188
+ " config option %s value does not fit into a C int" , name);
2189
+ return -1 ;
2190
+ }
2191
+
2192
+ *value = as_int;
2193
+ return 0 ;
2194
+ }
2195
+ #endif // PY_VERSION_HEX > 0x03090000 && !defined(PYPY_VERSION)
2196
+
2197
+
1936
2198
#ifdef __cplusplus
1937
2199
}
1938
2200
#endif
0 commit comments