mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Begin incorporating Python unit tests into build
We now build a separate APE binary for each test so they can run in parallel. We've got 148 tests running fast and stable so far.
This commit is contained in:
parent
51904e2687
commit
b5f743cdc3
121 changed files with 4995 additions and 4767 deletions
3
third_party/python/Python/_warnings.c
vendored
3
third_party/python/Python/_warnings.c
vendored
|
@ -23,8 +23,11 @@
|
|||
#include "third_party/python/Include/traceback.h"
|
||||
#include "third_party/python/Include/tupleobject.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_warnings");
|
||||
|
||||
#define MODULE_NAME "_warnings"
|
||||
|
||||
PyDoc_STRVAR(warnings__doc__,
|
||||
|
|
46
third_party/python/Python/atexit.c
vendored
Normal file
46
third_party/python/Python/atexit.c
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
#define NEXITFUNCS 32
|
||||
|
||||
static void (*_Py_exitfunc)(void);
|
||||
static void (*exitfuncs[NEXITFUNCS])(void);
|
||||
static int nexitfuncs = 0;
|
||||
|
||||
void
|
||||
_Py_PyAtExit(void (*func)(void))
|
||||
{
|
||||
_Py_exitfunc = func;
|
||||
}
|
||||
|
||||
void
|
||||
_Py_CallExitFuncs(void)
|
||||
{
|
||||
if (!_Py_exitfunc) return;
|
||||
_Py_exitfunc();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
int Py_AtExit(void (*func)(void))
|
||||
{
|
||||
if (nexitfuncs >= NEXITFUNCS)
|
||||
return -1;
|
||||
exitfuncs[nexitfuncs++] = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_Py_CallLlExitFuncs(void)
|
||||
{
|
||||
while (nexitfuncs > 0)
|
||||
(*exitfuncs[--nexitfuncs])();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
}
|
2
third_party/python/Python/bltinmodule.c
vendored
2
third_party/python/Python/bltinmodule.c
vendored
|
@ -208,7 +208,7 @@ PYTHON_PROVIDE("builtins.zip");
|
|||
Don't forget to modify PyUnicode_DecodeFSDefault() if you touch any of the
|
||||
values for Py_FileSystemDefaultEncoding!
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__) || defined(__COSMOPOLITAN__)
|
||||
const char *Py_FileSystemDefaultEncoding = "utf-8";
|
||||
int Py_HasFileSystemDefaultEncoding = 1;
|
||||
#elif defined(MS_WINDOWS)
|
||||
|
|
4
third_party/python/Python/errors.c
vendored
4
third_party/python/Python/errors.c
vendored
|
@ -1034,16 +1034,12 @@ done:
|
|||
PyErr_Clear(); /* Just in case */
|
||||
}
|
||||
|
||||
extern PyObject *PyModule_GetWarningsModule(void);
|
||||
|
||||
|
||||
void
|
||||
PyErr_SyntaxLocation(const char *filename, int lineno)
|
||||
{
|
||||
PyErr_SyntaxLocationEx(filename, lineno, -1);
|
||||
}
|
||||
|
||||
|
||||
/* Set file and line information for the current exception.
|
||||
If the exception is not a SyntaxError, also sets additional attributes
|
||||
to make printing of exceptions believe it is a syntax error. */
|
||||
|
|
169
third_party/python/Python/fatality.c
vendored
Normal file
169
third_party/python/Python/fatality.c
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/traceback.h"
|
||||
/* clang-format off */
|
||||
|
||||
_Py_IDENTIFIER(flush);
|
||||
_Py_IDENTIFIER(stdout);
|
||||
_Py_IDENTIFIER(stderr);
|
||||
|
||||
/* Import the site module (not into __main__ though) */
|
||||
|
||||
static void
|
||||
_Py_FatalError_DumpTracebacks(int fd)
|
||||
{
|
||||
fputc('\n', stderr);
|
||||
fflush(stderr);
|
||||
/* display the current Python stack */
|
||||
_Py_DumpTracebackThreads(fd, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Print the current exception (if an exception is set) with its traceback,
|
||||
or display the current Python stack.
|
||||
|
||||
Don't call PyErr_PrintEx() and the except hook, because Py_FatalError() is
|
||||
called on catastrophic cases.
|
||||
|
||||
Return 1 if the traceback was displayed, 0 otherwise. */
|
||||
|
||||
static int
|
||||
_Py_FatalError_PrintExc(int fd)
|
||||
{
|
||||
PyObject *ferr, *res;
|
||||
PyObject *exception, *v, *tb;
|
||||
int has_tb;
|
||||
|
||||
PyErr_Fetch(&exception, &v, &tb);
|
||||
if (exception == NULL) {
|
||||
/* No current exception */
|
||||
return 0;
|
||||
}
|
||||
|
||||
ferr = _PySys_GetObjectId(&PyId_stderr);
|
||||
if (ferr == NULL || ferr == Py_None) {
|
||||
/* sys.stderr is not set yet or set to None,
|
||||
no need to try to display the exception */
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_NormalizeException(&exception, &v, &tb);
|
||||
if (tb == NULL) {
|
||||
tb = Py_None;
|
||||
Py_INCREF(tb);
|
||||
}
|
||||
PyException_SetTraceback(v, tb);
|
||||
if (exception == NULL) {
|
||||
/* PyErr_NormalizeException() failed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
has_tb = (tb != Py_None);
|
||||
PyErr_Display(exception, v, tb);
|
||||
Py_XDECREF(exception);
|
||||
Py_XDECREF(v);
|
||||
Py_XDECREF(tb);
|
||||
|
||||
/* sys.stderr may be buffered: call sys.stderr.flush() */
|
||||
res = _PyObject_CallMethodId(ferr, &PyId_flush, NULL);
|
||||
if (res == NULL)
|
||||
PyErr_Clear();
|
||||
else
|
||||
Py_DECREF(res);
|
||||
|
||||
return has_tb;
|
||||
}
|
||||
|
||||
/* Print fatal error message and abort */
|
||||
|
||||
void
|
||||
Py_FatalError(const char *msg)
|
||||
{
|
||||
const int fd = fileno(stderr);
|
||||
static int reentrant = 0;
|
||||
#ifdef MS_WINDOWS
|
||||
size_t len;
|
||||
WCHAR* buffer;
|
||||
size_t i;
|
||||
#endif
|
||||
|
||||
if (reentrant) {
|
||||
/* Py_FatalError() caused a second fatal error.
|
||||
Example: _Py_FlushStdFiles() raises a recursion error. */
|
||||
goto exit;
|
||||
}
|
||||
reentrant = 1;
|
||||
|
||||
fprintf(stderr, "Fatal Python error: %s\n", msg);
|
||||
fflush(stderr); /* it helps in Windows debug build */
|
||||
|
||||
/* Check if the current thread has a Python thread state
|
||||
and holds the GIL */
|
||||
PyThreadState *tss_tstate = NULL; // PyGILState_GetThisThreadState();
|
||||
if (tss_tstate != NULL) {
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
if (tss_tstate != tstate) {
|
||||
/* The Python thread does not hold the GIL */
|
||||
tss_tstate = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Py_FatalError() has been called from a C thread
|
||||
which has no Python thread state. */
|
||||
}
|
||||
int has_tstate_and_gil = (tss_tstate != NULL);
|
||||
|
||||
if (has_tstate_and_gil) {
|
||||
/* If an exception is set, print the exception with its traceback */
|
||||
if (!_Py_FatalError_PrintExc(fd)) {
|
||||
/* No exception is set, or an exception is set without traceback */
|
||||
_Py_FatalError_DumpTracebacks(fd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_Py_FatalError_DumpTracebacks(fd);
|
||||
}
|
||||
|
||||
/* The main purpose of faulthandler is to display the traceback. We already
|
||||
* did our best to display it. So faulthandler can now be disabled.
|
||||
* (Don't trigger it on abort().) */
|
||||
_PyFaulthandler_Fini();
|
||||
|
||||
/* Check if the current Python thread hold the GIL */
|
||||
if (has_tstate_and_gil) {
|
||||
/* Flush sys.stdout and sys.stderr */
|
||||
_Py_FlushStdFiles();
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
len = strlen(msg);
|
||||
|
||||
/* Convert the message to wchar_t. This uses a simple one-to-one
|
||||
conversion, assuming that the this error message actually uses ASCII
|
||||
only. If this ceases to be true, we will have to convert. */
|
||||
buffer = alloca( (len+1) * (sizeof *buffer));
|
||||
for( i=0; i<=len; ++i)
|
||||
buffer[i] = msg[i];
|
||||
OutputDebugStringW(L"Fatal Python error: ");
|
||||
OutputDebugStringW(buffer);
|
||||
OutputDebugStringW(L"\n");
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
exit:
|
||||
#if defined(MS_WINDOWS) && defined(_DEBUG)
|
||||
DebugBreak();
|
||||
#endif
|
||||
if (weaken(__die)) weaken(__die)();
|
||||
abort();
|
||||
}
|
28
third_party/python/Python/fdisinteractive.c
vendored
Normal file
28
third_party/python/Python/fdisinteractive.c
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
/*
|
||||
* The file descriptor fd is considered ``interactive'' if either
|
||||
* a) isatty(fd) is TRUE, or
|
||||
* b) the -i flag was given, and the filename associated with
|
||||
* the descriptor is NULL or "<stdin>" or "???".
|
||||
*/
|
||||
int
|
||||
Py_FdIsInteractive(FILE *fp, const char *filename)
|
||||
{
|
||||
if (isatty((int)fileno(fp)))
|
||||
return 1;
|
||||
if (!Py_InteractiveFlag)
|
||||
return 0;
|
||||
return (filename == NULL) ||
|
||||
(strcmp(filename, "<stdin>") == 0) ||
|
||||
(strcmp(filename, "???") == 0);
|
||||
}
|
237
third_party/python/Python/finalize.c
vendored
Normal file
237
third_party/python/Python/finalize.c
vendored
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/fileobject.h"
|
||||
#include "third_party/python/Include/grammar.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Include/pystate.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Undo the effect of Py_Initialize().
|
||||
|
||||
Beware: if multiple interpreter and/or thread states exist, these
|
||||
are not wiped out; only the current thread and interpreter state
|
||||
are deleted. But since everything else is deleted, those other
|
||||
interpreter and thread states should no longer be used.
|
||||
|
||||
(XXX We should do better, e.g. wipe out all interpreters and
|
||||
threads.)
|
||||
|
||||
Locking: as above.
|
||||
*/
|
||||
|
||||
int
|
||||
Py_FinalizeEx(void)
|
||||
{
|
||||
PyInterpreterState *interp;
|
||||
PyThreadState *tstate;
|
||||
int status = 0;
|
||||
|
||||
if (!_Py_initialized)
|
||||
return status;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
wait_for_thread_shutdown();
|
||||
#endif
|
||||
|
||||
/* The interpreter is still entirely intact at this point, and the
|
||||
* exit funcs may be relying on that. In particular, if some thread
|
||||
* or exit func is still waiting to do an import, the import machinery
|
||||
* expects Py_IsInitialized() to return true. So don't say the
|
||||
* interpreter is uninitialized until after the exit funcs have run.
|
||||
* Note that Threading.py uses an exit func to do a join on all the
|
||||
* threads created thru it, so this also protects pending imports in
|
||||
* the threads created via Threading.
|
||||
*/
|
||||
_Py_CallExitFuncs();
|
||||
|
||||
/* Get current thread state and interpreter pointer */
|
||||
tstate = PyThreadState_GET();
|
||||
interp = tstate->interp;
|
||||
|
||||
/* Remaining threads (e.g. daemon threads) will automatically exit
|
||||
after taking the GIL (in PyEval_RestoreThread()). */
|
||||
_Py_Finalizing = tstate;
|
||||
_Py_initialized = 0;
|
||||
|
||||
/* Flush sys.stdout and sys.stderr */
|
||||
if (_Py_FlushStdFiles() < 0) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
/* Disable signal handling */
|
||||
PyOS_FiniInterrupts();
|
||||
|
||||
/* Collect garbage. This may call finalizers; it's nice to call these
|
||||
* before all modules are destroyed.
|
||||
* XXX If a __del__ or weakref callback is triggered here, and tries to
|
||||
* XXX import a module, bad things can happen, because Python no
|
||||
* XXX longer believes it's initialized.
|
||||
* XXX Fatal Python error: Interpreter not initialized (version mismatch?)
|
||||
* XXX is easy to provoke that way. I've also seen, e.g.,
|
||||
* XXX Exception exceptions.ImportError: 'No module named sha'
|
||||
* XXX in <function callback at 0x008F5718> ignored
|
||||
* XXX but I'm unclear on exactly how that one happens. In any case,
|
||||
* XXX I haven't seen a real-life report of either of these.
|
||||
*/
|
||||
_PyGC_CollectIfEnabled();
|
||||
#ifdef COUNT_ALLOCS
|
||||
/* With COUNT_ALLOCS, it helps to run GC multiple times:
|
||||
each collection might release some types from the type
|
||||
list, so they become garbage. */
|
||||
while (_PyGC_CollectIfEnabled() > 0)
|
||||
/* nothing */;
|
||||
#endif
|
||||
/* Destroy all modules */
|
||||
PyImport_Cleanup();
|
||||
|
||||
/* Flush sys.stdout and sys.stderr (again, in case more was printed) */
|
||||
if (_Py_FlushStdFiles() < 0) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
/* Collect final garbage. This disposes of cycles created by
|
||||
* class definitions, for example.
|
||||
* XXX This is disabled because it caused too many problems. If
|
||||
* XXX a __del__ or weakref callback triggers here, Python code has
|
||||
* XXX a hard time running, because even the sys module has been
|
||||
* XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc).
|
||||
* XXX One symptom is a sequence of information-free messages
|
||||
* XXX coming from threads (if a __del__ or callback is invoked,
|
||||
* XXX other threads can execute too, and any exception they encounter
|
||||
* XXX triggers a comedy of errors as subsystem after subsystem
|
||||
* XXX fails to find what it *expects* to find in sys to help report
|
||||
* XXX the exception and consequent unexpected failures). I've also
|
||||
* XXX seen segfaults then, after adding print statements to the
|
||||
* XXX Python code getting called.
|
||||
*/
|
||||
#if 0
|
||||
_PyGC_CollectIfEnabled();
|
||||
#endif
|
||||
|
||||
#ifdef MODE_DBG
|
||||
/* Disable tracemalloc after all Python objects have been destroyed,
|
||||
so it is possible to use tracemalloc in objects destructor. */
|
||||
_PyTraceMalloc_Fini();
|
||||
#endif
|
||||
/* Destroy the database used by _PyImport_{Fixup,Find}Extension */
|
||||
_PyImport_Fini();
|
||||
|
||||
/* Cleanup typeobject.c's internal caches. */
|
||||
_PyType_Fini();
|
||||
|
||||
/* unload faulthandler module */
|
||||
_PyFaulthandler_Fini();
|
||||
|
||||
/* Debugging stuff */
|
||||
#ifdef COUNT_ALLOCS
|
||||
dump_counts(stderr);
|
||||
#endif
|
||||
/* dump hash stats */
|
||||
_PyHash_Fini();
|
||||
|
||||
_PY_DEBUG_PRINT_TOTAL_REFS();
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
/* Display all objects still alive -- this can invoke arbitrary
|
||||
* __repr__ overrides, so requires a mostly-intact interpreter.
|
||||
* Alas, a lot of stuff may still be alive now that will be cleaned
|
||||
* up later.
|
||||
*/
|
||||
if (Py_GETENV("PYTHONDUMPREFS"))
|
||||
_Py_PrintReferences(stderr);
|
||||
#endif /* Py_TRACE_REFS */
|
||||
|
||||
/* Clear interpreter state and all thread states. */
|
||||
PyInterpreterState_Clear(interp);
|
||||
|
||||
/* Now we decref the exception classes. After this point nothing
|
||||
can raise an exception. That's okay, because each Fini() method
|
||||
below has been checked to make sure no exceptions are ever
|
||||
raised.
|
||||
*/
|
||||
|
||||
_PyExc_Fini();
|
||||
|
||||
/* Sundry finalizers */
|
||||
PyMethod_Fini();
|
||||
PyFrame_Fini();
|
||||
PyCFunction_Fini();
|
||||
PyTuple_Fini();
|
||||
PyList_Fini();
|
||||
PySet_Fini();
|
||||
PyBytes_Fini();
|
||||
PyByteArray_Fini();
|
||||
PyLong_Fini();
|
||||
PyFloat_Fini();
|
||||
PyDict_Fini();
|
||||
PySlice_Fini();
|
||||
_PyGC_Fini();
|
||||
_PyRandom_Fini();
|
||||
_PyArg_Fini();
|
||||
PyAsyncGen_Fini();
|
||||
|
||||
/* Cleanup Unicode implementation */
|
||||
_PyUnicode_Fini();
|
||||
|
||||
/* reset file system default encoding */
|
||||
if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) {
|
||||
PyMem_RawFree((char*)Py_FileSystemDefaultEncoding);
|
||||
Py_FileSystemDefaultEncoding = NULL;
|
||||
}
|
||||
|
||||
/* XXX Still allocated:
|
||||
- various static ad-hoc pointers to interned strings
|
||||
- int and float free list blocks
|
||||
- whatever various modules and libraries allocate
|
||||
*/
|
||||
|
||||
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
|
||||
|
||||
/* Cleanup auto-thread-state */
|
||||
#ifdef WITH_THREAD
|
||||
_PyGILState_Fini();
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
/* Delete current thread. After this, many C API calls become crashy. */
|
||||
PyThreadState_Swap(NULL);
|
||||
|
||||
PyInterpreterState_Delete(interp);
|
||||
|
||||
#ifdef Py_TRACE_REFS
|
||||
/* Display addresses (& refcnts) of all objects still alive.
|
||||
* An address can be used to find the repr of the object, printed
|
||||
* above by _Py_PrintReferences.
|
||||
*/
|
||||
if (Py_GETENV("PYTHONDUMPREFS"))
|
||||
_Py_PrintReferenceAddresses(stderr);
|
||||
#endif /* Py_TRACE_REFS */
|
||||
#ifdef WITH_PYMALLOC
|
||||
if (_PyMem_PymallocEnabled()) {
|
||||
char *opt = Py_GETENV("PYTHONMALLOCSTATS");
|
||||
if (opt != NULL && *opt != '\0')
|
||||
_PyObject_DebugMallocStats(stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
_Py_CallLlExitFuncs();
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
Py_Finalize(void)
|
||||
{
|
||||
Py_FinalizeEx();
|
||||
}
|
34
third_party/python/Python/flags.c
vendored
Normal file
34
third_party/python/Python/flags.c
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Global configuration variable declarations are in pydebug.h */
|
||||
/* XXX (ncoghlan): move those declarations to pylifecycle.h? */
|
||||
int Py_DebugFlag; /* Needed by parser.c */
|
||||
int Py_VerboseFlag; /* Needed by import.c */
|
||||
int Py_QuietFlag; /* Needed by sysmodule.c */
|
||||
int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
|
||||
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_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
|
||||
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; /* Uses mbcs instead of utf-8 */
|
||||
int Py_LegacyWindowsStdioFlag; /* Uses FileIO instead of WindowsConsoleIO */
|
||||
#endif
|
||||
|
||||
PyThreadState *_Py_Finalizing;
|
60
third_party/python/Python/flushstdfiles.c
vendored
Normal file
60
third_party/python/Python/flushstdfiles.c
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
/* clang-format off */
|
||||
|
||||
_Py_IDENTIFIER(flush);
|
||||
_Py_IDENTIFIER(stdout);
|
||||
_Py_IDENTIFIER(stderr);
|
||||
|
||||
static int
|
||||
file_is_closed(PyObject *fobj)
|
||||
{
|
||||
int r;
|
||||
PyObject *tmp = PyObject_GetAttrString(fobj, "closed");
|
||||
if (tmp == NULL) {
|
||||
PyErr_Clear();
|
||||
return 0;
|
||||
}
|
||||
r = PyObject_IsTrue(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (r < 0)
|
||||
PyErr_Clear();
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
int
|
||||
_Py_FlushStdFiles(void)
|
||||
{
|
||||
PyObject *fout = _PySys_GetObjectId(&PyId_stdout);
|
||||
PyObject *ferr = _PySys_GetObjectId(&PyId_stderr);
|
||||
PyObject *tmp;
|
||||
int status = 0;
|
||||
if (fout != NULL && fout != Py_None && !file_is_closed(fout)) {
|
||||
tmp = _PyObject_CallMethodId(fout, &PyId_flush, NULL);
|
||||
if (tmp == NULL) {
|
||||
PyErr_WriteUnraisable(fout);
|
||||
status = -1;
|
||||
}
|
||||
else
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) {
|
||||
tmp = _PyObject_CallMethodId(ferr, &PyId_flush, NULL);
|
||||
if (tmp == NULL) {
|
||||
PyErr_Clear();
|
||||
status = -1;
|
||||
}
|
||||
else
|
||||
Py_DECREF(tmp);
|
||||
}
|
||||
return status;
|
||||
}
|
76
third_party/python/Python/getsig.c
vendored
Normal file
76
third_party/python/Python/getsig.c
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/pyconfig.h"
|
||||
/* clang-format off */
|
||||
|
||||
PyOS_sighandler_t
|
||||
PyOS_getsig(int sig)
|
||||
{
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction context;
|
||||
if (sigaction(sig, NULL, &context) == -1)
|
||||
return SIG_ERR;
|
||||
return context.sa_handler;
|
||||
#else
|
||||
PyOS_sighandler_t handler;
|
||||
/* Special signal handling for the secure CRT in Visual Studio 2005 */
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
switch (sig) {
|
||||
/* Only these signals are valid */
|
||||
case SIGINT:
|
||||
case SIGILL:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGTERM:
|
||||
case SIGBREAK:
|
||||
case SIGABRT:
|
||||
break;
|
||||
/* Don't call signal() with other values or it will assert */
|
||||
default:
|
||||
return SIG_ERR;
|
||||
}
|
||||
#endif /* _MSC_VER && _MSC_VER >= 1400 */
|
||||
handler = signal(sig, SIG_IGN);
|
||||
if (handler != SIG_ERR)
|
||||
signal(sig, handler);
|
||||
return handler;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* All of the code in this function must only use async-signal-safe functions,
|
||||
* listed at `man 7 signal` or
|
||||
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
|
||||
*/
|
||||
PyOS_sighandler_t
|
||||
PyOS_setsig(int sig, PyOS_sighandler_t handler)
|
||||
{
|
||||
#ifdef HAVE_SIGACTION
|
||||
/* Some code in Modules/signalmodule.c depends on sigaction() being
|
||||
* used here if HAVE_SIGACTION is defined. Fix that if this code
|
||||
* changes to invalidate that assumption.
|
||||
*/
|
||||
struct sigaction context, ocontext;
|
||||
context.sa_handler = handler;
|
||||
sigemptyset(&context.sa_mask);
|
||||
context.sa_flags = 0;
|
||||
if (sigaction(sig, &context, &ocontext) == -1)
|
||||
return SIG_ERR;
|
||||
return ocontext.sa_handler;
|
||||
#else
|
||||
PyOS_sighandler_t oldhandler;
|
||||
oldhandler = signal(sig, handler);
|
||||
#ifdef HAVE_SIGINTERRUPT
|
||||
siginterrupt(sig, 1);
|
||||
#endif
|
||||
return oldhandler;
|
||||
#endif
|
||||
}
|
1
third_party/python/Python/graminit.c
vendored
1
third_party/python/Python/graminit.c
vendored
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "third_party/python/Include/pgenheaders.h"
|
||||
#include "third_party/python/Include/grammar.h"
|
||||
extern grammar _PyParser_Grammar;
|
||||
static arc arcs_0_0[3] = {
|
||||
{2, 1},
|
||||
{3, 1},
|
||||
|
|
107
third_party/python/Python/initfsencoding.c
vendored
Normal file
107
third_party/python/Python/initfsencoding.c
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/codecs.h"
|
||||
#include "third_party/python/Include/fileobject.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Include/pystate.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
_Py_IDENTIFIER(name);
|
||||
|
||||
static char *
|
||||
get_codec_name(const char *encoding)
|
||||
{
|
||||
char *name_utf8, *name_str;
|
||||
PyObject *codec, *name = NULL;
|
||||
codec = _PyCodec_Lookup(encoding);
|
||||
if (!codec)
|
||||
goto error;
|
||||
name = _PyObject_GetAttrId(codec, &PyId_name);
|
||||
Py_CLEAR(codec);
|
||||
if (!name)
|
||||
goto error;
|
||||
name_utf8 = PyUnicode_AsUTF8(name);
|
||||
if (name_utf8 == NULL)
|
||||
goto error;
|
||||
name_str = _PyMem_RawStrdup(name_utf8);
|
||||
Py_DECREF(name);
|
||||
if (name_str == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
return name_str;
|
||||
error:
|
||||
Py_XDECREF(codec);
|
||||
Py_XDECREF(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_locale_encoding(void)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
char codepage[100];
|
||||
PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP());
|
||||
return get_codec_name(codepage);
|
||||
#elif defined(__ANDROID__) || defined(__COSMOPOLITAN__)
|
||||
return get_codec_name("UTF-8");
|
||||
#elif defined(HAVE_LANGINFO_H) && defined(CODESET)
|
||||
char* codeset = nl_langinfo(CODESET);
|
||||
if (!codeset || codeset[0] == '\0') {
|
||||
PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty");
|
||||
return NULL;
|
||||
}
|
||||
return get_codec_name(codeset);
|
||||
#else
|
||||
PyErr_SetNone(PyExc_NotImplementedError);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
_Py_InitFsEncoding(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *codec;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
if (Py_LegacyWindowsFSEncodingFlag)
|
||||
{
|
||||
Py_FileSystemDefaultEncoding = "mbcs";
|
||||
Py_FileSystemDefaultEncodeErrors = "replace";
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_FileSystemDefaultEncoding = "utf-8";
|
||||
Py_FileSystemDefaultEncodeErrors = "surrogatepass";
|
||||
}
|
||||
#else
|
||||
if (Py_FileSystemDefaultEncoding == NULL)
|
||||
{
|
||||
Py_FileSystemDefaultEncoding = get_locale_encoding();
|
||||
if (Py_FileSystemDefaultEncoding == NULL)
|
||||
Py_FatalError("Py_Initialize: Unable to get the locale encoding");
|
||||
Py_HasFileSystemDefaultEncoding = 0;
|
||||
interp->fscodec_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* the encoding is mbcs, utf-8 or ascii */
|
||||
codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding);
|
||||
if (!codec) {
|
||||
/* Such error can only occurs in critical situations: no more
|
||||
* memory, import a module of the standard library failed,
|
||||
* etc. */
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(codec);
|
||||
interp->fscodec_initialized = 1;
|
||||
return 0;
|
||||
}
|
13
third_party/python/Python/initialized.c
vendored
Normal file
13
third_party/python/Python/initialized.c
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
|
||||
int _Py_initialized;
|
||||
|
||||
int Py_IsInitialized(void) {
|
||||
return _Py_initialized;
|
||||
}
|
93
third_party/python/Python/initimport.c
vendored
Normal file
93
third_party/python/Python/initimport.c
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/codecs.h"
|
||||
#include "third_party/python/Include/cosmo.h"
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Include/pystate.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_frozen_importlib");
|
||||
PYTHON_PROVIDE("_frozen_importlib_external");
|
||||
|
||||
void
|
||||
_Py_InitImport(PyInterpreterState *interp, PyObject *sysmod)
|
||||
{
|
||||
PyObject *importlib;
|
||||
PyObject *impmod;
|
||||
PyObject *cosmomod;
|
||||
PyObject *sys_modules;
|
||||
PyObject *value;
|
||||
|
||||
/* Import _importlib through its frozen version, _frozen_importlib. */
|
||||
if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) {
|
||||
Py_FatalError("Py_Initialize: can't import _frozen_importlib");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _frozen_importlib # frozen\n");
|
||||
}
|
||||
importlib = PyImport_AddModule("_frozen_importlib");
|
||||
if (importlib == NULL) {
|
||||
Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from "
|
||||
"sys.modules");
|
||||
}
|
||||
interp->importlib = importlib;
|
||||
Py_INCREF(interp->importlib);
|
||||
|
||||
interp->import_func = PyDict_GetItemString(interp->builtins, "__import__");
|
||||
if (interp->import_func == NULL)
|
||||
Py_FatalError("Py_Initialize: __import__ not found");
|
||||
Py_INCREF(interp->import_func);
|
||||
|
||||
/* Import the _imp module */
|
||||
impmod = PyInit_imp();
|
||||
if (impmod == NULL) {
|
||||
Py_FatalError("Py_Initialize: can't import _imp");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _imp # builtin\n");
|
||||
}
|
||||
sys_modules = PyImport_GetModuleDict();
|
||||
if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import sys # builtin\n");
|
||||
}
|
||||
if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) {
|
||||
Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
|
||||
}
|
||||
|
||||
/* Import the _cosmo module */
|
||||
cosmomod = PyInit_cosmo();
|
||||
if (impmod == NULL) {
|
||||
Py_FatalError("Py_Initialize: can't import _cosmo");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _cosmo # for bonus Cosmopolitan Libc features\n");
|
||||
}
|
||||
if (PyDict_SetItemString(sys_modules, "_cosmo", cosmomod) < 0) {
|
||||
Py_FatalError("Py_Initialize: can't save _cosmo to sys.modules");
|
||||
}
|
||||
|
||||
/* Install importlib as the implementation of import */
|
||||
value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
|
||||
if (value == NULL) {
|
||||
PyErr_Print();
|
||||
Py_FatalError("Py_Initialize: importlib install failed");
|
||||
}
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(impmod);
|
||||
}
|
59
third_party/python/Python/initmain.c
vendored
Normal file
59
third_party/python/Python/initmain.c
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pystate.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("__main__");
|
||||
|
||||
void
|
||||
_Py_InitMain(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *m, *d, *loader, *ann_dict;
|
||||
m = PyImport_AddModule("__main__");
|
||||
if (m == NULL)
|
||||
Py_FatalError("can't create __main__ module");
|
||||
d = PyModule_GetDict(m);
|
||||
ann_dict = PyDict_New();
|
||||
if ((ann_dict == NULL) ||
|
||||
(PyDict_SetItemString(d, "__annotations__", ann_dict) < 0)) {
|
||||
Py_FatalError("Failed to initialize __main__.__annotations__");
|
||||
}
|
||||
Py_DECREF(ann_dict);
|
||||
if (PyDict_GetItemString(d, "__builtins__") == NULL) {
|
||||
PyObject *bimod = PyImport_ImportModule("builtins");
|
||||
if (bimod == NULL) {
|
||||
Py_FatalError("Failed to retrieve builtins module");
|
||||
}
|
||||
if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) {
|
||||
Py_FatalError("Failed to initialize __main__.__builtins__");
|
||||
}
|
||||
Py_DECREF(bimod);
|
||||
}
|
||||
/* Main is a little special - imp.is_builtin("__main__") will return
|
||||
* False, but BuiltinImporter is still the most appropriate initial
|
||||
* setting for its __loader__ attribute. A more suitable value will
|
||||
* be set if __main__ gets further initialized later in the startup
|
||||
* process.
|
||||
*/
|
||||
loader = PyDict_GetItemString(d, "__loader__");
|
||||
if (loader == NULL || loader == Py_None) {
|
||||
PyObject *loader = PyObject_GetAttrString(interp->importlib,
|
||||
"BuiltinImporter");
|
||||
if (loader == NULL) {
|
||||
Py_FatalError("Failed to retrieve BuiltinImporter");
|
||||
}
|
||||
if (PyDict_SetItemString(d, "__loader__", loader) < 0) {
|
||||
Py_FatalError("Failed to initialize __main__.__loader__");
|
||||
}
|
||||
Py_DECREF(loader);
|
||||
}
|
||||
}
|
30
third_party/python/Python/initsigs.c
vendored
Normal file
30
third_party/python/Python/initsigs.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "third_party/python/Include/intrcheck.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
void
|
||||
_Py_InitSigs(void)
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
PyOS_setsig(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGXFZ
|
||||
PyOS_setsig(SIGXFZ, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
PyOS_setsig(SIGXFSZ, SIG_IGN);
|
||||
#endif
|
||||
PyOS_InitInterrupts(); /* May imply initsignal() */
|
||||
if (PyErr_Occurred()) {
|
||||
Py_FatalError("Py_Initialize: can't import signal");
|
||||
}
|
||||
}
|
33
third_party/python/Python/initsite.c
vendored
Normal file
33
third_party/python/Python/initsite.c
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* PYTHON_YOINK("site"); */
|
||||
/* PYTHON_YOINK("_sysconfigdata_m_cosmo_x86_64_cosmo"); */
|
||||
|
||||
void
|
||||
_Py_InitSite(void)
|
||||
{
|
||||
PyObject *m;
|
||||
m = PyImport_ImportModule("site");
|
||||
if (m == NULL) {
|
||||
fputs("Failed to import the site module\n", stderr);
|
||||
PyErr_Print();
|
||||
Py_Finalize();
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
Py_DECREF(m);
|
||||
}
|
||||
}
|
329
third_party/python/Python/initstdio.c
vendored
Normal file
329
third_party/python/Python/initstdio.c
vendored
Normal file
|
@ -0,0 +1,329 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/codecs.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/object.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pymem.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* PYTHON_YOINK("io"); */
|
||||
/* PYTHON_YOINK("encodings.aliases"); */
|
||||
/* PYTHON_YOINK("encodings.latin_1"); */
|
||||
/* PYTHON_YOINK("encodings.utf_8"); */
|
||||
|
||||
_Py_IDENTIFIER(name);
|
||||
_Py_IDENTIFIER(stdin);
|
||||
_Py_IDENTIFIER(stdout);
|
||||
_Py_IDENTIFIER(stderr);
|
||||
|
||||
char *_Py_StandardStreamEncoding;
|
||||
char *_Py_StandardStreamErrors;
|
||||
|
||||
/* Check if a file descriptor is valid or not.
|
||||
Return 0 if the file descriptor is invalid, return non-zero otherwise. */
|
||||
static int
|
||||
is_valid_fd(int fd)
|
||||
{
|
||||
if (IsWindows()) {
|
||||
return __isfdopen(fd);
|
||||
}
|
||||
if (IsXnu()) {
|
||||
/* bpo-30225: On macOS Tiger, when stdout is redirected to a pipe
|
||||
and the other side of the pipe is closed, dup(1) succeed, whereas
|
||||
fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect
|
||||
such error. */
|
||||
struct stat st;
|
||||
return (fstat(fd, &st) == 0);
|
||||
}
|
||||
int fd2;
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
_Py_BEGIN_SUPPRESS_IPH
|
||||
/* Prefer dup() over fstat(). fstat() can require input/output whereas
|
||||
dup() doesn't, there is a low risk of EMFILE/ENFILE at Python
|
||||
startup. */
|
||||
fd2 = dup(fd);
|
||||
if (fd2 >= 0)
|
||||
close(fd2);
|
||||
_Py_END_SUPPRESS_IPH
|
||||
return fd2 >= 0;
|
||||
}
|
||||
|
||||
/* returns Py_None if the fd is not valid */
|
||||
static PyObject*
|
||||
create_stdio(PyObject* io,
|
||||
int fd, int write_mode, const char* name,
|
||||
const char* encoding, const char* errors)
|
||||
{
|
||||
PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res;
|
||||
const char* mode;
|
||||
const char* newline;
|
||||
PyObject *line_buffering;
|
||||
int buffering, isatty;
|
||||
_Py_IDENTIFIER(open);
|
||||
_Py_IDENTIFIER(isatty);
|
||||
_Py_IDENTIFIER(TextIOWrapper);
|
||||
_Py_IDENTIFIER(mode);
|
||||
|
||||
if (!is_valid_fd(fd))
|
||||
Py_RETURN_NONE;
|
||||
|
||||
/* stdin is always opened in buffered mode, first because it shouldn't
|
||||
make a difference in common use cases, second because TextIOWrapper
|
||||
depends on the presence of a read1() method which only exists on
|
||||
buffered streams.
|
||||
*/
|
||||
if (Py_UnbufferedStdioFlag && write_mode)
|
||||
buffering = 0;
|
||||
else
|
||||
buffering = -1;
|
||||
if (write_mode)
|
||||
mode = "wb";
|
||||
else
|
||||
mode = "rb";
|
||||
buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi",
|
||||
fd, mode, buffering,
|
||||
Py_None, Py_None, /* encoding, errors */
|
||||
Py_None, 0); /* newline, closefd */
|
||||
if (buf == NULL)
|
||||
goto error;
|
||||
|
||||
if (buffering) {
|
||||
_Py_IDENTIFIER(raw);
|
||||
raw = _PyObject_GetAttrId(buf, &PyId_raw);
|
||||
if (raw == NULL)
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
raw = buf;
|
||||
Py_INCREF(raw);
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* Windows console IO is always UTF-8 encoded */
|
||||
if (PyWindowsConsoleIO_Check(raw))
|
||||
encoding = "utf-8";
|
||||
#endif
|
||||
|
||||
text = PyUnicode_FromString(name);
|
||||
if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0)
|
||||
goto error;
|
||||
res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
isatty = PyObject_IsTrue(res);
|
||||
Py_DECREF(res);
|
||||
if (isatty == -1)
|
||||
goto error;
|
||||
if (isatty || Py_UnbufferedStdioFlag)
|
||||
line_buffering = Py_True;
|
||||
else
|
||||
line_buffering = Py_False;
|
||||
|
||||
Py_CLEAR(raw);
|
||||
Py_CLEAR(text);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* sys.stdin: enable universal newline mode, translate "\r\n" and "\r"
|
||||
newlines to "\n".
|
||||
sys.stdout and sys.stderr: translate "\n" to "\r\n". */
|
||||
newline = NULL;
|
||||
#else
|
||||
/* sys.stdin: split lines at "\n".
|
||||
sys.stdout and sys.stderr: don't translate newlines (use "\n"). */
|
||||
newline = "\n";
|
||||
#endif
|
||||
|
||||
stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
|
||||
buf, encoding, errors,
|
||||
newline, line_buffering);
|
||||
Py_CLEAR(buf);
|
||||
if (stream == NULL)
|
||||
goto error;
|
||||
|
||||
if (write_mode)
|
||||
mode = "w";
|
||||
else
|
||||
mode = "r";
|
||||
text = PyUnicode_FromString(mode);
|
||||
if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0)
|
||||
goto error;
|
||||
Py_CLEAR(text);
|
||||
return stream;
|
||||
|
||||
error:
|
||||
Py_XDECREF(buf);
|
||||
Py_XDECREF(stream);
|
||||
Py_XDECREF(text);
|
||||
Py_XDECREF(raw);
|
||||
|
||||
if (PyErr_ExceptionMatches(PyExc_OSError) && !is_valid_fd(fd)) {
|
||||
/* Issue #24891: the file descriptor was closed after the first
|
||||
is_valid_fd() check was called. Ignore the OSError and set the
|
||||
stream to None. */
|
||||
PyErr_Clear();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize sys.stdin, stdout, stderr and builtins.open */
|
||||
int
|
||||
_Py_InitStdio(void)
|
||||
{
|
||||
PyObject *iomod = NULL, *wrapper;
|
||||
PyObject *bimod = NULL;
|
||||
PyObject *m;
|
||||
PyObject *std = NULL;
|
||||
int status = 0, fd;
|
||||
PyObject * encoding_attr;
|
||||
char *pythonioencoding = NULL, *encoding, *errors;
|
||||
|
||||
/* Hack to avoid a nasty recursion issue when Python is invoked
|
||||
in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
|
||||
if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(m);
|
||||
|
||||
if (!(m = PyImport_ImportModule("encodings.latin_1"))) {
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(m);
|
||||
|
||||
if (!(bimod = PyImport_ImportModule("builtins"))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(iomod = PyImport_ImportModule("io"))) {
|
||||
goto error;
|
||||
}
|
||||
if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set builtins.open */
|
||||
if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) {
|
||||
Py_DECREF(wrapper);
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(wrapper);
|
||||
|
||||
encoding = _Py_StandardStreamEncoding;
|
||||
errors = _Py_StandardStreamErrors;
|
||||
if (!encoding || !errors) {
|
||||
pythonioencoding = Py_GETENV("PYTHONIOENCODING");
|
||||
if (pythonioencoding) {
|
||||
char *err;
|
||||
pythonioencoding = _PyMem_Strdup(pythonioencoding);
|
||||
if (pythonioencoding == NULL) {
|
||||
PyErr_NoMemory();
|
||||
goto error;
|
||||
}
|
||||
err = strchr(pythonioencoding, ':');
|
||||
if (err) {
|
||||
*err = '\0';
|
||||
err++;
|
||||
if (*err && !errors) {
|
||||
errors = err;
|
||||
}
|
||||
}
|
||||
if (*pythonioencoding && !encoding) {
|
||||
encoding = pythonioencoding;
|
||||
}
|
||||
}
|
||||
if (!errors && !(pythonioencoding && *pythonioencoding)) {
|
||||
/* When the LC_CTYPE locale is the POSIX locale ("C locale"),
|
||||
stdin and stdout use the surrogateescape error handler by
|
||||
default, instead of the strict error handler. */
|
||||
char *loc = setlocale(LC_CTYPE, NULL);
|
||||
if (loc != NULL && strcmp(loc, "C") == 0)
|
||||
errors = "surrogateescape";
|
||||
}
|
||||
}
|
||||
|
||||
/* Set sys.stdin */
|
||||
fd = fileno(stdin);
|
||||
/* Under some conditions stdin, stdout and stderr may not be connected
|
||||
* and fileno() may point to an invalid file descriptor. For example
|
||||
* GUI apps don't have valid standard streams by default.
|
||||
*/
|
||||
std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors);
|
||||
if (std == NULL)
|
||||
goto error;
|
||||
PySys_SetObject("__stdin__", std);
|
||||
_PySys_SetObjectId(&PyId_stdin, std);
|
||||
Py_DECREF(std);
|
||||
|
||||
/* Set sys.stdout */
|
||||
fd = fileno(stdout);
|
||||
std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors);
|
||||
if (std == NULL)
|
||||
goto error;
|
||||
PySys_SetObject("__stdout__", std);
|
||||
_PySys_SetObjectId(&PyId_stdout, std);
|
||||
Py_DECREF(std);
|
||||
|
||||
#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
|
||||
/* Set sys.stderr, replaces the preliminary stderr */
|
||||
fd = fileno(stderr);
|
||||
std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace");
|
||||
if (std == NULL)
|
||||
goto error;
|
||||
|
||||
/* Same as hack above, pre-import stderr's codec to avoid recursion
|
||||
when import.c tries to write to stderr in verbose mode. */
|
||||
encoding_attr = PyObject_GetAttrString(std, "encoding");
|
||||
if (encoding_attr != NULL) {
|
||||
const char * std_encoding;
|
||||
std_encoding = PyUnicode_AsUTF8(encoding_attr);
|
||||
if (std_encoding != NULL) {
|
||||
PyObject *codec_info = _PyCodec_Lookup(std_encoding);
|
||||
Py_XDECREF(codec_info);
|
||||
}
|
||||
Py_DECREF(encoding_attr);
|
||||
}
|
||||
PyErr_Clear(); /* Not a fatal error if codec isn't available */
|
||||
|
||||
if (PySys_SetObject("__stderr__", std) < 0) {
|
||||
Py_DECREF(std);
|
||||
goto error;
|
||||
}
|
||||
if (_PySys_SetObjectId(&PyId_stderr, std) < 0) {
|
||||
Py_DECREF(std);
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(std);
|
||||
#endif
|
||||
|
||||
if (0) {
|
||||
error:
|
||||
status = -1;
|
||||
}
|
||||
|
||||
/* We won't need them anymore. */
|
||||
if (_Py_StandardStreamEncoding) {
|
||||
PyMem_RawFree(_Py_StandardStreamEncoding);
|
||||
_Py_StandardStreamEncoding = NULL;
|
||||
}
|
||||
if (_Py_StandardStreamErrors) {
|
||||
PyMem_RawFree(_Py_StandardStreamErrors);
|
||||
_Py_StandardStreamErrors = NULL;
|
||||
}
|
||||
PyMem_Free(pythonioencoding);
|
||||
Py_XDECREF(bimod);
|
||||
Py_XDECREF(iomod);
|
||||
return status;
|
||||
}
|
27
third_party/python/Python/progname.c
vendored
Normal file
27
third_party/python/Python/progname.c
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
static wchar_t *progname = L"python";
|
||||
#else
|
||||
static wchar_t *progname = L"python3";
|
||||
#endif
|
||||
|
||||
void
|
||||
Py_SetProgramName(wchar_t *pn)
|
||||
{
|
||||
if (pn && *pn)
|
||||
progname = pn;
|
||||
}
|
||||
|
||||
wchar_t *
|
||||
Py_GetProgramName(void)
|
||||
{
|
||||
return progname;
|
||||
}
|
1
third_party/python/Python/pyhash.c
vendored
1
third_party/python/Python/pyhash.c
vendored
|
@ -4,6 +4,7 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "third_party/python/Include/pyhash.h"
|
||||
/* clang-format off */
|
||||
|
||||
|
|
1264
third_party/python/Python/pylifecycle.c
vendored
1264
third_party/python/Python/pylifecycle.c
vendored
File diff suppressed because it is too large
Load diff
37
third_party/python/Python/pythonhome.c
vendored
Normal file
37
third_party/python/Python/pythonhome.c
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/python/Include/osdefs.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
/* clang-format off */
|
||||
|
||||
static wchar_t *default_home = NULL;
|
||||
static wchar_t env_home[MAXPATHLEN+1];
|
||||
|
||||
void
|
||||
Py_SetPythonHome(wchar_t *home)
|
||||
{
|
||||
default_home = home;
|
||||
}
|
||||
|
||||
wchar_t *
|
||||
Py_GetPythonHome(void)
|
||||
{
|
||||
wchar_t *home = default_home;
|
||||
if (home == NULL && !Py_IgnoreEnvironmentFlag) {
|
||||
char* chome = Py_GETENV("PYTHONHOME");
|
||||
if (chome) {
|
||||
size_t size = Py_ARRAY_LENGTH(env_home);
|
||||
size_t r = mbstowcs(env_home, chome, size);
|
||||
if (r != (size_t)-1 && r < size)
|
||||
home = env_home;
|
||||
}
|
||||
}
|
||||
return home;
|
||||
}
|
30
third_party/python/Python/restoresigs.c
vendored
Normal file
30
third_party/python/Python/restoresigs.c
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
|
||||
*
|
||||
* All of the code in this function must only use async-signal-safe functions,
|
||||
* listed at `man 7 signal` or
|
||||
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html.
|
||||
*/
|
||||
void
|
||||
_Py_RestoreSignals(void)
|
||||
{
|
||||
#ifdef SIGPIPE
|
||||
PyOS_setsig(SIGPIPE, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGXFZ
|
||||
PyOS_setsig(SIGXFZ, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGXFSZ
|
||||
PyOS_setsig(SIGXFSZ, SIG_DFL);
|
||||
#endif
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue