]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-108512: Add and use new replacements for PySys_GetObject() (GH-111035)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 28 May 2025 17:11:09 +0000 (20:11 +0300)
committerGitHub <noreply@github.com>
Wed, 28 May 2025 17:11:09 +0000 (20:11 +0300)
Add functions PySys_GetAttr(), PySys_GetAttrString(),
PySys_GetOptionalAttr() and PySys_GetOptionalAttrString().

32 files changed:
Doc/c-api/init_config.rst
Doc/c-api/sys.rst
Doc/data/stable_abi.dat
Doc/whatsnew/3.15.rst
Include/internal/pycore_sysmodule.h
Include/sysmodule.h
Lib/test/test_capi/test_sys.py
Lib/test/test_stable_abi_ctypes.py
Misc/NEWS.d/next/C_API/2023-10-18-14-36-35.gh-issue-108512.fMZLfr.rst [new file with mode: 0644]
Misc/stable_abi.toml
Modules/_cursesmodule.c
Modules/_lsprof.c
Modules/_pickle.c
Modules/_testlimitedcapi/sys.c
Modules/_threadmodule.c
Modules/_tkinter.c
Modules/faulthandler.c
Modules/main.c
Modules/syslogmodule.c
Objects/moduleobject.c
PC/python3dll.c
Python/_warnings.c
Python/bltinmodule.c
Python/ceval.c
Python/errors.c
Python/import.c
Python/initconfig.c
Python/intrinsics.c
Python/pylifecycle.c
Python/pythonrun.c
Python/sysmodule.c
Python/traceback.c

index e1931655618b1c928828924708644b8ce53eadd0..4fd10224262488011936f483c09e06e9a6deeebc 100644 (file)
@@ -2111,7 +2111,7 @@ initialization::
 
         /* Specify sys.path explicitly */
         /* If you want to modify the default set of paths, finish
-           initialization first and then use PySys_GetObject("path") */
+           initialization first and then use PySys_GetAttrString("path") */
         config.module_search_paths_set = 1;
         status = PyWideStringList_Append(&config.module_search_paths,
                                          L"/path/to/stdlib");
index b3c89800e386ff193cc308c7bf1ac51dc0d11478..b34936dd55e94ca9a6932ba9277b291e5e643f9d 100644 (file)
@@ -258,10 +258,57 @@ These are utility functions that make functionality from the :mod:`sys` module
 accessible to C code.  They all work with the current interpreter thread's
 :mod:`sys` module's dict, which is contained in the internal thread state structure.
 
+.. c:function:: PyObject *PySys_GetAttr(PyObject *name)
+
+   Get the attribute *name* of the :mod:`sys` module.
+   Return a :term:`strong reference`.
+   Raise :exc:`RuntimeError` and return ``NULL`` if it does not exist or
+   if the :mod:`sys` module cannot be found.
+
+   If the non-existing object should not be treated as a failure, you can use
+   :c:func:`PySys_GetOptionalAttr` instead.
+
+   .. versionadded:: next
+
+.. c:function:: PyObject *PySys_GetAttrString(const char *name)
+
+   This is the same as :c:func:`PySys_GetAttr`, but *name* is
+   specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
+   rather than a :c:expr:`PyObject*`.
+
+   If the non-existing object should not be treated as a failure, you can use
+   :c:func:`PySys_GetOptionalAttrString` instead.
+
+   .. versionadded:: next
+
+.. c:function:: int PySys_GetOptionalAttr(PyObject *name, PyObject **result)
+
+   Variant of :c:func:`PySys_GetAttr` which doesn't raise
+   exception if the object does not exist.
+
+   * Set *\*result* to a new :term:`strong reference` to the object and
+     return ``1`` if the object exists.
+   * Set *\*result* to ``NULL`` and return ``0`` without setting an exception
+     if the object does not exist.
+   * Set an exception, set *\*result* to ``NULL``, and return ``-1``,
+     if an error occurred.
+
+   .. versionadded:: next
+
+.. c:function:: int PySys_GetOptionalAttrString(const char *name, PyObject **result)
+
+   This is the same as :c:func:`PySys_GetOptionalAttr`, but *name* is
+   specified as a :c:expr:`const char*` UTF-8 encoded bytes string,
+   rather than a :c:expr:`PyObject*`.
+
+   .. versionadded:: next
+
 .. c:function:: PyObject *PySys_GetObject(const char *name)
 
-   Return the object *name* from the :mod:`sys` module or ``NULL`` if it does
-   not exist, without setting an exception.
+   Similar to :c:func:`PySys_GetAttrString`, but return a :term:`borrowed
+   reference` and return ``NULL`` *without* setting exception on failure.
+
+   Preserves exception that was set before the call.
 
 .. c:function:: int PySys_SetObject(const char *name, PyObject *v)
 
index e71a40e55e918c0edc5446555b3cd2a01797335b..0d0dfb3843260e524ec02fa670bc30eaf4a9362e 100644 (file)
@@ -628,7 +628,11 @@ func,PySys_Audit,3.13,,
 func,PySys_AuditTuple,3.13,,
 func,PySys_FormatStderr,3.2,,
 func,PySys_FormatStdout,3.2,,
+func,PySys_GetAttr,3.15,,
+func,PySys_GetAttrString,3.15,,
 func,PySys_GetObject,3.2,,
+func,PySys_GetOptionalAttr,3.15,,
+func,PySys_GetOptionalAttrString,3.15,,
 func,PySys_GetXOptions,3.7,,
 func,PySys_ResetWarnOptions,3.2,,
 func,PySys_SetArgv,3.2,,
index 4d1a27354fc62006a0a6266568671f4884b42833..87cca4eeff385a8c4b81dcaa055936c1cc638bdf 100644 (file)
@@ -213,7 +213,10 @@ C API changes
 New features
 ------------
 
-* TODO
+* Add :c:func:`PySys_GetAttr`, :c:func:`PySys_GetAttrString`,
+  :c:func:`PySys_GetOptionalAttr`, and :c:func:`PySys_GetOptionalAttrString`
+  functions as replacements for :c:func:`PySys_GetObject`.
+  (Contributed by Serhiy Storchaka in :gh:`108512`.)
 
 Porting to Python 3.15
 ----------------------
index 008a2da0d04fa7436aa10d85fd03ecf02bb8018a..347b0a7a790c0669872125a6c52246b78240946f 100644 (file)
@@ -8,11 +8,6 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
-PyAPI_FUNC(int) _PySys_GetOptionalAttr(PyObject *, PyObject **);
-PyAPI_FUNC(int) _PySys_GetOptionalAttrString(const char *, PyObject **);
-PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttr(PyObject *);
-PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttrString(const char *);
-
 // Export for '_pickle' shared extension
 PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
 
index c1d5f610fe08a58be896a1de4cb331aba3e338cc..2f362791797ded62948b707190a66162908e7906 100644 (file)
@@ -4,6 +4,12 @@
 extern "C" {
 #endif
 
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030f0000
+PyAPI_FUNC(PyObject *) PySys_GetAttr(PyObject *);
+PyAPI_FUNC(PyObject *) PySys_GetAttrString(const char *);
+PyAPI_FUNC(int) PySys_GetOptionalAttr(PyObject *, PyObject **);
+PyAPI_FUNC(int) PySys_GetOptionalAttrString(const char *, PyObject **);
+#endif
 PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
 PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
 
index d3a9b378e7769a5f4184d76e6bb5a59e4ed883c7..3793ce2461effddd580d590ede9f2666251c3da1 100644 (file)
@@ -19,6 +19,68 @@ class CAPITest(unittest.TestCase):
 
     maxDiff = None
 
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
+    def test_sys_getattr(self):
+        # Test PySys_GetAttr()
+        sys_getattr = _testlimitedcapi.sys_getattr
+
+        self.assertIs(sys_getattr('stdout'), sys.stdout)
+        with support.swap_attr(sys, '\U0001f40d', 42):
+            self.assertEqual(sys_getattr('\U0001f40d'), 42)
+
+        with self.assertRaisesRegex(RuntimeError, r'lost sys\.nonexistent'):
+            sys_getattr('nonexistent')
+        with self.assertRaisesRegex(RuntimeError, r'lost sys\.\U0001f40d'):
+            sys_getattr('\U0001f40d')
+        self.assertRaises(TypeError, sys_getattr, 1)
+        self.assertRaises(TypeError, sys_getattr, [])
+        # CRASHES sys_getattr(NULL)
+
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
+    def test_sys_getattrstring(self):
+        # Test PySys_GetAttrString()
+        getattrstring = _testlimitedcapi.sys_getattrstring
+
+        self.assertIs(getattrstring(b'stdout'), sys.stdout)
+        with support.swap_attr(sys, '\U0001f40d', 42):
+            self.assertEqual(getattrstring('\U0001f40d'.encode()), 42)
+
+        with self.assertRaisesRegex(RuntimeError, r'lost sys\.nonexistent'):
+            getattrstring(b'nonexistent')
+        with self.assertRaisesRegex(RuntimeError, r'lost sys\.\U0001f40d'):
+            getattrstring('\U0001f40d'.encode())
+        self.assertRaises(UnicodeDecodeError, getattrstring, b'\xff')
+        # CRASHES getattrstring(NULL)
+
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
+    def test_sys_getoptionalattr(self):
+        # Test PySys_GetOptionalAttr()
+        getoptionalattr = _testlimitedcapi.sys_getoptionalattr
+
+        self.assertIs(getoptionalattr('stdout'), sys.stdout)
+        with support.swap_attr(sys, '\U0001f40d', 42):
+            self.assertEqual(getoptionalattr('\U0001f40d'), 42)
+
+        self.assertIs(getoptionalattr('nonexistent'), AttributeError)
+        self.assertIs(getoptionalattr('\U0001f40d'), AttributeError)
+        self.assertRaises(TypeError, getoptionalattr, 1)
+        self.assertRaises(TypeError, getoptionalattr, [])
+        # CRASHES getoptionalattr(NULL)
+
+    @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
+    def test_sys_getoptionalattrstring(self):
+        # Test PySys_GetOptionalAttrString()
+        getoptionalattrstring = _testlimitedcapi.sys_getoptionalattrstring
+
+        self.assertIs(getoptionalattrstring(b'stdout'), sys.stdout)
+        with support.swap_attr(sys, '\U0001f40d', 42):
+            self.assertEqual(getoptionalattrstring('\U0001f40d'.encode()), 42)
+
+        self.assertIs(getoptionalattrstring(b'nonexistent'), AttributeError)
+        self.assertIs(getoptionalattrstring('\U0001f40d'.encode()), AttributeError)
+        self.assertRaises(UnicodeDecodeError, getoptionalattrstring, b'\xff')
+        # CRASHES getoptionalattrstring(NULL)
+
     @support.cpython_only
     @unittest.skipIf(_testlimitedcapi is None, 'need _testlimitedcapi module')
     def test_sys_getobject(self):
@@ -29,7 +91,7 @@ class CAPITest(unittest.TestCase):
         with support.swap_attr(sys, '\U0001f40d', 42):
             self.assertEqual(getobject('\U0001f40d'.encode()), 42)
 
-        self.assertIs(getobject(b'nonexisting'), AttributeError)
+        self.assertIs(getobject(b'nonexistent'), AttributeError)
         with support.catch_unraisable_exception() as cm:
             self.assertIs(getobject(b'\xff'), AttributeError)
             self.assertEqual(cm.unraisable.exc_type, UnicodeDecodeError)
index 1e6f69d49e933583dd8942499e430077368ccd46..5a6ba9de337904a157e12629bef0d62dff39c1f6 100644 (file)
@@ -658,7 +658,11 @@ SYMBOL_NAMES = (
     "PySys_AuditTuple",
     "PySys_FormatStderr",
     "PySys_FormatStdout",
+    "PySys_GetAttr",
+    "PySys_GetAttrString",
     "PySys_GetObject",
+    "PySys_GetOptionalAttr",
+    "PySys_GetOptionalAttrString",
     "PySys_GetXOptions",
     "PySys_HasWarnOptions",
     "PySys_ResetWarnOptions",
diff --git a/Misc/NEWS.d/next/C_API/2023-10-18-14-36-35.gh-issue-108512.fMZLfr.rst b/Misc/NEWS.d/next/C_API/2023-10-18-14-36-35.gh-issue-108512.fMZLfr.rst
new file mode 100644 (file)
index 0000000..279e588
--- /dev/null
@@ -0,0 +1,2 @@
+Add functions :c:func:`PySys_GetAttr`, :c:func:`PySys_GetAttrString`,
+:c:func:`PySys_GetOptionalAttr` and :c:func:`PySys_GetOptionalAttrString`.
index d38919a8ea9b62716452810945356aff004b7df9..1f323cc03973e5827284cf104aa3dc01a319fc0d 100644 (file)
     added = '3.14'
 [function.Py_PACK_VERSION]
     added = '3.14'
+[function.PySys_GetAttr]
+    added = '3.15'
+[function.PySys_GetAttrString]
+    added = '3.15'
+[function.PySys_GetOptionalAttr]
+    added = '3.15'
+[function.PySys_GetOptionalAttrString]
+    added = '3.15'
index 290ae4e55cd7a7b9e115391f41e743802633aec9..d7788ef7a585b04981364710957edb21124561d1 100644 (file)
@@ -108,7 +108,6 @@ static const char PyCursesVersion[] = "2.2";
 #include "pycore_capsule.h"     // _PyCapsule_SetTraverse()
 #include "pycore_long.h"        // _PyLong_GetZero()
 #include "pycore_structseq.h"   // _PyStructSequence_NewType()
-#include "pycore_sysmodule.h"   // _PySys_GetOptionalAttrString()
 #include "pycore_fileutils.h"   // _Py_set_inheritable
 
 #ifdef __hpux
@@ -3847,7 +3846,7 @@ _curses_setupterm_impl(PyObject *module, const char *term, int fd)
     if (fd == -1) {
         PyObject* sys_stdout;
 
-        if (_PySys_GetOptionalAttrString("stdout", &sys_stdout) < 0) {
+        if (PySys_GetOptionalAttrString("stdout", &sys_stdout) < 0) {
             return NULL;
         }
 
index 626c176715bdacd8b57a2f25aacb13b2679ae644..bbad5eb69032da6946cbd43ff623a6dfca286a6e 100644 (file)
@@ -782,7 +782,7 @@ _lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
         return NULL;
     }
 
-    PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
+    PyObject* monitoring = PySys_GetAttrString("monitoring");
     if (!monitoring) {
         return NULL;
     }
@@ -864,7 +864,7 @@ _lsprof_Profiler_disable_impl(ProfilerObject *self)
     }
     if (self->flags & POF_ENABLED) {
         PyObject* result = NULL;
-        PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
+        PyObject* monitoring = PySys_GetAttrString("monitoring");
 
         if (!monitoring) {
             return NULL;
@@ -983,7 +983,7 @@ profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit,
     Py_XSETREF(self->externalTimer, Py_XNewRef(timer));
     self->tool_id = PY_MONITORING_PROFILER_ID;
 
-    PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
+    PyObject* monitoring = PySys_GetAttrString("monitoring");
     if (!monitoring) {
         return -1;
     }
index 29ef0cb0c2e0882f3ef2185b1950c1a367f2cd3d..86d8b38620cb7fdffac4c2604e5baeefde84ebaf 100644 (file)
@@ -1915,7 +1915,7 @@ whichmodule(PickleState *st, PyObject *global, PyObject *global_name, PyObject *
            __module__ can be None. If it is so, then search sys.modules for
            the module of global. */
         Py_CLEAR(module_name);
-        modules = _PySys_GetRequiredAttr(&_Py_ID(modules));
+        modules = PySys_GetAttr(&_Py_ID(modules));
         if (modules == NULL) {
             return NULL;
         }
index 7d8b7a8569e51598434d4987246c0cfc3b29954d..cec7f8ab6120198df37b266812d3d266b3b81d8c 100644 (file)
@@ -1,7 +1,76 @@
+#include "pyconfig.h"   // Py_GIL_DISABLED
+// Need limited C API version 3.15 for PySys_GetAttr() etc
+#if !defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API)
+#  define Py_LIMITED_API 0x030f0000
+#endif
 #include "parts.h"
 #include "util.h"
 
 
+static PyObject *
+sys_getattr(PyObject *Py_UNUSED(module), PyObject *name)
+{
+    NULLABLE(name);
+    return PySys_GetAttr(name);
+}
+
+static PyObject *
+sys_getattrstring(PyObject *Py_UNUSED(module), PyObject *arg)
+{
+    const char *name;
+    Py_ssize_t size;
+    if (!PyArg_Parse(arg, "z#", &name, &size)) {
+        return NULL;
+    }
+    return PySys_GetAttrString(name);
+}
+
+static PyObject *
+sys_getoptionalattr(PyObject *Py_UNUSED(module), PyObject *name)
+{
+    PyObject *value = UNINITIALIZED_PTR;
+    NULLABLE(name);
+
+    switch (PySys_GetOptionalAttr(name, &value)) {
+        case -1:
+            assert(value == NULL);
+            assert(PyErr_Occurred());
+            return NULL;
+        case 0:
+            assert(value == NULL);
+            return Py_NewRef(PyExc_AttributeError);
+        case 1:
+            return value;
+        default:
+            Py_FatalError("PySys_GetOptionalAttr() returned invalid code");
+    }
+}
+
+static PyObject *
+sys_getoptionalattrstring(PyObject *Py_UNUSED(module), PyObject *arg)
+{
+    PyObject *value = UNINITIALIZED_PTR;
+    const char *name;
+    Py_ssize_t size;
+    if (!PyArg_Parse(arg, "z#", &name, &size)) {
+        return NULL;
+    }
+
+    switch (PySys_GetOptionalAttrString(name, &value)) {
+        case -1:
+            assert(value == NULL);
+            assert(PyErr_Occurred());
+            return NULL;
+        case 0:
+            assert(value == NULL);
+            return Py_NewRef(PyExc_AttributeError);
+        case 1:
+            return value;
+        default:
+            Py_FatalError("PySys_GetOptionalAttrString() returned invalid code");
+    }
+}
+
 static PyObject *
 sys_getobject(PyObject *Py_UNUSED(module), PyObject *arg)
 {
@@ -39,6 +108,10 @@ sys_getxoptions(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(ignored))
 
 
 static PyMethodDef test_methods[] = {
+    {"sys_getattr", sys_getattr, METH_O},
+    {"sys_getattrstring", sys_getattrstring, METH_O},
+    {"sys_getoptionalattr", sys_getoptionalattr, METH_O},
+    {"sys_getoptionalattrstring", sys_getoptionalattrstring, METH_O},
     {"sys_getobject", sys_getobject, METH_O},
     {"sys_setobject", sys_setobject, METH_VARARGS},
     {"sys_getxoptions", sys_getxoptions, METH_NOARGS},
index cc83be4b5ff311e6d62864c25626c349797f4486..150a266b521736c57404ef7a4277a433cb47da86 100644 (file)
@@ -10,7 +10,6 @@
 #include "pycore_object_deferred.h" // _PyObject_SetDeferredRefcount()
 #include "pycore_pylifecycle.h"
 #include "pycore_pystate.h"       // _PyThreadState_SetCurrent()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttr()
 #include "pycore_time.h"          // _PyTime_FromSeconds()
 #include "pycore_weakref.h"       // _PyWeakref_GET_REF()
 
@@ -2290,7 +2289,7 @@ thread_excepthook(PyObject *module, PyObject *args)
     PyObject *thread = PyStructSequence_GET_ITEM(args, 3);
 
     PyObject *file;
-    if (_PySys_GetOptionalAttr( &_Py_ID(stderr), &file) < 0) {
+    if (PySys_GetOptionalAttr( &_Py_ID(stderr), &file) < 0) {
         return NULL;
     }
     if (file == NULL || file == Py_None) {
index 77695401919cb7a205376b71f9bae5ea13ce2ac3..875840bd6a6364982202f8990ac2a5f23b36da4b 100644 (file)
@@ -31,7 +31,6 @@ Copyright (C) 1994 Steen Lumholt.
 #endif
 
 #include "pycore_long.h"          // _PyLong_IsNegative()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttrString()
 #include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8String
 
 #ifdef MS_WINDOWS
@@ -146,7 +145,7 @@ _get_tcl_lib_path(void)
         int stat_return_value;
         PyObject *prefix;
 
-        (void) _PySys_GetOptionalAttrString("base_prefix", &prefix);
+        (void) PySys_GetOptionalAttrString("base_prefix", &prefix);
         if (prefix == NULL) {
             return NULL;
         }
@@ -3547,7 +3546,7 @@ PyInit__tkinter(void)
 
     /* This helps the dynamic loader; in Unicode aware Tcl versions
        it also helps Tcl find its encodings. */
-    (void) _PySys_GetOptionalAttrString("executable", &uexe);
+    (void) PySys_GetOptionalAttrString("executable", &uexe);
     if (uexe && PyUnicode_Check(uexe)) {   // sys.executable can be None
         cexe = PyUnicode_EncodeFSDefault(uexe);
         Py_DECREF(uexe);
index c94f4f66366170a5c6dc7d391a855458f6ff26fe..73bea8172c7253dbdea92b9e4b748346f7855e53 100644 (file)
@@ -6,7 +6,6 @@
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_runtime.h"       // _Py_ID()
 #include "pycore_signal.h"        // Py_NSIG
-#include "pycore_sysmodule.h"     // _PySys_GetRequiredAttr()
 #include "pycore_time.h"          // _PyTime_FromSecondsObject()
 #include "pycore_traceback.h"     // _Py_DumpTracebackThreads
 #ifdef HAVE_UNISTD_H
@@ -98,7 +97,7 @@ faulthandler_get_fileno(PyObject **file_ptr)
     PyObject *file = *file_ptr;
 
     if (file == NULL || file == Py_None) {
-        file = _PySys_GetRequiredAttr(&_Py_ID(stderr));
+        file = PySys_GetAttr(&_Py_ID(stderr));
         if (file == NULL) {
             return -1;
         }
index 2d7ed25f5f979005ccea55c7d39ae01ad3e5ca79..74e48c9473256579fcef59c7d7de5992b388de0f 100644 (file)
@@ -497,16 +497,13 @@ error:
 static int
 pymain_run_interactive_hook(int *exitcode)
 {
-    PyObject *hook = PyImport_ImportModuleAttrString("sys",
-                                                     "__interactivehook__");
-    if (hook == NULL) {
-        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
-            // no sys.__interactivehook__ attribute
-            PyErr_Clear();
-            return 0;
-        }
+    PyObject *hook;
+    if (PySys_GetOptionalAttrString("__interactivehook__", &hook) < 0) {
         goto error;
     }
+    if (hook == NULL) {
+        return 0;
+    }
 
     if (PySys_Audit("cpython.run_interactivehook", "O", hook) < 0) {
         goto error;
index 9c54af51402a274a6a3f45719500222771874ec9..ab20fff1509dfeed8b0365008fd77060f0931b7d 100644 (file)
@@ -56,7 +56,6 @@ Revision history:
 
 #include "Python.h"
 #include "osdefs.h"               // SEP
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttrString()
 
 #include <syslog.h>
 
@@ -92,7 +91,7 @@ syslog_get_argv(void)
     Py_ssize_t slash;
     PyObject *argv;
 
-    if (_PySys_GetOptionalAttrString("argv", &argv) <= 0) {
+    if (PySys_GetOptionalAttrString("argv", &argv) <= 0) {
         return NULL;
     }
 
index f363ef173cbd469ceb75a026bf1558d884f15f1b..ba86b41e945e9d7f5c9fd9b4b1f6974ba56676ee 100644 (file)
@@ -12,7 +12,6 @@
 #include "pycore_object.h"        // _PyType_AllocNoTrack
 #include "pycore_pyerrors.h"      // _PyErr_FormatFromCause()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttrString()
 #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
 
 #include "osdefs.h"               // MAXPATHLEN
@@ -1058,7 +1057,7 @@ _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress)
     int is_possibly_shadowing_stdlib = 0;
     if (is_possibly_shadowing) {
         PyObject *stdlib_modules;
-        if (_PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
+        if (PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
             goto done;
         }
         if (stdlib_modules && PyAnySet_Check(stdlib_modules)) {
index f0c578e11c643bfda644551a44f57a1ede22fd78..8ec791f8280f139dd001869049c0544113ccf8d9 100755 (executable)
@@ -595,7 +595,11 @@ EXPORT_FUNC(PySys_Audit)
 EXPORT_FUNC(PySys_AuditTuple)
 EXPORT_FUNC(PySys_FormatStderr)
 EXPORT_FUNC(PySys_FormatStdout)
+EXPORT_FUNC(PySys_GetAttr)
+EXPORT_FUNC(PySys_GetAttrString)
 EXPORT_FUNC(PySys_GetObject)
+EXPORT_FUNC(PySys_GetOptionalAttr)
+EXPORT_FUNC(PySys_GetOptionalAttrString)
 EXPORT_FUNC(PySys_GetXOptions)
 EXPORT_FUNC(PySys_HasWarnOptions)
 EXPORT_FUNC(PySys_ResetWarnOptions)
index 39bf1b225ccb0c69333bf7e688995d66a733d0b7..12e6172b0cf82813556ee803afb2aa4a3083cfd7 100644 (file)
@@ -6,7 +6,6 @@
 #include "pycore_long.h"          // _PyLong_GetZero()
 #include "pycore_pylifecycle.h"   // _Py_IsInterpreterFinalizing()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttr()
 #include "pycore_traceback.h"     // _Py_DisplaySourceLine()
 #include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
 
@@ -678,7 +677,7 @@ show_warning(PyThreadState *tstate, PyObject *filename, int lineno,
         goto error;
     }
 
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &f_stderr) <= 0) {
         fprintf(stderr, "lost sys.stderr\n");
         goto error;
     }
index 3d0295ee3883f29cf4b980de70e11c8e7734fae9..e08c63924ca16d88e83e5716e8d19c162f3485ce 100644 (file)
@@ -14,7 +14,6 @@
 #include "pycore_pyerrors.h"      // _PyErr_NoMemory()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_pythonrun.h"     // _Py_SourceAsString()
-#include "pycore_sysmodule.h"     // _PySys_GetRequiredAttr()
 #include "pycore_tuple.h"         // _PyTuple_FromArray()
 #include "pycore_cell.h"          // PyCell_GetRef()
 
@@ -465,7 +464,7 @@ builtin_callable(PyObject *module, PyObject *obj)
 static PyObject *
 builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords)
 {
-    PyObject *hook = _PySys_GetRequiredAttrString("breakpointhook");
+    PyObject *hook = PySys_GetAttrString("breakpointhook");
     if (hook == NULL) {
         return NULL;
     }
@@ -2164,7 +2163,7 @@ builtin_print_impl(PyObject *module, PyObject * const *args,
     int i, err;
 
     if (file == Py_None) {
-        file = _PySys_GetRequiredAttr(&_Py_ID(stdout));
+        file = PySys_GetAttr(&_Py_ID(stdout));
         if (file == NULL) {
             return NULL;
         }
@@ -2270,7 +2269,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
     int tty;
 
     /* Check that stdin/out/err are intact */
-    fin = _PySys_GetRequiredAttr(&_Py_ID(stdin));
+    fin = PySys_GetAttr(&_Py_ID(stdin));
     if (fin == NULL) {
         goto error;
     }
@@ -2278,7 +2277,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdin");
         goto error;
     }
-    fout = _PySys_GetRequiredAttr(&_Py_ID(stdout));
+    fout = PySys_GetAttr(&_Py_ID(stdout));
     if (fout == NULL) {
         goto error;
     }
@@ -2286,7 +2285,7 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
         PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
         goto error;
     }
-    ferr = _PySys_GetRequiredAttr(&_Py_ID(stderr));
+    ferr = PySys_GetAttr(&_Py_ID(stderr));
     if (ferr == NULL) {
         goto error;
     }
index 4efa4b697fb59ad13e9d6942912507dd0c8d86fe..7aec196cb85704b83b1d76a081b59a80751d3ca4 100644 (file)
@@ -2979,7 +2979,7 @@ _PyEval_ImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
     int is_possibly_shadowing_stdlib = 0;
     if (is_possibly_shadowing) {
         PyObject *stdlib_modules;
-        if (_PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
+        if (PySys_GetOptionalAttrString("stdlib_module_names", &stdlib_modules) < 0) {
             goto done;
         }
         if (stdlib_modules && PyAnySet_Check(stdlib_modules)) {
index 81f267b043afafc2ab4843fbc5cc4399f2f4d799..a3122f76bdd87d5afc6c0542a747181621e96d20 100644 (file)
@@ -10,7 +10,6 @@
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_runtime.h"       // _Py_ID()
 #include "pycore_structseq.h"     // _PyStructSequence_FiniBuiltin()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttr()
 #include "pycore_traceback.h"     // _PyTraceBack_FromFrame()
 #include "pycore_unicodeobject.h" // _PyUnicode_Equal()
 
@@ -1570,7 +1569,7 @@ write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
                      PyObject *obj)
 {
     PyObject *file;
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
         return -1;
     }
     if (file == NULL || file == Py_None) {
@@ -1677,7 +1676,7 @@ format_unraisable_v(const char *format, va_list va, PyObject *obj)
     }
 
     PyObject *hook;
-    if (_PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(unraisablehook), &hook) < 0) {
         Py_DECREF(hook_args);
         err_msg_str = NULL;
         obj = NULL;
index e7be1b90751a6c0f7dba00a44874126fc413017d..98557991378e05c23a7ae0f003d3f001e67ed0e4 100644 (file)
@@ -3369,11 +3369,11 @@ PyObject *
 PyImport_GetImporter(PyObject *path)
 {
     PyThreadState *tstate = _PyThreadState_GET();
-    PyObject *path_importer_cache = _PySys_GetRequiredAttrString("path_importer_cache");
+    PyObject *path_importer_cache = PySys_GetAttrString("path_importer_cache");
     if (path_importer_cache == NULL) {
         return NULL;
     }
-    PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
+    PyObject *path_hooks = PySys_GetAttrString("path_hooks");
     if (path_hooks == NULL) {
         Py_DECREF(path_importer_cache);
         return NULL;
@@ -3682,14 +3682,14 @@ import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
     PyTime_t t1 = 0, accumulated_copy = accumulated;
 
     PyObject *sys_path, *sys_meta_path, *sys_path_hooks;
-    if (_PySys_GetOptionalAttrString("path", &sys_path) < 0) {
+    if (PySys_GetOptionalAttrString("path", &sys_path) < 0) {
         return NULL;
     }
-    if (_PySys_GetOptionalAttrString("meta_path", &sys_meta_path) < 0) {
+    if (PySys_GetOptionalAttrString("meta_path", &sys_meta_path) < 0) {
         Py_XDECREF(sys_path);
         return NULL;
     }
-    if (_PySys_GetOptionalAttrString("path_hooks", &sys_path_hooks) < 0) {
+    if (PySys_GetOptionalAttrString("path_hooks", &sys_path_hooks) < 0) {
         Py_XDECREF(sys_meta_path);
         Py_XDECREF(sys_path);
         return NULL;
@@ -4127,7 +4127,7 @@ _PyImport_FiniCore(PyInterpreterState *interp)
 static int
 init_zipimport(PyThreadState *tstate, int verbose)
 {
-    PyObject *path_hooks = _PySys_GetRequiredAttrString("path_hooks");
+    PyObject *path_hooks = PySys_GetAttrString("path_hooks");
     if (path_hooks == NULL) {
         return -1;
     }
index 25e30aa648e8aa6d11eedaace280b0386bc579bf..71d7cfed5c44c1f9ebc2a9358d94eeb46bd5928a 100644 (file)
@@ -3647,7 +3647,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
 #define DUMP_SYS(NAME) \
         do { \
             PySys_FormatStderr("  sys.%s = ", #NAME); \
-            if (_PySys_GetOptionalAttrString(#NAME, &obj) < 0) { \
+            if (PySys_GetOptionalAttrString(#NAME, &obj) < 0) { \
                 PyErr_Clear(); \
             } \
             if (obj != NULL) { \
@@ -3671,7 +3671,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
 #undef DUMP_SYS
 
     PyObject *sys_path;
-    (void) _PySys_GetOptionalAttrString("path", &sys_path);
+    (void) PySys_GetOptionalAttrString("path", &sys_path);
     if (sys_path != NULL && PyList_Check(sys_path)) {
         PySys_WriteStderr("  sys.path = [\n");
         Py_ssize_t len = PyList_GET_SIZE(sys_path);
@@ -4294,7 +4294,7 @@ _PyConfig_CreateXOptionsDict(const PyConfig *config)
 static int
 config_get_sys_write_bytecode(const PyConfig *config, int *value)
 {
-    PyObject *attr = _PySys_GetRequiredAttrString("dont_write_bytecode");
+    PyObject *attr = PySys_GetAttrString("dont_write_bytecode");
     if (attr == NULL) {
         return -1;
     }
@@ -4315,7 +4315,7 @@ config_get(const PyConfig *config, const PyConfigSpec *spec,
 {
     if (use_sys) {
         if (spec->sys.attr != NULL) {
-            return _PySys_GetRequiredAttrString(spec->sys.attr);
+            return PySys_GetAttrString(spec->sys.attr);
         }
 
         if (strcmp(spec->name, "write_bytecode") == 0) {
index ff44ba0ee64fa92d0eae474dbccef85d8dbe9dd9..8ea920e690cd0dc66e6633ee9ab90594ba47daff 100644 (file)
@@ -9,7 +9,6 @@
 #include "pycore_intrinsics.h"    // INTRINSIC_PRINT
 #include "pycore_pyerrors.h"      // _PyErr_SetString()
 #include "pycore_runtime.h"       // _Py_ID()
-#include "pycore_sysmodule.h"     // _PySys_GetRequiredAttr()
 #include "pycore_tuple.h"         // _PyTuple_FromArray()
 #include "pycore_typevarobject.h" // _Py_make_typevar()
 #include "pycore_unicodeobject.h" // _PyUnicode_FromASCII()
@@ -27,7 +26,7 @@ no_intrinsic1(PyThreadState* tstate, PyObject *unused)
 static PyObject *
 print_expr(PyThreadState* Py_UNUSED(ignored), PyObject *value)
 {
-    PyObject *hook = _PySys_GetRequiredAttr(&_Py_ID(displayhook));
+    PyObject *hook = PySys_GetAttr(&_Py_ID(displayhook));
     if (hook == NULL) {
         return NULL;
     }
index 8394245d373030121371f10ae76dadc98e3b0317..724fda6351128299cedab539b4199e33d325b356 100644 (file)
@@ -1283,7 +1283,7 @@ init_interp_main(PyThreadState *tstate)
     if (is_main_interp) {
         /* Initialize warnings. */
         PyObject *warnoptions;
-        if (_PySys_GetOptionalAttrString("warnoptions", &warnoptions) < 0) {
+        if (PySys_GetOptionalAttrString("warnoptions", &warnoptions) < 0) {
             return _PyStatus_ERR("can't initialize warnings");
         }
         if (warnoptions != NULL && PyList_Check(warnoptions) &&
@@ -1806,7 +1806,7 @@ flush_std_files(void)
     PyObject *file;
     int status = 0;
 
-    if (_PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stdout), &file) < 0) {
         status = -1;
     }
     else if (file != NULL && file != Py_None && !file_is_closed(file)) {
@@ -1819,7 +1819,7 @@ flush_std_files(void)
     }
     Py_XDECREF(file);
 
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
         PyErr_Clear();
         status = -1;
     }
@@ -3046,7 +3046,7 @@ _Py_FatalError_PrintExc(PyThreadState *tstate)
     }
 
     PyObject *ferr;
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &ferr) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &ferr) < 0) {
         _PyErr_Clear(tstate);
     }
     if (ferr == NULL || ferr == Py_None) {
index f67b72aa91f671a09c341808681dac448ea12ad4..8f1c78bf831863d5c36cab21d55007f7faefbc2d 100644 (file)
@@ -114,7 +114,7 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag
     }
 
     PyObject *v;
-    if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(ps1), &v) < 0) {
         PyErr_Print();
         return -1;
     }
@@ -128,7 +128,7 @@ _PyRun_InteractiveLoopObject(FILE *fp, PyObject *filename, PyCompilerFlags *flag
         }
     }
     Py_XDECREF(v);
-    if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &v) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(ps2), &v) < 0) {
         PyErr_Print();
         return -1;
     }
@@ -206,7 +206,7 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
     PyObject *encoding_obj = NULL;
     const char *encoding = NULL;
     if (fp == stdin) {
-        if (_PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
+        if (PySys_GetOptionalAttr(&_Py_ID(stdin), &attr) < 0) {
             PyErr_Clear();
         }
         else if (attr != NULL && attr != Py_None) {
@@ -226,7 +226,7 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
     // Get sys.ps1 (as UTF-8)
     PyObject *ps1_obj = NULL;
     const char *ps1 = "";
-    if (_PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(ps1), &attr) < 0) {
         PyErr_Clear();
     }
     else if (attr != NULL) {
@@ -247,7 +247,7 @@ pyrun_one_parse_ast(FILE *fp, PyObject *filename,
     // Get sys.ps2 (as UTF-8)
     PyObject *ps2_obj = NULL;
     const char *ps2 = "";
-    if (_PySys_GetOptionalAttr(&_Py_ID(ps2), &attr) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(ps2), &attr) < 0) {
         PyErr_Clear();
     }
     else if (attr != NULL) {
@@ -658,7 +658,7 @@ _Py_HandleSystemExitAndKeyboardInterrupt(int *exitcode_p)
     }
 
     PyObject *sys_stderr;
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &sys_stderr) < 0) {
         PyErr_Clear();
     }
     else if (sys_stderr != NULL && sys_stderr != Py_None) {
@@ -722,7 +722,7 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars)
             _PyErr_Clear(tstate);
         }
     }
-    if (_PySys_GetOptionalAttr(&_Py_ID(excepthook), &hook) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(excepthook), &hook) < 0) {
         PyErr_Clear();
     }
     if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None,
@@ -1197,7 +1197,7 @@ void
 PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb)
 {
     PyObject *file;
-    if (_PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(stderr), &file) < 0) {
         PyObject *exc = PyErr_GetRaisedException();
         _PyObject_Dump(value);
         fprintf(stderr, "lost sys.stderr\n");
@@ -1321,7 +1321,7 @@ static void
 flush_io_stream(PyThreadState *tstate, PyObject *name)
 {
     PyObject *f;
-    if (_PySys_GetOptionalAttr(name, &f) < 0) {
+    if (PySys_GetOptionalAttr(name, &f) < 0) {
         PyErr_Clear();
     }
     if (f != NULL) {
index 4ed045e3297bbcc4b21024271886a3322dedea3c..e5ae841d195d4f9b1abb011c36dac381923380be 100644 (file)
@@ -76,12 +76,12 @@ module sys
 
 
 PyObject *
-_PySys_GetRequiredAttr(PyObject *name)
+PySys_GetAttr(PyObject *name)
 {
     if (!PyUnicode_Check(name)) {
         PyErr_Format(PyExc_TypeError,
-                     "attribute name must be string, not '%.200s'",
-                     Py_TYPE(name)->tp_name);
+                     "attribute name must be string, not '%T'",
+                     name);
         return NULL;
     }
     PyThreadState *tstate = _PyThreadState_GET();
@@ -98,7 +98,7 @@ _PySys_GetRequiredAttr(PyObject *name)
 }
 
 PyObject *
-_PySys_GetRequiredAttrString(const char *name)
+PySys_GetAttrString(const char *name)
 {
     PyThreadState *tstate = _PyThreadState_GET();
     PyObject *sysdict = tstate->interp->sysdict;
@@ -114,12 +114,12 @@ _PySys_GetRequiredAttrString(const char *name)
 }
 
 int
-_PySys_GetOptionalAttr(PyObject *name, PyObject **value)
+PySys_GetOptionalAttr(PyObject *name, PyObject **value)
 {
     if (!PyUnicode_Check(name)) {
         PyErr_Format(PyExc_TypeError,
-                     "attribute name must be string, not '%.200s'",
-                     Py_TYPE(name)->tp_name);
+                     "attribute name must be string, not '%T'",
+                     name);
         *value = NULL;
         return -1;
     }
@@ -133,7 +133,7 @@ _PySys_GetOptionalAttr(PyObject *name, PyObject **value)
 }
 
 int
-_PySys_GetOptionalAttrString(const char *name, PyObject **value)
+PySys_GetOptionalAttrString(const char *name, PyObject **value)
 {
     PyThreadState *tstate = _PyThreadState_GET();
     PyObject *sysdict = tstate->interp->sysdict;
@@ -773,7 +773,7 @@ sys_displayhook(PyObject *module, PyObject *o)
     }
     if (PyObject_SetAttr(builtins, _Py_LATIN1_CHR('_'), Py_None) != 0)
         return NULL;
-    outf = _PySys_GetRequiredAttr(&_Py_ID(stdout));
+    outf = PySys_GetAttr(&_Py_ID(stdout));
     if (outf == NULL) {
         return NULL;
     }
@@ -3005,7 +3005,7 @@ static PyObject *
 get_warnoptions(PyThreadState *tstate)
 {
     PyObject *warnoptions;
-    if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
         return NULL;
     }
     if (warnoptions == NULL || !PyList_Check(warnoptions)) {
@@ -3042,7 +3042,7 @@ PySys_ResetWarnOptions(void)
     }
 
     PyObject *warnoptions;
-    if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
         PyErr_Clear();
         return;
     }
@@ -3106,7 +3106,7 @@ PyAPI_FUNC(int)
 PySys_HasWarnOptions(void)
 {
     PyObject *warnoptions;
-    if (_PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(warnoptions), &warnoptions) < 0) {
         PyErr_Clear();
         return 0;
     }
@@ -3120,7 +3120,7 @@ static PyObject *
 get_xoptions(PyThreadState *tstate)
 {
     PyObject *xoptions;
-    if (_PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(_xoptions), &xoptions) < 0) {
         return NULL;
     }
     if (xoptions == NULL || !PyDict_Check(xoptions)) {
@@ -3373,7 +3373,7 @@ sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
 int
 _PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
 {
-    PyObject *flags = _PySys_GetRequiredAttrString("flags");
+    PyObject *flags = PySys_GetAttrString("flags");
     if (flags == NULL) {
         return -1;
     }
@@ -3935,7 +3935,7 @@ _PySys_UpdateConfig(PyThreadState *tstate)
 #undef COPY_WSTR
 
     // sys.flags
-    PyObject *flags = _PySys_GetRequiredAttrString("flags");
+    PyObject *flags = PySys_GetAttrString("flags");
     if (flags == NULL) {
         return -1;
     }
@@ -4251,7 +4251,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
             }
 
             PyObject *sys_path;
-            if (_PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
+            if (PySys_GetOptionalAttr(&_Py_ID(path), &sys_path) < 0) {
                 Py_FatalError("can't get sys.path");
             }
             else if (sys_path != NULL) {
@@ -4347,7 +4347,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
 
     PyObject *exc = _PyErr_GetRaisedException(tstate);
     written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
-    file = _PySys_GetRequiredAttr(key);
+    file = PySys_GetAttr(key);
     if (sys_pyfile_write(buffer, file) != 0) {
         _PyErr_Clear(tstate);
         fputs(buffer, fp);
@@ -4391,7 +4391,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
     PyObject *exc = _PyErr_GetRaisedException(tstate);
     message = PyUnicode_FromFormatV(format, va);
     if (message != NULL) {
-        file = _PySys_GetRequiredAttr(key);
+        file = PySys_GetAttr(key);
         if (sys_pyfile_write_unicode(message, file) != 0) {
             _PyErr_Clear(tstate);
             utf8 = PyUnicode_AsUTF8(message);
index c06cb1a59089e29f3eaf6caa09fa1b424f437db2..4f674eaf55715b024e9e3970994a8b3d2d4717db 100644 (file)
@@ -9,7 +9,6 @@
 #include "pycore_interpframe.h"   // _PyFrame_GetCode()
 #include "pycore_pyerrors.h"      // _PyErr_GetRaisedException()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
-#include "pycore_sysmodule.h"     // _PySys_GetOptionalAttr()
 #include "pycore_traceback.h"     // EXCEPTION_TB_HEADER
 
 #include "frameobject.h"          // PyFrame_New()
@@ -399,7 +398,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
     taillen = strlen(tail);
 
     PyThreadState *tstate = _PyThreadState_GET();
-    if (_PySys_GetOptionalAttr(&_Py_ID(path), &syspath) < 0) {
+    if (PySys_GetOptionalAttr(&_Py_ID(path), &syspath) < 0) {
         PyErr_Clear();
         goto error;
     }
@@ -777,7 +776,7 @@ _PyTraceBack_Print(PyObject *v, const char *header, PyObject *f)
         PyErr_BadInternalCall();
         return -1;
     }
-    if (_PySys_GetOptionalAttrString("tracebacklimit", &limitv) < 0) {
+    if (PySys_GetOptionalAttrString("tracebacklimit", &limitv) < 0) {
         return -1;
     }
     else if (limitv != NULL && PyLong_Check(limitv)) {