Commit b56859e3 authored by zaur's avatar zaur

Merge branch 'master' of https://github.com/intellimath/cython

parents 334a195b 23350e5a
......@@ -19,6 +19,9 @@ Features added
Bugs fixed
----------
* ``dir()`` without arguments previously returned an unsorted list, which now
gets sorted as expected.
* ``dict.items()``, ``dict.keys()`` and ``dict.values()`` no longer return lists
in Python 3.
......
......@@ -4993,8 +4993,10 @@ class AttributeNode(ExprNode):
def generate_result_code(self, code):
if self.is_py_attr:
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
code.putln(
'%s = PyObject_GetAttr(%s, %s); %s' % (
'%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s' % (
self.result(),
self.obj.py_result(),
code.intern_identifier(self.attribute),
......@@ -10262,33 +10264,13 @@ class DocstringRefNode(ExprNode):
code.put_gotref(self.result())
#------------------------------------------------------------------------------------
#
# Runtime support code
#
#------------------------------------------------------------------------------------
get_name_interned_utility_code = UtilityCode(
proto = """
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
""",
impl = """
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result;
result = PyObject_GetAttr(dict, name);
if (!result) {
if (dict != %(BUILTINS)s) {
PyErr_Clear();
result = PyObject_GetAttr(%(BUILTINS)s, name);
}
if (!result) {
PyErr_SetObject(PyExc_NameError, name);
}
}
return result;
}
""" % {'BUILTINS' : Naming.builtins_cname})
get_name_interned_utility_code = UtilityCode.load("GetGlobalName", "ObjectHandling.c")
#------------------------------------------------------------------------------------
......
......@@ -1073,7 +1073,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for entry in cpp_class_attrs:
code.putln("new((void*)&(p->%s)) %s();" %
(entry.cname, entry.type.declaration_code("")));
(entry.cname, entry.type.declaration_code("")))
for entry in py_attrs:
if scope.is_internal or entry.name == "__weakref__":
......@@ -1100,7 +1100,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(
"if (%s(%s) < 0) {" %
(new_func_entry.func_cname, cinit_args))
code.put_decref_clear("o", py_object_type, nanny=False);
code.put_decref_clear("o", py_object_type, nanny=False)
code.putln(
"}")
code.putln(
......@@ -1133,7 +1133,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# We must mark ths object as (gc) untracked while tearing it down, lest
# the garbage collection is invoked while running this destructor.
if scope.needs_gc():
code.putln("PyObject_GC_UnTrack(o);");
code.putln("PyObject_GC_UnTrack(o);")
# call the user's __dealloc__
self.generate_usr_dealloc_call(scope, code)
......@@ -1158,12 +1158,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_xdecref_memoryviewslice("p->%s" % entry.cname,
have_gil=True)
# The base class deallocator probably expects this to be tracked, so
# undo the untracking above.
if scope.needs_gc():
code.putln("PyObject_GC_Track(o);");
if base_type:
# The base class deallocator probably expects this to be tracked, so
# undo the untracking above.
if scope.needs_gc():
code.putln("PyObject_GC_Track(o);")
tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
if tp_dealloc is not None:
code.putln("%s(o);" % tp_dealloc)
......@@ -1857,8 +1857,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c"))
code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)))
code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)))
code.putln("#ifdef __Pyx_CyFunction_USED")
code.putln("if (__Pyx_CyFunction_init() < 0) %s" % code.error_goto(self.pos))
......
......@@ -3856,8 +3856,10 @@ class OverrideCheckNode(StatNode):
func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
self.func_node.set_cname(func_node_temp)
# need to get attribute manually--scope would return cdef method
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
err = code.error_goto_if_null(func_node_temp, self.pos)
code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
code.putln("%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s" % (
func_node_temp, self_arg, interned_attr_cname, err))
code.put_gotref(func_node_temp)
is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
......@@ -5849,10 +5851,12 @@ class WithStatNode(StatNode):
code.putln("/*with:*/ {")
self.manager.generate_evaluation_code(code)
self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
code.putln("%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s" % (
self.exit_var,
self.manager.py_result(),
code.get_py_string_const(EncodedString('__exit__'), identifier=True),
code.intern_identifier(EncodedString('__exit__')),
code.error_goto_if_null(self.exit_var, self.pos),
))
code.put_gotref(self.exit_var)
......@@ -6710,10 +6714,12 @@ class FromImportStatNode(StatNode):
code.error_goto(self.pos)))
item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
self.item.set_cname(item_temp)
code.globalstate.use_utility_code(
UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
for name, target, coerced_item in self.interned_items:
cname = code.intern_identifier(name)
code.putln(
'%s = PyObject_GetAttr(%s, %s);' % (
'%s = __Pyx_PyObject_GetAttrStr(%s, %s);' % (
item_temp,
self.module.py_result(),
cname))
......
......@@ -2294,6 +2294,7 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform):
PyrexTypes.CFuncTypeArg("dict", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("key", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("default", PyrexTypes.py_object_type, None),
PyrexTypes.CFuncTypeArg("is_safe_type", PyrexTypes.c_int_type, None),
])
def _handle_simple_method_dict_setdefault(self, node, args, is_unbound_method):
......@@ -2304,12 +2305,22 @@ class OptimizeBuiltinCalls(Visitor.MethodDispatcherTransform):
elif len(args) != 3:
self._error_wrong_arg_count('dict.setdefault', node, args, "2 or 3")
return node
key_type = args[1].type
if key_type.is_builtin_type:
is_safe_type = int(key_type.name in
'str bytes unicode float int long bool')
elif key_type is PyrexTypes.py_object_type:
is_safe_type = -1 # don't know
else:
is_safe_type = 0 # definitely not
args.append(ExprNodes.IntNode(
node.pos, value=is_safe_type, constant_result=is_safe_type))
return self._substitute_method_call(
node, "__Pyx_PyDict_SetDefault", self.Pyx_PyDict_SetDefault_func_type,
'setdefault', is_unbound_method, args,
may_return_none = True,
utility_code = load_c_utility('dict_setdefault'))
may_return_none=True,
utility_code=load_c_utility('dict_setdefault'))
### unicode type methods
......
......@@ -56,6 +56,7 @@ static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
//@requires: Exceptions.c::PyErrFetchRestore
//@requires: Exceptions.c::SwapException
//@requires: Exceptions.c::RaiseException
//@requires: ObjectHandling.c::PyObjectCallMethod
static PyObject *__Pyx_Generator_Next(PyObject *self);
static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
......@@ -285,7 +286,7 @@ static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
if (value == Py_None)
ret = PyIter_Next(yf);
else
ret = PyObject_CallMethod(yf, (char*)"send", (char*)"O", value);
ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value);
}
gen->is_running = 0;
//Py_DECREF(yf);
......
......@@ -23,8 +23,9 @@ typedef struct {
#define __pyx_atomic_int_type int
/* todo: Portland pgcc, maybe OS X's OSAtomicIncrement32,
libatomic + autotools-like distutils support? Such a pain... */
#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
(__GNUC_MINOR__ == 1 && __GNUC_PATHLEVEL >= 2))
#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
(__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
!defined(WIN32) && !defined(MS_WINDOWS)
/* gcc >= 4.1.2 */
#define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
#define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
......
......@@ -221,8 +221,12 @@ static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
PyObject *value;
value = PyDict_GetItemWithError(d, key);
if (unlikely(!value)) {
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
if (!PyErr_Occurred()) {
PyObject* args = PyTuple_Pack(1, key);
if (likely(args))
PyErr_SetObject(PyExc_KeyError, args);
Py_XDECREF(args);
}
return NULL;
}
Py_INCREF(value);
......@@ -581,3 +585,68 @@ static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq
static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) {
return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b);
}
/////////////// GetGlobalName.proto ///////////////
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
/////////////// GetGlobalName ///////////////
//@requires: PyObjectGetAttrStr
//@substitute: naming
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result;
result = __Pyx_PyObject_GetAttrStr(dict, name);
if (!result) {
if (dict != $builtins_cname) {
PyErr_Clear();
result = __Pyx_PyObject_GetAttrStr($builtins_cname, name);
}
if (!result) {
PyErr_SetObject(PyExc_NameError, name);
}
}
return result;
}
/////////////// PyObjectGetAttrStr.proto ///////////////
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
PyTypeObject* tp = Py_TYPE(obj);
if (likely(tp->tp_getattro))
return tp->tp_getattro(obj, attr_name);
#if PY_MAJOR_VERSION < 3
if (likely(tp->tp_getattr))
return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
#endif
return PyObject_GetAttr(obj, attr_name);
}
#else
#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
#endif
/////////////// PyObjectCallMethod.proto ///////////////
//@requires: PyObjectGetAttrStr
//@substitute: naming
static PyObject* __Pyx_PyObject_CallMethodTuple(PyObject* obj, PyObject* method_name, PyObject* args) {
PyObject *method, *result = NULL;
if (unlikely(!args)) return NULL;
method = __Pyx_PyObject_GetAttrStr(obj, method_name);
if (unlikely(!method)) goto bad;
result = PyObject_Call(method, args, NULL);
Py_DECREF(method);
bad:
Py_DECREF(args);
return result;
}
#define __Pyx_PyObject_CallMethod3(obj, name, arg1, arg2, arg3) \
__Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(3, arg1, arg2, arg3))
#define __Pyx_PyObject_CallMethod2(obj, name, arg1, arg2) \
__Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(2, arg1, arg2))
#define __Pyx_PyObject_CallMethod1(obj, name, arg1) \
__Pyx_PyObject_CallMethodTuple(obj, name, PyTuple_Pack(1, arg1))
#define __Pyx_PyObject_CallMethod0(obj, name) \
__Pyx_PyObject_CallMethodTuple(obj, name, (Py_INCREF($empty_tuple), $empty_tuple))
......@@ -4,6 +4,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x);
/////////////// append ///////////////
//@requires: ListAppend
//@requires: ObjectHandling.c::PyObjectCallMethod
static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
if (likely(PyList_CheckExact(L))) {
......@@ -11,7 +12,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
Py_INCREF(Py_None);
return Py_None; /* this is just to have an accurate signature */
} else {
return PyObject_CallMethodObjArgs(L, PYIDENT("append"), x, NULL);
return __Pyx_PyObject_CallMethod1(L, PYIDENT("append"), x);
}
}
......@@ -56,6 +57,7 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L); /*proto*/
/////////////// pop ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod
static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
......@@ -71,7 +73,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
}
#endif
#endif
return PyObject_CallMethodObjArgs(L, PYIDENT("pop"), NULL);
return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop"));
}
......@@ -80,44 +82,33 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_Pop(PyObject* L) {
static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix); /*proto*/
/////////////// pop_index ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod
static PyObject* __Pyx_PyObject_PopIndex(PyObject* L, Py_ssize_t ix) {
PyObject *r, *m, *t, *py_ix;
#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02040000
PyObject *r, *py_ix;
#if CYTHON_COMPILING_IN_CPYTHON
if (likely(PyList_CheckExact(L))) {
Py_ssize_t size = PyList_GET_SIZE(L);
if (likely(size > (((PyListObject*)L)->allocated >> 1))) {
if (ix < 0) {
ix += size;
Py_ssize_t cix = ix;
if (cix < 0) {
cix += size;
}
if (likely(0 <= ix && ix < size)) {
PyObject* v = PyList_GET_ITEM(L, ix);
if (likely(0 <= cix && cix < size)) {
PyObject* v = PyList_GET_ITEM(L, cix);
Py_SIZE(L) -= 1;
size -= 1;
memmove(&PyList_GET_ITEM(L, ix), &PyList_GET_ITEM(L, ix+1), (size-ix)*sizeof(PyObject*));
memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size-cix)*sizeof(PyObject*));
return v;
}
}
}
#endif
py_ix = t = NULL;
m = PyObject_GetAttr(L, PYIDENT("pop"));
if (!m) goto bad;
py_ix = PyInt_FromSsize_t(ix);
if (!py_ix) goto bad;
t = PyTuple_New(1);
if (!t) goto bad;
PyTuple_SET_ITEM(t, 0, py_ix);
py_ix = NULL;
r = PyObject_CallObject(m, t);
Py_DECREF(m);
Py_DECREF(t);
if (!py_ix) return NULL;
r = __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix);
Py_DECREF(py_ix);
return r;
bad:
Py_XDECREF(m);
Py_XDECREF(t);
Py_XDECREF(py_ix);
return NULL;
}
......@@ -315,25 +306,28 @@ static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObjec
/////////////// dict_setdefault.proto ///////////////
static PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); /*proto*/
static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value, int is_safe_type); /*proto*/
/////////////// dict_setdefault ///////////////
//@requires: ObjectHandling.c::PyObjectCallMethod
static PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) {
static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value, int is_safe_type) {
PyObject* value;
if (is_safe_type == 1 || (is_safe_type == -1 &&
/* the following builtins presumably have repeatably safe and fast hash functions */
#if PY_MAJOR_VERSION >= 3
value = PyDict_GetItemWithError(d, key);
if (unlikely(!value)) {
if (unlikely(PyErr_Occurred()))
return NULL;
if (unlikely(PyDict_SetItem(d, key, default_value) == -1))
return NULL;
value = default_value;
}
Py_INCREF(value);
(PyUnicode_CheckExact(key) || PyString_CheckExact(key) || PyLong_CheckExact(key)))) {
value = PyDict_GetItemWithError(d, key);
if (unlikely(!value)) {
if (unlikely(PyErr_Occurred()))
return NULL;
if (unlikely(PyDict_SetItem(d, key, default_value) == -1))
return NULL;
value = default_value;
}
Py_INCREF(value);
#else
if (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key)) {
/* these presumably have safe hash functions */
(PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key) || PyLong_CheckExact(key)))) {
value = PyDict_GetItem(d, key);
if (unlikely(!value)) {
if (unlikely(PyDict_SetItem(d, key, default_value) == -1))
......@@ -341,10 +335,10 @@ static PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *d
value = default_value;
}
Py_INCREF(value);
#endif
} else {
value = PyObject_CallMethodObjArgs(d, PYIDENT("setdefault"), key, default_value, NULL);
value = __Pyx_PyObject_CallMethod2(d, PYIDENT("setdefault"), key, default_value);
}
#endif
return value;
}
......@@ -411,6 +405,7 @@ static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t
/////////////// dict_iter ///////////////
//@requires: ObjectHandling.c::UnpackTuple2
//@requires: ObjectHandling.c::IterFinish
//@requires: ObjectHandling.c::PyObjectCallMethod
static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
Py_ssize_t* p_orig_length, int* p_source_is_dict) {
......@@ -426,7 +421,7 @@ static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_di
*p_orig_length = 0;
if (method_name) {
PyObject* iter;
iterable = PyObject_CallMethodObjArgs(iterable, method_name, NULL);
iterable = __Pyx_PyObject_CallMethod0(iterable, method_name);
if (!iterable)
return NULL;
#if !CYTHON_COMPILING_IN_PYPY
......
......@@ -17,6 +17,22 @@ def test(dict d, index):
Traceback (most recent call last):
KeyError: (1, 2)
>>> import sys
>>> try: d[(1,)]
... except KeyError:
... args = sys.exc_info()[1].args
... if sys.version_info >= (2,5): print(args)
... else: print((args,)) # fake it for older CPython versions
((1,),)
>>> import sys
>>> try: test(d, (1,))
... except KeyError:
... args = sys.exc_info()[1].args
... if sys.version_info >= (2,5): print(args)
... else: print((args,)) # fake it for older CPython versions
((1,),)
>>> class Unhashable:
... def __hash__(self):
... raise ValueError
......
......@@ -11,6 +11,17 @@ class Hashable(object):
def __eq__(self, other):
return isinstance(other, Hashable)
class CountedHashable(object):
def __init__(self):
self.hash_count = 0
self.eq_count = 0
def __hash__(self):
self.hash_count += 1
return 42
def __eq__(self, other):
self.eq_count += 1
return id(self) == id(other)
@cython.test_fail_if_path_exists('//AttributeNode')
@cython.test_assert_path_exists('//PythonCapiCallNode')
@cython.locals(d=dict)
......@@ -36,6 +47,23 @@ def setdefault1(d, key):
>>> len(d)
2
>>> d[Hashable()]
# CPython's behaviour depends on version and py_debug setting, so just compare to it
>>> py_hashed1 = CountedHashable()
>>> y = {py_hashed1: 5}
>>> py_hashed2 = CountedHashable()
>>> y.setdefault(py_hashed2)
>>> cy_hashed1 = CountedHashable()
>>> y = {cy_hashed1: 5}
>>> cy_hashed2 = CountedHashable()
>>> setdefault1(y, cy_hashed2)
>>> py_hashed1.hash_count - cy_hashed1.hash_count
0
>>> py_hashed2.hash_count - cy_hashed2.hash_count
0
>>> (py_hashed1.eq_count + py_hashed2.eq_count) - (cy_hashed1.eq_count + cy_hashed2.eq_count)
0
"""
return d.setdefault(key)
......@@ -72,5 +100,24 @@ def setdefault2(d, key, value):
3
>>> d[Hashable()]
55
# CPython's behaviour depends on version and py_debug setting, so just compare to it
>>> py_hashed1 = CountedHashable()
>>> y = {py_hashed1: 5}
>>> py_hashed2 = CountedHashable()
>>> y.setdefault(py_hashed2, [])
[]
>>> cy_hashed1 = CountedHashable()
>>> y = {cy_hashed1: 5}
>>> cy_hashed2 = CountedHashable()
>>> setdefault2(y, cy_hashed2, [])
[]
>>> py_hashed1.hash_count - cy_hashed1.hash_count
0
>>> py_hashed2.hash_count - cy_hashed2.hash_count
0
>>> (py_hashed1.eq_count + py_hashed2.eq_count) - (cy_hashed1.eq_count + cy_hashed2.eq_count)
0
"""
return d.setdefault(key, value)
......@@ -24,7 +24,6 @@ def simple_pop(L):
[]
>>> simple_pop(L)
Traceback (most recent call last):
...
IndexError: pop from empty list
>>> simple_pop(A())
......@@ -50,7 +49,6 @@ def simple_pop_typed(list L):
[]
>>> simple_pop_typed(L)
Traceback (most recent call last):
...
IndexError: pop from empty list
"""
return L.pop()
......@@ -63,17 +61,18 @@ def index_pop(L, int i):
>>> L = list(range(10))
>>> index_pop(L, 2)
2
>>> index_pop(L, -10)
Traceback (most recent call last):
IndexError: pop index out of range
>>> index_pop(L, -2)
8
>>> L
[0, 1, 3, 4, 5, 6, 7, 9]
>>> index_pop(L, 100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> index_pop(L, -100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> while L:
......@@ -84,7 +83,6 @@ def index_pop(L, int i):
>>> index_pop(L, 0)
Traceback (most recent call last):
...
IndexError: pop from empty list
>>> index_pop(A(), 3)
......@@ -105,11 +103,9 @@ def index_pop_typed(list L, int i):
[0, 1, 3, 4, 5, 6, 7, 9]
>>> index_pop_typed(L, 100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> index_pop_typed(L, -100)
Traceback (most recent call last):
...
IndexError: pop index out of range
>>> while L:
......@@ -120,7 +116,6 @@ def index_pop_typed(list L, int i):
>>> index_pop_typed(L, 0)
Traceback (most recent call last):
...
IndexError: pop from empty list
"""
return L.pop(i)
......@@ -143,7 +138,6 @@ def index_pop_literal(list L):
>>> index_pop_literal(L)
Traceback (most recent call last):
...
IndexError: pop from empty list
"""
return L.pop(0)
......
......@@ -526,11 +526,6 @@ def test_broken_getattr_handling():
def __getattr__(self, attr):
1/0
if sys.version_info >= (3,3):
expected_exception = ZeroDivisionError
else:
expected_exception = AttributeError
def g():
yield from Broken()
......@@ -539,7 +534,7 @@ def test_broken_getattr_handling():
gi = g()
assert next(gi) == 1
gi.send(1)
except expected_exception:
except ZeroDivisionError:
pass
else:
not_raised.append(1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment