diff options
author | Stefan Krah <skrah@bytereef.org> | 2012-03-21 19:27:33 (GMT) |
---|---|---|
committer | Stefan Krah <skrah@bytereef.org> | 2012-03-21 19:27:33 (GMT) |
commit | 04fb08f6907c8e00947435e346c919da313116a6 (patch) | |
tree | 1ffc01b2cb2e8495109f549d25e159e2a02be572 | |
parent | 7cc5521d402316cd4faaa9442f323b3a946ad44b (diff) | |
parent | 1da08e77dff8ba59c87e8f0473a00f7df21a806f (diff) | |
download | cpython-04fb08f6907c8e00947435e346c919da313116a6.zip cpython-04fb08f6907c8e00947435e346c919da313116a6.tar.gz cpython-04fb08f6907c8e00947435e346c919da313116a6.tar.bz2 |
Merge.
-rw-r--r-- | Include/abstract.h | 15 | ||||
-rw-r--r-- | Lib/doctest.py | 10 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 1 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/abstract.c | 94 | ||||
-rw-r--r-- | Python/ceval.c | 3 |
6 files changed, 48 insertions, 78 deletions
diff --git a/Include/abstract.h b/Include/abstract.h index 3a99c4e..4a27bfb 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -773,21 +773,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); /* - Returns the Integral instance converted to an int. The - instance is expected to be int or long or have an __int__ - method. Steals integral's reference. error_format will be - used to create the TypeError if integral isn't actually an - Integral instance. error_format should be a format string - that can accept a char* naming integral's type. - */ - -#ifndef Py_LIMITED_API - PyAPI_FUNC(PyObject *) _PyNumber_ConvertIntegralToInt( - PyObject *integral, - const char* error_format); -#endif - - /* Returns the object converted to Py_ssize_t by going through PyNumber_Index first. If an overflow error occurs while converting the int-or-long to Py_ssize_t, then the second argument diff --git a/Lib/doctest.py b/Lib/doctest.py index aba98dc..620451f 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -2267,7 +2267,8 @@ class DocTestCase(unittest.TestCase): return "Doctest: " + self._dt_test.name class SkipDocTestCase(DocTestCase): - def __init__(self): + def __init__(self, module): + self.module = module DocTestCase.__init__(self, None) def setUp(self): @@ -2277,7 +2278,10 @@ class SkipDocTestCase(DocTestCase): pass def shortDescription(self): - return "Skipping tests from %s" % module.__name__ + return "Skipping tests from %s" % self.module.__name__ + + __str__ = shortDescription + def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, **options): @@ -2325,7 +2329,7 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, if not tests and sys.flags.optimize >=2: # Skip doctests when running with -O2 suite = unittest.TestSuite() - suite.addTest(SkipDocTestCase()) + suite.addTest(SkipDocTestCase(module)) return suite elif not tests: # Why do we want to do this? Because it reveals a bug that might diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 5759eff..3051e57 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1770,6 +1770,7 @@ order (MRO) for bases """ ("__format__", format, format_impl, set(), {}), ("__floor__", math.floor, zero, set(), {}), ("__trunc__", math.trunc, zero, set(), {}), + ("__trunc__", int, zero, set(), {}), ("__ceil__", math.ceil, zero, set(), {}), ("__dir__", dir, empty_seq, set(), {}), ] @@ -30,6 +30,9 @@ Core and Builtins Library ------- +- Issue #12757: Fix the skipping of doctests when python is run with -OO so + that it works in unittest's verbose mode as well as non-verbose mode. + - Issue #7652: Integrate the decimal floating point libmpdec library to speed up the decimal module. Performance gains of the new C implementation are between 12x and 80x, depending on the application. diff --git a/Objects/abstract.c b/Objects/abstract.c index 39dffac..4737d54 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1268,37 +1268,32 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) } -PyObject * -_PyNumber_ConvertIntegralToInt(PyObject *integral, const char* error_format) -{ - static PyObject *int_name = NULL; - if (int_name == NULL) { - int_name = PyUnicode_InternFromString("__int__"); - if (int_name == NULL) - return NULL; - } - - if (integral && !PyLong_Check(integral)) { - /* Don't go through tp_as_number->nb_int to avoid - hitting the classic class fallback to __trunc__. */ - PyObject *int_func = PyObject_GetAttr(integral, int_name); - if (int_func == NULL) { - PyErr_Clear(); /* Raise a different error. */ - goto non_integral_error; - } +/* + Returns the Integral instance converted to an int. The instance is expected + to be an int or have an __int__ method. Steals integral's + reference. error_format will be used to create the TypeError if integral + isn't actually an Integral instance. error_format should be a format string + that can accept a char* naming integral's type. +*/ +static PyObject * +convert_integral_to_int(PyObject *integral, const char *error_format) +{ + PyNumberMethods *nb; + if (PyLong_Check(integral)) + return integral; + nb = Py_TYPE(integral)->tp_as_number; + if (nb->nb_int) { + PyObject *as_int = nb->nb_int(integral); Py_DECREF(integral); - integral = PyEval_CallObject(int_func, NULL); - Py_DECREF(int_func); - if (integral && !PyLong_Check(integral)) { - goto non_integral_error; - } + if (!as_int) + return NULL; + if (PyLong_Check(as_int)) + return as_int; + Py_DECREF(as_int); } - return integral; - -non_integral_error: PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name); Py_DECREF(integral); - return NULL; + return NULL; } @@ -1325,16 +1320,10 @@ PyObject * PyNumber_Long(PyObject *o) { PyNumberMethods *m; - static PyObject *trunc_name = NULL; PyObject *trunc_func; const char *buffer; Py_ssize_t buffer_len; - - if (trunc_name == NULL) { - trunc_name = PyUnicode_InternFromString("__trunc__"); - if (trunc_name == NULL) - return NULL; - } + _Py_IDENTIFIER(__trunc__); if (o == NULL) return null_error(); @@ -1356,23 +1345,23 @@ PyNumber_Long(PyObject *o) } if (PyLong_Check(o)) /* An int subclass without nb_int */ return _PyLong_Copy((PyLongObject *)o); - trunc_func = PyObject_GetAttr(o, trunc_name); + trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); if (trunc_func) { PyObject *truncated = PyEval_CallObject(trunc_func, NULL); PyObject *int_instance; Py_DECREF(trunc_func); /* __trunc__ is specified to return an Integral type, - but long() needs to return a long. */ - int_instance = _PyNumber_ConvertIntegralToInt( - truncated, + but int() needs to return a int. */ + int_instance = convert_integral_to_int(truncated, "__trunc__ returned non-Integral (type %.200s)"); return int_instance; } - PyErr_Clear(); /* It's not an error if o.__trunc__ doesn't exist. */ + if (PyErr_Occurred()) + return NULL; if (PyBytes_Check(o)) /* need to do extra error checking that PyLong_FromString() - * doesn't do. In particular long('9.5') must raise an + * doesn't do. In particular int('9.5') must raise an * exception, not truncate the float. */ return long_from_string(PyBytes_AS_STRING(o), @@ -2411,10 +2400,8 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...) /* isinstance(), issubclass() */ -/* abstract_get_bases() has logically 4 return states, with a sort of 0th - * state that will almost never happen. +/* abstract_get_bases() has logically 4 return states: * - * 0. creating the __bases__ static string could get a MemoryError * 1. getattr(cls, '__bases__') could raise an AttributeError * 2. getattr(cls, '__bases__') could raise some other exception * 3. getattr(cls, '__bases__') could return a tuple @@ -2440,16 +2427,11 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...) static PyObject * abstract_get_bases(PyObject *cls) { - static PyObject *__bases__ = NULL; + _Py_IDENTIFIER(__bases__); PyObject *bases; - if (__bases__ == NULL) { - __bases__ = PyUnicode_InternFromString("__bases__"); - if (__bases__ == NULL) - return NULL; - } Py_ALLOW_RECURSION - bases = PyObject_GetAttr(cls, __bases__); + bases = _PyObject_GetAttrId(cls, &PyId___bases__); Py_END_ALLOW_RECURSION if (bases == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) @@ -2519,19 +2501,13 @@ static int recursive_isinstance(PyObject *inst, PyObject *cls) { PyObject *icls; - static PyObject *__class__ = NULL; int retval = 0; - - if (__class__ == NULL) { - __class__ = PyUnicode_InternFromString("__class__"); - if (__class__ == NULL) - return -1; - } + _Py_IDENTIFIER(__class__); if (PyType_Check(cls)) { retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls); if (retval == 0) { - PyObject *c = PyObject_GetAttr(inst, __class__); + PyObject *c = _PyObject_GetAttrId(inst, &PyId___class__); if (c == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); @@ -2552,7 +2528,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls) if (!check_class(cls, "isinstance() arg 2 must be a type or tuple of types")) return -1; - icls = PyObject_GetAttr(inst, __class__); + icls = _PyObject_GetAttrId(inst, &PyId___class__); if (icls == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); diff --git a/Python/ceval.c b/Python/ceval.c index 5498056..4182378 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1837,10 +1837,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (PyGen_CheckExact(x)) { retval = _PyGen_Send((PyGenObject *)x, u); } else { + _Py_IDENTIFIER(send); if (u == Py_None) retval = PyIter_Next(x); else - retval = PyObject_CallMethod(x, "send", "O", u); + retval = _PyObject_CallMethodId(x, &PyId_send, "O", u); } Py_DECREF(u); if (!retval) { |