[pypy-commit] pypy default: Issue #2865

2018-08-09 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r94982:95232deededb
Date: 2018-08-09 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/95232deededb/

Log:Issue #2865

Make types.MemberDescriptorType be the type of app-level slots

diff --git a/lib-python/2.7/types.py b/lib-python/2.7/types.py
--- a/lib-python/2.7/types.py
+++ b/lib-python/2.7/types.py
@@ -83,9 +83,19 @@
 DictProxyType = type(TypeType.__dict__)
 NotImplementedType = type(NotImplemented)
 
-# For Jython, the following two types are identical
+#
+# On CPython, FunctionType.__code__ is a 'getset_descriptor', but
+# FunctionType.__globals__ is a 'member_descriptor', just like app-level
+# slots.  On PyPy, all descriptors of built-in types are
+# 'getset_descriptor', but the app-level slots are 'member_descriptor'
+# as well.  (On Jython the situation might still be different.)
+#
+# Note that MemberDescriptorType was equal to GetSetDescriptorType in
+# PyPy <= 6.0.
+#
 GetSetDescriptorType = type(FunctionType.func_code)
-MemberDescriptorType = type(FunctionType.func_globals)
+class _C(object): __slots__ = 's'
+MemberDescriptorType = type(_C.s)
 
 del sys, _f, _g, _C, _x   # Not for export
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: hg merge default (and port the changes from 2.7/types.py to 3/types.py)

2018-08-09 Thread arigo
Author: Armin Rigo 
Branch: py3.5
Changeset: r94983:f938ea58f52c
Date: 2018-08-09 16:32 +0200
http://bitbucket.org/pypy/pypy/changeset/f938ea58f52c/

Log:hg merge default (and port the changes from 2.7/types.py to
3/types.py)

diff --git a/lib-python/3/types.py b/lib-python/3/types.py
--- a/lib-python/3/types.py
+++ b/lib-python/3/types.py
@@ -41,9 +41,19 @@
 FrameType = type(tb.tb_frame)
 tb = None; del tb
 
-# For Jython, the following two types are identical
+#
+# On CPython, FunctionType.__code__ is a 'getset_descriptor', but
+# FunctionType.__globals__ is a 'member_descriptor', just like app-level
+# slots.  On PyPy, all descriptors of built-in types are
+# 'getset_descriptor', but the app-level slots are 'member_descriptor'
+# as well.  (On Jython the situation might still be different.)
+#
+# Note that MemberDescriptorType was equal to GetSetDescriptorType in
+# PyPy <= 6.0.
+#
 GetSetDescriptorType = type(FunctionType.__code__)
-MemberDescriptorType = type(FunctionType.__globals__)
+class _C: __slots__ = 's'
+MemberDescriptorType = type(_C.s)
 
 del sys, _f, _g, _C, _c,   # Not for export
 
diff --git a/lib_pypy/cffi/_cffi_errors.h b/lib_pypy/cffi/_cffi_errors.h
--- a/lib_pypy/cffi/_cffi_errors.h
+++ b/lib_pypy/cffi/_cffi_errors.h
@@ -50,7 +50,9 @@
 "import sys\n"
 "class FileLike:\n"
 "  def write(self, x):\n"
-"of.write(x)\n"
+"try:\n"
+"  of.write(x)\n"
+"except: pass\n"
 "self.buf += x\n"
 "fl = FileLike()\n"
 "fl.buf = ''\n"
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -2076,7 +2076,7 @@
 else:
 skip_leading_underscores = False
 for name in all:
-if skip_leading_underscores and name[0]=='_':
+if skip_leading_underscores and name and name[0] == '_':
 continue
 into_locals[name] = getattr(module, name)
 ''', filename=__file__)
diff --git a/pypy/module/imp/test/test_import.py 
b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -101,8 +101,8 @@
  foobar= "found = 123",
  barbaz= "other = 543")
 setuppkg("pkg.withoutall",
- __init__  = "",
- foobar= "found = 123")
+ __init__  = "globals()[''] = 456",
+ foobar= "found = 123\n")
 setuppkg("pkg.bogusall",
  __init__  = "__all__ = 42")
 setuppkg("pkg_r", inpkg = "import x.y")
@@ -703,6 +703,13 @@
 exec("from pkg.withoutall import *", d)
 assert d["foobar"].found == 123
 
+def test_import_star_empty_string(self):
+for case in ["not-imported-yet", "already-imported"]:
+d = {}
+exec("from pkg.withoutall import *", d)
+assert "" in d
+
+
 def test_import_star_with_bogus___all__(self):
 for case in ["not-imported-yet", "already-imported"]:
 try:
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1946,3 +1946,30 @@
 # only works with the Python FFI instances
 ffi = FFI(backend=self.Backend())
 assert ffi.sizeof("struct{int a;}") == ffi.sizeof("int")
+
+def test_callback_large_struct(self):
+ffi = FFI(backend=self.Backend())
+# more than 8 bytes
+ffi.cdef("struct foo_s { unsigned long a, b, c; };")
+#
+@ffi.callback("void(struct foo_s)")
+def cb(s):
+seen.append(ffi.typeof(s))
+s.a += 1
+s.b += 2
+s.c += 3
+seen.append(s.a)
+seen.append(s.b)
+seen.append(s.c)
+#
+s1 = ffi.new("struct foo_s *", {'a': 100, 'b': 200, 'c': 300})
+seen = []
+cb(s1[0])
+assert len(seen) == 4
+assert s1.a == 100 # unmodified
+assert s1.b == 200
+assert s1.c == 300
+assert seen[0] == ffi.typeof("struct foo_s")
+assert seen[1] == 101
+assert seen[2] == 202
+assert seen[3] == 303
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ownlib.py
@@ -103,6 +103,11 @@
 {
 return (unsigned int)(a + 42);
 }
+
+EXPORT void modify_struct_value(RECT r)
+{
+r.left = r.right = r.top = r.bottom = 500;
+}
 """
 
 class TestOwnLib(object):
@@ -331,3 +336,25 @@
 assert lib.foo_2bytes(u+'\u1234') == u+'\u125e'
 assert l

[pypy-commit] pypy unicode-utf8-py3: add a lgt arg to newtext, change error _compute_value accordingly

2018-08-09 Thread mattip
Author: Matti Picus 
Branch: unicode-utf8-py3
Changeset: r94984:07a4929a661d
Date: 2018-08-09 13:27 -0700
http://bitbucket.org/pypy/pypy/changeset/07a4929a661d/

Log:add a lgt arg to newtext, change error _compute_value accordingly

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -9,7 +9,7 @@
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rlib.objectmodel import dont_inline, not_rpython
 from rpython.rlib import rstack, rstackovf
-from rpython.rlib import rwin32
+from rpython.rlib import rwin32, runicode
 
 from pypy.interpreter import debug
 
@@ -71,7 +71,7 @@
 space = getattr(self.w_type, 'space', None)
 if space is not None:
 if self.__class__ is not OperationError and s is None:
-s = self._compute_value(space)
+s, lgt = self._compute_value(space)
 try:
 s = space.text_w(s)
 except Exception:
@@ -305,8 +305,8 @@
 def get_w_value(self, space):
 w_value = self._w_value
 if w_value is None:
-value = self._compute_value(space)
-self._w_value = w_value = space.newtext(value)
+value, lgt = self._compute_value(space)
+self._w_value = w_value = space.newtext(value, lgt)
 return w_value
 
 def _compute_value(self, space):
@@ -477,10 +477,10 @@
 if isinstance(string, unicode):
 return string
 assert isinstance(string, str)
-return string.decode('utf8')
-#result, consumed = runicode.str_decode_utf_8(
-#string, len(string), "replace", final=True)
-#return result
+#return string.decode('utf8')
+result, consumed = runicode.str_decode_utf_8(
+string, len(string), "replace", final=True)
+return result
 
 def get_operrcls2(valuefmt):
 valuefmt = valuefmt.decode('ascii')
@@ -502,6 +502,7 @@
 self.setup(w_type)
 
 def _compute_value(self, space):
+# TODO: avoid utf8->unicode->utf8 dance
 lst = [None] * (len(formats) + len(formats) + 1)
 for i, fmt, attr in entries:
 lst[i + i] = self.xstrings[i]
@@ -523,7 +524,8 @@
 elif fmt == '8':
 # u'str\u' -> 'str\xXX\xXX' -> u"'str\xXX\xXX'"
 if isinstance(value, unicode):
-result = value.encode('utf8')
+result = runicode.unicode_encode_utf_8(value,
+ len(value), 'strict', 
allow_surrogates=True)
 else:
 from pypy.interpreter import unicodehelper
 result = 
_decode_utf8(unicodehelper.str_decode_utf8(
@@ -536,7 +538,12 @@
 result = _decode_utf8(str(value))
 lst[i + i + 1] = result
 lst[-1] = self.xstrings[-1]
-return u''.join(lst)
+retval = u''.join(lst)
+# We need to annotate both allow_surrogates=True,False
+# since this function is used to replace uni.encode('utf8')
+# deep in rpython
+return runicode.unicode_encode_utf_8(retval, len(retval),
+ 'strict', allow_surrogates=False), len(retval)
 #
 _fmtcache2[formats] = OpErrFmt
 return OpErrFmt, strings
@@ -547,7 +554,7 @@
 self.setup(w_type)
 
 def _compute_value(self, space):
-return self._value.decode('utf-8')
+return self._value, len(self._value)
 
 def async(self, space):
 # also matches a RuntimeError("maximum rec.") if the stack is
@@ -639,7 +646,7 @@
 msg = u'Windows Error %d' % winerror
 w_errno = space.w_None
 w_winerror = space.newint(winerror)
-w_msg = space.newtext(msg)
+w_msg = space.newtext(msg.encode('utf8'), len(msg))
 else:
 errno = e.errno
 if errno == EINTR:
@@ -653,7 +660,7 @@
 msg = u'error %d' % errno
 w_errno = space.newint(errno)
 w_winerror = space.w_None
-w_msg = space.newtext(msg)
+w_msg = space.newtext(msg.encode('utf8'), len(msg))
 
 if w_filename is None:
 w_filename = space.w_None
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -1122,7 +1122,7 @@
 kw_defs_w = []
 for name, w_def in sorted(alldefs_w.items()):
 assert name in sig.kwonlyargnames
-w_name = space.newtext(name.decode('utf-8'))
+w_name = space.newtext(name)
 kw_defs_w.append((w_name, w_def))
 
 return defs_w, kw_defs_w
diff --git a/pypy/interpreter/pyparser/error.py 
b/pypy/interpreter/pyparser/error.py

[pypy-commit] pypy unicode-utf8-py3: fix test

2018-08-09 Thread mattip
Author: Matti Picus 
Branch: unicode-utf8-py3
Changeset: r94987:d7d67afa0ca8
Date: 2018-08-09 13:29 -0700
http://bitbucket.org/pypy/pypy/changeset/d7d67afa0ca8/

Log:fix test

diff --git a/pypy/module/_codecs/test/test_locale.py 
b/pypy/module/_codecs/test/test_locale.py
--- a/pypy/module/_codecs/test/test_locale.py
+++ b/pypy/module/_codecs/test/test_locale.py
@@ -49,7 +49,7 @@
 utf8_encoder = self.getencoder('utf-8')
 encode_error_handler = self.getstate().encode_error_handler
 for val in u'foo\udc80bar', u'\udcff\U0001320C':
-expected = utf8_encoder(val, 'surrogateescape',
+expected = utf8_encoder(val.encode('utf8'), 'surrogateescape',
 encode_error_handler)
 assert locale_encoder(val).encode('utf8') == expected
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy unicode-utf8-py3: replace utf8 with W_Unicode , saves a conversion or two

2018-08-09 Thread mattip
Author: Matti Picus 
Branch: unicode-utf8-py3
Changeset: r94985:f6f71b76311e
Date: 2018-08-09 13:28 -0700
http://bitbucket.org/pypy/pypy/changeset/f6f71b76311e/

Log:replace utf8 with W_Unicode , saves a conversion or two

diff --git a/pypy/interpreter/astcompiler/fstring.py 
b/pypy/interpreter/astcompiler/fstring.py
--- a/pypy/interpreter/astcompiler/fstring.py
+++ b/pypy/interpreter/astcompiler/fstring.py
@@ -3,6 +3,7 @@
 from pypy.interpreter import error
 from pypy.interpreter import unicodehelper
 from rpython.rlib.rstring import StringBuilder
+from rpython.rlib.rutf8 import codepoints_in_utf8
 
 
 def add_constant_string(astbuilder, joined_pieces, w_string, atom_node):
@@ -21,10 +22,8 @@
 joined_pieces.append(node(w_string, atom_node.get_lineno(),
 atom_node.get_column()))
 
-def f_constant_string(astbuilder, joined_pieces, u, atom_node):
-space = astbuilder.space
-add_constant_string(astbuilder, joined_pieces, space.newtext(u),
-atom_node)
+def f_constant_string(astbuilder, joined_pieces, w_u, atom_node):
+add_constant_string(astbuilder, joined_pieces, w_u, atom_node)
 
 def f_string_compile(astbuilder, source, atom_node):
 # Note: a f-string is kept as a single literal up to here.
@@ -259,19 +258,20 @@
 i += 1
 
 fstr.current_index = i
+space = astbuilder.space
 literal = builder.build()
+lgt = codepoints_in_utf8(literal)
 if not fstr.raw_mode and '\\' in literal:
-space = astbuilder.space
 literal = parsestring.decode_unicode_utf8(space, literal, 0,
   len(literal))
-literal, lgt, _ = unicodehelper.decode_unicode_escape(space, literal)
-return literal.decode('utf-8')
+literal, pos, lgt = unicodehelper.decode_unicode_escape(space, literal)
+return space.newtext(literal, lgt)
 
 
 def fstring_find_literal_and_expr(astbuilder, fstr, atom_node, rec):
-# Return a tuple with the next literal part, and optionally the
+# Return a tuple with the next literal part as a W_Unicode, and optionally 
the
 # following expression node.  Updates the current index inside 'fstr'.
-literal = fstring_find_literal(astbuilder, fstr, atom_node, rec)
+w_u = fstring_find_literal(astbuilder, fstr, atom_node, rec)
 
 s = fstr.unparsed
 i = fstr.current_index
@@ -283,7 +283,7 @@
 # We must now be the start of an expression, on a '{'.
 assert s[i] == '{'
 expr = fstring_find_expr(astbuilder, fstr, atom_node, rec)
-return literal, expr
+return w_u, expr
 
 
 def parse_f_string(astbuilder, joined_pieces, fstr, atom_node, rec=0):
@@ -302,11 +302,11 @@
 "really the case", atom_node)
 
 while True:
-literal, expr = fstring_find_literal_and_expr(astbuilder, fstr,
+w_u, expr = fstring_find_literal_and_expr(astbuilder, fstr,
   atom_node, rec)
 
 # add the literal part
-f_constant_string(astbuilder, joined_pieces, literal, atom_node)
+f_constant_string(astbuilder, joined_pieces, w_u, atom_node)
 
 if expr is None:
 break # We're done with this f-string.
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy unicode-utf8-py3: start to replace s.encode('utf8') with calls to unicode_encode_utf_8

2018-08-09 Thread mattip
Author: Matti Picus 
Branch: unicode-utf8-py3
Changeset: r94986:3125af5a0967
Date: 2018-08-09 13:29 -0700
http://bitbucket.org/pypy/pypy/changeset/3125af5a0967/

Log:start to replace s.encode('utf8') with calls to unicode_encode_utf_8

diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -6,10 +6,10 @@
 from rpython.rlib import jit
 from rpython.rlib.objectmodel import enforceargs
 from rpython.rlib.rstring import StringBuilder
+from rpython.rlib.runicode import unicode_encode_utf_8
 
 from pypy.interpreter.error import OperationError, oefmt
 
-
 class Arguments(object):
 """
 Collects the arguments of a function call.
@@ -603,7 +603,8 @@
 def getmsg(self):
 if self.num_kwds == 1:
 if isinstance(self.kwd_name, unicode):
-uname = self.kwd_name.encode('utf8')
+uname = unicode_encode_utf_8(self.kwd_name, len(self.kwd_name),
+'strict', allow_surroagates=False)
 else:
 uname = self.kwd_name
 msg = "got an unexpected keyword argument '%s'" % uname
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy default: Issue #2839

2018-08-09 Thread arigo
Author: Armin Rigo 
Branch: 
Changeset: r94988:dc18c3e11193
Date: 2018-08-09 22:37 +0200
http://bitbucket.org/pypy/pypy/changeset/dc18c3e11193/

Log:Issue #2839

max(list-of-int) was much slower when run from non-jitted code.
Fixed.

diff --git a/pypy/module/__builtin__/functional.py 
b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -209,8 +209,12 @@
 
 @specialize.arg(2)
 def min_max(space, args, implementation_of):
-if not jit.we_are_jitted() or len(args.arguments_w) != 1 and \
-jit.loop_unrolling_heuristic(args.arguments_w, 
len(args.arguments_w)):
+# the 'normal' version includes a JIT merge point, which will make a
+# new loop (from the interpreter or from another JIT loop).  If we
+# give exactly two arguments to the call to max(), or a JIT virtual
+# list of arguments, then we pick the 'unroll' version with no JIT
+# merge point.
+if jit.isvirtual(args.arguments_w) or len(args.arguments_w) == 2:
 return min_max_unroll(space, args, implementation_of)
 else:
 return min_max_normal(space, args, implementation_of)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit