branch[len] = '\0'; len = br_end2 - (br_end + 1); strncpy(shortbranch, br_end + 1, len); shortbranch[len] = '\0'; } else { Py_FatalError("bad HeadURL"); return; } svnversion = _Py_svnversion(); if (strcmp(svnversion, "exported") != 0) svn_revision = svnversion; else if (istag) { len = strlen(_patchlevel_revision); strncpy(patchlevel_revision, _patchlevel_revision + 11, len - 13); patchlevel_revision[len - 13] = '\0'; svn_revision = patchlevel_revision; } else svn_revision = ""; svn_initialized = 1;} /* Return svnversion output if available. Else return Revision of patchlevel.h if on branch. Else return empty string */const char*Py_SubversionRevision(){ svnversion_init(); return svn_revision;} const char*Py_SubversionShortBranch(){ svnversion_init(); return shortbranch;} PyObject *_PySys_Init(void){ PyObject *m, *v, *sysdict; PyObject *sysin, *sysout, *syserr; char *s;#ifdef MS_WINDOWS char buf[128];#endif m = Py_InitModule3("sys", sys_methods, sys_doc); if (m == NULL) return NULL; sysdict = PyModule_GetDict(m); { /* XXX: does this work on Win/Win64? (see posix_fstat) */ struct stat sb; if (fstat(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { /* There's nothing more we can do. */ /* Py_FatalError() will core dump, so just exit. */ PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n"); exit(EXIT_FAILURE); } } /* Closing the standard FILE* if sys.std* goes aways causes problems * for embedded Python usages. Closing them when somebody explicitly * invokes .close() might be possible, but the FAQ promises they get * never closed. However, we still need to get write errors when * writing fails (e.g. because stdout is redirected), so we flush the * streams and check for errors before the file objects are deleted. * On OS X, fflush()ing stdin causes an error, so we exempt stdin * from that procedure. */ sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL); sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush); syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush); if (PyErr_Occurred()) return NULL;#ifdef MS_WINDOWS if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) { sprintf(buf, "cp%d", GetConsoleCP()); if (!PyFile_SetEncoding(sysin, buf)) return NULL; } if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) { sprintf(buf, "cp%d", GetConsoleOutputCP()); if (!PyFile_SetEncoding(sysout, buf)) return NULL; } if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) { sprintf(buf, "cp%d", GetConsoleOutputCP()); if (!PyFile_SetEncoding(syserr, buf)) return NULL; }#endif PyDict_SetItemString(sysdict, "stdin", sysin); PyDict_SetItemString(sysdict, "stdout", sysout); PyDict_SetItemString(sysdict, "stderr", syserr); /* Make backup copies for cleanup */ PyDict_SetItemString(sysdict, "__stdin__", sysin); PyDict_SetItemString(sysdict, "__stdout__", sysout); PyDict_SetItemString(sysdict, "__stderr__", syserr); PyDict_SetItemString(sysdict, "__displayhook__", PyDict_GetItemString(sysdict, "displayhook")); PyDict_SetItemString(sysdict, "__excepthook__", PyDict_GetItemString(sysdict, "excepthook")); Py_XDECREF(sysin); Py_XDECREF(sysout); Py_XDECREF(syserr); PyDict_SetItemString(sysdict, "version", v = PyString_FromString(Py_GetVersion())); Py_XDECREF(v); PyDict_SetItemString(sysdict, "hexversion", v = PyInt_FromLong(PY_VERSION_HEX)); Py_XDECREF(v); svnversion_init(); v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! */#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA s = "alpha";#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA s = "beta";#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA s = "candidate";#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL s = "final";#endif #define SET_SYS_FROM_STRING(key, value) \ v = value; \ if (v != NULL) \ PyDict_SetItemString(sysdict, key, v); \ Py_XDECREF(v) SET_SYS_FROM_STRING("version_info", Py_BuildValue("iiisi", PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, s, PY_RELEASE_SERIAL)); SET_SYS_FROM_STRING("api_version", PyInt_FromLong(PYTHON_API_VERSION)); SET_SYS_FROM_STRING("copyright", PyString_FromString(Py_GetCopyright())); SET_SYS_FROM_STRING("platform", PyString_FromString(Py_GetPlatform())); SET_SYS_FROM_STRING("executable", PyString_FromString(Py_GetProgramFullPath())); SET_SYS_FROM_STRING("prefix", PyString_FromString(Py_GetPrefix())); SET_SYS_FROM_STRING("exec_prefix", PyString_FromString(Py_GetExecPrefix())); SET_SYS_FROM_STRING("maxint", PyInt_FromLong(PyInt_GetMax()));#ifdef Py_USING_UNICODE SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax()));#endif SET_SYS_FROM_STRING("builtin_module_names", list_builtin_module_names()); { /* Assumes that longs are at least 2 bytes long. Should be safe! */ unsigned long number = 1; char *value; s = (char *) &number; if (s[0] == 0) value = "big"; else value = "little"; SET_SYS_FROM_STRING("byteorder", PyString_FromString(value)); }#ifdef MS_COREDLL SET_SYS_FROM_STRING("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); SET_SYS_FROM_STRING("winver", PyString_FromString(PyWin_DLLVersionString));#endif#undef SET_SYS_FROM_STRING if (warnoptions == NULL) { warnoptions = PyList_New(0); } else { Py_INCREF(warnoptions); } if (warnoptions != NULL) { PyDict_SetItemString(sysdict, "warnoptions", warnoptions); } if (PyErr_Occurred()) return NULL; return m;} static PyObject *makepathobject(char *path, int delim){ int i, n; char *p; PyObject *v, *w; n = 1; p = path; while ((p = strchr(p, delim)) != NULL) { n++; p++; } v = PyList_New(n); if (v == NULL) return NULL; for (i = 0; ; i++) { p = strchr(path, delim); if (p == NULL) p = strchr(path, '\0'); /* End of string */ w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path)); if (w == NULL) { Py_DECREF(v); return NULL; } PyList_SetItem(v, i, w); if (*p == '\0') break; path = p+1; } return v;} voidPySys_SetPath(char *path){ PyObject *v; if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); if (PySys_SetObject("path", v) != 0) Py_FatalError("can't assign sys.path"); Py_DECREF(v);} static PyObject *makeargvobject(int argc, char **argv){ PyObject *av; if (argc <= 0 || argv == NULL) { /* Ensure at least one (empty) argument is seen */ static char *empty_argv[1] = {""}; argv = empty_argv; argc = 1; } av = PyList_New(argc); if (av != NULL) { int i; for (i = 0; i < argc; i++) {#ifdef __VMS PyObject *v; /* argv[0] is the script pathname if known */ if (i == 0) { char* fn = decc$translate_vms(argv[0]); if ((fn == (char *)0) || fn == (char *)-1) v = PyString_FromString(argv[0]); else v = PyString_FromString( decc$translate_vms(argv[0])); } else v = PyString_FromString(argv[i]);#else PyObject *v = PyString_FromString(argv[i]);#endif if (v == NULL) { Py_DECREF(av); av = NULL; break; } PyList_SetItem(av, i, v); } } return av;} voidPySys_SetArgv(int argc, char **argv){#if defined(HAVE_REALPATH) char fullpath[MAXPATHLEN];#elif defined(MS_WINDOWS) char fullpath[MAX_PATH];#endif PyObject *av = makeargvobject(argc, argv); PyObject *path = PySys_GetObject("path"); if (av == NULL) Py_FatalError("no mem for sys.argv"); if (PySys_SetObject("argv", av) != 0) Py_FatalError("can't assign sys.argv"); if (path != NULL) { char *argv0 = argv[0]; char *p = NULL; Py_ssize_t n = 0; PyObject *a;#ifdef HAVE_READLINK char link[MAXPATHLEN+1]; char argv0copy[2*MAXPATHLEN+1]; int nr = 0; if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) nr = readlink(argv0, link, MAXPATHLEN); if (nr > 0) { /* It's a symlink */ link[nr] = '\0'; if (link[0] == SEP) argv0 = link; /* Link to absolute path */ else if (strchr(link, SEP) == NULL) ; /* Link without path */ else { /* Must join(dirname(argv0), link) */ char *q = strrchr(argv0, SEP); if (q == NULL) argv0 = link; /* argv0 without path */ else { /* Must make a copy */ strcpy(argv0copy, argv0); q = strrchr(argv0copy, SEP); strcpy(q+1, link); argv0 = argv0copy; } } }#endif /* HAVE_READLINK */#if SEP == '\\' /* Special case for MS filename syntax */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { char *q;#ifdef MS_WINDOWS char *ptemp; if (GetFullPathName(argv0, sizeof(fullpath), fullpath, &ptemp)) { argv0 = fullpath; }#endif p = strrchr(argv0, SEP); /* Test for alternate separator */ q = strrchr(p ? p : argv0, '/'); if (q != NULL) p = q; if (p != NULL) { n = p + 1 - argv0; if (n > 1 && p[-1] != ':') n--; /* Drop trailing separator */ } }#else /* All other filename syntaxes */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {#if defined(HAVE_REALPATH) if (realpath(argv0, fullpath)) { argv0 = fullpath; }#endif p = strrchr(argv0, SEP); } if (p != NULL) {#ifndef RISCOS n = p + 1 - argv0;#else /* don't include trailing separator */ n = p - argv0;#endif /* RISCOS */#if SEP == '/' /* Special case for Unix filename syntax */ if (n > 1) n--; /* Drop trailing separator */#endif /* Unix */ }#endif /* All others */ a = PyString_FromStringAndSize(argv0, n); if (a == NULL) Py_FatalError("no mem for sys.path insertion"); if (PyList_Insert(path, 0, a) < 0) Py_FatalError("sys.path.insert(0) failed"); Py_DECREF(a); } Py_DECREF(av);} /* APIs to write to sys.stdout or sys.stderr using a printf-like interface. Adapted from code submitted by Just van Rossum. PySys_WriteStdout(format, ...) PySys_WriteStderr(format, ...) The first function writes to sys.stdout; the second to sys.stderr. When there is a problem, they write to the real (C level) stdout or stderr; no exceptions are raised. Both take a printf-style format string as their first argument followed by a variable length argument list determined by the format string. *** WARNING *** The format should limit the total size of the formatted output string to 1000 bytes. In particular, this means that no unrestricted "%s" formats should occur; these should be limited using "%.<N>s where <N> is a decimal number calculated so that <N> plus the maximum size of other formatted text does not exceed 1000 bytes. Also watch out for "%f", which can print hundreds of digits for very large numbers. */ static voidmywrite(char *name, FILE *fp, const char *format, va_list va){ PyObject *file; PyObject *error_type, *error_value, *error_traceback; PyErr_Fetch(&error_type, &error_value, &error_traceback); file = PySys_GetObject(name); if (file == NULL || PyFile_AsFile(file) == fp) vfprintf(fp, format, va); else { char buffer[1001]; const int written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (PyFile_WriteString(buffer, file) != 0) { PyErr_Clear(); fputs(buffer, fp); } if (written < 0 || (size_t)written >= sizeof(buffer)) { const char *truncated = "... truncated"; if (PyFile_WriteString(truncated, file) != 0) { PyErr_Clear(); fputs(truncated, fp); } } } PyErr_Restore(error_type, error_value, error_traceback);} voidPySys_WriteStdout(const char *format, ...){ va_list va; va_start(va, format); mywrite("stdout", stdout, format, va); va_end(va);} voidPySys_WriteStderr(const char *format, ...){ va_list va; va_start(va, format); mywrite("stderr", stderr, format, va); va_end(va);}Lines 1001–1468 of 1468. Previous lines
branch[len] = '\0'; len = br_end2 - (br_end + 1); strncpy(shortbranch, br_end + 1, len); shortbranch[len] = '\0'; } else { Py_FatalError("bad HeadURL"); return; } svnversion = _Py_svnversion(); if (strcmp(svnversion, "exported") != 0) svn_revision = svnversion; else if (istag) { len = strlen(_patchlevel_revision); strncpy(patchlevel_revision, _patchlevel_revision + 11, len - 13); patchlevel_revision[len - 13] = '\0'; svn_revision = patchlevel_revision; } else svn_revision = ""; svn_initialized = 1; } /* Return svnversion output if available. Else return Revision of patchlevel.h if on branch. Else return empty string */ const char* Py_SubversionRevision() { svnversion_init(); return svn_revision; } const char* Py_SubversionShortBranch() { svnversion_init(); return shortbranch; } PyObject * _PySys_Init(void) { PyObject *m, *v, *sysdict; PyObject *sysin, *sysout, *syserr; char *s; #ifdef MS_WINDOWS char buf[128]; #endif m = Py_InitModule3("sys", sys_methods, sys_doc); if (m == NULL) return NULL; sysdict = PyModule_GetDict(m); { /* XXX: does this work on Win/Win64? (see posix_fstat) */ struct stat sb; if (fstat(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { /* There's nothing more we can do. */ /* Py_FatalError() will core dump, so just exit. */ PySys_WriteStderr("Python error: <stdin> is a directory, cannot continue\n"); exit(EXIT_FAILURE); } } /* Closing the standard FILE* if sys.std* goes aways causes problems * for embedded Python usages. Closing them when somebody explicitly * invokes .close() might be possible, but the FAQ promises they get * never closed. However, we still need to get write errors when * writing fails (e.g. because stdout is redirected), so we flush the * streams and check for errors before the file objects are deleted. * On OS X, fflush()ing stdin causes an error, so we exempt stdin * from that procedure. */ sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL); sysout = PyFile_FromFile(stdout, "<stdout>", "w", _check_and_flush); syserr = PyFile_FromFile(stderr, "<stderr>", "w", _check_and_flush); if (PyErr_Occurred()) return NULL; #ifdef MS_WINDOWS if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) { sprintf(buf, "cp%d", GetConsoleCP()); if (!PyFile_SetEncoding(sysin, buf)) return NULL; } if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) { sprintf(buf, "cp%d", GetConsoleOutputCP()); if (!PyFile_SetEncoding(sysout, buf)) return NULL; } if(isatty(_fileno(stderr)) && PyFile_Check(syserr)) { sprintf(buf, "cp%d", GetConsoleOutputCP()); if (!PyFile_SetEncoding(syserr, buf)) return NULL; } #endif PyDict_SetItemString(sysdict, "stdin", sysin); PyDict_SetItemString(sysdict, "stdout", sysout); PyDict_SetItemString(sysdict, "stderr", syserr); /* Make backup copies for cleanup */ PyDict_SetItemString(sysdict, "__stdin__", sysin); PyDict_SetItemString(sysdict, "__stdout__", sysout); PyDict_SetItemString(sysdict, "__stderr__", syserr); PyDict_SetItemString(sysdict, "__displayhook__", PyDict_GetItemString(sysdict, "displayhook")); PyDict_SetItemString(sysdict, "__excepthook__", PyDict_GetItemString(sysdict, "excepthook")); Py_XDECREF(sysin); Py_XDECREF(sysout); Py_XDECREF(syserr); PyDict_SetItemString(sysdict, "version", v = PyString_FromString(Py_GetVersion())); Py_XDECREF(v); PyDict_SetItemString(sysdict, "hexversion", v = PyInt_FromLong(PY_VERSION_HEX)); Py_XDECREF(v); svnversion_init(); v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! */ #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA s = "alpha"; #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA s = "beta"; #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA s = "candidate"; #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL s = "final"; #endif #define SET_SYS_FROM_STRING(key, value) \ v = value; \ if (v != NULL) \ PyDict_SetItemString(sysdict, key, v); \ Py_XDECREF(v) SET_SYS_FROM_STRING("version_info", Py_BuildValue("iiisi", PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION, s, PY_RELEASE_SERIAL)); SET_SYS_FROM_STRING("api_version", PyInt_FromLong(PYTHON_API_VERSION)); SET_SYS_FROM_STRING("copyright", PyString_FromString(Py_GetCopyright())); SET_SYS_FROM_STRING("platform", PyString_FromString(Py_GetPlatform())); SET_SYS_FROM_STRING("executable", PyString_FromString(Py_GetProgramFullPath())); SET_SYS_FROM_STRING("prefix", PyString_FromString(Py_GetPrefix())); SET_SYS_FROM_STRING("exec_prefix", PyString_FromString(Py_GetExecPrefix())); SET_SYS_FROM_STRING("maxint", PyInt_FromLong(PyInt_GetMax())); #ifdef Py_USING_UNICODE SET_SYS_FROM_STRING("maxunicode", PyInt_FromLong(PyUnicode_GetMax())); #endif SET_SYS_FROM_STRING("builtin_module_names", list_builtin_module_names()); { /* Assumes that longs are at least 2 bytes long. Should be safe! */ unsigned long number = 1; char *value; s = (char *) &number; if (s[0] == 0) value = "big"; else value = "little"; SET_SYS_FROM_STRING("byteorder", PyString_FromString(value)); } #ifdef MS_COREDLL SET_SYS_FROM_STRING("dllhandle", PyLong_FromVoidPtr(PyWin_DLLhModule)); SET_SYS_FROM_STRING("winver", PyString_FromString(PyWin_DLLVersionString)); #endif #undef SET_SYS_FROM_STRING if (warnoptions == NULL) { warnoptions = PyList_New(0); } else { Py_INCREF(warnoptions); } if (warnoptions != NULL) { PyDict_SetItemString(sysdict, "warnoptions", warnoptions); } if (PyErr_Occurred()) return NULL; return m; } static PyObject * makepathobject(char *path, int delim) { int i, n; char *p; PyObject *v, *w; n = 1; p = path; while ((p = strchr(p, delim)) != NULL) { n++; p++; } v = PyList_New(n); if (v == NULL) return NULL; for (i = 0; ; i++) { p = strchr(path, delim); if (p == NULL) p = strchr(path, '\0'); /* End of string */ w = PyString_FromStringAndSize(path, (Py_ssize_t) (p - path)); if (w == NULL) { Py_DECREF(v); return NULL; } PyList_SetItem(v, i, w); if (*p == '\0') break; path = p+1; } return v; } void PySys_SetPath(char *path) { PyObject *v; if ((v = makepathobject(path, DELIM)) == NULL) Py_FatalError("can't create sys.path"); if (PySys_SetObject("path", v) != 0) Py_FatalError("can't assign sys.path"); Py_DECREF(v); } static PyObject * makeargvobject(int argc, char **argv) { PyObject *av; if (argc <= 0 || argv == NULL) { /* Ensure at least one (empty) argument is seen */ static char *empty_argv[1] = {""}; argv = empty_argv; argc = 1; } av = PyList_New(argc); if (av != NULL) { int i; for (i = 0; i < argc; i++) { #ifdef __VMS PyObject *v; /* argv[0] is the script pathname if known */ if (i == 0) { char* fn = decc$translate_vms(argv[0]); if ((fn == (char *)0) || fn == (char *)-1) v = PyString_FromString(argv[0]); else v = PyString_FromString( decc$translate_vms(argv[0])); } else v = PyString_FromString(argv[i]); #else PyObject *v = PyString_FromString(argv[i]); #endif if (v == NULL) { Py_DECREF(av); av = NULL; break; } PyList_SetItem(av, i, v); } } return av; } void PySys_SetArgv(int argc, char **argv) { #if defined(HAVE_REALPATH) char fullpath[MAXPATHLEN]; #elif defined(MS_WINDOWS) char fullpath[MAX_PATH]; #endif PyObject *av = makeargvobject(argc, argv); PyObject *path = PySys_GetObject("path"); if (av == NULL) Py_FatalError("no mem for sys.argv"); if (PySys_SetObject("argv", av) != 0) Py_FatalError("can't assign sys.argv"); if (path != NULL) { char *argv0 = argv[0]; char *p = NULL; Py_ssize_t n = 0; PyObject *a; #ifdef HAVE_READLINK char link[MAXPATHLEN+1]; char argv0copy[2*MAXPATHLEN+1]; int nr = 0; if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) nr = readlink(argv0, link, MAXPATHLEN); if (nr > 0) { /* It's a symlink */ link[nr] = '\0'; if (link[0] == SEP) argv0 = link; /* Link to absolute path */ else if (strchr(link, SEP) == NULL) ; /* Link without path */ else { /* Must join(dirname(argv0), link) */ char *q = strrchr(argv0, SEP); if (q == NULL) argv0 = link; /* argv0 without path */ else { /* Must make a copy */ strcpy(argv0copy, argv0); q = strrchr(argv0copy, SEP); strcpy(q+1, link); argv0 = argv0copy; } } } #endif /* HAVE_READLINK */ #if SEP == '\\' /* Special case for MS filename syntax */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { char *q; #ifdef MS_WINDOWS char *ptemp; if (GetFullPathName(argv0, sizeof(fullpath), fullpath, &ptemp)) { argv0 = fullpath; } #endif p = strrchr(argv0, SEP); /* Test for alternate separator */ q = strrchr(p ? p : argv0, '/'); if (q != NULL) p = q; if (p != NULL) { n = p + 1 - argv0; if (n > 1 && p[-1] != ':') n--; /* Drop trailing separator */ } } #else /* All other filename syntaxes */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { #if defined(HAVE_REALPATH) if (realpath(argv0, fullpath)) { argv0 = fullpath; } #endif p = strrchr(argv0, SEP); } if (p != NULL) { #ifndef RISCOS n = p + 1 - argv0; #else /* don't include trailing separator */ n = p - argv0; #endif /* RISCOS */ #if SEP == '/' /* Special case for Unix filename syntax */ if (n > 1) n--; /* Drop trailing separator */ #endif /* Unix */ } #endif /* All others */ a = PyString_FromStringAndSize(argv0, n); if (a == NULL) Py_FatalError("no mem for sys.path insertion"); if (PyList_Insert(path, 0, a) < 0) Py_FatalError("sys.path.insert(0) failed"); Py_DECREF(a); } Py_DECREF(av); } /* APIs to write to sys.stdout or sys.stderr using a printf-like interface. Adapted from code submitted by Just van Rossum. PySys_WriteStdout(format, ...) PySys_WriteStderr(format, ...) The first function writes to sys.stdout; the second to sys.stderr. When there is a problem, they write to the real (C level) stdout or stderr; no exceptions are raised. Both take a printf-style format string as their first argument followed by a variable length argument list determined by the format string. *** WARNING *** The format should limit the total size of the formatted output string to 1000 bytes. In particular, this means that no unrestricted "%s" formats should occur; these should be limited using "%.<N>s where <N> is a decimal number calculated so that <N> plus the maximum size of other formatted text does not exceed 1000 bytes. Also watch out for "%f", which can print hundreds of digits for very large numbers. */ static void mywrite(char *name, FILE *fp, const char *format, va_list va) { PyObject *file; PyObject *error_type, *error_value, *error_traceback; PyErr_Fetch(&error_type, &error_value, &error_traceback); file = PySys_GetObject(name); if (file == NULL || PyFile_AsFile(file) == fp) vfprintf(fp, format, va); else { char buffer[1001]; const int written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (PyFile_WriteString(buffer, file) != 0) { PyErr_Clear(); fputs(buffer, fp); } if (written < 0 || (size_t)written >= sizeof(buffer)) { const char *truncated = "... truncated"; if (PyFile_WriteString(truncated, file) != 0) { PyErr_Clear(); fputs(truncated, fp); } } } PyErr_Restore(error_type, error_value, error_traceback); } void PySys_WriteStdout(const char *format, ...) { va_list va; va_start(va, format); mywrite("stdout", stdout, format, va); va_end(va); } void PySys_WriteStderr(const char *format, ...) { va_list va; va_start(va, format); mywrite("stderr", stderr, format, va); va_end(va); }