Author: Richard Plangger <[email protected]>
Branch: py3.5-memoryview
Changeset: r86725:d3b1d21c38e2
Date: 2016-08-30 10:13 +0200
http://bitbucket.org/pypy/pypy/changeset/d3b1d21c38e2/

Log:    merge py3.5

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -28,3 +28,5 @@
 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3
 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1
 68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0
+68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0
+77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -74,6 +74,7 @@
   Seo Sanghyeon
   Ronny Pfannschmidt
   Justin Peel
+  Raffael Tfirst
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
@@ -117,7 +118,6 @@
   Wenzhu Man
   John Witulski
   Laurence Tratt
-  Raffael Tfirst
   Ivan Sichmann Freitas
   Greg Price
   Dario Bertini
@@ -141,6 +141,7 @@
   tav
   Taavi Burns
   Georg Brandl
+  Nicolas Truessel
   Bert Freudenberg
   Stian Andreassen
   Wanja Saatkamp
@@ -211,6 +212,7 @@
   Vaibhav Sood
   Alan McIntyre
   Alexander Sedov
+  [email protected]
   Attila Gobi
   Jasper.Schulz
   Christopher Pope
@@ -221,6 +223,7 @@
   Arjun Naik
   Valentina Mukhamedzhanova
   Stefano Parmesan
+  touilleMan
   Alexis Daboville
   Jens-Uwe Mager
   Carl Meyer
@@ -229,12 +232,14 @@
   Gabriel
   Lukas Vacek
   Kunal Grover
+  Aaron Gallagher
   Andrew Dalke
   Sylvain Thenault
   Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
   Omer Katz
+  Mark Williams
   Jacek Generowicz
   Alejandro J. Cura
   Jacob Oscarson
@@ -355,12 +360,15 @@
   yasirs
   Michael Chermside
   Anna Ravencroft
+  pizi
   Andrey Churin
   Dan Crosta
+  Eli Stevens
   Tobias Diaz
   Julien Phalip
   Roman Podoliaka
   Dan Loewenherz
+  werat
 
   Heinrich-Heine University, Germany 
   Open End AB (formerly AB Strakt), Sweden
@@ -468,15 +476,3 @@
 
     https://github.com/gperftools/gperftools/blob/master/COPYING
 
-License for 'liblzma and 'lzmaffi'
-----------------------------------
-
-This copy of PyPy may be linked (dynamically or statically) with the
-liblzma library, which was put in the "public domain":
-
-    http://tukaani.org/xz/
-
-The cffi bindings to liblzma (in lib_pypy/_lzma.py) are derived from
-the lzmaffi project which is distributed under a BSD license:
-
-    https://pypi.python.org/pypi/lzmaffi/0.3.0
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -342,7 +342,7 @@
             thisarg = cast(thisvalue, POINTER(POINTER(c_void_p)))
             keepalives, newargs, argtypes, outargs, errcheckargs = (
                 self._convert_args(argtypes, args[1:], kwargs))
-            newargs.insert(0, thisvalue.value)
+            newargs.insert(0, thisarg)
             argtypes.insert(0, c_void_p)
         else:
             thisarg = None
diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst
--- a/pypy/doc/contributor.rst
+++ b/pypy/doc/contributor.rst
@@ -44,6 +44,7 @@
   Seo Sanghyeon
   Ronny Pfannschmidt
   Justin Peel
+  Raffael Tfirst
   David Edelsohn
   Anders Hammarquist
   Jakub Gustak
@@ -87,7 +88,6 @@
   Wenzhu Man
   John Witulski
   Laurence Tratt
-  Raffael Tfirst
   Ivan Sichmann Freitas
   Greg Price
   Dario Bertini
@@ -111,6 +111,7 @@
   tav
   Taavi Burns
   Georg Brandl
+  Nicolas Truessel
   Bert Freudenberg
   Stian Andreassen
   Wanja Saatkamp
@@ -181,6 +182,7 @@
   Vaibhav Sood
   Alan McIntyre
   Alexander Sedov
+  [email protected]
   Attila Gobi
   Jasper.Schulz
   Christopher Pope
@@ -191,6 +193,7 @@
   Arjun Naik
   Valentina Mukhamedzhanova
   Stefano Parmesan
+  touilleMan
   Alexis Daboville
   Jens-Uwe Mager
   Carl Meyer
@@ -199,12 +202,14 @@
   Gabriel
   Lukas Vacek
   Kunal Grover
+  Aaron Gallagher
   Andrew Dalke
   Sylvain Thenault
   Jakub Stasiak
   Nathan Taylor
   Vladimir Kryachko
   Omer Katz
+  Mark Williams
   Jacek Generowicz
   Alejandro J. Cura
   Jacob Oscarson
@@ -325,9 +330,12 @@
   yasirs
   Michael Chermside
   Anna Ravencroft
+  pizi
   Andrey Churin
   Dan Crosta
+  Eli Stevens
   Tobias Diaz
   Julien Phalip
   Roman Podoliaka
   Dan Loewenherz
+  werat
diff --git a/pypy/doc/release-pypy2.7-v5.4.0.rst 
b/pypy/doc/release-pypy2.7-v5.4.0.rst
--- a/pypy/doc/release-pypy2.7-v5.4.0.rst
+++ b/pypy/doc/release-pypy2.7-v5.4.0.rst
@@ -3,7 +3,8 @@
 ============
 
 We have released PyPy2.7 v5.4, a little under two months after PyPy2.7 v5.3.
-This new PyPy2.7 release includes further improvements to our C-API 
compatability layer (cpyext), enabling us to pass over 99% of the upstream
+This new PyPy2.7 release includes incremental improvements to our C-API
+compatability layer (cpyext), enabling us to pass over 99% of the upstream
 numpy `test suite`_. We updated built-in cffi_ support to version 1.8,
 which now supports the "limited API" mode for c-extensions on 
 CPython >=3.2.
@@ -12,9 +13,7 @@
 support to OpenBSD and Dragon Fly BSD
 
 As always, this release fixed many issues and bugs raised by the
-growing community of PyPy users. 
-
-XXXXX MORE ???
+growing community of PyPy users. We strongly recommend updating.
 
 You can download the PyPy2.7 v5.4 release here:
 
@@ -110,8 +109,8 @@
 
   * (RPython) add `rposix_scandir` portably, needed for Python 3.5
 
-  * Support for memoryview attributes (format, itemsize, ...) which also
-    adds support for `PyMemoryView_FromObject`
+  * Increased but incomplete support for memoryview attributes (format, 
+    itemsize, ...) which also adds support for `PyMemoryView_FromObject`
 
 * Bug Fixes
 
@@ -153,10 +152,6 @@
   * Make `hash(-1)` return -2, as CPython does, and fix all the
     ancilary places this matters
 
-  * Issues reported with our previous release were resolved_ after
-    reports from users on our issue tracker at
-    https://bitbucket.org/pypy/pypy/issues or on IRC at #pypy
-
   * Fix `PyNumber_Check()` to behave more like CPython
 
   * (VMProf) Try hard to not miss any Python-level frame in the
@@ -169,6 +164,10 @@
   * Fix the mapdict cache for subclasses of builtin types that
     provide a dict
 
+  * Issues reported with our previous release were resolved_ after
+    reports from users on our issue tracker at
+    https://bitbucket.org/pypy/pypy/issues or on IRC at #pypy
+
 * Performance improvements:
 
   * Add a before_call()-like equivalent before a few operations like
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -5,4 +5,5 @@
 .. this is a revision shortly after release-pypy2.7-v5.4
 .. startrev: 522736f816dc
 
-
+.. branch: rpython-resync
+Backport rpython changes made directly on the py3k and py3.5 branches.
diff --git a/pypy/module/_sre/interp_sre.py b/pypy/module/_sre/interp_sre.py
--- a/pypy/module/_sre/interp_sre.py
+++ b/pypy/module/_sre/interp_sre.py
@@ -13,7 +13,7 @@
 #
 # Constants and exposed functions
 
-from rpython.rlib.rsre import rsre_core
+from rpython.rlib.rsre import rsre_core, rsre_char
 from rpython.rlib.rsre.rsre_char import CODESIZE, MAXREPEAT, MAXGROUPS, 
getlower, set_unicode_db
 
 
@@ -92,6 +92,10 @@
 #
 # SRE_Pattern class
 
+FLAG_NAMES = ["re.TEMPLATE", "re.IGNORECASE", "re.LOCALE", "re.MULTILINE",
+              "re.DOTALL", "re.UNICODE", "re.VERBOSE", "re.DEBUG",
+              "re.ASCII"]
+
 class W_SRE_Pattern(W_Root):
     _immutable_fields_ = ["code", "flags", "num_groups", "w_groupindex"]
 
@@ -99,7 +103,44 @@
         space = self.space
         raise oefmt(space.w_TypeError, "cannot copy this pattern object")
 
-    def make_ctx(self, w_string, pos=0, endpos=sys.maxint):
+    def repr_w(self):
+        space = self.space
+        u = space.unicode_w(space.repr(self.w_pattern))
+        flag_items = []
+        flags = self.flags
+        if self.is_known_unicode():
+            if ((flags & (rsre_char.SRE_FLAG_LOCALE |
+                          rsre_char.SRE_FLAG_UNICODE |
+                          256))     # rsre_char.SRE_FLAG_ASCII
+                    == rsre_char.SRE_FLAG_UNICODE):
+                flags &= ~rsre_char.SRE_FLAG_UNICODE
+        for i, name in enumerate(FLAG_NAMES):
+            if flags & (1 << i):
+                flags -= (1 << i)
+                flag_items.append(name)
+        if flags != 0:
+            flag_items.append('0x%x' % flags)
+        if len(flag_items) == 0:
+            usep = u''
+            uflags = u''
+        else:
+            usep = u', '
+            uflags = u'|'.join([item.decode('latin-1') for item in flag_items])
+        return space.wrap(u're.compile(%s%s%s)' % (u, usep, uflags))
+
+    def is_known_bytes(self):
+        space = self.space
+        if space.is_none(self.w_pattern):
+            return False
+        return not space.isinstance_w(self.w_pattern, space.w_unicode)
+
+    def is_known_unicode(self):
+        space = self.space
+        if space.is_none(self.w_pattern):
+            return False
+        return space.isinstance_w(self.w_pattern, space.w_unicode)
+
+    def make_ctx(self, w_string, pos=0, endpos=sys.maxint, flags=0):
         """Make a StrMatchContext, BufMatchContext or a UnicodeMatchContext for
         searching in the given w_string object."""
         space = self.space
@@ -107,10 +148,10 @@
             pos = 0
         if endpos < pos:
             endpos = pos
+        flags = self.flags | flags
         if space.isinstance_w(w_string, space.w_unicode):
             unicodestr = space.unicode_w(w_string)
-            if not (space.is_none(self.w_pattern) or
-                    space.isinstance_w(self.w_pattern, space.w_unicode)):
+            if self.is_known_bytes():
                 raise oefmt(space.w_TypeError,
                             "can't use a bytes pattern on a string-like "
                             "object")
@@ -119,10 +160,9 @@
             if endpos > len(unicodestr):
                 endpos = len(unicodestr)
             return rsre_core.UnicodeMatchContext(self.code, unicodestr,
-                                                 pos, endpos, self.flags)
+                                                 pos, endpos, flags)
         elif space.isinstance_w(w_string, space.w_str):
-            if (not space.is_none(self.w_pattern) and
-                space.isinstance_w(self.w_pattern, space.w_unicode)):
+            if self.is_known_unicode():
                 raise oefmt(space.w_TypeError,
                             "can't use a string pattern on a bytes-like "
                             "object")
@@ -132,11 +172,10 @@
             if endpos > len(str):
                 endpos = len(str)
             return rsre_core.StrMatchContext(self.code, str,
-                                             pos, endpos, self.flags)
+                                             pos, endpos, flags)
         else:
             buf = space.readbuf_w(w_string)
-            if (not space.is_none(self.w_pattern) and
-                space.isinstance_w(self.w_pattern, space.w_unicode)):
+            if self.is_known_unicode():
                 raise oefmt(space.w_TypeError,
                             "can't use a string pattern on a bytes-like "
                             "object")
@@ -147,7 +186,7 @@
             if endpos > size:
                 endpos = size
             return rsre_core.BufMatchContext(self.code, buf,
-                                             pos, endpos, self.flags)
+                                             pos, endpos, flags)
 
     def getmatch(self, ctx, found):
         if found:
@@ -161,6 +200,12 @@
         return self.getmatch(ctx, matchcontext(self.space, ctx))
 
     @unwrap_spec(pos=int, endpos=int)
+    def fullmatch_w(self, w_string, pos=0, endpos=sys.maxint):
+        ctx = self.make_ctx(w_string, pos, endpos)
+        ctx.fullmatch_only = True
+        return self.getmatch(ctx, matchcontext(self.space, ctx))
+
+    @unwrap_spec(pos=int, endpos=int)
     def search_w(self, w_string, pos=0, endpos=sys.maxint):
         ctx = self.make_ctx(w_string, pos, endpos)
         return self.getmatch(ctx, searchcontext(self.space, ctx))
@@ -415,10 +460,12 @@
     __new__      = interp2app(SRE_Pattern__new__),
     __copy__     = interp2app(W_SRE_Pattern.cannot_copy_w),
     __deepcopy__ = interp2app(W_SRE_Pattern.cannot_copy_w),
+    __repr__     = interp2app(W_SRE_Pattern.repr_w),
     __weakref__  = make_weakref_descr(W_SRE_Pattern),
     findall      = interp2app(W_SRE_Pattern.findall_w),
     finditer     = interp2app(W_SRE_Pattern.finditer_w),
     match        = interp2app(W_SRE_Pattern.match_w),
+    fullmatch    = interp2app(W_SRE_Pattern.fullmatch_w),
     scanner      = interp2app(W_SRE_Pattern.finditer_w),    # reuse finditer()
     search       = interp2app(W_SRE_Pattern.search_w),
     split        = interp2app(W_SRE_Pattern.split_w),
diff --git a/pypy/module/_sre/test/test_app_sre.py 
b/pypy/module/_sre/test/test_app_sre.py
--- a/pypy/module/_sre/test/test_app_sre.py
+++ b/pypy/module/_sre/test/test_app_sre.py
@@ -116,6 +116,22 @@
         import _sre
         raises(TypeError, _sre.compile, {}, 0, [])
 
+    def test_fullmatch(self):
+        import re
+        assert re.compile(r"ab*c").fullmatch("abbcdef") is None
+        assert re.compile(r"ab*c").fullmatch("abbc") is not None
+        assert re.fullmatch(r"ab*c", "abbbcdef") is None
+        assert re.fullmatch(r"ab*c", "abbbc") is not None
+
+    def test_repr(self):
+        import re
+        r = re.compile(r'f(o"\d)', 0)
+        assert repr(r) == (
+            r"""re.compile('f(o"\\d)')""")
+        r = re.compile(r'f(o"\d)', re.IGNORECASE|re.DOTALL|re.VERBOSE)
+        assert repr(r) == (
+            r"""re.compile('f(o"\\d)', re.IGNORECASE|re.DOTALL|re.VERBOSE)""")
+
 
 class AppTestSreMatch:
     spaceconfig = dict(usemodules=('array', ))
diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -92,10 +92,20 @@
             link_extra=link_extra,
             libraries=libraries)
     from pypy.module.imp.importing import get_so_extension
-    pydname = soname.new(purebasename=modname, ext=get_so_extension(space))
+    ext = get_so_extension(space)
+    pydname = soname.new(purebasename=modname, ext=ext)
     soname.rename(pydname)
     return str(pydname)
 
+def get_so_suffix():
+    from imp import get_suffixes, C_EXTENSION
+    for suffix, mode, typ in get_suffixes():
+        if typ == C_EXTENSION:
+            return suffix
+    else:
+        raise RuntimeError("This interpreter does not define a filename "
+            "suffix for C extensions!")
+
 def compile_extension_module_applevel(space, modname, include_dirs=[],
         source_files=None, source_strings=None):
     """
@@ -126,13 +136,9 @@
             source_strings=source_strings,
             compile_extra=compile_extra,
             link_extra=link_extra)
-    from imp import get_suffixes, C_EXTENSION
-    pydname = soname
-    for suffix, mode, typ in get_suffixes():
-        if typ == C_EXTENSION:
-            pydname = soname.new(purebasename=modname, ext=suffix)
-            soname.rename(pydname)
-            break
+    ext = get_so_suffix()
+    pydname = soname.new(purebasename=modname, ext=ext)
+    soname.rename(pydname)
     return str(pydname)
 
 def freeze_refcnts(self):
@@ -145,6 +151,24 @@
     #state.print_refcounts()
     self.frozen_ll2callocations = set(ll2ctypes.ALLOCATED.values())
 
+class FakeSpace(object):
+    """Like TinyObjSpace, but different"""
+    def __init__(self, config):
+        from distutils.sysconfig import get_python_inc
+        self.config = config
+        self.include_dir = get_python_inc()
+
+    def passthrough(self, arg):
+        return arg
+    listview = passthrough
+    str_w = passthrough
+
+    def unwrap(self, args):
+        try:
+            return args.str_w(None)
+        except:
+            return args
+
 class LeakCheckingTest(object):
     """Base class for all cpyext tests."""
     spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array',
@@ -440,21 +464,8 @@
         self.imported_module_names = []
 
         if self.runappdirect:
+            fake = FakeSpace(self.space.config)
             def interp2app(func):
-                from distutils.sysconfig import get_python_inc
-                class FakeSpace(object):
-                    def passthrough(self, arg):
-                        return arg
-                    listview = passthrough
-                    str_w = passthrough
-                    def unwrap(self, args):
-                        try:
-                            return args.str_w(None)
-                        except:
-                            return args
-                fake = FakeSpace()
-                fake.include_dir = get_python_inc()
-                fake.config = self.space.config
                 def run(*args, **kwargs):
                     for k in kwargs.keys():
                         if k not in func.unwrap_spec and not 
k.startswith('w_'):
diff --git a/pypy/module/posix/interp_scandir.py 
b/pypy/module/posix/interp_scandir.py
--- a/pypy/module/posix/interp_scandir.py
+++ b/pypy/module/posix/interp_scandir.py
@@ -94,9 +94,10 @@
                     break
             #
             known_type = rposix_scandir.get_known_type(entry)
+            inode = rposix_scandir.get_inode(entry)
         finally:
             self._in_next = False
-        direntry = W_DirEntry(self, name, known_type)
+        direntry = W_DirEntry(self, name, known_type, inode)
         return space.wrap(direntry)
 
 
@@ -122,10 +123,11 @@
 class W_DirEntry(W_Root):
     w_path = None
 
-    def __init__(self, scandir_iterator, name, known_type):
+    def __init__(self, scandir_iterator, name, known_type, inode):
         self.space = scandir_iterator.space
         self.scandir_iterator = scandir_iterator
         self.name = name     # always bytes on Posix
+        self.inode = inode
         self.flags = known_type
         assert known_type == (known_type & 255)
         #
@@ -134,6 +136,10 @@
             w_name = self.space.fsdecode(w_name)
         self.w_name = w_name
 
+    def descr_repr(self, space):
+        u = space.unicode_w(space.repr(self.w_name))
+        return space.wrap(u"<DirEntry %s>" % u)
+
     def fget_name(self, space):
         return self.w_name
 
@@ -281,9 +287,13 @@
         st = self.get_stat_or_lstat(follow_symlinks)
         return build_stat_result(self.space, st)
 
+    def descr_inode(self, space):
+        return space.wrap(self.inode)
+
 
 W_DirEntry.typedef = TypeDef(
     'posix.DirEntry',
+    __repr__ = interp2app(W_DirEntry.descr_repr),
     name = GetSetProperty(W_DirEntry.fget_name,
                           doc="the entry's base filename, relative to "
                               'scandir() "path" argument'),
@@ -294,5 +304,6 @@
     is_file = interp2app(W_DirEntry.descr_is_file),
     is_symlink = interp2app(W_DirEntry.descr_is_symlink),
     stat = interp2app(W_DirEntry.descr_stat),
+    inode = interp2app(W_DirEntry.descr_inode),
 )
 W_DirEntry.typedef.acceptable_as_base_class = False
diff --git a/pypy/module/posix/test/test_scandir.py 
b/pypy/module/posix/test/test_scandir.py
--- a/pypy/module/posix/test/test_scandir.py
+++ b/pypy/module/posix/test/test_scandir.py
@@ -157,3 +157,15 @@
     def test_fdopendir_unsupported(self):
         posix = self.posix
         raises(TypeError, posix.scandir, 1234)
+
+    def test_inode(self):
+        posix = self.posix
+        d = next(posix.scandir(self.dir1))
+        assert d.name == 'file1'
+        ino = d.inode()
+        assert ino == d.stat().st_ino
+
+    def test_repr(self):
+        posix = self.posix
+        d = next(posix.scandir(self.dir1))
+        assert repr(d) == "<DirEntry 'file1'>"
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -114,6 +114,31 @@
         return w_item
 
 
+class W_StringIterObject(W_AbstractSeqIterObject):
+    """Sequence iterator specialized for string-like objects, used
+    for bytes.__iter__() or str.__iter__() or bytearray.__iter__().
+    Needed because otherwise these methods would call the possibly
+    overridden __getitem__() method, which they must not.
+    """
+    def __init__(self, w_seq, getitem_fn):
+        W_AbstractSeqIterObject.__init__(self, w_seq)
+        self.getitem_fn = getitem_fn
+
+    def descr_next(self, space):
+        if self.w_seq is None:
+            raise OperationError(space.w_StopIteration, space.w_None)
+        index = self.index
+        try:
+            w_item = self.getitem_fn(self.w_seq, space, index)
+        except OperationError as e:
+            self.w_seq = None
+            if not e.match(space, space.w_IndexError):
+                raise
+            raise OperationError(space.w_StopIteration, space.w_None)
+        self.index = index + 1
+        return w_item
+
+
 class W_ReverseSeqIterObject(W_Root):
     def __init__(self, space, w_seq, index=-1):
         self.w_seq = w_seq
diff --git a/pypy/objspace/std/stringmethods.py 
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -75,7 +75,8 @@
         return space.wrap(self._len())
 
     def descr_iter(self, space):
-        return space.newseqiter(self)
+        from pypy.objspace.std.iterobject import W_StringIterObject
+        return W_StringIterObject(self, self.__class__._getitem_result)
 
     def descr_contains(self, space, w_sub):
         value = self._val(space)
@@ -133,14 +134,15 @@
         return self._getitem_result(space, index)
 
     def _getitem_result(self, space, index):
+        # Returns the result of 'self[index]', where index is an unwrapped int.
+        # Used by descr_getitem() and by descr_iter().
         selfvalue = self._val(space)
         try:
             character = selfvalue[index]
         except IndexError:
             raise oefmt(space.w_IndexError, "string index out of range")
         from pypy.objspace.std.bytesobject import W_BytesObject
-        from pypy.objspace.std.bytearrayobject import W_BytearrayObject
-        if isinstance(self, W_BytesObject) or isinstance(self, 
W_BytearrayObject):
+        if isinstance(self, W_BytesObject):
             return space.wrap(ord(character))
         return self._new(character)
 
diff --git a/pypy/objspace/std/test/test_listobject.py 
b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -432,7 +432,7 @@
 
 
 class AppTestListObject(object):
-    spaceconfig = {"objspace.std.withliststrategies": True}  # it's the default
+    #spaceconfig = {"objspace.std.withliststrategies": True}  # it's the 
default
 
     def setup_class(cls):
         import platform
@@ -1524,6 +1524,16 @@
             def __iter__(self):
                 yield "ok"
         assert list(U("don't see me")) == ["ok"]
+        #
+        class S(bytes):
+            def __getitem__(self, index):
+                never_called
+        assert list(S(b"abc")) == list(b"abc")   # __getitem__ ignored
+        #
+        class U(str):
+            def __getitem__(self, index):
+                never_called
+        assert list(U("abc")) == list("abc")     # __getitem__ ignored
 
     def test_extend_from_nonempty_list_with_subclasses(self):
         l = ["hi!"]
@@ -1549,6 +1559,20 @@
         l.extend(U("don't see me"))
         #
         assert l == ["hi!", "okT", "okL", "okL", "okS", "okU"]
+        #
+        class S(bytes):
+            def __getitem__(self, index):
+                never_called
+        l = []
+        l.extend(S(b"abc"))
+        assert l == list(b"abc")    # __getitem__ ignored
+        #
+        class U(str):
+            def __getitem__(self, index):
+                never_called
+        l = []
+        l.extend(U("abc"))
+        assert l == list("abc")     # __getitem__ ignored
 
     def test_issue1266(self):
         l = list(range(1))
diff --git a/rpython/rlib/rjitlog/rjitlog.py b/rpython/rlib/rjitlog/rjitlog.py
--- a/rpython/rlib/rjitlog/rjitlog.py
+++ b/rpython/rlib/rjitlog/rjitlog.py
@@ -430,9 +430,8 @@
 
 def encode_merge_point(log, compressor, values):
     line = []
-    unrolled = unrolling_iterable(values)
     i = 0
-    for value in unrolled:
+    for value in values:
         line.append(value.encode(log,i,compressor))
         i += 1
     return ''.join(line)
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -623,7 +623,8 @@
     class CConfig:
         _compilation_info_ = eci
         DIRENT = rffi_platform.Struct('struct dirent',
-            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1))]
+            [('d_name', lltype.FixedSizeArray(rffi.CHAR, 1)),
+             ('d_ino', lltype.Signed)]
             + [('d_type', rffi.INT)] if HAVE_D_TYPE else [])
         if HAVE_D_TYPE:
             DT_UNKNOWN = rffi_platform.ConstantInteger('DT_UNKNOWN')
@@ -1159,23 +1160,18 @@
     # 'flags' might be ignored.  Check the result.
     if _WIN32:
         # 'flags' ignored
-        pread  = lltype.malloc(rwin32.LPHANDLE.TO, 1, flavor='raw')
-        pwrite = lltype.malloc(rwin32.LPHANDLE.TO, 1, flavor='raw')
-        try:
-            ok = CreatePipe(
-                    pread, pwrite, lltype.nullptr(rffi.VOIDP.TO), 0)
-            hread = rffi.cast(rffi.INTPTR_T, pread[0])
-            hwrite = rffi.cast(rffi.INTPTR_T, pwrite[0])
-        finally:
-            lltype.free(pwrite, flavor='raw')
-            lltype.free(pread, flavor='raw')
-        if ok:
-            fdread = c_open_osfhandle(hread, 0)
-            fdwrite = c_open_osfhandle(hwrite, 1)
-            if not (fdread == -1 or fdwrite == -1):
-                return (fdread, fdwrite)
-            rwin32.CloseHandle(pread)
-            rwin32.CloseHandle(pwrite)
+        ralloc = lltype.scoped_alloc(rwin32.LPHANDLE.TO, 1)
+        walloc = lltype.scoped_alloc(rwin32.LPHANDLE.TO, 1)
+        with ralloc as pread, walloc as pwrite:
+            if CreatePipe(pread, pwrite, lltype.nullptr(rffi.VOIDP.TO), 0):
+                hread = pread[0]
+                hwrite = pwrite[0]
+                fdread = c_open_osfhandle(rffi.cast(rffi.INTPTR_T, hread), 0)
+                fdwrite = c_open_osfhandle(rffi.cast(rffi.INTPTR_T, hwrite), 1)
+                if not (fdread == -1 or fdwrite == -1):
+                    return (fdread, fdwrite)
+                rwin32.CloseHandle(hread)
+                rwin32.CloseHandle(hwrite)
         raise WindowsError(rwin32.GetLastError_saved(), "CreatePipe failed")
     else:
         filedes = lltype.malloc(INT_ARRAY_P.TO, 2, flavor='raw')
diff --git a/rpython/rlib/rposix_scandir.py b/rpython/rlib/rposix_scandir.py
--- a/rpython/rlib/rposix_scandir.py
+++ b/rpython/rlib/rposix_scandir.py
@@ -50,3 +50,6 @@
     if rposix.HAVE_D_TYPE:
         return rffi.getintfield(direntp, 'c_d_type')
     return DT_UNKNOWN
+
+def get_inode(direntp):
+    return rffi.getintfield(direntp, 'c_d_ino')
diff --git a/rpython/rlib/rsre/rsre_core.py b/rpython/rlib/rsre/rsre_core.py
--- a/rpython/rlib/rsre/rsre_core.py
+++ b/rpython/rlib/rsre/rsre_core.py
@@ -89,6 +89,7 @@
     match_end = 0
     match_marks = None
     match_marks_flat = None
+    fullmatch_only = False
 
     def __init__(self, pattern, match_start, end, flags):
         # 'match_start' and 'end' must be known to be non-negative
@@ -526,9 +527,16 @@
         if op == OPCODE_FAILURE:
             return
 
-        if (op == OPCODE_SUCCESS or
-            op == OPCODE_MAX_UNTIL or
-            op == OPCODE_MIN_UNTIL):
+        elif op == OPCODE_SUCCESS:
+            if ctx.fullmatch_only:
+                if ptr != ctx.end:
+                    return     # not a full match
+            ctx.match_end = ptr
+            ctx.match_marks = marks
+            return MATCHED_OK
+
+        elif (op == OPCODE_MAX_UNTIL or
+              op == OPCODE_MIN_UNTIL):
             ctx.match_end = ptr
             ctx.match_marks = marks
             return MATCHED_OK
@@ -551,7 +559,11 @@
             # assert subpattern
             # <ASSERT> <0=skip> <1=back> <pattern>
             ptr1 = ptr - ctx.pat(ppos+1)
-            if ptr1 < 0 or sre_match(ctx, ppos + 2, ptr1, marks) is None:
+            saved = ctx.fullmatch_only
+            ctx.fullmatch_only = False
+            stop = ptr1 < 0 or sre_match(ctx, ppos + 2, ptr1, marks) is None
+            ctx.fullmatch_only = saved
+            if stop:
                 return
             marks = ctx.match_marks
             ppos += ctx.pat(ppos)
@@ -560,7 +572,12 @@
             # assert not subpattern
             # <ASSERT_NOT> <0=skip> <1=back> <pattern>
             ptr1 = ptr - ctx.pat(ppos+1)
-            if ptr1 >= 0 and sre_match(ctx, ppos + 2, ptr1, marks) is not None:
+            saved = ctx.fullmatch_only
+            ctx.fullmatch_only = False
+            stop = (ptr1 >= 0 and sre_match(ctx, ppos + 2, ptr1, marks)
+                                      is not None)
+            ctx.fullmatch_only = saved
+            if stop:
                 return
             ppos += ctx.pat(ppos)
 
@@ -999,14 +1016,18 @@
     elif end > length: end = length
     return start, end
 
-def match(pattern, string, start=0, end=sys.maxint, flags=0):
+def match(pattern, string, start=0, end=sys.maxint, flags=0, fullmatch=False):
     start, end = _adjust(start, end, len(string))
     ctx = StrMatchContext(pattern, string, start, end, flags)
+    ctx.fullmatch_only = fullmatch
     if match_context(ctx):
         return ctx
     else:
         return None
 
+def fullmatch(pattern, string, start=0, end=sys.maxint, flags=0):
+    return match(pattern, string, start, end, flags, fullmatch=True)
+
 def search(pattern, string, start=0, end=sys.maxint, flags=0):
     start, end = _adjust(start, end, len(string))
     ctx = StrMatchContext(pattern, string, start, end, flags)
diff --git a/rpython/rlib/rsre/test/test_match.py 
b/rpython/rlib/rsre/test/test_match.py
--- a/rpython/rlib/rsre/test/test_match.py
+++ b/rpython/rlib/rsre/test/test_match.py
@@ -272,3 +272,30 @@
         r = get_code("\\{\\{((?:.*?)+)\\}\\}")
         match = rsre_core.match(r, "{{a}}{{b}}")
         assert match.group(1) == "a"
+
+    def test_fullmatch_1(self):
+        r = get_code(r"ab*c")
+        assert not rsre_core.fullmatch(r, "abbbcdef")
+        assert rsre_core.fullmatch(r, "abbbc")
+
+    def test_fullmatch_2(self):
+        r = get_code(r"a(b*?)")
+        match = rsre_core.fullmatch(r, "abbb")
+        assert match.group(1) == "bbb"
+        assert not rsre_core.fullmatch(r, "abbbc")
+
+    def test_fullmatch_3(self):
+        r = get_code(r"a((bp)*?)c")
+        match = rsre_core.fullmatch(r, "abpbpbpc")
+        assert match.group(1) == "bpbpbp"
+
+    def test_fullmatch_4(self):
+        r = get_code(r"a((bp)*)c")
+        match = rsre_core.fullmatch(r, "abpbpbpc")
+        assert match.group(1) == "bpbpbp"
+
+    def test_fullmatch_assertion(self):
+        r = get_code(r"(?=a).b")
+        assert rsre_core.fullmatch(r, "ab")
+        r = get_code(r"(?!a)..")
+        assert not rsre_core.fullmatch(r, "ab")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to