[pypy-commit] pypy optimizeopt-cleanup: remove broken test

2019-04-13 Thread rlamy
Author: Ronan Lamy 
Branch: optimizeopt-cleanup
Changeset: r96466:eebbb92a8dfb
Date: 2019-04-14 00:36 +0100
http://bitbucket.org/pypy/pypy/changeset/eebbb92a8dfb/

Log:remove broken test

diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -4072,64 +4072,6 @@
 
 
 class TestLLtype(BaseLLtypeTests, LLJitMixin):
-def test_tagged(self):
-py.test.skip("tagged unsupported")
-from rpython.rlib.objectmodel import UnboxedValue
-class Base(object):
-__slots__ = ()
-
-class Int(UnboxedValue, Base):
-__slots__ = ["a"]
-
-def is_pos(self):
-return self.a > 0
-
-def dec(self):
-try:
-return Int(self.a - 1)
-except OverflowError:
-raise
-
-class Float(Base):
-def __init__(self, a):
-self.a = a
-
-def is_pos(self):
-return self.a > 0
-
-def dec(self):
-return Float(self.a - 1)
-
-driver = JitDriver(greens=['pc', 's'], reds=['o'])
-
-def main(fl, n, s):
-if s:
-s = "--j"
-else:
-s = "---j"
-if fl:
-o = Float(float(n))
-else:
-o = Int(n)
-pc = 0
-while True:
-driver.jit_merge_point(s=s, pc=pc, o=o)
-c = s[pc]
-if c == "j":
-driver.can_enter_jit(s=s, pc=pc, o=o)
-if o.is_pos():
-pc = 0
-continue
-else:
-break
-elif c == "-":
-o = o.dec()
-pc += 1
-return pc
-topt = {'taggedpointers': True}
-res = self.meta_interp(main, [False, 100, True],
-   translationoptions=topt)
-
 def test_rerased(self):
 eraseX, uneraseX = rerased.new_erasing_pair("X")
 #
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy optimizeopt-cleanup: LoopCompileData.optimize() is only called with unroll=True; simplify optimize() and optimize_trace()

2019-04-13 Thread rlamy
Author: Ronan Lamy 
Branch: optimizeopt-cleanup
Changeset: r96465:f6577bae1fb3
Date: 2019-04-13 23:52 +0100
http://bitbucket.org/pypy/pypy/changeset/f6577bae1fb3/

Log:LoopCompileData.optimize() is only called with unroll=True; simplify
optimize() and optimize_trace()

diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -35,7 +35,7 @@
 for arg in self.trace.inputargs:
 arg.set_forwarded(None)
 
-class LoopCompileData(CompileData):
+class PreambleCompileData(CompileData):
 """ An object that accumulates all of the necessary info for
 the optimization phase, but does not actually have any other state
 
@@ -49,19 +49,13 @@
 assert runtime_boxes is not None
 self.runtime_boxes = runtime_boxes
 
-def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
-from rpython.jit.metainterp.optimizeopt.unroll import (UnrollOptimizer,
-   Optimizer)
-
-if unroll:
-opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
-return opt.optimize_preamble(self.trace,
- self.runtime_boxes,
- self.call_pure_results,
- self.box_names_memo)
-else:
-opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations)
-return opt.propagate_all_forward(self.trace, 
self.call_pure_results)
+def optimize(self, metainterp_sd, jitdriver_sd, optimizations):
+from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
+opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
+return opt.optimize_preamble(self.trace,
+self.runtime_boxes,
+self.call_pure_results,
+self.box_names_memo)
 
 class SimpleCompileData(CompileData):
 """ This represents label() ops jump with no extra info associated with
@@ -74,11 +68,9 @@
 self.call_pure_results = call_pure_results
 self.enable_opts = enable_opts
 
-def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
+def optimize(self, metainterp_sd, jitdriver_sd, optimizations):
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer
 from rpython.jit.metainterp.optimizeopt.bridgeopt import 
deserialize_optimizer_knowledge
-
-#assert not unroll
 opt = Optimizer(metainterp_sd, jitdriver_sd, optimizations)
 traceiter = self.trace.get_iter()
 if self.resumestorage:
@@ -101,7 +93,7 @@
 self.inline_short_preamble = inline_short_preamble
 self.resumestorage = resumestorage
 
-def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
+def optimize(self, metainterp_sd, jitdriver_sd, optimizations):
 from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
 
 opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
@@ -113,7 +105,7 @@
 
 class UnrolledLoopData(CompileData):
 """ This represents label() ops jump with extra info that's from the
-run of LoopCompileData. Jump goes to the same label
+run of PreambleCompileData. Jump goes to the same label
 """
 log_noopt = False
 
@@ -127,10 +119,8 @@
 self.call_pure_results = call_pure_results
 self.inline_short_preamble = inline_short_preamble
 
-def optimize(self, metainterp_sd, jitdriver_sd, optimizations, unroll):
+def optimize(self, metainterp_sd, jitdriver_sd, optimizations):
 from rpython.jit.metainterp.optimizeopt.unroll import UnrollOptimizer
-
-assert unroll # we should not be here if it's disabled
 opt = UnrollOptimizer(metainterp_sd, jitdriver_sd, optimizations)
 return opt.optimize_peeled_loop(self.trace, self.celltoken, self.state,
 self.call_pure_results, self.inline_short_preamble)
@@ -217,7 +207,7 @@
 
 def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts,
 cut_at):
-from rpython.jit.metainterp.optimizeopt import optimize_trace, 
use_unrolling
+from rpython.jit.metainterp.optimizeopt import optimize_trace
 
 jitdriver_sd = metainterp.jitdriver_sd
 metainterp_sd = metainterp.staticdata
@@ -225,11 +215,9 @@
 call_pure_results = metainterp.call_pure_results
 data = SimpleCompileData(trace, call_pure_results=call_pure_results,
  enable_opts=enable_opts)
-use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts)
 try:
 loop_info, ops = optimize_trace(
-metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo,
-use_unrolling=use_unroll)
+

[pypy-commit] pypy issue2996: add a failing test (issue 2996)

2019-04-13 Thread mattip
Author: Matti Picus 
Branch: issue2996
Changeset: r96464:f91f6fa3ca10
Date: 2019-04-13 22:51 +0300
http://bitbucket.org/pypy/pypy/changeset/f91f6fa3ca10/

Log:add a failing test (issue 2996)

diff --git a/pypy/objspace/std/test/test_callmethod.py 
b/pypy/objspace/std/test/test_callmethod.py
--- a/pypy/objspace/std/test/test_callmethod.py
+++ b/pypy/objspace/std/test/test_callmethod.py
@@ -22,6 +22,17 @@
 assert c.m(**{'u': 4}) == ((c,), {'u': 4})
 """)
 
+def test_call_star(self):
+exec("""if 1:
+class Foo:
+def meth(self, a1, *args, offset=42):
+return args, offset
+
+ret = Foo().meth(12, **{})
+assert type(ret[0][0]) is Foo
+assert ret[1] == 42
+""")
+
 def test_call_attribute(self):
 exec("""if 1:
 class C(object):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy optimizeopt-cleanup: Pull use_unrolling() call out of optimize_trace()

2019-04-13 Thread rlamy
Author: Ronan Lamy 
Branch: optimizeopt-cleanup
Changeset: r96463:dab1526f28a6
Date: 2019-04-13 20:19 +0100
http://bitbucket.org/pypy/pypy/changeset/dab1526f28a6/

Log:Pull use_unrolling() call out of optimize_trace()

diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -8,8 +8,6 @@
 from rpython.rlib import rstack
 from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside
 from rpython.rlib.rjitlog import rjitlog as jl
-from rpython.rlib.objectmodel import compute_unique_id
-from rpython.conftest import option
 
 from rpython.jit.metainterp.resoperation import ResOperation, rop,\
  get_deep_immutable_oplist, OpHelpers, InputArgInt, InputArgRef,\
@@ -138,6 +136,7 @@
 self.call_pure_results, self.inline_short_preamble)
 
 def show_procedures(metainterp_sd, procedure=None, error=None):
+from rpython.conftest import option
 # debugging
 if option and (option.view or option.viewloops):
 if error:
@@ -218,7 +217,7 @@
 
 def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts,
 cut_at):
-from rpython.jit.metainterp.optimizeopt import optimize_trace
+from rpython.jit.metainterp.optimizeopt import optimize_trace, 
use_unrolling
 
 jitdriver_sd = metainterp.jitdriver_sd
 metainterp_sd = metainterp.staticdata
@@ -226,9 +225,11 @@
 call_pure_results = metainterp.call_pure_results
 data = SimpleCompileData(trace, call_pure_results=call_pure_results,
  enable_opts=enable_opts)
+use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts)
 try:
-loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd,
-data, metainterp.box_names_memo)
+loop_info, ops = optimize_trace(
+metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo,
+use_unrolling=use_unroll)
 except InvalidLoop:
 metainterp_sd.jitlog.trace_aborted()
 trace.cut_at(cut_at)
@@ -257,7 +258,7 @@
 """Try to compile a new procedure by closing the current history back
 to the first operation.
 """
-from rpython.jit.metainterp.optimizeopt import optimize_trace
+from rpython.jit.metainterp.optimizeopt import optimize_trace, 
use_unrolling
 
 metainterp_sd = metainterp.staticdata
 jitdriver_sd = metainterp.jitdriver_sd
@@ -269,18 +270,20 @@
 faildescr=None, entry_bridge=False)
 #
 enable_opts = jitdriver_sd.warmstate.enable_opts
+use_unroll = use_unrolling(metainterp_sd.cpu, enable_opts)
 if try_disabling_unroll:
-if 'unroll' not in enable_opts:
+if not use_unroll:
 return None
 enable_opts = enable_opts.copy()
 del enable_opts['unroll']
+use_unroll = False
 
 jitcell_token = make_jitcell_token(jitdriver_sd)
 cut_at = history.get_trace_position()
 history.record(rop.JUMP, jumpargs, None, descr=jitcell_token)
 if start != (0, 0, 0):
 trace = trace.cut_trace_from(start, inputargs)
-if 'unroll' not in enable_opts or not 
metainterp.cpu.supports_guard_gc_type:
+if not use_unroll:
 return compile_simple_loop(metainterp, greenkey, trace, jumpargs,
enable_opts, cut_at)
 call_pure_results = metainterp.call_pure_results
@@ -288,9 +291,9 @@
 call_pure_results=call_pure_results,
 enable_opts=enable_opts)
 try:
-start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd,
-   preamble_data,
-   metainterp.box_names_memo)
+start_state, preamble_ops = optimize_trace(
+metainterp_sd, jitdriver_sd, preamble_data,
+metainterp.box_names_memo, use_unrolling=use_unroll)
 except InvalidLoop:
 metainterp_sd.jitlog.trace_aborted()
 history.cut(cut_at)
@@ -305,9 +308,9 @@
  call_pure_results=call_pure_results,
  enable_opts=enable_opts)
 try:
-loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd,
- loop_data,
- metainterp.box_names_memo)
+loop_info, loop_ops = optimize_trace(
+metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo,
+use_unrolling=use_unroll)
 except InvalidLoop:
 metainterp_sd.jitlog.trace_aborted()
 history.cut(cut_at)
@@ -354,7 +357,7 @@
 """Try to compile a new procedure by closing the current history back
 to the first operation.
 """
-from rpython.jit.metainterp.optimizeopt import optimize_trace
+from 

[pypy-commit] pypy py3.6: Translation fix

2019-04-13 Thread arigo
Author: Armin Rigo 
Branch: py3.6
Changeset: r96460:c9339f40372b
Date: 2019-04-13 18:28 +0200
http://bitbucket.org/pypy/pypy/changeset/c9339f40372b/

Log:Translation fix

diff --git a/pypy/objspace/std/unicodeobject.py 
b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -98,7 +98,9 @@
 
 def listview_ascii(self):
 if self.is_ascii():
-return list(self._utf8)
+return [c for c in self._utf8]
+# rpython note: can't use list() to return a list of strings
+# (only a list of chars is supported)
 return None
 
 def descr_iter(self, space):
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy winoverlapped: Fixed Subprocess tests

2019-04-13 Thread andrewjlawrence
Author: andrewjlawrence
Branch: winoverlapped
Changeset: r96455:80e8863b95ef
Date: 2019-04-13 15:11 +0100
http://bitbucket.org/pypy/pypy/changeset/80e8863b95ef/

Log:Fixed Subprocess tests

diff --git a/lib_pypy/_overlapped.py b/lib_pypy/_overlapped.py
--- a/lib_pypy/_overlapped.py
+++ b/lib_pypy/_overlapped.py
@@ -87,6 +87,8 @@
 def _int2handle(val):
 return _ffi.cast("HANDLE", val)
 
+def _int2overlappedptr(val):
+return _ffi.cast("OVERLAPPED*", val)
 
 def _handle2int(handle):
 return int(_ffi.cast("intptr_t", handle))
@@ -437,10 +439,10 @@
 
 @property
 def address(self):
-return self.overlapped
+return _handle2int(self.overlapped)
 
 def SetEvent(handle):
-ret = _kernel32.SetEvent(handle)
+ret = _kernel32.SetEvent(_int2handle(handle))
 if not ret:
raise _winapi._WinError()
 
@@ -451,6 +453,7 @@
 
 def CreateEvent(eventattributes, manualreset, initialstate, name):
 event = _kernel32.CreateEventW(NULL, manualreset, initialstate, _Z(name))
+event = _handle2int(event)
 if not event:
 raise _winapi._WinError()
 return event
@@ -466,8 +469,7 @@
   numberofconcurrentthreads)
 if result == _ffi.NULL:
 raise SetFromWindowsErr(0)
-
-return result
+return _handle2int(result)
 
 def PostQueuedCompletionStatus(completionport, ms):
 raise _winapi._WinError()
@@ -475,6 +477,7 @@
 def GetQueuedCompletionStatus(completionport, milliseconds):
 numberofbytes = _ffi.new('DWORD[1]', [0])
 completionkey  = _ffi.new('ULONG**')
+completionport = _int2handle(completionport)
 
 if completionport is None:
 raise _winapi._WinError()
@@ -495,20 +498,21 @@
 return None
 return SetFromWindowsErr(err)
 
-return (err, numberofbytes, _handle2int(completionkey[0]), 
_ffi.addressof(overlapped[0][0]))
+return (err, numberofbytes, _handle2int(completionkey[0]), 
_handle2int(_ffi.addressof(overlapped[0][0])))
 
 @_ffi.callback("void(void*, int)")
 def post_to_queue_callback(lpparameter, timerorwaitfired):
-pdata = _ffi.cast("PostCallbackData *", lpparameter)
+pdata = _ffi.cast("PostCallbackData*", lpparameter)
 ret = _kernel32.PostQueuedCompletionStatus(pdata.hCompletionPort, 
timerorwaitfired, _ffi.cast("ULONG_PTR",0), pdata.Overlapped)
 result = False
+_winapi.free(pdata)
 
 
 def RegisterWaitWithQueue(object, completionport, ovaddress, miliseconds):
-data = _ffi.new('PostCallbackData*')
+data = _ffi.cast('PostCallbackData*', _winapi.malloc( 
_ffi.sizeof("PostCallbackData")))
 newwaitobject = _ffi.new("HANDLE*")
-data[0].hCompletionPort = completionport
-data[0].Overlapped = ovaddress
+data[0].hCompletionPort = _int2handle(completionport)
+data[0].Overlapped = _int2overlappedptr(ovaddress)
 ret = _kernel32.RegisterWaitForSingleObject(newwaitobject,
 _int2handle(object),
 
_ffi.cast("WAITORTIMERCALLBACK",post_to_queue_callback),
diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py
--- a/lib_pypy/_pypy_winbase_build.py
+++ b/lib_pypy/_pypy_winbase_build.py
@@ -152,6 +152,10 @@
 #define WT_EXECUTEINWAITTHREAD 0x0004
 #define WT_EXECUTEONLYONCE 0x0008
 
+HANDLE GetProcessHeap();
+LPVOID HeapAlloc(HANDLE, DWORD, SIZE_T);
+BOOL HeapFree(HANDLE, DWORD, LPVOID);
+
 """)
 
 #  Win Sock 2 --
diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py
--- a/lib_pypy/_pypy_winbase_cffi.py
+++ b/lib_pypy/_pypy_winbase_cffi.py
@@ -3,8 +3,8 @@
 
 ffi = _cffi_backend.FFI('_pypy_winbase_cffi',
 _version = 0x2601,
-_types = 
b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x5C\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x01\x36\x03\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x1B\x03\x00\x01\x2F\x03\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x01\x40\x03\x00\x00\x22\x11\x00\x00\x11\x11\x00\x00\x11\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x22\x11\x00\x00\x22\x11\x00\x01\x3B\x03\x00\x01\x30\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x03\x00\x00\x2E\x11\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x2E\x11\x00\x00\x11\x11\x00\x01\x26\x03\x00\x00\x11\x11\x00\x00\x0A\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x11\x11\x00\x
 

[pypy-commit] pypy default: Fix the general testing for newstr(utf8, length_in_number_of_chars),

2019-04-13 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r96454:1f16a5e43952
Date: 2019-04-13 15:36 +0200
http://bitbucket.org/pypy/pypy/changeset/1f16a5e43952/

Log:Fix the general testing for newstr(utf8, length_in_number_of_chars),
which *now* should work and complain if we give an invalid number of
chars.

Fix array.array for a place where invalid utf8 strings were still
being made, found by the above.

diff --git a/pypy/module/array/interp_array.py 
b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -1053,21 +1053,17 @@
 code = r_uint(ord(item))
 # cpython will allow values > sys.maxunicode
 # while silently truncating the top bits
-if code <= r_uint(0x7F):
-# Encode ASCII
-item = chr(code)
-elif code <= r_uint(0x07FF):
-item = (chr((0xc0 | (code >> 6))) + 
-chr((0x80 | (code & 0x3f
-elif code <= r_uint(0x):
-item = (chr((0xe0 | (code >> 12))) +
-chr((0x80 | ((code >> 6) & 0x3f))) +
-chr((0x80 | (code & 0x3f
-else:
-item = (chr((0xf0 | (code >> 18)) & 0xff) +
-chr((0x80 | ((code >> 12) & 0x3f))) +
-chr((0x80 | ((code >> 6) & 0x3f))) +
-chr((0x80 | (code & 0x3f
+# For now I (arigo) am going to ignore that and
+# raise a ValueError always here, instead of getting
+# some invalid utf8-encoded string which makes things
+# potentially explode left and right.
+try:
+item = rutf8.unichr_as_utf8(code)
+except rutf8.OutOfRange:
+raise oefmt(space.w_ValueError,
+"cannot operate on this array('u') because it contains"
+" character %s not in range [U+; U+10]"
+" at index %d", 'U+%x' % code, idx)
 return space.newutf8(item, 1)
 assert 0, "unreachable"
 
diff --git a/pypy/module/array/test/test_array.py 
b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -851,7 +851,13 @@
 a = self.array('u', input_unicode)
 b = self.array('u', input_unicode)
 b.byteswap()
-assert a != b
+assert b[2] == u'\u'
+raises(ValueError, "b[1]")# doesn't work
+e = raises(ValueError, "a != b")  # doesn't work
+assert str(e.value) == (
+"cannot operate on this array('u') because it contains"
+" character U+100 not in range [U+; U+10]"
+" at index 0")
 assert str(a) == "array('u', %r)" % (input_unicode,)
 assert str(b) == ("array('u', )")
diff --git a/pypy/objspace/std/unicodeobject.py 
b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -42,13 +42,10 @@
 self._length = length
 self._index_storage = rutf8.null_storage()
 if not we_are_translated():
-try:
-# best effort, too expensive to handle surrogates
-ulength = rutf8.codepoints_in_utf(utf8str)
-except:
-ulength = length 
-assert ulength == length
-
+# utf8str must always be a valid utf8 string, except maybe with
+# explicit surrogate characters---which .decode('utf-8') doesn't
+# special-case in Python 2, which is exactly what we want here
+assert length == len(utf8str.decode('utf-8'))
 
 
 @staticmethod
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit