diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2011-10-09 08:38:36 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2011-10-09 08:38:36 (GMT) |
commit | afe55bba33a20f87a58f940186359237064b428f (patch) | |
tree | 66d64a1518d79c3d0e90c0a1d0080cd88e887d99 /Objects | |
parent | 67df285a3389c7fdb8c7bd301314ac45e17f8074 (diff) | |
download | cpython-afe55bba33a20f87a58f940186359237064b428f.zip cpython-afe55bba33a20f87a58f940186359237064b428f.tar.gz cpython-afe55bba33a20f87a58f940186359237064b428f.tar.bz2 |
Add API for static strings, primarily good for identifiers.
Thanks to Konrad Schöbel and Jasper Schulz for helping with the mass-editing.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 111 | ||||
-rw-r--r-- | Objects/descrobject.c | 15 | ||||
-rw-r--r-- | Objects/dictobject.c | 12 | ||||
-rw-r--r-- | Objects/fileobject.c | 3 | ||||
-rw-r--r-- | Objects/object.c | 36 | ||||
-rw-r--r-- | Objects/typeobject.c | 9 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 31 | ||||
-rw-r--r-- | Objects/weakrefobject.c | 5 |
8 files changed, 172 insertions, 50 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 9105769..57424a6 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2082,10 +2082,11 @@ PyMapping_Keys(PyObject *o) { 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"); @@ -2098,10 +2099,11 @@ PyMapping_Items(PyObject *o) { 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"); @@ -2114,10 +2116,11 @@ PyMapping_Values(PyObject *o) { 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"); @@ -2223,22 +2226,11 @@ _PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...) 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); @@ -2246,9 +2238,10 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) } 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); @@ -2263,10 +2256,9 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) } 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; @@ -2279,28 +2271,75 @@ _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...) 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) diff --git a/Objects/descrobject.c b/Objects/descrobject.c index a786bae..046eebd 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -703,34 +703,39 @@ static PyObject * 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[] = { diff --git a/Objects/dictobject.c b/Objects/dictobject.c index c4265da..220e621 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2707,10 +2707,12 @@ dictviews_sub(PyObject* self, PyObject *other) { 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; @@ -2725,10 +2727,12 @@ dictviews_and(PyObject* self, PyObject *other) { 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; @@ -2761,10 +2765,12 @@ dictviews_xor(PyObject* self, PyObject *other) { 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); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 6421543..f3006d0 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -30,11 +30,12 @@ PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, 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); diff --git a/Objects/object.c b/Objects/object.c index aeaa4b5..7db60f3 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -811,6 +811,42 @@ PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w) } 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) { PyTypeObject *tp = Py_TYPE(v); diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2e6eb0a..f94dfbf 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2897,6 +2897,7 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *sorted; PyObject *sorted_methods = NULL; PyObject *joined = NULL; + _Py_identifier(join); /* Compute ", ".join(sorted(type.__abstractmethods__)) into joined. */ @@ -2919,7 +2920,7 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (comma == NULL) goto error; } - joined = PyObject_CallMethod(comma, "join", + joined = _PyObject_CallMethodId(comma, &PyId_join, "O", sorted_methods); if (joined == NULL) goto error; @@ -3184,6 +3185,7 @@ slotnames(PyObject *cls) PyObject *copyreg; PyObject *slotnames; static PyObject *str_slotnames; + _Py_identifier(_slotnames); if (str_slotnames == NULL) { str_slotnames = PyUnicode_InternFromString("__slotnames__"); @@ -3202,7 +3204,7 @@ slotnames(PyObject *cls) 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 && @@ -3323,7 +3325,8 @@ reduce_2(PyObject *obj) 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); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e904b6e..af92368 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -201,6 +201,9 @@ static PyObject *interned; /* 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]; @@ -1609,6 +1612,33 @@ PyUnicode_FromString(const char *u) 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) { @@ -13523,6 +13553,7 @@ _PyUnicode_Fini(void) unicode_latin1[i] = NULL; } } + _PyUnicode_ClearStaticStrings(); (void)PyUnicode_ClearFreeList(); } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index c99f6ba..594f0ea 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -440,8 +440,9 @@ proxy_checkref(PyWeakReference *proxy) #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, ""); \ } @@ -584,7 +585,7 @@ proxy_iternext(PyWeakReference *proxy) } -WRAP_METHOD(proxy_bytes, "__bytes__") +WRAP_METHOD(proxy_bytes, __bytes__) static PyMethodDef proxy_methods[] = { |