diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-26 00:13:12 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-26 00:13:12 (GMT) |
commit | c366117820eb34e14f4bf2b1f82a47b7a9cbc04a (patch) | |
tree | a9a703511caf473574a2d312c5143fa2c8486beb /Objects | |
parent | f0effe637988e936b5a6ece2da789b67723d675c (diff) | |
parent | 0fdfceb782424dcddca848357736f24ef40c91be (diff) | |
download | cpython-c366117820eb34e14f4bf2b1f82a47b7a9cbc04a.zip cpython-c366117820eb34e14f4bf2b1f82a47b7a9cbc04a.tar.gz cpython-c366117820eb34e14f4bf2b1f82a47b7a9cbc04a.tar.bz2 |
Merge heads
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/funcobject.c | 44 | ||||
-rw-r--r-- | Objects/typeobject.c | 56 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 131 |
3 files changed, 113 insertions, 118 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 45f9f57..2839a24 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -6,7 +6,7 @@ #include "structmember.h" PyObject * -PyFunction_New(PyObject *code, PyObject *globals) +PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname) { PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); @@ -54,6 +54,11 @@ PyFunction_New(PyObject *code, PyObject *globals) Py_INCREF(module); op->func_module = module; } + if (qualname) + op->func_qualname = qualname; + else + op->func_qualname = op->func_name; + Py_INCREF(op->func_qualname); } else return NULL; @@ -62,6 +67,12 @@ PyFunction_New(PyObject *code, PyObject *globals) } PyObject * +PyFunction_New(PyObject *code, PyObject *globals) +{ + return PyFunction_NewWithQualName(code, globals, NULL); +} + +PyObject * PyFunction_GetCode(PyObject *op) { if (!PyFunction_Check(op)) { @@ -334,6 +345,32 @@ func_set_name(PyFunctionObject *op, PyObject *value) } static PyObject * +func_get_qualname(PyFunctionObject *op) +{ + Py_INCREF(op->func_qualname); + return op->func_qualname; +} + +static int +func_set_qualname(PyFunctionObject *op, PyObject *value) +{ + PyObject *tmp; + + /* Not legal to del f.__qualname__ or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + tmp = op->func_qualname; + Py_INCREF(value); + op->func_qualname = value; + Py_DECREF(tmp); + return 0; +} + +static PyObject * func_get_defaults(PyFunctionObject *op) { if (op->func_defaults == NULL) { @@ -441,6 +478,7 @@ static PyGetSetDef func_getsetlist[] = { (setter)func_set_annotations}, {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, {"__name__", (getter)func_get_name, (setter)func_set_name}, + {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname}, {NULL} /* Sentinel */ }; @@ -561,6 +599,7 @@ func_dealloc(PyFunctionObject *op) Py_XDECREF(op->func_dict); Py_XDECREF(op->func_closure); Py_XDECREF(op->func_annotations); + Py_XDECREF(op->func_qualname); PyObject_GC_Del(op); } @@ -568,7 +607,7 @@ static PyObject* func_repr(PyFunctionObject *op) { return PyUnicode_FromFormat("<function %U at %p>", - op->func_name, op); + op->func_qualname, op); } static int @@ -584,6 +623,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg) Py_VISIT(f->func_dict); Py_VISIT(f->func_closure); Py_VISIT(f->func_annotations); + Py_VISIT(f->func_qualname); return 0; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index d53ae93..010120a 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -242,6 +242,19 @@ type_name(PyTypeObject *type, void *context) } } +static PyObject * +type_qualname(PyTypeObject *type, void *context) +{ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { + PyHeapTypeObject* et = (PyHeapTypeObject*)type; + Py_INCREF(et->ht_qualname); + return et->ht_qualname; + } + else { + return type_name(type, context); + } +} + static int type_set_name(PyTypeObject *type, PyObject *value, void *context) { @@ -286,6 +299,25 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) return 0; } +static int +type_set_qualname(PyTypeObject *type, PyObject *value, void *context) +{ + PyHeapTypeObject* et; + + if (!PyUnicode_Check(value)) { + PyErr_Format(PyExc_TypeError, + "can only assign string to %s.__qualname__, not '%s'", + type->tp_name, Py_TYPE(value)->tp_name); + return -1; + } + + et = (PyHeapTypeObject*)type; + Py_INCREF(value); + Py_DECREF(et->ht_qualname); + et->ht_qualname = value; + return 0; +} + static PyObject * type_module(PyTypeObject *type, void *context) { @@ -631,6 +663,7 @@ type___subclasscheck__(PyObject *type, PyObject *inst) static PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, (setter)type_set_name, NULL}, + {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL}, {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__abstractmethods__", (getter)type_abstractmethods, @@ -652,7 +685,7 @@ type_repr(PyTypeObject *type) Py_DECREF(mod); mod = NULL; } - name = type_name(type, NULL); + name = type_qualname(type, NULL); if (name == NULL) return NULL; @@ -1955,7 +1988,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) { PyObject *name, *bases, *dict; static char *kwlist[] = {"name", "bases", "dict", 0}; - PyObject *slots, *tmp, *newslots; + PyObject *qualname, *slots, *tmp, *newslots; PyTypeObject *type, *base, *tmptype, *winner; PyHeapTypeObject *et; PyMemberDef *mp; @@ -2032,6 +2065,18 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) return NULL; } + /* Check for a __qualname__ variable in dict */ + qualname = PyDict_GetItemString(dict, "__qualname__"); + if (qualname == NULL) { + qualname = name; + } + else { + if (PyDict_DelItemString(dict, "__qualname__") < 0) { + Py_DECREF(bases); + return NULL; + } + } + /* Check for a __slots__ sequence variable in dict, and count it */ slots = PyDict_GetItemString(dict, "__slots__"); nslots = 0; @@ -2185,7 +2230,9 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* Keep name and slots alive in the extended type object */ et = (PyHeapTypeObject *)type; Py_INCREF(name); + Py_INCREF(qualname); et->ht_name = name; + et->ht_qualname = qualname; et->ht_slots = slots; /* Initialize tp_flags */ @@ -2369,6 +2416,8 @@ PyObject* PyType_FromSpec(PyType_Spec *spec) res->ht_name = PyUnicode_FromString(spec->name); if (!res->ht_name) goto fail; + res->ht_qualname = res->ht_name; + Py_INCREF(res->ht_qualname); res->ht_type.tp_name = _PyUnicode_AsString(res->ht_name); if (!res->ht_type.tp_name) goto fail; @@ -2568,6 +2617,7 @@ type_dealloc(PyTypeObject *type) */ PyObject_Free((char *)type->tp_doc); Py_XDECREF(et->ht_name); + Py_XDECREF(et->ht_qualname); Py_XDECREF(et->ht_slots); Py_TYPE(type)->tp_free((PyObject *)type); } @@ -2983,7 +3033,7 @@ object_repr(PyObject *self) Py_DECREF(mod); mod = NULL; } - name = type_name(type, NULL); + name = type_qualname(type, NULL); if (name == NULL) return NULL; if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins")) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 2fefdbe..a9bf677 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8839,15 +8839,8 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, char *output, const char *errors) { - PyObject *errorHandler = NULL; - PyObject *exc = NULL; PyObject *unicode; - const char *encoding = "decimal"; - const char *reason = "invalid decimal Unicode string"; - /* the following variable is used for caching string comparisons - * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ - int known_errorHandler = -1; - Py_ssize_t i, j; + Py_ssize_t i; enum PyUnicode_Kind kind; void *data; @@ -8860,15 +8853,20 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, if (unicode == NULL) return -1; - if (PyUnicode_READY(unicode) < 0) - goto onError; + if (PyUnicode_READY(unicode) < 0) { + Py_DECREF(unicode); + return -1; + } kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); for (i=0; i < length; ) { - Py_UCS4 ch = PyUnicode_READ(kind, data, i); + PyObject *exc; + Py_UCS4 ch; int decimal; - Py_ssize_t startpos, endpos; + Py_ssize_t startpos; + + ch = PyUnicode_READ(kind, data, i); if (Py_UNICODE_ISSPACE(ch)) { *output++ = ' '; @@ -8886,113 +8884,20 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, i++; continue; } - /* All other characters are considered unencodable */ - startpos = i; - endpos = i+1; - for (; endpos < length; endpos++) { - ch = PyUnicode_READ(kind, data, endpos); - if ((0 < ch && ch < 256) || - Py_UNICODE_ISSPACE(ch) || - 0 <= Py_UNICODE_TODECIMAL(ch)) - break; - } - /* cache callback name lookup - * (if not done yet, i.e. it's the first error) */ - if (known_errorHandler==-1) { - if ((errors==NULL) || (!strcmp(errors, "strict"))) - known_errorHandler = 1; - else if (!strcmp(errors, "replace")) - known_errorHandler = 2; - else if (!strcmp(errors, "ignore")) - known_errorHandler = 3; - else if (!strcmp(errors, "xmlcharrefreplace")) - known_errorHandler = 4; - else - known_errorHandler = 0; - } - switch (known_errorHandler) { - case 1: /* strict */ - raise_encode_exception(&exc, encoding, unicode, startpos, endpos, reason); - goto onError; - case 2: /* replace */ - for (j=startpos; j < endpos; j++) - *output++ = '?'; - i = endpos; - break; - case 3: /* ignore */ - i = endpos; - break; - case 4: /* xmlcharrefreplace */ - /* generate replacement */ - for (j=startpos; j < endpos; j++) { - ch = PyUnicode_READ(kind, data, i); - output += sprintf(output, "&#%d;", (int)ch); - i++; - } - break; - default: - { - PyObject *repunicode; - Py_ssize_t repsize, newpos, k; - enum PyUnicode_Kind repkind; - void *repdata; - - repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, - encoding, reason, unicode, &exc, - startpos, endpos, &newpos); - if (repunicode == NULL) - goto onError; - if (!PyUnicode_Check(repunicode)) { - /* Byte results not supported, since they have no decimal property. */ - PyErr_SetString(PyExc_TypeError, "error handler should return unicode"); - Py_DECREF(repunicode); - goto onError; - } - if (PyUnicode_READY(repunicode) < 0) { - Py_DECREF(repunicode); - goto onError; - } - repkind = PyUnicode_KIND(repunicode); - repdata = PyUnicode_DATA(repunicode); - /* generate replacement */ - repsize = PyUnicode_GET_SIZE(repunicode); - for (k=0; k<repsize; k++) { - ch = PyUnicode_READ(repkind, repdata, k); - if (Py_UNICODE_ISSPACE(ch)) - *output++ = ' '; - else { - decimal = Py_UNICODE_TODECIMAL(ch); - if (decimal >= 0) - *output++ = '0' + decimal; - else if (0 < ch && ch < 256) - *output++ = (char)ch; - else { - Py_DECREF(repunicode); - raise_encode_exception(&exc, encoding, - unicode, startpos, endpos, - reason); - goto onError; - } - } - } - i = newpos; - Py_DECREF(repunicode); - } - } + startpos = i; + exc = NULL; + raise_encode_exception(&exc, "decimal", unicode, + startpos, startpos+1, + "invalid decimal Unicode string"); + Py_XDECREF(exc); + Py_DECREF(unicode); + return -1; } /* 0-terminate the output string */ *output++ = '\0'; - Py_XDECREF(exc); - Py_XDECREF(errorHandler); Py_DECREF(unicode); return 0; - - onError: - Py_XDECREF(exc); - Py_XDECREF(errorHandler); - Py_DECREF(unicode); - return -1; } /* --- Helpers ------------------------------------------------------------ */ |