[pypy-dev] [pypy-commit] pypy default: issue1059 testing
Alex Gaynor
alex.gaynor at gmail.com
Mon Feb 20 18:50:00 CET 2012
Unfortunately this commit has some bad effects. Going through an iterator
in popitem() will result in O(N**2) behavior for repeated calls. If you
look at the r_dict implementation of popitem() you can see the fix there.
Alex
On Mon, Feb 20, 2012 at 6:18 AM, cfbolz <noreply at buildbot.pypy.org> wrote:
> Author: Carl Friedrich Bolz <cfbolz at gmx.de>
> Branch:
> Changeset: r52670:4b254e123047
> Date: 2012-02-20 12:17 +0100
> http://bitbucket.org/pypy/pypy/changeset/4b254e123047/
>
> Log: issue1059 testing
>
> make the .__dict__.clear method of builtin types raise an error. Fix
> popitem on dict proxies (builtin types raise an error, normal types
> work normally).
>
> diff --git a/pypy/objspace/std/dictmultiobject.py
> b/pypy/objspace/std/dictmultiobject.py
> --- a/pypy/objspace/std/dictmultiobject.py
> +++ b/pypy/objspace/std/dictmultiobject.py
> @@ -142,6 +142,13 @@
> else:
> return result
>
> + def popitem(self, w_dict):
> + space = self.space
> + iterator = self.iter(w_dict)
> + w_key, w_value = iterator.next()
> + self.delitem(w_dict, w_key)
> + return (w_key, w_value)
> +
> def clear(self, w_dict):
> strategy = self.space.fromcache(EmptyDictStrategy)
> storage = strategy.get_empty_storage()
> diff --git a/pypy/objspace/std/dictproxyobject.py
> b/pypy/objspace/std/dictproxyobject.py
> --- a/pypy/objspace/std/dictproxyobject.py
> +++ b/pypy/objspace/std/dictproxyobject.py
> @@ -3,7 +3,7 @@
> from pypy.objspace.std.dictmultiobject import W_DictMultiObject,
> IteratorImplementation
> from pypy.objspace.std.dictmultiobject import DictStrategy
> from pypy.objspace.std.typeobject import unwrap_cell
> -from pypy.interpreter.error import OperationError
> +from pypy.interpreter.error import OperationError, operationerrfmt
>
> from pypy.rlib import rerased
>
> @@ -44,7 +44,8 @@
> raise
> if not w_type.is_cpytype():
> raise
> - # xxx obscure workaround: allow cpyext to write to
> type->tp_dict.
> + # xxx obscure workaround: allow cpyext to write to
> type->tp_dict
> + # xxx even in the case of a builtin type.
> # xxx like CPython, we assume that this is only done early
> after
> # xxx the type is created, and we don't invalidate any cache.
> w_type.dict_w[key] = w_value
> @@ -86,8 +87,14 @@
> for (key, w_value) in
> self.unerase(w_dict.dstorage).dict_w.iteritems()]
>
> def clear(self, w_dict):
> - self.unerase(w_dict.dstorage).dict_w.clear()
> - self.unerase(w_dict.dstorage).mutated(None)
> + space = self.space
> + w_type = self.unerase(w_dict.dstorage)
> + if (not space.config.objspace.std.mutable_builtintypes
> + and not w_type.is_heaptype()):
> + msg = "can't clear dictionary of type '%s'"
> + raise operationerrfmt(space.w_TypeError, msg, w_type.name)
> + w_type.dict_w.clear()
> + w_type.mutated(None)
>
> class DictProxyIteratorImplementation(IteratorImplementation):
> def __init__(self, space, strategy, dictimplementation):
> diff --git a/pypy/objspace/std/test/test_dictproxy.py
> b/pypy/objspace/std/test/test_dictproxy.py
> --- a/pypy/objspace/std/test/test_dictproxy.py
> +++ b/pypy/objspace/std/test/test_dictproxy.py
> @@ -22,6 +22,9 @@
> assert NotEmpty.string == 1
> raises(TypeError, 'NotEmpty.__dict__.setdefault(15, 1)')
>
> + key, value = NotEmpty.__dict__.popitem()
> + assert (key == 'a' and value == 1) or (key == 'b' and value == 4)
> +
> def test_dictproxyeq(self):
> class a(object):
> pass
> @@ -43,6 +46,11 @@
> assert s1 == s2
> assert s1.startswith('{') and s1.endswith('}')
>
> + def test_immutable_dict_on_builtin_type(self):
> + raises(TypeError, "int.__dict__['a'] = 1")
> + raises(TypeError, int.__dict__.popitem)
> + raises(TypeError, int.__dict__.clear)
> +
> class AppTestUserObjectMethodCache(AppTestUserObject):
> def setup_class(cls):
> cls.space = gettestobjspace(
> diff --git a/pypy/objspace/std/test/test_typeobject.py
> b/pypy/objspace/std/test/test_typeobject.py
> --- a/pypy/objspace/std/test/test_typeobject.py
> +++ b/pypy/objspace/std/test/test_typeobject.py
> @@ -993,7 +993,9 @@
> raises(TypeError, setattr, list, 'append', 42)
> raises(TypeError, setattr, list, 'foobar', 42)
> raises(TypeError, delattr, dict, 'keys')
> -
> + raises(TypeError, 'int.__dict__["a"] = 1')
> + raises(TypeError, 'int.__dict__.clear()')
> +
> def test_nontype_in_mro(self):
> class OldStyle:
> pass
> _______________________________________________
> pypy-commit mailing list
> pypy-commit at python.org
> http://mail.python.org/mailman/listinfo/pypy-commit
>
--
"I disapprove of what you say, but I will defend to the death your right to
say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20120220/a3fa0b4c/attachment.html>
More information about the pypy-dev
mailing list