Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: expose-jsonmap
Changeset: r97840:8504b741f563
Date: 2019-10-24 07:49 +0200
http://bitbucket.org/pypy/pypy/changeset/8504b741f563/
Log: expose a way to create a dict structure from applevel, and
instantiate it. can be used in csv module and other places.
diff --git a/pypy/module/__pypy__/interp_dictstructure.py
b/pypy/module/__pypy__/interp_dictstructure.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_dictstructure.py
@@ -0,0 +1,26 @@
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import oefmt
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef
+
+def make_terminator(space):
+ from pypy.module._pypyjson.interp_decoder import Terminator
+ return Terminator(space)
+
+def newdictstructure(space, w_list=None):
+ from pypy.objspace.std.unicodeobject import W_UnicodeObject
+ m = terminator = space.fromcache(make_terminator) # a different one than
the one _pypyjson uses
+ if w_list is None:
+ return m
+ for w_x in space.listview(w_list):
+ if type(w_x) is not W_UnicodeObject:
+ raise oefmt(space.w_TypeError, "expected unicode, got %T", w_x)
+ u = space.utf8_w(w_x)
+ m = m.get_next(w_x, u, 0, len(u), terminator)
+ if not m.is_state_useful():
+ m.mark_useful(terminator) # XXX too aggressive?
+ return m
+
+
+
+
diff --git a/pypy/module/__pypy__/moduledef.py
b/pypy/module/__pypy__/moduledef.py
--- a/pypy/module/__pypy__/moduledef.py
+++ b/pypy/module/__pypy__/moduledef.py
@@ -118,6 +118,8 @@
'stack_almost_full' : 'interp_magic.stack_almost_full',
'pyos_inputhook' : 'interp_magic.pyos_inputhook',
'newmemoryview' : 'interp_buffer.newmemoryview',
+
+ 'newdictstructure' : 'interp_dictstructure.newdictstructure',
}
if sys.platform == 'win32':
interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp'
diff --git a/pypy/module/__pypy__/test/test_dictstructure.py
b/pypy/module/__pypy__/test/test_dictstructure.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_dictstructure.py
@@ -0,0 +1,26 @@
+
+class AppTestDictStructure(object):
+ spaceconfig = dict(usemodules=['__pypy__', '_pypyjson'])
+
+ def test_simple(self):
+ from __pypy__ import newdictstructure, strategy
+ m = newdictstructure([u"a", u"b", u"c"])
+ assert m.last_key == u"c"
+ assert m.previous.last_key == u"b"
+ m2 = newdictstructure([u"a", u"b", u"c"])
+ assert m2 is m
+ d = m.instantiate_dict([1, 2, 3])
+ assert d == {u"a": 1, u"b": 2, u"c": 3}
+ assert strategy(d) == "JsonDictStrategy"
+
+ with raises(ValueError):
+ m.instantiate_dict([5])
+
+ with raises(TypeError):
+ newdictstructure([b"a"])
+
+
+ def test_repr(self):
+ from __pypy__ import newdictstructure, strategy
+ m = newdictstructure([u"a"])
+ assert repr(m) == "<DictStructure [u'a']>"
diff --git a/pypy/module/_pypyjson/interp_decoder.py
b/pypy/module/_pypyjson/interp_decoder.py
--- a/pypy/module/_pypyjson/interp_decoder.py
+++ b/pypy/module/_pypyjson/interp_decoder.py
@@ -9,6 +9,9 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.module._pypyjson import simd
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+
OVF_DIGITS = len(str(sys.maxint))
def is_whitespace(ch):
@@ -692,7 +695,7 @@
return True
-class MapBase(object):
+class MapBase(W_Root):
""" A map implementation to speed up parsing of json dicts, and to
represent the resulting dicts more compactly and make access faster. """
@@ -866,6 +869,30 @@
reading from values_w."""
raise NotImplementedError("abstract base")
+ # ____________________________________________________________
+ # exposed methods
+
+ def descr_instantiate_dict(self, space, w_l):
+ from pypy.objspace.std.jsondict import from_values_and_jsonmap
+ from pypy.objspace.std.jsondict import devolve_jsonmap_dict
+ l_w = space.listview(w_l)
+ if not isinstance(self, JSONMap):
+ return space.newdict()
+ keys_w = self.get_keys_in_order()
+ if len(l_w) != len(keys_w):
+ raise oefmt(space.w_ValueError, "expected %s values, got %s",
str(len(keys_w)), str(len(l_w)))
+ w_dict = from_values_and_jsonmap(self.space, l_w[:], self)
+ if self.is_state_blocked():
+ devolve_jsonmap_dict(w_dict)
+ return w_dict
+
+ def descr_repr(self, space):
+ return space.newtext("<DictStructure [%s]>" % ",
".join([space.text_w(space.repr(w_key)) for w_key in self.get_keys_in_order()]))
+
+
+ # ____________________________________________________________
+ # graphviz
+
def _all_dot(self, output):
identity = objectmodel.compute_unique_id(self)
output.append('%s [shape=box%s];' % (identity, self._get_dot_text()))
@@ -1166,3 +1193,18 @@
finally:
decoder.close()
+
+
+def get_last_key(w_obj, space):
+ return w_obj.w_key if isinstance(w_obj, JSONMap) else space.w_None
+
+def get_previous(w_obj, space):
+ return w_obj.prev if isinstance(w_obj, JSONMap) else space.w_None
+
+MapBase.typedef = TypeDef("DictStructure",
+ instantiate_dict = interp2app(MapBase.descr_instantiate_dict),
+ __repr__ = interp2app(MapBase.descr_repr),
+ last_key = GetSetProperty(get_last_key, name="last_key"),
+ previous = GetSetProperty(get_previous, name="previous"),
+)
+MapBase.typedef.acceptable_as_base_class = False
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit