Thanks to Konrad Schöbel and Jasper Schulz for helping with the mass-editing.
#ifdef PY_SSIZE_T_CLEAN
#define PyObject_CallFunction _PyObject_CallFunction_SizeT
#define PyObject_CallMethod _PyObject_CallMethod_SizeT
+#define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT
#endif
/* Abstract Object Interface (many thanks to Jim Fulton) */
Python expression: o.method(args).
*/
+ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *o, _Py_Identifier *method,
+ char *format, ...);
+
+ /*
+ Like PyObject_CallMethod, but expect a _Py_Identifier* as the
+ method name.
+ */
+
PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable,
char *format, ...);
PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o,
char *name,
char *format, ...);
+ PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *o,
+ _Py_Identifier *name,
+ char *format, ...);
PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable,
...);
PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
/* Generic operations on objects */
+struct _Py_Identifier;
#ifndef Py_LIMITED_API
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void);
PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *);
PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
+PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *);
+PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *);
+PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *);
#ifndef Py_LIMITED_API
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
#endif
int check_content);
#endif
+/********************* String Literals ****************************************/
+/* This structure helps managing static strings. The basic usage goes like this:
+ Instead of doing
+
+ r = PyObject_CallMethod(o, "foo", "args", ...);
+
+ do
+
+ _Py_identifier(foo);
+ ...
+ r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
+
+ PyId_foo is a static variable, either on block level or file level. On first
+ usage, the string "foo" is interned, and the structures are linked. On interpreter
+ shutdown, all strings are released (through _PyUnicode_ClearStaticStrings).
+
+ Alternatively, _Py_static_string allows to choose the variable name.
+ _PyUnicode_FromId returns a new reference to the interned string.
+ _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
+*/
+typedef struct _Py_Identifier {
+ struct _Py_Identifier *next;
+ const char* string;
+ PyObject *object;
+} _Py_Identifier;
+
+#define _Py_static_string(varname, value) static _Py_Identifier varname = { 0, value, 0 };
+#define _Py_identifier(varname) _Py_static_string(PyId_##varname, #varname)
+
+/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/
+PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
+/* Clear all static strings. */
+PyAPI_FUNC(void) _PyUnicode_ClearStaticStrings(void);
+
#ifdef __cplusplus
}
#endif
Core and Builtins
-----------------
+- Add internal API for static strings (_Py_identifier et.al.).
+
- Issue #13063: the Windows error ERROR_NO_DATA (numbered 232 and described
as "The pipe is being closed") is now mapped to POSIX errno EPIPE
(previously EINVAL).
if (PyList_Insert(list, index, item) < 0)
return NULL;
} else {
- result = PyObject_CallMethod(list, "insert", "nO", index, item);
+ _Py_identifier(insert);
+
+ result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item);
if (result == NULL)
return NULL;
Py_DECREF(result);
if (PyList_Insert(list, index, item) < 0)
return NULL;
} else {
- result = PyObject_CallMethod(list, "insert", "iO", index, item);
+ _Py_identifier(insert);
+
+ result = _PyObject_CallMethodId(list, &PyId_insert, "iO", index, item);
if (result == NULL)
return NULL;
Py_DECREF(result);
PyObject *items;
PyObject *iter;
PyObject *result;
+ _Py_identifier(items);
+
if (dd->default_factory == NULL || dd->default_factory == Py_None)
args = PyTuple_New(0);
else
args = PyTuple_Pack(1, dd->default_factory);
if (args == NULL)
return NULL;
- items = PyObject_CallMethod((PyObject *)dd, "items", "()");
+ items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()");
if (items == NULL) {
Py_DECREF(args);
return NULL;
PyTuple_SET_ITEM(tup, index, v);
index++;
} else if (bit & outmask) {
+ _Py_identifier(__ctypes_from_outparam__);
+
v = PyTuple_GET_ITEM(callargs, i);
- v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
+ v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
if (v == NULL || numretvals == 1) {
Py_DECREF(callargs);
return v;
PyObject *state;
PyObject *result;
PyObject *tmp;
+ _Py_identifier(__new__);
+ _Py_identifier(__setstate__);
if (!PyArg_ParseTuple(args, "OO", &typ, &state))
return NULL;
- result = PyObject_CallMethod(typ, "__new__", "O", typ);
+ result = _PyObject_CallMethodId(typ, &PyId___new__, "O", typ);
if (result == NULL)
return NULL;
- tmp = PyObject_CallMethod(result, "__setstate__", "O", state);
+ tmp = _PyObject_CallMethodId(result, &PyId___setstate__, "O", state);
if (tmp == NULL) {
Py_DECREF(result);
return NULL;
while (1) {
char buf[BUFSIZ];
Py_ssize_t n = fread(buf, 1, BUFSIZ, fp);
+ _Py_identifier(write);
+
if (n <= 0)
break;
Py_DECREF(res);
- res = PyObject_CallMethod(stream, "write", "y#", buf, n);
+ res = _PyObject_CallMethodId(stream, &PyId_write, "y#", buf, n);
if (res == NULL)
break;
}
WINDOW *win;
PyCursesInitialised;
+ _Py_identifier(read);
strcpy(fn, "/tmp/py.curses.getwin.XXXXXX");
fd = mkstemp(fn);
remove(fn);
return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
}
- data = PyObject_CallMethod(stream, "read", "");
+ data = _PyObject_CallMethodId(stream, &PyId_read, "");
if (data == NULL) {
fclose(fp);
remove(fn);
call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
{
PyObject *result;
+ _Py_identifier(tzname);
assert(tzinfo != NULL);
assert(check_tzinfo_subclass(tzinfo) >= 0);
if (tzinfo == Py_None)
Py_RETURN_NONE;
- result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
+ result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg);
if (result == NULL || result == Py_None)
return result;
PyObject *temp;
PyObject *tzinfo = get_tzinfo_member(object);
PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0);
+ _Py_identifier(replace);
+
if (Zreplacement == NULL)
return NULL;
if (tzinfo == Py_None || tzinfo == NULL)
* strftime doesn't treat them as format codes.
*/
Py_DECREF(Zreplacement);
- Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%");
+ Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%");
Py_DECREF(temp);
if (Zreplacement == NULL)
return NULL;
{
PyObject *format;
PyObject *time = PyImport_ImportModuleNoBlock("time");
+
if (time == NULL)
goto Done;
format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt));
if (format != NULL) {
- result = PyObject_CallMethod(time, "strftime", "OO",
- format, timetuple, NULL);
+ _Py_identifier(strftime);
+
+ result = _PyObject_CallMethodId(time, &PyId_strftime, "OO",
+ format, timetuple, NULL);
Py_DECREF(format);
}
Py_DECREF(time);
PyObject *time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
- result = PyObject_CallMethod(time, "time", "()");
+ _Py_identifier(time);
+
+ result = _PyObject_CallMethodId(time, &PyId_time, "()");
Py_DECREF(time);
}
return result;
time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
- result = PyObject_CallMethod(time, "struct_time",
- "((iiiiiiiii))",
- y, m, d,
- hh, mm, ss,
- weekday(y, m, d),
- days_before_month(y, m) + d,
- dstflag);
+ _Py_identifier(struct_time);
+
+ result = _PyObject_CallMethodId(time, &PyId_struct_time,
+ "((iiiiiiiii))",
+ y, m, d,
+ hh, mm, ss,
+ weekday(y, m, d),
+ days_before_month(y, m) + d,
+ dstflag);
Py_DECREF(time);
}
return result;
PyObject *result = NULL;
PyObject *pyus_in = NULL, *temp, *pyus_out;
PyObject *ratio = NULL;
+ _Py_identifier(as_integer_ratio);
pyus_in = delta_to_microseconds(delta);
if (pyus_in == NULL)
return NULL;
- ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL);
+ ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
if (ratio == NULL)
goto error;
temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
PyObject *result = NULL;
PyObject *pyus_in = NULL, *temp, *pyus_out;
PyObject *ratio = NULL;
+ _Py_identifier(as_integer_ratio);
pyus_in = delta_to_microseconds(delta);
if (pyus_in == NULL)
return NULL;
- ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL);
+ ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
if (ratio == NULL)
goto error;
temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
{
PyObject *time;
PyObject *result;
+ _Py_identifier(fromtimestamp);
time = time_time();
if (time == NULL)
* time.time() delivers; if someone were gonzo about optimization,
* date.today() could get away with plain C time().
*/
- result = PyObject_CallMethod(cls, "fromtimestamp", "O", time);
+ result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time);
Py_DECREF(time);
return result;
}
static PyObject *
date_str(PyDateTime_Date *self)
{
- return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+ _Py_identifier(isoformat);
+
+ return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
}
PyObject *result;
PyObject *tuple;
PyObject *format;
+ _Py_identifier(timetuple);
static char *keywords[] = {"format", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
&format))
return NULL;
- tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
+ tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()");
if (tuple == NULL)
return NULL;
result = wrap_strftime((PyObject *)self, format, tuple,
date_format(PyDateTime_Date *self, PyObject *args)
{
PyObject *format;
+ _Py_identifier(strftime);
if (!PyArg_ParseTuple(args, "U:__format__", &format))
return NULL;
if (PyUnicode_GetSize(format) == 0)
return PyObject_Str((PyObject *)self);
- return PyObject_CallMethod((PyObject *)self, "strftime", "O", format);
+ return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format);
}
/* ISO methods. */
static PyObject *
time_str(PyDateTime_Time *self)
{
- return PyObject_CallMethod((PyObject *)self, "isoformat", "()");
+ _Py_identifier(isoformat);
+
+ return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()");
}
static PyObject *
if (self != NULL && tzinfo != Py_None) {
/* Convert UTC to tzinfo's zone. */
PyObject *temp = self;
- self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+ _Py_identifier(fromutc);
+
+ self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Py_DECREF(temp);
}
return self;
if (self != NULL && tzinfo != Py_None) {
/* Convert UTC to tzinfo's zone. */
PyObject *temp = self;
- self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
+ _Py_identifier(fromutc);
+
+ self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self);
Py_DECREF(temp);
}
return self;
{
static PyObject *module = NULL;
PyObject *string, *format;
+ _Py_identifier(_strptime_datetime);
if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format))
return NULL;
if (module == NULL)
return NULL;
}
- return PyObject_CallMethod(module, "_strptime_datetime", "OOO",
- cls, string, format);
+ return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO",
+ cls, string, format);
}
/* Return new datetime from date/datetime and time arguments. */
static PyObject *
datetime_str(PyDateTime_DateTime *self)
{
- return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " ");
+ _Py_identifier(isoformat);
+
+ return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " ");
}
static PyObject *
PyObject *offset;
PyObject *temp;
PyObject *tzinfo;
+ _Py_identifier(fromutc);
static char *keywords[] = {"tz", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords,
Py_DECREF(temp);
temp = result;
- result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp);
+ result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp);
Py_DECREF(temp);
return result;
element_find(ElementObject* self, PyObject* args)
{
int i;
-
PyObject* tag;
PyObject* namespaces = Py_None;
+
if (!PyArg_ParseTuple(args, "O|O:find", &tag, &namespaces))
return NULL;
- if (checkpath(tag) || namespaces != Py_None)
- return PyObject_CallMethod(
- elementpath_obj, "find", "OOO", self, tag, namespaces
+ if (checkpath(tag) || namespaces != Py_None) {
+ _Py_identifier(find);
+ return _PyObject_CallMethodId(
+ elementpath_obj, &PyId_find, "OOO", self, tag, namespaces
);
+ }
if (!self->extra)
Py_RETURN_NONE;
element_findtext(ElementObject* self, PyObject* args)
{
int i;
-
PyObject* tag;
PyObject* default_value = Py_None;
PyObject* namespaces = Py_None;
+ _Py_identifier(findtext);
+
if (!PyArg_ParseTuple(args, "O|OO:findtext", &tag, &default_value, &namespaces))
return NULL;
if (checkpath(tag) || namespaces != Py_None)
- return PyObject_CallMethod(
- elementpath_obj, "findtext", "OOOO", self, tag, default_value, namespaces
+ return _PyObject_CallMethodId(
+ elementpath_obj, &PyId_findtext, "OOOO", self, tag, default_value, namespaces
);
if (!self->extra) {
{
int i;
PyObject* out;
-
PyObject* tag;
PyObject* namespaces = Py_None;
+
if (!PyArg_ParseTuple(args, "O|O:findall", &tag, &namespaces))
return NULL;
- if (checkpath(tag) || namespaces != Py_None)
- return PyObject_CallMethod(
- elementpath_obj, "findall", "OOO", self, tag, namespaces
+ if (checkpath(tag) || namespaces != Py_None) {
+ _Py_identifier(findall);
+ return _PyObject_CallMethodId(
+ elementpath_obj, &PyId_findall, "OOO", self, tag, namespaces
);
+ }
out = PyList_New(0);
if (!out)
{
PyObject* tag;
PyObject* namespaces = Py_None;
+ _Py_identifier(iterfind);
+
if (!PyArg_ParseTuple(args, "O|O:iterfind", &tag, &namespaces))
return NULL;
- return PyObject_CallMethod(
- elementpath_obj, "iterfind", "OOO", self, tag, namespaces
+ return _PyObject_CallMethodId(
+ elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces
);
}
PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL;
+ _Py_identifier(isatty);
+ _Py_identifier(fileno);
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist,
&file, &mode, &buffering,
&encoding, &errors, &newline,
/* buffering */
{
- PyObject *res = PyObject_CallMethod(raw, "isatty", NULL);
+ PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
if (res == NULL)
goto error;
isatty = PyLong_AsLong(res);
{
struct stat st;
long fileno;
- PyObject *res = PyObject_CallMethod(raw, "fileno", NULL);
+ PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL);
if (res == NULL)
goto error;
#include "pythread.h"
#include "_iomodule.h"
+_Py_identifier(close);
+_Py_identifier(_dealloc_warn);
+_Py_identifier(flush);
+_Py_identifier(isatty);
+_Py_identifier(peek);
+_Py_identifier(read);
+_Py_identifier(read1);
+_Py_identifier(readable);
+_Py_identifier(readinto);
+_Py_identifier(writable);
+_Py_identifier(write);
+
/*
* BufferedIOBase class, inherits from IOBase.
*/
Py_buffer buf;
Py_ssize_t len;
PyObject *data;
+ _Py_identifier(read);
if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) {
return NULL;
}
- data = PyObject_CallMethod(self, "read", "n", buf.len);
+ data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len);
if (data == NULL)
goto error;
{
if (self->ok && self->raw) {
PyObject *r;
- r = PyObject_CallMethod(self->raw, "_dealloc_warn", "O", source);
+ r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source);
if (r)
Py_DECREF(r);
else
}
static PyObject *
-_forward_call(buffered *self, const char *name, PyObject *args)
+_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
{
- PyObject *func = PyObject_GetAttrString((PyObject *)self, name);
+ PyObject *func = _PyObject_GetAttrId((PyObject *)self, name);
PyObject *ret;
if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
+ PyErr_SetString(PyExc_AttributeError, name->string);
return NULL;
}
static PyObject *
bufferedrwpair_read(rwpair *self, PyObject *args)
{
- return _forward_call(self->reader, "read", args);
+ return _forward_call(self->reader, &PyId_read, args);
}
static PyObject *
bufferedrwpair_peek(rwpair *self, PyObject *args)
{
- return _forward_call(self->reader, "peek", args);
+ return _forward_call(self->reader, &PyId_peek, args);
}
static PyObject *
bufferedrwpair_read1(rwpair *self, PyObject *args)
{
- return _forward_call(self->reader, "read1", args);
+ return _forward_call(self->reader, &PyId_read1, args);
}
static PyObject *
bufferedrwpair_readinto(rwpair *self, PyObject *args)
{
- return _forward_call(self->reader, "readinto", args);
+ return _forward_call(self->reader, &PyId_readinto, args);
}
static PyObject *
bufferedrwpair_write(rwpair *self, PyObject *args)
{
- return _forward_call(self->writer, "write", args);
+ return _forward_call(self->writer, &PyId_write, args);
}
static PyObject *
bufferedrwpair_flush(rwpair *self, PyObject *args)
{
- return _forward_call(self->writer, "flush", args);
+ return _forward_call(self->writer, &PyId_flush, args);
}
static PyObject *
bufferedrwpair_readable(rwpair *self, PyObject *args)
{
- return _forward_call(self->reader, "readable", args);
+ return _forward_call(self->reader, &PyId_readable, args);
}
static PyObject *
bufferedrwpair_writable(rwpair *self, PyObject *args)
{
- return _forward_call(self->writer, "writable", args);
+ return _forward_call(self->writer, &PyId_writable, args);
}
static PyObject *
bufferedrwpair_close(rwpair *self, PyObject *args)
{
- PyObject *ret = _forward_call(self->writer, "close", args);
+ PyObject *ret = _forward_call(self->writer, &PyId_close, args);
if (ret == NULL)
return NULL;
Py_DECREF(ret);
- return _forward_call(self->reader, "close", args);
+ return _forward_call(self->reader, &PyId_close, args);
}
static PyObject *
bufferedrwpair_isatty(rwpair *self, PyObject *args)
{
- PyObject *ret = _forward_call(self->writer, "isatty", args);
+ PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
if (ret != Py_False) {
/* either True or exception */
}
Py_DECREF(ret);
- return _forward_call(self->reader, "isatty", args);
+ return _forward_call(self->reader, &PyId_isatty, args);
}
static PyObject *
static PyObject *
fileio_close(fileio *self)
{
+ _Py_identifier(close);
if (!self->closefd) {
self->fd = -1;
Py_RETURN_NONE;
if (errno < 0)
return NULL;
- return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type,
- "close", "O", self);
+ return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type,
+ &PyId_close, "O", self);
}
static PyObject *
static PyObject *
iobase_tell(PyObject *self, PyObject *args)
{
- return PyObject_CallMethod(self, "seek", "ii", 0, 1);
+ _Py_identifier(seek);
+
+ return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1);
}
PyDoc_STRVAR(iobase_truncate_doc,
int has_peek = 0;
PyObject *buffer, *result;
Py_ssize_t old_size = -1;
+ _Py_identifier(read);
if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
return NULL;
PyObject *b;
if (has_peek) {
- PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
+ _Py_identifier(peek);
+ PyObject *readahead = _PyObject_CallMethodId(self, &PyId_peek, "i", 1);
+
if (readahead == NULL)
goto fail;
if (!PyBytes_Check(readahead)) {
Py_DECREF(readahead);
}
- b = PyObject_CallMethod(self, "read", "n", nreadahead);
+ b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead);
if (b == NULL)
goto fail;
if (!PyBytes_Check(b)) {
/* XXX special-casing this made sense in the Python version in order
to remove the bytecode interpretation overhead, but it could
probably be removed here. */
- PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
+ _Py_identifier(extend);
+ PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self);
+
if (ret == NULL) {
Py_DECREF(result);
return NULL;
return NULL;
}
- if (n < 0)
- return PyObject_CallMethod(self, "readall", NULL);
+ if (n < 0) {
+ _Py_identifier(readall);
+
+ return _PyObject_CallMethodId(self, &PyId_readall, NULL);
+ }
/* TODO: allocate a bytes object directly instead and manually construct
a writable memoryview pointing to it. */
return NULL;
while (1) {
- PyObject *data = PyObject_CallMethod(self, "read",
- "i", DEFAULT_BUFFER_SIZE);
+ _Py_identifier(read);
+ PyObject *data = _PyObject_CallMethodId(self, &PyId_read,
+ "i", DEFAULT_BUFFER_SIZE);
if (!data) {
Py_DECREF(chunks);
return NULL;
#include "structmember.h"
#include "_iomodule.h"
+_Py_identifier(close);
+_Py_identifier(_dealloc_warn);
+_Py_identifier(decode);
+_Py_identifier(device_encoding);
+_Py_identifier(fileno);
+_Py_identifier(flush);
+_Py_identifier(getpreferredencoding);
+_Py_identifier(isatty);
+_Py_identifier(read);
+_Py_identifier(readable);
+_Py_identifier(replace);
+_Py_identifier(reset);
+_Py_identifier(seek);
+_Py_identifier(seekable);
+_Py_identifier(setstate);
+_Py_identifier(tell);
+_Py_identifier(writable);
+
/* TextIOBase */
PyDoc_STRVAR(textiobase_doc,
flag >>= 1;
if (self->decoder != Py_None)
- return PyObject_CallMethod(self->decoder,
- "setstate", "((OK))", buffer, flag);
+ return _PyObject_CallMethodId(self->decoder,
+ &PyId_setstate, "((OK))", buffer, flag);
else
Py_RETURN_NONE;
}
if (encoding == NULL) {
/* Try os.device_encoding(fileno) */
PyObject *fileno;
- fileno = PyObject_CallMethod(buffer, "fileno", NULL);
+ fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL);
/* Ignore only AttributeError and UnsupportedOperation */
if (fileno == NULL) {
if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
}
}
else {
- self->encoding = PyObject_CallMethod(state->os_module,
- "device_encoding",
- "N", fileno);
+ self->encoding = _PyObject_CallMethodId(state->os_module,
+ &PyId_device_encoding,
+ "N", fileno);
if (self->encoding == NULL)
goto error;
else if (!PyUnicode_Check(self->encoding))
}
else {
use_locale:
- self->encoding = PyObject_CallMethod(
- state->locale_module, "getpreferredencoding", NULL);
+ self->encoding = _PyObject_CallMethodId(
+ state->locale_module, &PyId_getpreferredencoding, NULL);
if (self->encoding == NULL) {
catch_ImportError:
/*
#endif
/* Build the decoder object */
- res = PyObject_CallMethod(buffer, "readable", NULL);
+ res = _PyObject_CallMethodId(buffer, &PyId_readable, NULL);
if (res == NULL)
goto error;
r = PyObject_IsTrue(res);
}
/* Build the encoder object */
- res = PyObject_CallMethod(buffer, "writable", NULL);
+ res = _PyObject_CallMethodId(buffer, &PyId_writable, NULL);
if (res == NULL)
goto error;
r = PyObject_IsTrue(res);
Py_DECREF(raw);
}
- res = PyObject_CallMethod(buffer, "seekable", NULL);
+ res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
if (res == NULL)
goto error;
self->seekable = self->telling = PyObject_IsTrue(res);
haslf = 1;
if (haslf && self->writetranslate && self->writenl != NULL) {
- PyObject *newtext = PyObject_CallMethod(
- text, "replace", "ss", "\n", self->writenl);
+ PyObject *newtext = _PyObject_CallMethodId(
+ text, &PyId_replace, "ss", "\n", self->writenl);
Py_DECREF(text);
if (newtext == NULL)
return NULL;
Py_CLEAR(self->snapshot);
if (self->decoder) {
- ret = PyObject_CallMethod(self->decoder, "reset", NULL);
+ ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
if (ret == NULL)
return NULL;
Py_DECREF(ret);
if (n < 0) {
/* Read everything */
- PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
+ PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL);
PyObject *decoded;
if (bytes == NULL)
goto fail;
if (cookie->start_pos == 0 && cookie->dec_flags == 0)
res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
else
- res = PyObject_CallMethod(self->decoder, "setstate",
- "((yi))", "", cookie->dec_flags);
+ res = _PyObject_CallMethodId(self->decoder, &PyId_setstate,
+ "((yi))", "", cookie->dec_flags);
if (res == NULL)
return -1;
Py_DECREF(res);
* sync the underlying buffer with the current position.
*/
Py_DECREF(cookieObj);
- cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
+ cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL);
if (cookieObj == NULL)
goto fail;
}
else if (whence == 2) {
/* seek relative to end of file */
-
cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
if (cmp < 0)
goto fail;
goto fail;
}
- res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+ res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
if (res == NULL)
goto fail;
Py_DECREF(res);
textiowrapper_set_decoded_chars(self, NULL);
Py_CLEAR(self->snapshot);
if (self->decoder) {
- res = PyObject_CallMethod(self->decoder, "reset", NULL);
+ res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
if (res == NULL)
goto fail;
Py_DECREF(res);
}
- res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
+ res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2);
Py_XDECREF(cookieObj);
return res;
}
if (cookie.chars_to_skip) {
/* Just like _read_chunk, feed the decoder and save a snapshot. */
- PyObject *input_chunk = PyObject_CallMethod(
- self->buffer, "read", "i", cookie.bytes_to_feed);
+ PyObject *input_chunk = _PyObject_CallMethodId(
+ self->buffer, &PyId_read, "i", cookie.bytes_to_feed);
PyObject *decoded;
if (input_chunk == NULL)
goto fail;
}
- decoded = PyObject_CallMethod(self->decoder, "decode",
- "Oi", input_chunk, (int)cookie.need_eof);
+ decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode,
+ "Oi", input_chunk, (int)cookie.need_eof);
if (decoded == NULL)
goto fail;
if (_textiowrapper_writeflush(self) < 0)
return NULL;
- res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+ res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
if (res == NULL)
goto fail;
Py_DECREF(res);
- posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
+ posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL);
if (posobj == NULL)
goto fail;
/* TODO: replace assert with exception */
#define DECODER_DECODE(start, len, res) do { \
- PyObject *_decoded = PyObject_CallMethod( \
- self->decoder, "decode", "y#", start, len); \
+ PyObject *_decoded = _PyObject_CallMethodId( \
+ self->decoder, &PyId_decode, "y#", start, len); \
if (_decoded == NULL) \
goto fail; \
assert (PyUnicode_Check(_decoded)); \
}
if (input == input_end) {
/* We didn't get enough decoded data; signal EOF to get more. */
- PyObject *decoded = PyObject_CallMethod(
- self->decoder, "decode", "yi", "", /* final = */ 1);
+ PyObject *decoded = _PyObject_CallMethodId(
+ self->decoder, &PyId_decode, "yi", "", /* final = */ 1);
if (decoded == NULL)
goto fail;
assert (PyUnicode_Check(decoded));
}
finally:
- res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
+ res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state);
Py_DECREF(saved_state);
if (res == NULL)
return NULL;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
- res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
+ res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state);
Py_DECREF(saved_state);
if (res == NULL)
return NULL;
textiowrapper_fileno(textio *self, PyObject *args)
{
CHECK_INITIALIZED(self);
- return PyObject_CallMethod(self->buffer, "fileno", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
}
static PyObject *
textiowrapper_seekable(textio *self, PyObject *args)
{
CHECK_INITIALIZED(self);
- return PyObject_CallMethod(self->buffer, "seekable", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
}
static PyObject *
textiowrapper_readable(textio *self, PyObject *args)
{
CHECK_INITIALIZED(self);
- return PyObject_CallMethod(self->buffer, "readable", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
}
static PyObject *
textiowrapper_writable(textio *self, PyObject *args)
{
CHECK_INITIALIZED(self);
- return PyObject_CallMethod(self->buffer, "writable", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
}
static PyObject *
textiowrapper_isatty(textio *self, PyObject *args)
{
CHECK_INITIALIZED(self);
- return PyObject_CallMethod(self->buffer, "isatty", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
}
static PyObject *
self->telling = self->seekable;
if (_textiowrapper_writeflush(self) < 0)
return NULL;
- return PyObject_CallMethod(self->buffer, "flush", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL);
}
static PyObject *
}
else {
if (self->deallocating) {
- res = PyObject_CallMethod(self->buffer, "_dealloc_warn", "O", self);
+ res = _PyObject_CallMethodId(self->buffer, &PyId__dealloc_warn, "O", self);
if (res)
Py_DECREF(res);
else
PyErr_Clear();
}
- res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
+ res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
if (res == NULL) {
return NULL;
}
else
Py_DECREF(res);
- return PyObject_CallMethod(self->buffer, "close", NULL);
+ return _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
}
}
status = batch_dict_exact(self, obj);
Py_LeaveRecursiveCall();
} else {
- items = PyObject_CallMethod(obj, "items", "()");
+ _Py_identifier(items);
+
+ items = _PyObject_CallMethodId(obj, &PyId_items, "()");
if (items == NULL)
goto error;
iter = PyObject_GetIter(items);
static PyObject *
find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
{
- return PyObject_CallMethod((PyObject *)self, "find_class", "OO",
- module_name, global_name);
+ _Py_identifier(find_class);
+
+ return _PyObject_CallMethodId((PyObject *)self, &PyId_find_class, "OO",
+ module_name, global_name);
}
static Py_ssize_t
result = PyObject_CallObject(cls, args);
}
else {
- result = PyObject_CallMethod(cls, "__new__", "O", cls);
+ _Py_identifier(__new__);
+
+ result = _PyObject_CallMethodId(cls, &PyId___new__, "O", cls);
}
return result;
}
static int _enable_gc(PyObject *gc_module)
{
PyObject *result;
- result = PyObject_CallMethod(gc_module, "enable", NULL);
+ _Py_identifier(enable);
+
+ result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL);
if (result == NULL)
return 1;
Py_DECREF(result);
/* We need to call gc.disable() when we'll be calling preexec_fn */
if (preexec_fn != Py_None) {
PyObject *result;
+ _Py_identifier(isenabled);
+ _Py_identifier(disable);
+
gc_module = PyImport_ImportModule("gc");
if (gc_module == NULL)
return NULL;
- result = PyObject_CallMethod(gc_module, "isenabled", NULL);
+ result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, NULL);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
Py_DECREF(gc_module);
return NULL;
}
- result = PyObject_CallMethod(gc_module, "disable", NULL);
+ result = _PyObject_CallMethodId(gc_module, &PyId_disable, NULL);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
{
PyObject* function_result = NULL;
PyObject** aggregate_instance;
+ _Py_identifier(finalize);
#ifdef WITH_THREAD
PyGILState_STATE threadstate;
goto error;
}
- function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
+ function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, "");
if (!function_result) {
if (_enable_callback_tracebacks) {
PyErr_Print();
PyObject* cursor = 0;
PyObject* result = 0;
PyObject* method = 0;
+ _Py_identifier(cursor);
- cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, "");
if (!cursor) {
goto error;
}
PyObject* cursor = 0;
PyObject* result = 0;
PyObject* method = 0;
+ _Py_identifier(cursor);
- cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, "");
if (!cursor) {
goto error;
}
PyObject* cursor = 0;
PyObject* result = 0;
PyObject* method = 0;
+ _Py_identifier(cursor);
- cursor = PyObject_CallMethod((PyObject*)self, "cursor", "");
+ cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, "");
if (!cursor) {
goto error;
}
PyObject* name;
PyObject* retval;
Py_ssize_t i, len;
+ _Py_identifier(upper);
char *uppercase_name_str;
int rc;
unsigned int kind;
goto finally;
}
- uppercase_name = PyObject_CallMethod(name, "upper", "");
+ uppercase_name = _PyObject_CallMethodId(name, &PyId_upper, "");
if (!uppercase_name) {
goto finally;
}
{
PyObject* upcase_key;
PyObject* retval;
+ _Py_identifier(upper);
- upcase_key = PyObject_CallMethod(key, "upper", "");
+ upcase_key = _PyObject_CallMethodId(key, &PyId_upper, "");
if (!upcase_key) {
return NULL;
}
/* try to have the protocol adapt this object*/
if (PyObject_HasAttrString(proto, "__adapt__")) {
- PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
+ _Py_identifier(__adapt__);
+ PyObject *adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj);
+
if (adapted) {
if (adapted != Py_None) {
return adapted;
/* and finally try to have the object adapt itself */
if (PyObject_HasAttrString(obj, "__conform__")) {
- PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
+ _Py_identifier(__conform__);
+ PyObject *adapted = _PyObject_CallMethodId(obj, &PyId___conform__,"O", proto);
+
if (adapted) {
if (adapted != Py_None) {
return adapted;
PyObject* name = NULL;
PyObject* callable;
PyObject* retval = NULL;
+ _Py_identifier(upper);
if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) {
return NULL;
}
/* convert the name to upper case */
- name = PyObject_CallMethod(orig_name, "upper", "");
+ name = _PyObject_CallMethodId(orig_name, &PyId_upper, "");
if (!name) {
goto error;
}
PyObject *f, *b, *res;
Py_ssize_t itemsize = self->ob_descr->itemsize;
Py_ssize_t n, nbytes;
+ _Py_identifier(read);
int not_enough_bytes;
if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n))
return NULL;
}
- b = PyObject_CallMethod(f, "read", "n", nbytes);
+ b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes);
if (b == NULL)
return NULL;
char* ptr = self->ob_item + i*BLOCKSIZE;
Py_ssize_t size = BLOCKSIZE;
PyObject *bytes, *res;
+ _Py_identifier(write);
+
if (i*BLOCKSIZE + size > nbytes)
size = nbytes - i*BLOCKSIZE;
bytes = PyBytes_FromStringAndSize(ptr, size);
if (bytes == NULL)
return NULL;
- res = PyObject_CallMethod(f, "write", "O", bytes);
+ res = _PyObject_CallMethodId(f, &PyId_write, "O", bytes);
Py_DECREF(bytes);
if (res == NULL)
return NULL;
PyObject *unistr)
{
PyObject *str, *wr;
+ _Py_identifier(write);
str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0);
if (str == NULL)
return -1;
- wr = PyObject_CallMethod(self->stream, "write", "O", str);
+ wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", str);
Py_DECREF(str);
if (wr == NULL)
return -1;
assert(PyBytes_Check(pwrt));
if (PyBytes_Size(pwrt) > 0) {
PyObject *wr;
- wr = PyObject_CallMethod(self->stream, "write", "O", pwrt);
+ _Py_identifier(write);
+
+ wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", pwrt);
if (wr == NULL) {
Py_DECREF(pwrt);
return NULL;
faulthandler_get_fileno(PyObject *file, int *p_fd)
{
PyObject *result;
+ _Py_identifier(fileno);
+ _Py_identifier(flush);
long fd_long;
int fd;
}
}
- result = PyObject_CallMethod(file, "fileno", "");
+ result = _PyObject_CallMethodId(file, &PyId_fileno, "");
if (result == NULL)
return NULL;
return NULL;
}
- result = PyObject_CallMethod(file, "flush", "");
+ result = _PyObject_CallMethodId(file, &PyId_flush, "");
if (result != NULL)
Py_DECREF(result);
else {
faulthandler_env_options(void)
{
PyObject *xoptions, *key, *module, *res;
+ _Py_identifier(enable);
if (!Py_GETENV("PYTHONFAULTHANDLER")) {
int has_key;
if (module == NULL) {
return -1;
}
- res = PyObject_CallMethod(module, "enable", "");
+ res = _PyObject_CallMethodId(module, &PyId_enable, "");
Py_DECREF(module);
if (res == NULL)
return -1;
{
double result = 0;
if (tmod != NULL) {
- PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
+ _Py_identifier(time);
+
+ PyObject *f = _PyObject_CallMethodId(tmod, &PyId_time, NULL);
if (f == NULL) {
PyErr_Clear();
}
copyable = it;
PyTuple_SET_ITEM(result, 0, copyable);
for (i=1 ; i<n ; i++) {
- copyable = PyObject_CallMethod(copyable, "__copy__", NULL);
+ _Py_identifier(__copy__);
+
+ copyable = _PyObject_CallMethodId(copyable, &PyId___copy__, NULL);
if (copyable == NULL) {
Py_DECREF(result);
return NULL;
static PyObject *
mmap__exit__method(PyObject *self, PyObject *args)
{
- return PyObject_CallMethod(self, "close", NULL);
+ _Py_identifier(close);
+
+ return _PyObject_CallMethodId(self, &PyId_close, NULL);
}
static struct PyMethodDef mmap_object_methods[] = {
static PyObject *
oss_exit(PyObject *self, PyObject *unused)
{
- PyObject *ret = PyObject_CallMethod(self, "close", NULL);
+ _Py_identifier(close);
+
+ PyObject *ret = _PyObject_CallMethodId(self, &PyId_close, NULL);
if (!ret)
return NULL;
Py_DECREF(ret);
if (hobj == Py_None) {
hptr = NULL;
} else if (PyUnicode_Check(hobj)) {
- idna = PyObject_CallMethod(hobj, "encode", "s", "idna");
+ _Py_identifier(encode);
+
+ idna = _PyObject_CallMethodId(hobj, &PyId_encode, "s", "idna");
if (!idna)
return NULL;
assert(PyBytes_Check(idna));
{
PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");
PyObject *strptime_result;
+ _Py_identifier(_strptime_time);
if (!strptime_module)
return NULL;
- strptime_result = PyObject_CallMethod(strptime_module,
- "_strptime_time", "O", args);
+ strptime_result = _PyObject_CallMethodId(strptime_module,
+ &PyId__strptime_time, "O", args);
Py_DECREF(strptime_module);
return strptime_result;
}
{
PyObject *keys;
PyObject *fast;
+ _Py_identifier(keys);
if (PyDict_CheckExact(o))
return PyDict_Keys(o);
- keys = PyObject_CallMethod(o, "keys", NULL);
+ keys = _PyObject_CallMethodId(o, &PyId_keys, NULL);
if (keys == NULL)
return NULL;
fast = PySequence_Fast(keys, "o.keys() are not iterable");
{
PyObject *items;
PyObject *fast;
+ _Py_identifier(items);
if (PyDict_CheckExact(o))
return PyDict_Items(o);
- items = PyObject_CallMethod(o, "items", NULL);
+ items = _PyObject_CallMethodId(o, &PyId_items, NULL);
if (items == NULL)
return NULL;
fast = PySequence_Fast(items, "o.items() are not iterable");
{
PyObject *values;
PyObject *fast;
+ _Py_identifier(values);
if (PyDict_CheckExact(o))
return PyDict_Values(o);
- values = PyObject_CallMethod(o, "values", NULL);
+ values = _PyObject_CallMethodId(o, &PyId_values, NULL);
if (values == NULL)
return NULL;
fast = PySequence_Fast(values, "o.values() are not iterable");
return call_function_tail(callable, args);
}
-PyObject *
-PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
+static PyObject*
+callmethod(PyObject* func, char *format, va_list va, int is_size_t)
{
- va_list va;
- PyObject *args;
- PyObject *func = NULL;
PyObject *retval = NULL;
-
- if (o == NULL || name == NULL)
- return null_error();
-
- func = PyObject_GetAttrString(o, name);
- if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
- return 0;
- }
+ PyObject *args;
if (!PyCallable_Check(func)) {
type_error("attribute of type '%.200s' is not callable", func);
}
if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
+ if (is_size_t)
+ args = _Py_VaBuildValue_SizeT(format, va);
+ else
+ args = Py_VaBuildValue(format, va);
}
else
args = PyTuple_New(0);
}
PyObject *
-_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
{
va_list va;
- PyObject *args;
PyObject *func = NULL;
PyObject *retval = NULL;
return 0;
}
- if (!PyCallable_Check(func)) {
- type_error("attribute of type '%.200s' is not callable", func);
- goto exit;
- }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 0);
+ va_end(va);
+ return retval;
+}
- if (format && *format) {
- va_start(va, format);
- args = _Py_VaBuildValue_SizeT(format, va);
- va_end(va);
+PyObject *
+_PyObject_CallMethodId(PyObject *o, _Py_Identifier *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = _PyObject_GetAttrId(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name->string);
+ return 0;
}
- else
- args = PyTuple_New(0);
- retval = call_function_tail(func, args);
+ va_start(va, format);
+ retval = callmethod(func, format, va, 0);
+ va_end(va);
+ return retval;
+}
- exit:
- /* args gets consumed in call_function_tail */
- Py_XDECREF(func);
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return 0;
+ }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 1);
+ va_end(va);
return retval;
}
+PyObject *
+_PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name, char *format, ...)
+{
+ va_list va;
+ PyObject *func = NULL;
+ PyObject *retval;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = _PyObject_GetAttrId(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name->string);
+ return NULL;
+ }
+ va_start(va, format);
+ retval = callmethod(func, format, va, 1);
+ va_end(va);
+ return retval;
+}
static PyObject *
objargs_mktuple(va_list va)
proxy_get(proxyobject *pp, PyObject *args)
{
PyObject *key, *def = Py_None;
+ _Py_identifier(get);
if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def))
return NULL;
- return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def);
+ return _PyObject_CallMethodId(pp->dict, &PyId_get, "(OO)", key, def);
}
static PyObject *
proxy_keys(proxyobject *pp)
{
- return PyObject_CallMethod(pp->dict, "keys", NULL);
+ _Py_identifier(keys);
+ return _PyObject_CallMethodId(pp->dict, &PyId_keys, NULL);
}
static PyObject *
proxy_values(proxyobject *pp)
{
- return PyObject_CallMethod(pp->dict, "values", NULL);
+ _Py_identifier(values);
+ return _PyObject_CallMethodId(pp->dict, &PyId_values, NULL);
}
static PyObject *
proxy_items(proxyobject *pp)
{
- return PyObject_CallMethod(pp->dict, "items", NULL);
+ _Py_identifier(items);
+ return _PyObject_CallMethodId(pp->dict, &PyId_items, NULL);
}
static PyObject *
proxy_copy(proxyobject *pp)
{
- return PyObject_CallMethod(pp->dict, "copy", NULL);
+ _Py_identifier(copy);
+ return _PyObject_CallMethodId(pp->dict, &PyId_copy, NULL);
}
static PyMethodDef proxy_methods[] = {
{
PyObject *result = PySet_New(self);
PyObject *tmp;
+ _Py_identifier(difference_update);
+
if (result == NULL)
return NULL;
- tmp = PyObject_CallMethod(result, "difference_update", "O", other);
+ tmp = _PyObject_CallMethodId(result, &PyId_difference_update, "O", other);
if (tmp == NULL) {
Py_DECREF(result);
return NULL;
{
PyObject *result = PySet_New(self);
PyObject *tmp;
+ _Py_identifier(intersection_update);
+
if (result == NULL)
return NULL;
- tmp = PyObject_CallMethod(result, "intersection_update", "O", other);
+ tmp = _PyObject_CallMethodId(result, &PyId_intersection_update, "O", other);
if (tmp == NULL) {
Py_DECREF(result);
return NULL;
{
PyObject *result = PySet_New(self);
PyObject *tmp;
+ _Py_identifier(symmetric_difference_update);
+
if (result == NULL)
return NULL;
- tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O",
+ tmp = _PyObject_CallMethodId(result, &PyId_symmetric_difference_update, "O",
other);
if (tmp == NULL) {
Py_DECREF(result);
char *errors, char *newline, int closefd)
{
PyObject *io, *stream;
+ _Py_identifier(open);
io = PyImport_ImportModule("io");
if (io == NULL)
return NULL;
- stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode,
+ stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
buffering, encoding, errors,
newline, closefd);
Py_DECREF(io);
return res;
}
+PyObject *
+_PyObject_GetAttrId(PyObject *v, _Py_Identifier *name)
+{
+ PyObject *result;
+ PyObject *oname = _PyUnicode_FromId(name);
+ if (!oname)
+ return NULL;
+ result = PyObject_GetAttr(v, oname);
+ Py_DECREF(oname);
+ return result;
+}
+
+int
+_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name)
+{
+ int result;
+ PyObject *oname = _PyUnicode_FromId(name);
+ if (!oname)
+ return -1;
+ result = PyObject_HasAttr(v, oname);
+ Py_DECREF(oname);
+ return result;
+}
+
+int
+_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w)
+{
+ int result;
+ PyObject *oname = _PyUnicode_FromId(name);
+ if (!oname)
+ return -1;
+ result = PyObject_SetAttr(v, oname, w);
+ Py_DECREF(oname);
+ return result;
+}
+
PyObject *
PyObject_GetAttr(PyObject *v, PyObject *name)
{
PyObject *sorted;
PyObject *sorted_methods = NULL;
PyObject *joined = NULL;
+ _Py_identifier(join);
/* Compute ", ".join(sorted(type.__abstractmethods__))
into joined. */
if (comma == NULL)
goto error;
}
- joined = PyObject_CallMethod(comma, "join",
+ joined = _PyObject_CallMethodId(comma, &PyId_join,
"O", sorted_methods);
if (joined == NULL)
goto error;
PyObject *copyreg;
PyObject *slotnames;
static PyObject *str_slotnames;
+ _Py_identifier(_slotnames);
if (str_slotnames == NULL) {
str_slotnames = PyUnicode_InternFromString("__slotnames__");
if (copyreg == NULL)
return NULL;
- slotnames = PyObject_CallMethod(copyreg, "_slotnames", "O", cls);
+ slotnames = _PyObject_CallMethodId(copyreg, &PyId__slotnames, "O", cls);
Py_DECREF(copyreg);
if (slotnames != NULL &&
slotnames != Py_None &&
Py_INCREF(dictitems);
}
else {
- PyObject *items = PyObject_CallMethod(obj, "items", "");
+ _Py_identifier(items);
+ PyObject *items = _PyObject_CallMethodId(obj, &PyId_items, "");
if (items == NULL)
goto end;
dictitems = PyObject_GetIter(items);
/* The empty Unicode object is shared to improve performance. */
static PyObject *unicode_empty;
+/* List of static strings. */
+static _Py_Identifier *static_strings;
+
/* Single character Unicode strings in the Latin-1 range are being
shared as well. */
static PyObject *unicode_latin1[256];
return PyUnicode_FromStringAndSize(u, size);
}
+PyObject *
+_PyUnicode_FromId(_Py_Identifier *id)
+{
+ if (!id->object) {
+ id->object = PyUnicode_FromString(id->string);
+ if (!id->object)
+ return NULL;
+ PyUnicode_InternInPlace(&id->object);
+ assert(!id->next);
+ id->next = static_strings;
+ static_strings = id;
+ }
+ Py_INCREF(id->object);
+ return id->object;
+}
+
+void
+_PyUnicode_ClearStaticStrings()
+{
+ _Py_Identifier *i;
+ for (i = static_strings; i; i = i->next) {
+ Py_DECREF(i->object);
+ i->object = NULL;
+ i->next = NULL;
+ }
+}
+
static PyObject*
unicode_fromascii(const unsigned char* s, Py_ssize_t size)
{
unicode_latin1[i] = NULL;
}
}
+ _PyUnicode_ClearStaticStrings();
(void)PyUnicode_ClearFreeList();
}
#define WRAP_METHOD(method, special) \
static PyObject * \
method(PyObject *proxy) { \
+ _Py_identifier(special); \
UNWRAP(proxy); \
- return PyObject_CallMethod(proxy, special, ""); \
+ return _PyObject_CallMethodId(proxy, &PyId_##special, ""); \
}
}
-WRAP_METHOD(proxy_bytes, "__bytes__")
+WRAP_METHOD(proxy_bytes, __bytes__)
static PyMethodDef proxy_methods[] = {
static FNFCISTATUS(cb_status)
{
if (pv) {
- PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2);
+ _Py_identifier(status);
+
+ PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2);
if (result == NULL)
return -1;
Py_DECREF(result);
static FNFCIGETNEXTCABINET(cb_getnextcabinet)
{
if (pv) {
- PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab);
+ _Py_identifier(getnextcabinet);
+
+ PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab);
if (result == NULL)
return -1;
if (!PyBytes_Check(result)) {
fp_setreadl(struct tok_state *tok, const char* enc)
{
PyObject *readline = NULL, *stream = NULL, *io = NULL;
+ _Py_identifier(open);
int fd;
io = PyImport_ImportModuleNoBlock("io");
goto cleanup;
}
- stream = PyObject_CallMethod(io, "open", "isisOOO",
+ stream = _PyObject_CallMethodId(io, &PyId_open, "isisOOO",
fd, "r", -1, enc, Py_None, Py_None, Py_False);
if (stream == NULL)
goto cleanup;
check_matched(PyObject *obj, PyObject *arg)
{
PyObject *result;
+ _Py_identifier(match);
int rc;
if (obj == Py_None)
return 1;
- result = PyObject_CallMethod(obj, "match", "O", arg);
+ result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg);
if (result == NULL)
return -1;
static identifier
new_identifier(const char* n, PyArena *arena)
{
+ _Py_identifier(normalize);
PyObject* id = PyUnicode_DecodeUTF8(n, strlen(n), NULL);
if (!id || PyUnicode_READY(id) == -1)
return NULL;
PyObject *id2;
if (!m)
return NULL;
- id2 = PyObject_CallMethod(m, "normalize", "sO", "NFKC", id);
+ id2 = _PyObject_CallMethodId(m, &PyId_normalize, "sO", "NFKC", id);
Py_DECREF(m);
if (!id2)
return NULL;
int Py_HasFileSystemDefaultEncoding = 0;
#endif
+_Py_identifier(fileno);
+_Py_identifier(flush);
+
static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{
}
/* First of all, flush stderr */
- tmp = PyObject_CallMethod(ferr, "flush", "");
+ tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
if (tmp == NULL)
PyErr_Clear();
else
/* We should only use (GNU) readline if Python's sys.stdin and
sys.stdout are the same as C's stdin and stdout, because we
need to pass it those. */
- tmp = PyObject_CallMethod(fin, "fileno", "");
+ tmp = _PyObject_CallMethodId(fin, &PyId_fileno, "");
if (tmp == NULL) {
PyErr_Clear();
tty = 0;
tty = fd == fileno(stdin) && isatty(fd);
}
if (tty) {
- tmp = PyObject_CallMethod(fout, "fileno", "");
+ tmp = _PyObject_CallMethodId(fout, &PyId_fileno, "");
if (tmp == NULL)
PyErr_Clear();
else {
Py_DECREF(stdin_encoding);
return NULL;
}
- tmp = PyObject_CallMethod(fout, "flush", "");
+ tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
if (tmp == NULL)
PyErr_Clear();
else
if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)
return NULL;
}
- tmp = PyObject_CallMethod(fout, "flush", "");
+ tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
if (tmp == NULL)
PyErr_Clear();
else
void
PyEval_ReInitThreads(void)
{
+ _Py_identifier(_after_fork);
PyObject *threading, *result;
PyThreadState *tstate = PyThreadState_GET();
PyErr_Clear();
return;
}
- result = PyObject_CallMethod(threading, "_after_fork", NULL);
+ result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL);
if (result == NULL)
PyErr_WriteUnraisable(threading);
else
/* sys.path_hooks import hook */
if (p_loader != NULL) {
+ _Py_identifier(find_module);
PyObject *importer;
importer = get_path_importer(path_importer_cache,
/* Note: importer is a borrowed reference */
if (importer != Py_None) {
PyObject *loader;
- loader = PyObject_CallMethod(importer,
- "find_module", "O", fullname);
+ loader = _PyObject_CallMethodId(importer,
+ &PyId_find_module, "O", fullname);
if (loader == NULL)
return -1; /* error */
if (loader != Py_None) {
/* sys.meta_path import hook */
if (p_loader != NULL) {
+ _Py_identifier(find_module);
PyObject *meta_path;
meta_path = PySys_GetObject("meta_path");
for (i = 0; i < npath; i++) {
PyObject *loader;
PyObject *hook = PyList_GetItem(meta_path, i);
- loader = PyObject_CallMethod(hook, "find_module",
+ loader = _PyObject_CallMethodId(hook, &PyId_find_module,
"OO", fullname,
search_path_list != NULL ?
search_path_list : Py_None);
break;
case IMP_HOOK: {
+ _Py_identifier(load_module);
if (loader == NULL) {
PyErr_SetString(PyExc_ImportError,
"import hook without loader");
return NULL;
}
- m = PyObject_CallMethod(loader, "load_module", "O", name);
+ m = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name);
break;
}
}
}
else {
- PyObject *data = PyObject_CallMethod(p->readable, "read", "i", n);
+ _Py_identifier(read);
+
+ PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "i", n);
read = 0;
if (data != NULL) {
if (!PyBytes_Check(data)) {
int version = Py_MARSHAL_VERSION;
PyObject *s;
PyObject *res;
+ _Py_identifier(write);
+
if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
return NULL;
s = PyMarshal_WriteObjectToString(x, version);
if (s == NULL)
return NULL;
- res = PyObject_CallMethod(f, "write", "O", s);
+ res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
Py_DECREF(s);
return res;
}
marshal_load(PyObject *self, PyObject *f)
{
PyObject *data, *result;
+ _Py_identifier(read);
RFILE rf;
/*
* This is to ensure that the object passed in at least
* has a read method which returns bytes.
*/
- data = PyObject_CallMethod(f, "read", "i", 0);
+ data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
if (data == NULL)
return NULL;
if (!PyBytes_Check(data)) {
PyObject *fout = PySys_GetObject("stdout");
PyObject *ferr = PySys_GetObject("stderr");
PyObject *tmp;
+ _Py_identifier(flush);
if (fout != NULL && fout != Py_None) {
- tmp = PyObject_CallMethod(fout, "flush", "");
+ tmp = _PyObject_CallMethodId(fout, &PyId_flush, "");
if (tmp == NULL)
PyErr_WriteUnraisable(fout);
else
}
if (ferr != NULL && ferr != Py_None) {
- tmp = PyObject_CallMethod(ferr, "flush", "");
+ tmp = _PyObject_CallMethodId(ferr, &PyId_flush, "");
if (tmp == NULL)
PyErr_Clear();
else
const char* newline;
PyObject *line_buffering;
int buffering, isatty;
+ _Py_identifier(open);
+ _Py_identifier(isatty);
+ _Py_identifier(TextIOWrapper);
/* stdin is always opened in buffered mode, first because it shouldn't
make a difference in common use cases, second because TextIOWrapper
mode = "wb";
else
mode = "rb";
- buf = PyObject_CallMethod(io, "open", "isiOOOi",
- fd, mode, buffering,
- Py_None, Py_None, Py_None, 0);
+ buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi",
+ fd, mode, buffering,
+ Py_None, Py_None, Py_None, 0);
if (buf == NULL)
goto error;
text = PyUnicode_FromString(name);
if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0)
goto error;
- res = PyObject_CallMethod(raw, "isatty", "");
+ res = _PyObject_CallMethodId(raw, &PyId_isatty, "");
if (res == NULL)
goto error;
isatty = PyObject_IsTrue(res);
}
#endif
- stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO",
- buf, encoding, errors,
- newline, line_buffering);
+ stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO",
+ buf, encoding, errors,
+ newline, line_buffering);
Py_CLEAR(buf);
if (stream == NULL)
goto error;
{
PyObject *f, *r;
PyObject *type, *value, *traceback;
+ _Py_identifier(flush);
/* Save the current exception */
PyErr_Fetch(&type, &value, &traceback);
f = PySys_GetObject("stderr");
if (f != NULL) {
- r = PyObject_CallMethod(f, "flush", "");
+ r = _PyObject_CallMethodId(f, &PyId_flush, "");
if (r)
Py_DECREF(r);
else
}
f = PySys_GetObject("stdout");
if (f != NULL) {
- r = PyObject_CallMethod(f, "flush", "");
+ r = _PyObject_CallMethodId(f, &PyId_flush, "");
if (r)
Py_DECREF(r);
else
wait_for_thread_shutdown(void)
{
#ifdef WITH_THREAD
+ _Py_identifier(_shutdown);
PyObject *result;
PyThreadState *tstate = PyThreadState_GET();
PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,
PyErr_Clear();
return;
}
- result = PyObject_CallMethod(threading, "_shutdown", "");
+ result = _PyObject_CallMethodId(threading, &PyId__shutdown, "");
if (result == NULL) {
PyErr_WriteUnraisable(threading);
}
buffer = PyObject_GetAttrString(outf, "buffer");
if (buffer) {
- result = PyObject_CallMethod(buffer, "write", "(O)", encoded);
+ _Py_identifier(write);
+ result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded);
Py_DECREF(buffer);
Py_DECREF(encoded);
if (result == NULL)
const char* filepath;
Py_ssize_t len;
PyObject* result;
+ _Py_identifier(open);
filebytes = PyUnicode_EncodeFSDefault(filename);
if (filebytes == NULL) {
namebuf[len++] = SEP;
strcpy(namebuf+len, tail);
- binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb");
+ binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb");
if (binary != NULL) {
result = binary;
goto finally;
char buf[MAXPATHLEN+1];
int kind;
void *data;
+ _Py_identifier(close);
+ _Py_identifier(open);
+ _Py_identifier(TextIOWrapper);
/* open the file */
if (filename == NULL)
io = PyImport_ImportModuleNoBlock("io");
if (io == NULL)
return -1;
- binary = PyObject_CallMethod(io, "open", "Os", filename, "rb");
+ binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb");
if (binary == NULL) {
binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io);
found_encoding = PyTokenizer_FindEncodingFilename(fd, filename);
encoding = (found_encoding != NULL) ? found_encoding : "utf-8";
lseek(fd, 0, 0); /* Reset position */
- fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding);
+ fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding);
Py_DECREF(io);
Py_DECREF(binary);
PyMem_FREE(found_encoding);
break;
}
}
- res = PyObject_CallMethod(fob, "close", "");
+ res = _PyObject_CallMethodId(fob, &PyId_close, "");
if (res)
Py_DECREF(res);
else