summaryrefslogtreecommitdiffstats
path: root/Python/modsupport.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/modsupport.c')
-rw-r--r--Python/modsupport.c392
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)