diff options
Diffstat (limited to 'Python/modsupport.c')
-rw-r--r-- | Python/modsupport.c | 392 |
1 files changed, 191 insertions, 201 deletions
diff --git a/Python/modsupport.c b/Python/modsupport.c index 6255822..ebe62c3 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -7,42 +7,109 @@ typedef double va_double; static PyObject *va_build_value(const char *, va_list, int); -static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); /* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; +char *_Py_PackageContext = NULL; +/* Py_InitModule4() parameters: + - name is the module name + - methods is the list of top-level functions + - doc is the documentation string + - passthrough is passed as self to functions defined in the module + - api_version is the value of PYTHON_API_VERSION at the time the + module was compiled -int -_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) + Return value is a borrowed reference to the module object; or NULL + if an error occurred (in Python 1.4 and before, errors were fatal). + Errors may still leak memory. +*/ + +static char api_version_warning[] = +"Python C API version mismatch for module %.100s:\ + This Python has API version %d, module %.100s has version %d."; + +PyObject * +Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc, + PyObject *passthrough, int module_api_version) { - Py_ssize_t limit; - if (obj == Py_None) { - return 1; + PyObject *m, *d, *v, *n; + PyMethodDef *ml; + PyInterpreterState *interp = PyThreadState_Get()->interp; + if (interp->modules == NULL) + Py_FatalError("Python import machinery not initialized"); + if (module_api_version != PYTHON_API_VERSION) { + char message[512]; + PyOS_snprintf(message, sizeof(message), + api_version_warning, name, + PYTHON_API_VERSION, name, + module_api_version); + if (PyErr_Warn(PyExc_RuntimeWarning, message)) + return NULL; } - else if (PyIndex_Check(obj)) { - limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) { - return 0; + /* Make sure name is fully qualified. + + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + Py_InitModule*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _Py_PackageContext, and Py_InitModule*() will substitute this + (if the name actually matches). + */ + if (_Py_PackageContext != NULL) { + char *p = strrchr(_Py_PackageContext, '.'); + if (p != NULL && strcmp(name, p+1) == 0) { + name = _Py_PackageContext; + _Py_PackageContext = NULL; } } - else { - PyErr_Format(PyExc_TypeError, - "argument should be integer or None, not '%.200s'", - Py_TYPE(obj)->tp_name); - return 0; + if ((m = PyImport_AddModule(name)) == NULL) + return NULL; + d = PyModule_GetDict(m); + if (methods != NULL) { + n = PyString_FromString(name); + if (n == NULL) + return NULL; + for (ml = methods; ml->ml_name != NULL; ml++) { + if ((ml->ml_flags & METH_CLASS) || + (ml->ml_flags & METH_STATIC)) { + PyErr_SetString(PyExc_ValueError, + "module functions cannot set" + " METH_CLASS or METH_STATIC"); + Py_DECREF(n); + return NULL; + } + v = PyCFunction_NewEx(ml, passthrough, n); + if (v == NULL) { + Py_DECREF(n); + return NULL; + } + if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { + Py_DECREF(v); + Py_DECREF(n); + return NULL; + } + Py_DECREF(v); + } + Py_DECREF(n); + } + if (doc != NULL) { + v = PyString_FromString(doc); + if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { + Py_XDECREF(v); + return NULL; + } + Py_DECREF(v); } - *((Py_ssize_t *)result) = limit; - return 1; + return m; } /* Helper for mkvalue() to scan the length of a format */ -static Py_ssize_t -countformat(const char *format, char endchar) +static int +countformat(const char *format, int endchar) { - Py_ssize_t count = 0; + int count = 0; int level = 0; while (level > 0 || *format != endchar) { switch (*format) { @@ -54,9 +121,8 @@ countformat(const char *format, char endchar) case '(': case '[': case '{': - if (level == 0) { + if (level == 0) count++; - } level++; break; case ')': @@ -72,9 +138,8 @@ countformat(const char *format, char endchar) case '\t': break; default: - if (level == 0) { + if (level == 0) count++; - } } format++; } @@ -85,23 +150,21 @@ countformat(const char *format, char endchar) /* Generic function to create a value -- the inverse of getargs() */ /* After an original idea and first implementation by Steven Miale */ -static PyObject *do_mktuple(const char**, va_list *, char, Py_ssize_t, int); -static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mktuple(const char**, va_list *, int, int, int); +static PyObject *do_mklist(const char**, va_list *, int, int, int); +static PyObject *do_mkdict(const char**, va_list *, int, int, int); static PyObject *do_mkvalue(const char**, va_list *, int); static void -do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_ignore(const char **p_format, va_list *p_va, int endchar, int n, int flags) { PyObject *v; - Py_ssize_t i; + int i; assert(PyErr_Occurred()); v = PyTuple_New(n); for (i = 0; i < n; i++) { PyObject *exception, *value, *tb, *w; - PyErr_Fetch(&exception, &value, &tb); w = do_mkvalue(p_format, p_va, flags); PyErr_Restore(exception, value, tb); @@ -120,16 +183,15 @@ do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int "Unmatched paren in format"); return; } - if (endchar) { + if (endchar) ++*p_format; - } } static PyObject * -do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags) { PyObject *d; - Py_ssize_t i; + int i; if (n < 0) return NULL; if (n % 2) { @@ -176,10 +238,10 @@ do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int } static PyObject * -do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags) { PyObject *v; - Py_ssize_t i; + int i; if (n < 0) return NULL; /* Note that we can't bail immediately on error as this will leak @@ -209,48 +271,22 @@ do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int return v; } +#ifdef Py_USING_UNICODE static int -do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, - char endchar, Py_ssize_t n, int flags) +_ustrlen(Py_UNICODE *u) { - Py_ssize_t i; - - if (n < 0) { - return -1; - } - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - goto error; - } - stack[i] = w; - } - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - goto error; - } - if (endchar) { - ++*p_format; - } - return 0; - -error: - n = i; - for (i=0; i < n; i++) { - Py_DECREF(stack[i]); - } - return -1; + int i = 0; + Py_UNICODE *v = u; + while (*v != 0) { i++; v++; } + return i; } +#endif static PyObject * -do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags) { PyObject *v; - Py_ssize_t i; + int i; if (n < 0) return NULL; /* Note that we can't bail immediately on error as this will leak @@ -300,39 +336,47 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) case 'B': case 'h': case 'i': - return PyLong_FromLong((long)va_arg(*p_va, int)); + return PyInt_FromLong((long)va_arg(*p_va, int)); case 'H': - return PyLong_FromLong((long)va_arg(*p_va, unsigned int)); + return PyInt_FromLong((long)va_arg(*p_va, unsigned int)); case 'I': { unsigned int n; n = va_arg(*p_va, unsigned int); - return PyLong_FromUnsignedLong(n); + if (n > (unsigned long)PyInt_GetMax()) + return PyLong_FromUnsignedLong((unsigned long)n); + else + return PyInt_FromLong(n); } case 'n': #if SIZEOF_SIZE_T!=SIZEOF_LONG - return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t)); + return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t)); #endif /* Fall through from 'n' to 'l' if Py_ssize_t is long */ case 'l': - return PyLong_FromLong(va_arg(*p_va, long)); + return PyInt_FromLong(va_arg(*p_va, long)); case 'k': { unsigned long n; n = va_arg(*p_va, unsigned long); - return PyLong_FromUnsignedLong(n); + if (n > (unsigned long)PyInt_GetMax()) + return PyLong_FromUnsignedLong(n); + else + return PyInt_FromLong(n); } +#ifdef HAVE_LONG_LONG case 'L': - return PyLong_FromLongLong((long long)va_arg(*p_va, long long)); + return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG)); case 'K': - return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long)); - + return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG)); +#endif +#ifdef Py_USING_UNICODE case 'u': { PyObject *v; @@ -342,13 +386,8 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) ++*p_format; if (flags & FLAG_SIZE_T) n = va_arg(*p_va, Py_ssize_t); - else { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } + else n = va_arg(*p_va, int); - } } else n = -1; @@ -358,50 +397,42 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) } else { if (n < 0) - n = wcslen(u); - v = PyUnicode_FromWideChar(u, n); + n = _ustrlen(u); + v = PyUnicode_FromUnicode(u, n); } return v; } +#endif case 'f': case 'd': return PyFloat_FromDouble( (double)va_arg(*p_va, va_double)); +#ifndef WITHOUT_COMPLEX case 'D': return PyComplex_FromCComplex( *((Py_complex *)va_arg(*p_va, Py_complex *))); +#endif /* WITHOUT_COMPLEX */ case 'c': { char p[1]; p[0] = (char)va_arg(*p_va, int); - return PyBytes_FromStringAndSize(p, 1); - } - case 'C': - { - int i = va_arg(*p_va, int); - return PyUnicode_FromOrdinal(i); + return PyString_FromStringAndSize(p, 1); } case 's': case 'z': - case 'U': /* XXX deprecated alias */ { PyObject *v; - const char *str = va_arg(*p_va, const char *); + char *str = va_arg(*p_va, char *); Py_ssize_t n; if (**p_format == '#') { ++*p_format; if (flags & FLAG_SIZE_T) n = va_arg(*p_va, Py_ssize_t); - else { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } + else n = va_arg(*p_va, int); - } } else n = -1; @@ -419,45 +450,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) } n = (Py_ssize_t)m; } - v = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'y': - { - PyObject *v; - const char *str = va_arg(*p_va, const char *); - Py_ssize_t n; - if (**p_format == '#') { - ++*p_format; - if (flags & FLAG_SIZE_T) - n = va_arg(*p_va, Py_ssize_t); - else { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { - return NULL; - } - n = va_arg(*p_va, int); - } - } - else - n = -1; - if (str == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) { - size_t m = strlen(str); - if (m > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "string too long for Python bytes"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyBytes_FromStringAndSize(str, n); + v = PyString_FromStringAndSize(str, n); } return v; } @@ -547,84 +540,81 @@ static PyObject * va_build_value(const char *format, va_list va, int flags) { const char *f = format; - Py_ssize_t n = countformat(f, '\0'); + int n = countformat(f, '\0'); va_list lva; - PyObject *retval; + +#ifdef VA_LIST_IS_ARRAY + memcpy(lva, va, sizeof(va_list)); +#else +#ifdef __va_copy + __va_copy(lva, va); +#else + lva = va; +#endif +#endif if (n < 0) return NULL; if (n == 0) { - Py_RETURN_NONE; - } - va_copy(lva, va); - if (n == 1) { - retval = do_mkvalue(&f, &lva, flags); - } else { - retval = do_mktuple(&f, &lva, '\0', n, flags); + Py_INCREF(Py_None); + return Py_None; } - va_end(lva); - return retval; + if (n == 1) + return do_mkvalue(&f, &lva, flags); + return do_mktuple(&f, &lva, '\0', n, flags); } -PyObject ** -_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); -} -PyObject ** -_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) +PyObject * +PyEval_CallFunction(PyObject *obj, const char *format, ...) { - return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); + va_list vargs; + PyObject *args; + PyObject *res; + + va_start(vargs, format); + + args = Py_VaBuildValue(format, vargs); + va_end(vargs); + + if (args == NULL) + return NULL; + + res = PyEval_CallObject(obj, args); + Py_DECREF(args); + + return res; } -static PyObject ** -va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, int flags, Py_ssize_t *p_nargs) + +PyObject * +PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...) { - const char *f; - Py_ssize_t n; - va_list lva; - PyObject **stack; - int res; + va_list vargs; + PyObject *meth; + PyObject *args; + PyObject *res; - n = countformat(format, '\0'); - if (n < 0) { - *p_nargs = 0; + meth = PyObject_GetAttrString(obj, methodname); + if (meth == NULL) return NULL; - } - - if (n == 0) { - *p_nargs = 0; - return small_stack; - } - if (n <= small_stack_len) { - stack = small_stack; - } - else { - stack = PyMem_Malloc(n * sizeof(stack[0])); - if (stack == NULL) { - PyErr_NoMemory(); - return NULL; - } - } + va_start(vargs, format); - va_copy(lva, va); - f = format; - res = do_mkstack(stack, &f, &lva, '\0', n, flags); - va_end(lva); + args = Py_VaBuildValue(format, vargs); + va_end(vargs); - if (res < 0) { + if (args == NULL) { + Py_DECREF(meth); return NULL; } - *p_nargs = n; - return stack; -} + res = PyEval_CallObject(meth, args); + Py_DECREF(meth); + Py_DECREF(args); + return res; +} int PyModule_AddObject(PyObject *m, const char *name, PyObject *o) @@ -658,7 +648,7 @@ PyModule_AddObject(PyObject *m, const char *name, PyObject *o) int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - PyObject *o = PyLong_FromLong(value); + PyObject *o = PyInt_FromLong(value); if (!o) return -1; if (PyModule_AddObject(m, name, o) == 0) @@ -670,7 +660,7 @@ PyModule_AddIntConstant(PyObject *m, const char *name, long value) int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - PyObject *o = PyUnicode_FromString(value); + PyObject *o = PyString_FromString(value); if (!o) return -1; if (PyModule_AddObject(m, name, o) == 0) |