Author: Brian Kearns <bdkea...@gmail.com> Branch: use-file-star-for-file Changeset: r73371:224dfb42e83d Date: 2014-09-07 18:42 -0400 http://bitbucket.org/pypy/pypy/changeset/224dfb42e83d/
Log: merge default diff too long, truncating to 2000 out of 5130 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -35,280 +35,290 @@ the beginning of each file) the files in the 'pypy' directory are each copyrighted by one or more of the following people and organizations: - Armin Rigo - Maciej Fijalkowski - Carl Friedrich Bolz - Antonio Cuni - Amaury Forgeot d'Arc - Samuele Pedroni - Alex Gaynor - Michael Hudson - David Schneider - Matti Picus - Brian Kearns - Philip Jenvey - Holger Krekel - Christian Tismer - Hakan Ardo - Benjamin Peterson - Manuel Jacob - Anders Chrigstrom - Eric van Riet Paap - Wim Lavrijsen - Ronan Lamy - Richard Emslie - Alexander Schremmer - Dan Villiom Podlaski Christiansen - Lukas Diekmann - Sven Hager - Anders Lehmann - Aurelien Campeas - Niklaus Haldimann - Camillo Bruni - Laura Creighton - Toon Verwaest - Remi Meier - Leonardo Santagada - Seo Sanghyeon - Romain Guillebert - Justin Peel - Ronny Pfannschmidt - David Edelsohn - Anders Hammarquist - Jakub Gustak - Guido Wesdorp - Lawrence Oluyede - Bartosz Skowron - Daniel Roberts - Niko Matsakis - Adrien Di Mascio - Alexander Hesse - Ludovic Aubry - Jacob Hallen - Jason Creighton - Alex Martelli - Michal Bendowski - Jan de Mooij - stian - Michael Foord - Stephan Diehl - Stefan Schwarzer - Valentino Volonghi - Tomek Meka - Patrick Maupin - Bob Ippolito - Bruno Gola - Jean-Paul Calderone - Timo Paulssen - Squeaky - Alexandre Fayolle - Simon Burton - Marius Gedminas - John Witulski - Konstantin Lopuhin - Greg Price - Dario Bertini - Mark Pearse - Simon Cross - Andreas Stührk - Jean-Philippe St. Pierre - Guido van Rossum - Pavel Vinogradov - Paweł Piotr Przeradowski - Paul deGrandis - Ilya Osadchiy - Tobias Oberstein - Adrian Kuhn - Boris Feigin - Stefano Rivera - tav - Taavi Burns - Georg Brandl - Bert Freudenberg - Stian Andreassen - Laurence Tratt - Wanja Saatkamp - Ivan Sichmann Freitas - Gerald Klix - Mike Blume - Oscar Nierstrasz - Stefan H. Muller - Jeremy Thurgood - Gregor Wegberg - Rami Chowdhury - Tobias Pape - Edd Barrett - David Malcolm - Eugene Oden - Henry Mason - Preston Timmons - Jeff Terrace - David Ripton - Dusty Phillips - Lukas Renggli - Guenter Jantzen - Ned Batchelder - Amit Regmi - Ben Young - Nicolas Chauvat - Andrew Durdin - Andrew Chambers - Michael Schneider - Nicholas Riley - Jason Chu - Igor Trindade Oliveira - Rocco Moretti - Gintautas Miliauskas - Michael Twomey - Lucian Branescu Mihaila - Tim Felgentreff - Tyler Wade - Gabriel Lavoie - Olivier Dormond - Jared Grubb - Karl Bartel - Brian Dorsey - Victor Stinner - Andrews Medina - Stuart Williams - Jasper Schulz - Christian Hudon - Toby Watson - Antoine Pitrou - Aaron Iles - Michael Cheng - Justas Sadzevicius - Mikael Schönenberg - Gasper Zejn - Neil Shepperd - Elmo Mäntynen - Jonathan David Riehl - Stanislaw Halik - Anders Qvist - Chirag Jadwani - Beatrice During - Alex Perry - Vincent Legoll - Alan McIntyre - Alexander Sedov - Corbin Simpson - Christopher Pope - wenzhuman - Christian Tismer - Marc Abramowitz - Dan Stromberg - Stefano Parmesan - Alexis Daboville - Jens-Uwe Mager - Carl Meyer - Karl Ramm - Pieter Zieschang - Gabriel - Lukas Vacek - Andrew Dalke - Sylvain Thenault - Nathan Taylor - Vladimir Kryachko - Jacek Generowicz - Alejandro J. Cura - Jacob Oscarson - Travis Francis Athougies - Ryan Gonzalez - Kristjan Valur Jonsson - Sebastian Pawluś - Neil Blakey-Milner - anatoly techtonik - Lutz Paelike - Lucio Torre - Lars Wassermann - Henrik Vendelbo - Dan Buch - Miguel de Val Borro - Artur Lisiecki - Sergey Kishchenko - Ignas Mikalajunas - Christoph Gerum - Martin Blais - Lene Wagner - Tomo Cocoa - roberto@goyle - Yury V. Zaytsev - Anna Katrina Dominguez - William Leslie - Bobby Impollonia - t...@eistee.fritz.box - Andrew Thompson - Ben Darnell - Roberto De Ioris - Juan Francisco Cantero Hurtado - Godefroid Chappelle - Joshua Gilbert - Dan Colish - Christopher Armstrong - Michael Hudson-Doyle - Anders Sigfridsson - Yasir Suhail - rafalgalczyn...@gmail.com - Floris Bruynooghe - Laurens Van Houtven - Akira Li - Gustavo Niemeyer - Stephan Busemann - Rafał Gałczyński - Yusei Tahara - Christian Muirhead - James Lan - shoma hosaka - Daniel Neuh?user - Matthew Miller - Buck Golemon - Konrad Delong - Dinu Gherman - Chris Lambacher - coolbutusel...@gmail.com - Rodrigo Araújo - w31rd0 - Jim Baker - James Robert - Armin Ronacher - Brett Cannon - yrttyr - aliceinwire - OlivierBlanvillain - Zooko Wilcox-O Hearn - Tomer Chachamu - Christopher Groskopf - Asmo Soinio - Stefan Marr - jiaaro - opassembler.py - Antony Lee - Jim Hunziker - Markus Unterwaditzer - Even Wiik Thomassen - jbs - soareschen - Kurt Griffiths - Mike Bayer - Flavio Percoco - Kristoffer Kleine - yasirs - Michael Chermside - Anna Ravencroft - Julien Phalip - Dan Loewenherz + Armin Rigo + Maciej Fijalkowski + Carl Friedrich Bolz + Antonio Cuni + Amaury Forgeot d'Arc + Samuele Pedroni + Alex Gaynor + Michael Hudson + David Schneider + Matti Picus + Brian Kearns + Philip Jenvey + Holger Krekel + Christian Tismer + Hakan Ardo + Benjamin Peterson + Manuel Jacob + Anders Chrigstrom + Eric van Riet Paap + Ronan Lamy + Wim Lavrijsen + Richard Emslie + Alexander Schremmer + Dan Villiom Podlaski Christiansen + Lukas Diekmann + Sven Hager + Anders Lehmann + Aurelien Campeas + Niklaus Haldimann + Remi Meier + Camillo Bruni + Laura Creighton + Toon Verwaest + Leonardo Santagada + Seo Sanghyeon + Romain Guillebert + Justin Peel + Ronny Pfannschmidt + David Edelsohn + Anders Hammarquist + Jakub Gustak + Guido Wesdorp + Lawrence Oluyede + Bartosz Skowron + Gregor Wegberg + Daniel Roberts + Niko Matsakis + Adrien Di Mascio + Alexander Hesse + Ludovic Aubry + Jacob Hallen + Jason Creighton + Alex Martelli + Michal Bendowski + Jan de Mooij + stian + Michael Foord + Stephan Diehl + Tyler Wade + Stefan Schwarzer + Valentino Volonghi + Tomek Meka + Patrick Maupin + Bob Ippolito + Bruno Gola + Jean-Paul Calderone + Timo Paulssen + Squeaky + Alexandre Fayolle + Simon Burton + Marius Gedminas + Martin Matusiak + Konstantin Lopuhin + John Witulski + Wenzhu Man + Greg Price + Dario Bertini + Mark Pearse + Simon Cross + Ivan Sichmann Freitas + Andreas Stührk + Jean-Philippe St. Pierre + Guido van Rossum + Pavel Vinogradov + Stefano Rivera + Paweł Piotr Przeradowski + Paul deGrandis + Ilya Osadchiy + Tobias Oberstein + Adrian Kuhn + Boris Feigin + tav + Taavi Burns + Georg Brandl + Laurence Tratt + Bert Freudenberg + Stian Andreassen + Wanja Saatkamp + Gerald Klix + Mike Blume + Oscar Nierstrasz + Stefan H. Muller + Edd Barrett + Jeremy Thurgood + Rami Chowdhury + Tobias Pape + David Malcolm + Eugene Oden + Henry Mason + Vasily Kuznetsov + Preston Timmons + Jeff Terrace + David Ripton + Dusty Phillips + Lukas Renggli + Guenter Jantzen + Ned Batchelder + Amit Regmi + Ben Young + Nicolas Chauvat + Andrew Durdin + Andrew Chambers + Michael Schneider + Nicholas Riley + Jason Chu + Igor Trindade Oliveira + Tim Felgentreff + Rocco Moretti + Gintautas Miliauskas + Michael Twomey + Lucian Branescu Mihaila + Gabriel Lavoie + Olivier Dormond + Jared Grubb + Karl Bartel + Brian Dorsey + Victor Stinner + Andrews Medina + Stuart Williams + Jasper Schulz + Christian Hudon + Toby Watson + Antoine Pitrou + Aaron Iles + Michael Cheng + Justas Sadzevicius + Gasper Zejn + anatoly techtonik + Neil Shepperd + Mikael Schönenberg + Elmo M?ntynen + Jonathan David Riehl + Stanislaw Halik + Anders Qvist + Corbin Simpson + Chirag Jadwani + Beatrice During + Alex Perry + Vincent Legoll + Alan McIntyre + Alexander Sedov + Christopher Pope + Christian Tismer + Marc Abramowitz + Dan Stromberg + Stefano Parmesan + Alexis Daboville + Jens-Uwe Mager + Carl Meyer + Karl Ramm + Pieter Zieschang + Sebastian Pawluś + Gabriel + Lukas Vacek + Andrew Dalke + Sylvain Thenault + Nathan Taylor + Vladimir Kryachko + Arjun Naik + Attila Gobi + Jacek Generowicz + Alejandro J. Cura + Jacob Oscarson + Travis Francis Athougies + Ryan Gonzalez + Ian Foote + Kristjan Valur Jonsson + Neil Blakey-Milner + Lutz Paelike + Lucio Torre + Lars Wassermann + Valentina Mukhamedzhanova + Henrik Vendelbo + Dan Buch + Miguel de Val Borro + Artur Lisiecki + Sergey Kishchenko + Yichao Yu + Ignas Mikalajunas + Christoph Gerum + Martin Blais + Lene Wagner + Tomo Cocoa + roberto@goyle + Yury V. Zaytsev + Anna Katrina Dominguez + William Leslie + Bobby Impollonia + t...@eistee.fritz.box + Andrew Thompson + Yusei Tahara + Ben Darnell + Roberto De Ioris + Juan Francisco Cantero Hurtado + Godefroid Chappelle + Joshua Gilbert + Dan Colish + Christopher Armstrong + Michael Hudson-Doyle + Anders Sigfridsson + Yasir Suhail + Jason Michalski + rafalgalczyn...@gmail.com + Floris Bruynooghe + Laurens Van Houtven + Akira Li + Gustavo Niemeyer + Stephan Busemann + Rafał Gałczyński + Christian Muirhead + James Lan + shoma hosaka + Daniel Neuh?user + Matthew Miller + Buck Golemon + Konrad Delong + Dinu Gherman + Chris Lambacher + coolbutusel...@gmail.com + Rodrigo Araújo + Jim Baker + James Robert + Armin Ronacher + Brett Cannon + yrttyr + aliceinwire + OlivierBlanvillain + Zooko Wilcox-O Hearn + Tomer Chachamu + Christopher Groskopf + Asmo Soinio + Stefan Marr + jiaaro + Mads Kiilerich + opassembler.py + Antony Lee + Jim Hunziker + Markus Unterwaditzer + Even Wiik Thomassen + jbs + soareschen + Kurt Griffiths + Mike Bayer + Matthew Miller + Flavio Percoco + Kristoffer Kleine + yasirs + Michael Chermside + Anna Ravencroft + Dan Crosta + Julien Phalip + Dan Loewenherz - Heinrich-Heine University, Germany - Open End AB (formerly AB Strakt), Sweden - merlinux GmbH, Germany - tismerysoft GmbH, Germany - Logilab Paris, France - DFKI GmbH, Germany - Impara, Germany - Change Maker, Sweden - University of California Berkeley, USA - Google Inc. - King's College London + Heinrich-Heine University, Germany + Open End AB (formerly AB Strakt), Sweden + merlinux GmbH, Germany + tismerysoft GmbH, Germany + Logilab Paris, France + DFKI GmbH, Germany + Impara, Germany + Change Maker, Sweden + University of California Berkeley, USA + Google Inc. + King's College London The PyPy Logo as used by http://speed.pypy.org and others was created by Samuel Reis and is distributed on terms of Creative Commons Share Alike diff --git a/_pytest/README-BEFORE-UPDATING b/_pytest/README-BEFORE-UPDATING new file mode 100644 --- /dev/null +++ b/_pytest/README-BEFORE-UPDATING @@ -0,0 +1,17 @@ +This is PyPy's code of the pytest lib. We don't expect to upgrade it +very often, but once we do: + + WARNING! + + WE HAVE MADE A FEW TWEAKS HERE! + +Please be sure that you don't just copy the newer version from +upstream without checking the few changes that we did. This +can be done like this: + + cd <this directory> + hg log . -v | less + +then search for all " _pytest/" in that list to know which are the +relevant checkins. (Look for the checkins that only edit one +or two files in this directory.) diff --git a/_pytest/resultlog.py b/_pytest/resultlog.py --- a/_pytest/resultlog.py +++ b/_pytest/resultlog.py @@ -53,16 +53,24 @@ self.config = config self.logfile = logfile # preferably line buffered - def write_log_entry(self, testpath, lettercode, longrepr): - py.builtin.print_("%s %s" % (lettercode, testpath), file=self.logfile) + def write_log_entry(self, testpath, lettercode, longrepr, sections=None): + _safeprint("%s %s" % (lettercode, testpath), file=self.logfile) for line in longrepr.splitlines(): - py.builtin.print_(" %s" % line, file=self.logfile) + _safeprint(" %s" % line, file=self.logfile) + if sections is not None and ( + lettercode in ('E', 'F')): # to limit the size of logs + for title, content in sections: + _safeprint(" ---------- %s ----------" % (title,), + file=self.logfile) + for line in content.splitlines(): + _safeprint(" %s" % line, file=self.logfile) def log_outcome(self, report, lettercode, longrepr): testpath = getattr(report, 'nodeid', None) if testpath is None: testpath = report.fspath - self.write_log_entry(testpath, lettercode, longrepr) + self.write_log_entry(testpath, lettercode, longrepr, + getattr(report, 'sections', None)) def pytest_runtest_logreport(self, report): if report.when != "call" and report.passed: @@ -98,3 +106,8 @@ if path is None: path = "cwd:%s" % py.path.local() self.write_log_entry(path, '!', str(excrepr)) + +def _safeprint(s, file): + if isinstance(s, unicode): + s = s.encode('utf-8') + py.builtin.print_(s, file=file) diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -7,30 +7,30 @@ _INSTALL_SCHEMES = { 'posix_prefix': { - 'stdlib': '{base}/lib/python{py_version_short}', - 'platstdlib': '{platbase}/lib/python{py_version_short}', - 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', - 'include': '{base}/include/python{py_version_short}', - 'platinclude': '{platbase}/include/python{py_version_short}', + 'stdlib': '{base}/lib/{implementation_lower}{py_version_short}', + 'platstdlib': '{platbase}/lib/{implementation_lower}{py_version_short}', + 'purelib': '{base}/lib/{implementation_lower}{py_version_short}/site-packages', + 'platlib': '{platbase}/lib/{implementation_lower}{py_version_short}/site-packages', + 'include': '{base}/include/{implementation_lower}{py_version_short}', + 'platinclude': '{platbase}/include/{implementation_lower}{py_version_short}', 'scripts': '{base}/bin', 'data': '{base}', }, 'posix_home': { - 'stdlib': '{base}/lib/python', - 'platstdlib': '{base}/lib/python', - 'purelib': '{base}/lib/python', - 'platlib': '{base}/lib/python', - 'include': '{base}/include/python', - 'platinclude': '{base}/include/python', + 'stdlib': '{base}/lib/{implementation_lower}', + 'platstdlib': '{base}/lib/{implementation_lower}', + 'purelib': '{base}/lib/{implementation_lower}', + 'platlib': '{base}/lib/{implementation_lower}', + 'include': '{base}/include/{implementation_lower}', + 'platinclude': '{base}/include/{implementation_lower}', 'scripts': '{base}/bin', 'data' : '{base}', }, 'pypy': { - 'stdlib': '{base}/lib-python/{py_version_short}', - 'platstdlib': '{base}/lib-python/{py_version_short}', - 'purelib': '{base}/lib-python/{py_version_short}', - 'platlib': '{base}/lib-python/{py_version_short}', + 'stdlib': '{base}/lib-{implementation_lower}/{py_version_short}', + 'platstdlib': '{base}/lib-{implementation_lower}/{py_version_short}', + 'purelib': '{base}/lib-{implementation_lower}/{py_version_short}', + 'platlib': '{base}/lib-{implementation_lower}/{py_version_short}', 'include': '{base}/include', 'platinclude': '{base}/include', 'scripts': '{base}/bin', @@ -57,37 +57,37 @@ 'data' : '{base}', }, 'os2_home': { - 'stdlib': '{userbase}/lib/python{py_version_short}', - 'platstdlib': '{userbase}/lib/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', + 'stdlib': '{userbase}/lib/{implementation_lower}{py_version_short}', + 'platstdlib': '{userbase}/lib/{implementation_lower}{py_version_short}', + 'purelib': '{userbase}/lib/{implementation_lower}{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/{implementation_lower}{py_version_short}/site-packages', + 'include': '{userbase}/include/{implementation_lower}{py_version_short}', 'scripts': '{userbase}/bin', 'data' : '{userbase}', }, 'nt_user': { - 'stdlib': '{userbase}/Python{py_version_nodot}', - 'platstdlib': '{userbase}/Python{py_version_nodot}', - 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', - 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', - 'include': '{userbase}/Python{py_version_nodot}/Include', + 'stdlib': '{userbase}/{implementation}{py_version_nodot}', + 'platstdlib': '{userbase}/{implementation}{py_version_nodot}', + 'purelib': '{userbase}/{implementation}{py_version_nodot}/site-packages', + 'platlib': '{userbase}/{implementation}{py_version_nodot}/site-packages', + 'include': '{userbase}/{implementation}{py_version_nodot}/Include', 'scripts': '{userbase}/Scripts', 'data' : '{userbase}', }, 'posix_user': { - 'stdlib': '{userbase}/lib/python{py_version_short}', - 'platstdlib': '{userbase}/lib/python{py_version_short}', - 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', - 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', - 'include': '{userbase}/include/python{py_version_short}', + 'stdlib': '{userbase}/lib/{implementation_lower}{py_version_short}', + 'platstdlib': '{userbase}/lib/{implementation_lower}{py_version_short}', + 'purelib': '{userbase}/lib/{implementation_lower}{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/{implementation_lower}{py_version_short}/site-packages', + 'include': '{userbase}/include/{implementation_lower}{py_version_short}', 'scripts': '{userbase}/bin', 'data' : '{userbase}', }, 'osx_framework_user': { - 'stdlib': '{userbase}/lib/python', - 'platstdlib': '{userbase}/lib/python', - 'purelib': '{userbase}/lib/python/site-packages', - 'platlib': '{userbase}/lib/python/site-packages', + 'stdlib': '{userbase}/lib/{implementation_lower}', + 'platstdlib': '{userbase}/lib/{implementation_lower}', + 'purelib': '{userbase}/lib/{implementation_lower}/site-packages', + 'platlib': '{userbase}/lib/{implementation_lower}/site-packages', 'include': '{userbase}/include', 'scripts': '{userbase}/bin', 'data' : '{userbase}', @@ -104,6 +104,11 @@ _CONFIG_VARS = None _USER_BASE = None +def _get_implementation(): + if '__pypy__' in sys.builtin_module_names: + return 'PyPy' + return 'Python' + def _safe_realpath(path): try: return realpath(path) @@ -475,6 +480,8 @@ _CONFIG_VARS['base'] = _PREFIX _CONFIG_VARS['platbase'] = _EXEC_PREFIX _CONFIG_VARS['projectbase'] = _PROJECT_BASE + _CONFIG_VARS['implementation'] = _get_implementation() + _CONFIG_VARS['implementation_lower'] = _get_implementation().lower() if os.name in ('nt', 'os2'): _init_non_posix(_CONFIG_VARS) @@ -644,6 +651,8 @@ _print_dict('Paths', get_paths()) print _print_dict('Variables', get_config_vars()) + print + _print_dict('User', get_paths('%s_user' % os.name)) if __name__ == '__main__': diff --git a/lib-python/2.7/test/pickletester.py b/lib-python/2.7/test/pickletester.py --- a/lib-python/2.7/test/pickletester.py +++ b/lib-python/2.7/test/pickletester.py @@ -6,14 +6,16 @@ import pickletools import copy_reg -from test.test_support import TestFailed, verbose, have_unicode, TESTFN, impl_detail +from test.test_support import TestFailed, verbose, have_unicode, TESTFN try: - from test.test_support import _2G, _1M, precisionbigmemtest + from test.test_support import _2G, _1M, precisionbigmemtest, impl_detail except ImportError: # this import might fail when run on older Python versions by test_xpickle _2G = _1M = 0 def precisionbigmemtest(*args, **kwargs): return lambda self: None + def impl_detail(*args, **kwargs): + return lambda self: None # Tests that try a number of pickle protocols should have a # for proto in protocols: diff --git a/lib-python/2.7/test/test_mmap.py b/lib-python/2.7/test/test_mmap.py --- a/lib-python/2.7/test/test_mmap.py +++ b/lib-python/2.7/test/test_mmap.py @@ -179,25 +179,27 @@ import sys f = open(TESTFN, "r+b") try: - m = mmap.mmap(f.fileno(), mapsize+1) - except ValueError: - # we do not expect a ValueError on Windows - # CAUTION: This also changes the size of the file on disk, and - # later tests assume that the length hasn't changed. We need to - # repair that. + try: + m = mmap.mmap(f.fileno(), mapsize+1) + except ValueError: + # we do not expect a ValueError on Windows + # CAUTION: This also changes the size of the file on disk, and + # later tests assume that the length hasn't changed. We need to + # repair that. + if sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should work on Windows.") + else: + # we expect a ValueError on Unix, but not on Windows + if not sys.platform.startswith('win'): + self.fail("Opening mmap with size+1 should raise ValueError.") + m.close() + finally: + f.close() if sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should work on Windows.") - else: - # we expect a ValueError on Unix, but not on Windows - if not sys.platform.startswith('win'): - self.fail("Opening mmap with size+1 should raise ValueError.") - m.close() - f.close() - if sys.platform.startswith('win'): - # Repair damage from the resizing test. - f = open(TESTFN, 'r+b') - f.truncate(mapsize) - f.close() + # Repair damage from the resizing test. + f = open(TESTFN, 'r+b') + f.truncate(mapsize) + f.close() # Opening mmap with access=ACCESS_WRITE f = open(TESTFN, "r+b") diff --git a/py/README-BEFORE-UPDATING b/py/README-BEFORE-UPDATING new file mode 100644 --- /dev/null +++ b/py/README-BEFORE-UPDATING @@ -0,0 +1,17 @@ +This is PyPy's code of the py lib. We don't expect to upgrade it +very often, but once we do: + + WARNING! + + WE HAVE MADE A FEW TWEAKS HERE! + +Please be sure that you don't just copy the newer version from +upstream without checking the few changes that we did. This +can be done like this: + + cd <this directory> + hg log . -v | less + +then search for all " py/" in that list to know which are the +relevant checkins. (Look for the checkins that only edit one +or two files in this directory.) diff --git a/py/_code/code.py b/py/_code/code.py --- a/py/_code/code.py +++ b/py/_code/code.py @@ -588,7 +588,7 @@ class TerminalRepr: def __str__(self): s = self.__unicode__() - if sys.version_info[0] < 3: + if sys.version_info[0] < 3 and isinstance(s, unicode): s = s.encode('utf-8') return s diff --git a/py/_path/local.py b/py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -750,7 +750,8 @@ mkdtemp = classmethod(mkdtemp) def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3, - lock_timeout = 172800): # two days + lock_timeout = 172800, # two days + min_timeout = 300): # five minutes """ return unique directory with a number greater than the current maximum one. The number is assumed to start directly after prefix. if keep is true directories with a number less than (maxnum-keep) @@ -818,6 +819,20 @@ for path in rootdir.listdir(): num = parse_num(path) if num is not None and num <= (maxnum - keep): + if min_timeout: + # NB: doing this is needed to prevent (or reduce + # a lot the chance of) the following situation: + # 'keep+1' processes call make_numbered_dir() at + # the same time, they create dirs, but then the + # last process notices the first dir doesn't have + # (yet) a .lock in it and kills it. + try: + t1 = path.lstat().mtime + t2 = lockfile.lstat().mtime + if abs(t2-t1) < min_timeout: + continue # skip directories too recent + except py.error.Error: + continue # failure to get a time, better skip lf = path.join('.lock') try: t1 = lf.lstat().mtime diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -52,11 +52,10 @@ if sys.platform == "win32": working_modules.add("_winreg") # unix only modules - working_modules.remove("crypt") - working_modules.remove("fcntl") - working_modules.remove("pwd") - working_modules.remove("termios") - working_modules.remove("_minimal_curses") + for name in ["crypt", "fcntl", "pwd", "termios", "_minimal_curses"]: + working_modules.remove(name) + if name in translation_modules: + translation_modules.remove(name) if "cppyy" in working_modules: working_modules.remove("cppyy") # not tested on win32 diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -65,9 +65,9 @@ # built documents. # # The short X.Y version. -version = '2.3' +version = '2.4' # The full version, including alpha/beta/rc tags. -release = '2.3.0' +release = '2.4.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -80,7 +80,7 @@ Martin Matusiak Konstantin Lopuhin John Witulski - wenzhu man + Wenzhu Man Greg Price Dario Bertini Mark Pearse diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-2.4.0.rst release-2.3.1.rst release-2.3.0.rst release-2.2.1.rst diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -40,7 +40,7 @@ * `FAQ`_: some frequently asked questions. -* `Release 2.3.1`_: the latest official release +* `Release 2.4.0`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -110,7 +110,7 @@ .. _`Getting Started`: getting-started.html .. _`Papers`: extradoc.html .. _`Videos`: video-index.html -.. _`Release 2.3.1`: http://pypy.org/download.html +.. _`Release 2.4.0`: http://pypy.org/download.html .. _`speed.pypy.org`: http://speed.pypy.org .. _`RPython toolchain`: translation.html .. _`potential project ideas`: project-ideas.html diff --git a/pypy/doc/release-2.4.rst b/pypy/doc/release-2.4.0.rst rename from pypy/doc/release-2.4.rst rename to pypy/doc/release-2.4.0.rst --- a/pypy/doc/release-2.4.rst +++ b/pypy/doc/release-2.4.0.rst @@ -1,67 +1,75 @@ ================================================= -PyPy 2.4 - ???????? +PyPy 2.4 - Snow White ================================================= -We're pleased to announce PyPy 2.4, a significant milestone on it's own right -and the proud parent of our recent PyPy3 and STM releases. +We're pleased to announce PyPy 2.4, which contains significant performance +enhancements and bug fixes. -This release contains several improvements and bugfixes. +You can already download the PyPy 2.4-beta1 pre-release here: -You can download the PyPy 2.4 release here: + https://bitbucket.org/pypy/pypy/downloads + +It should also soon be available on: http://pypy.org/download.html We would like to thank our donors for the continued support of the PyPy project, and for those who donate to our three sub-projects. -We've shown quite a bit of progress -but we're slowly running out of funds. +We've shown quite a bit of progress, but we're slowly running out of funds. Please consider donating more, or even better convince your employer to donate, -so we can finish those projects! The three sub-projects are: +so we can finish those projects! We would like to also point out that in +September, `the Python Software Foundation`_ will `match funds`_ for +any donations up to $10k! The three sub-projects are: -* `Py3k`_ (supporting Python 3.x): We have released a Python 3.2.5 compatable version - we call PyPy3 2.3.1, and are working toward a Python 3.3 compatable version +* `Py3k`_ (supporting Python 3.x): We have released a Python 3.2.5 compatible version + we call PyPy3 2.3.1, and are working toward a Python 3.3 compatible version -* `STM`_ (software transactional memory): We have release a first working version, and -continue to try out new promising paths of acheiving a fast multithreaded python +* `STM`_ (software transactional memory): We have released a first working version, + and continue to try out new promising paths of achieving a fast multithreaded Python -* `NumPy`_ which requires installation of our fork of upstream numpy, available `on bitbucket`_ +* `NumPy`_ which requires installation of our fork of upstream numpy, + available `on bitbucket`_ .. _`Py3k`: http://pypy.org/py3donate.html .. _`STM`: http://pypy.org/tmdonate2.html .. _`NumPy`: http://pypy.org/numpydonate.html .. _`on bitbucket`: https://www.bitbucket.org/pypy/numpy +.. _`the Python Software Foundation`: https://www.python.org/psf/ +.. _`match funds`: http://morepypy.blogspot.com/2014/09/python-software-foundation-matching.html What is PyPy? ============= PyPy is a very compliant Python interpreter, almost a drop-in replacement for -CPython 2.7. It's fast (`pypy 2.3 and cpython 2.7.x`_ performance comparison; -note that cpython's speed has not changed since 2.7.2) +CPython 2.7. It's fast (`pypy 2.4 and cpython 2.7.x`_ performance comparison) due to its integrated tracing JIT compiler. -This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows, -and OpenBSD, -as well as newer ARM hardware (ARMv6 or ARMv7, with VFPv3) running Linux. +This release supports **x86** machines on most common operating systems +(Linux 32/64, Mac OS X 64, Windows, and OpenBSD), +as well as newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux. While we support 32 bit python on Windows, work on the native Windows 64 bit python is still stalling, we would welcome a volunteer to `handle that`_. -.. _`pypy 2.3 and cpython 2.7.x`: http://speed.pypy.org +.. _`pypy 2.4 and cpython 2.7.x`: http://speed.pypy.org .. _`handle that`: http://doc.pypy.org/en/latest/windows.html#what-is-missing-for-a-full-64-bit-translation Highlights ========== -Benchmarks improved after internal improvements in string and bytearray handling, -and a major rewrite of the GIL handling. Many of these improvements are offshoots -of the STM work. +Benchmarks improved after internal enhancements in string and +bytearray handling, and a major rewrite of the GIL handling. This means +that external calls are now a lot faster, especially the CFFI ones. It also +means better performance in a lot of corner cases with handling strings or +bytearrays. -We merged in Python's 2.7.8 stdlib in a record time of one week, proving the -maturity of our underlying RPython code base and PyPy interpreter. +PyPy now uses Python 2.7.8 standard library. -We welcomed more than 12 new contributors, and conducted two Google Summer of Code -projects XXX details? +We welcomed more than 12 new contributors, and conducted two Google +Summer of Code projects, as well as other student projects not +directly related to Summer of Code. + Issues reported with our previous release were fixed after reports from users on our new issue tracker at https://bitbucket.org/pypy/pypy/issues or on IRC at @@ -71,33 +79,39 @@ * Reduced internal copying of bytearray operations * Tweak the internal structure of StringBuilder to speed up large string -handling, which becomes advantageous on large programs at the cost of slightly -slower small *benchmark* type programs. + handling, which becomes advantageous on large programs at the cost of slightly + slower small *benchmark* type programs. -* Boost performance of thread-local variables in both unjitted and jitted code +* Boost performance of thread-local variables in both unjitted and jitted code, + this mostly affects errno handling on linux, which makes external calls + faster. * Move to a mixed polling and mutex GIL model that make mutli-threaded jitted code run *much* faster -* Optimize errno handling in linux +* Optimize errno handling in linux (x86 and x86-64 only) * Remove ctypes pythonapi and ctypes.PyDLL, which never worked on PyPy * Fix performance regression on ufunc(<scalar>, <scalar>) in numpy -* Classes in the ast module are now distinct from structures used by the compiler, - which simplifies and speeds up translation of our source code to the PyPy binary - interpreter +* Classes in the ast module are now distinct from structures used by + the compiler, which simplifies and speeds up translation of our + source code to the PyPy binary interpreter * Upgrade stdlib from 2.7.5 to 2.7.8 -* - +* Win32 now links statically to zlib, expat, bzip, and openssl-1.0.1i. + No more missing DLLs + * Many issues were resolved_ since the 2.3.1 release on June 8 .. _`whats-new`: http://doc.pypy.org/en/latest/whatsnew-2.3.1.html .. _resolved: https://bitbucket.org/pypy/pypy/issues?status=resolved +We have further improvements on the way: rpython file handling and +usable numpy linalg compatabiity should be merged soon. + Please try it out and let us know what you think. We especially welcome success stories, we know you are using PyPy, please tell us about it! diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py --- a/pypy/doc/tool/makecontributor.py +++ b/pypy/doc/tool/makecontributor.py @@ -68,7 +68,7 @@ 'Manuel Jacob': ['mjacob'], 'Rami Chowdhury': ['necaris'], 'Stanislaw Halik':['w31rd0'], - 'wenzhu man':['wenzhuman'], + 'Wenzhu Man':['wenzhu man', 'wenzhuman'], } alias_map = {} diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.4.0.rst copy from pypy/doc/whatsnew-head.rst copy to pypy/doc/whatsnew-2.4.0.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-2.4.0.rst @@ -60,3 +60,7 @@ .. branch: stdlib-2.7.8 Upgrades from 2.7.6 to 2.7.8 + +.. branch: cpybug-seq-radd-rmul +Fix issue #1861 - cpython compatability madness + 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 @@ -1,62 +1,8 @@ + ======================= -What's new in PyPy 2.4+ +What's new in PyPy 2.5+ ======================= -.. this is a revision shortly after release-2.3.x -.. startrev: ca9b7cf02cf4 +.. this is a revision shortly after release-2.4.x +.. startrev: 7026746cbb1b -.. branch: fix-bytearray-complexity -Bytearray operations no longer copy the bytearray unnecessarily - -Added support for ``__getitem__``, ``__setitem__``, ``__getslice__``, -``__setslice__``, and ``__len__`` to RPython - -.. branch: stringbuilder2-perf -Give the StringBuilder a more flexible internal structure, with a -chained list of strings instead of just one string. This make it -more efficient when building large strings, e.g. with cStringIO(). - -Also, use systematically jit.conditional_call() instead of regular -branches. This lets the JIT make more linear code, at the cost of -forcing a bit more data (to be passed as arguments to -conditional_calls). I would expect the net result to be a slight -slow-down on some simple benchmarks and a speed-up on bigger -programs. - -.. branch: ec-threadlocal -Change the executioncontext's lookup to be done by reading a thread- -local variable (which is implemented in C using '__thread' if -possible, and pthread_getspecific() otherwise). On Linux x86 and -x86-64, the JIT backend has a special optimization that lets it emit -directly a single MOV from a %gs- or %fs-based address. It seems -actually to give a good boost in performance. - -.. branch: fast-gil -A faster way to handle the GIL, particularly in JIT code. The GIL is -now a composite of two concepts: a global number (it's just set from -1 to 0 and back around CALL_RELEASE_GIL), and a real mutex. If there -are threads waiting to acquire the GIL, one of them is actively -checking the global number every 0.1 ms to 1 ms. Overall, JIT loops -full of external function calls now run a bit faster (if no thread was -started yet), or a *lot* faster (if threads were started already). - -.. branch: jit-get-errno -Optimize the errno handling in the JIT, notably around external -function calls. Linux-only. - -.. branch: disable_pythonapi -Remove non-functioning ctypes.pyhonapi and ctypes.PyDLL, document this -incompatibility with cpython. Recast sys.dllhandle to an int. - -.. branch: scalar-operations -Fix performance regression on ufunc(<scalar>, <scalar>) in numpy. - -.. branch: pytest-25 -Update our copies of py.test and pylib to versions 2.5.2 and 1.4.20, -respectively. - -.. branch: split-ast-classes -Classes in the ast module are now distinct from structures used by the compiler. - -.. branch: stdlib-2.7.8 -Upgrades from 2.7.6 to 2.7.8 diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -7,7 +7,6 @@ class MixedModule(Module): applevel_name = None - expose__file__attribute = True # The following attribute is None as long as the module has not been # imported yet, and when it has been, it is mod.__dict__.items() just @@ -144,8 +143,6 @@ for name, spec in cls.appleveldefs.items(): loaders[name] = getappfileloader(pkgroot, appname, spec) assert '__file__' not in loaders - if cls.expose__file__attribute: - loaders['__file__'] = cls.get__file__ if '__doc__' not in loaders: loaders['__doc__'] = cls.get__doc__ @@ -159,28 +156,6 @@ w_obj = loader(space) space.setattr(space.wrap(self), space.wrap(name), w_obj) - def get__file__(cls, space): - """ NOT_RPYTHON. - return the __file__ attribute of a MixedModule - which is the root-directory for the various - applevel and interplevel snippets that make - up the module. - """ - try: - fname = cls._fname - except AttributeError: - pkgroot = cls.__module__ - mod = __import__(pkgroot, None, None, ['__doc__']) - fname = mod.__file__ - assert os.path.basename(fname).startswith('__init__.py') - # make it clear that it's not really the interp-level module - # at this path that we are seeing, but an app-level version of it - fname = os.path.dirname(fname) - cls._fname = fname - return space.wrap(fname) - - get__file__ = classmethod(get__file__) - def get__doc__(cls, space): return space.wrap(cls.__doc__) get__doc__ = classmethod(get__doc__) diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py --- a/pypy/interpreter/module.py +++ b/pypy/interpreter/module.py @@ -29,6 +29,17 @@ space.w_None) self.startup_called = False + def _cleanup_(self): + """Called by the annotator on prebuilt Module instances. + We don't have many such modules, but for the ones that + show up, remove their __file__ rather than translate it + statically inside the executable.""" + try: + space = self.space + space.delitem(self.w_dict, space.wrap('__file__')) + except OperationError: + pass + def install(self): """NOT_RPYTHON: installs this module into space.builtin_modules""" w_mod = self.space.wrap(self) diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py --- a/pypy/interpreter/test/test_app_main.py +++ b/pypy/interpreter/test/test_app_main.py @@ -985,6 +985,11 @@ assert sys.path == old_sys_path + [self.goal_dir] app_main.setup_bootstrap_path(self.fake_exe) + assert sys.executable == '' # not executable! + assert sys.path == old_sys_path + [self.goal_dir] + + os.chmod(self.fake_exe, 0755) + app_main.setup_bootstrap_path(self.fake_exe) assert sys.executable == self.fake_exe assert self.goal_dir not in sys.path diff --git a/pypy/interpreter/test/test_extmodules.py b/pypy/interpreter/test/test_extmodules.py --- a/pypy/interpreter/test/test_extmodules.py +++ b/pypy/interpreter/test/test_extmodules.py @@ -64,5 +64,5 @@ @pytest.mark.skipif("config.option.runappdirect") def test_import(self): import extmod - assert extmod.__file__.endswith('extmod') + assert not hasattr(extmod, '__file__') assert type(extmod.time()) is float diff --git a/pypy/interpreter/test/test_module.py b/pypy/interpreter/test/test_module.py --- a/pypy/interpreter/test/test_module.py +++ b/pypy/interpreter/test/test_module.py @@ -1,4 +1,5 @@ - +import py +from pypy.interpreter.error import OperationError from pypy.interpreter.module import Module class TestModule: @@ -17,6 +18,18 @@ space.raises_w(space.w_AttributeError, space.delattr, w_m, w('x')) + def test___file__(self, space): + w = space.wrap + m = Module(space, space.wrap('m')) + py.test.raises(OperationError, space.getattr, w(m), w('__file__')) + m._cleanup_() + py.test.raises(OperationError, space.getattr, w(m), w('__file__')) + space.setattr(w(m), w('__file__'), w('m.py')) + space.getattr(w(m), w('__file__')) # does not raise + m._cleanup_() + py.test.raises(OperationError, space.getattr, w(m), w('__file__')) + + class AppTest_ModuleObject: def test_attr(self): m = __import__('__builtin__') @@ -42,12 +55,9 @@ bar = type(sys)('bar','docstring') assert bar.__doc__ == 'docstring' - def test___file__(self): - import sys, os - if not hasattr(sys, "pypy_objspaceclass"): - skip("need PyPy for sys.__file__ checking") - assert sys.__file__ - assert os.path.basename(sys.__file__) == 'sys' + def test___file__(self): + import sys + assert not hasattr(sys, '__file__') def test_repr(self): import sys diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -7,7 +7,6 @@ class Module(MixedModule): """Built-in functions, exceptions, and other objects.""" - expose__file__attribute = False appleveldefs = { 'execfile' : 'app_io.execfile', diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -182,8 +182,12 @@ value = misc.read_raw_long_data(cdata, self.size) return self.space.wrap(value) else: - value = misc.read_raw_signed_data(cdata, self.size) - return self.space.wrap(value) # r_longlong => on 32-bit, 'long' + return self._convert_to_object_longlong(cdata) + + def _convert_to_object_longlong(self, cdata): + # in its own function: LONGLONG may make the whole function jit-opaque + value = misc.read_raw_signed_data(cdata, self.size) + return self.space.wrap(value) # r_longlong => on 32-bit, 'long' def convert_from_object(self, cdata, w_ob): if self.value_fits_long: @@ -193,8 +197,12 @@ self._overflow(w_ob) misc.write_raw_signed_data(cdata, value, self.size) else: - value = misc.as_long_long(self.space, w_ob) - misc.write_raw_signed_data(cdata, value, self.size) + self._convert_from_object_longlong(cdata, w_ob) + + def _convert_from_object_longlong(self, cdata, w_ob): + # in its own function: LONGLONG may make the whole function jit-opaque + value = misc.as_long_long(self.space, w_ob) + misc.write_raw_signed_data(cdata, value, self.size) def get_vararg_type(self): if self.size < rffi.sizeof(rffi.INT): @@ -264,8 +272,12 @@ self._overflow(w_ob) misc.write_raw_unsigned_data(cdata, value, self.size) else: - value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) - misc.write_raw_unsigned_data(cdata, value, self.size) + self._convert_from_object_longlong(cdata, w_ob) + + def _convert_from_object_longlong(self, cdata, w_ob): + # in its own function: LONGLONG may make the whole function jit-opaque + value = misc.as_unsigned_long_long(self.space, w_ob, strict=True) + misc.write_raw_unsigned_data(cdata, value, self.size) def convert_to_object(self, cdata): if self.value_fits_ulong: @@ -275,8 +287,12 @@ else: return self.space.wrap(value) # r_uint => 'long' object else: - value = misc.read_raw_unsigned_data(cdata, self.size) - return self.space.wrap(value) # r_ulonglong => 'long' object + return self._convert_to_object_longlong(cdata) + + def _convert_to_object_longlong(self, cdata): + # in its own function: LONGLONG may make the whole function jit-opaque + value = misc.read_raw_unsigned_data(cdata, self.size) + return self.space.wrap(value) # r_ulonglong => 'long' object def get_vararg_type(self): if self.size < rffi.sizeof(rffi.INT): diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py --- a/pypy/module/_cffi_backend/ctypestruct.py +++ b/pypy/module/_cffi_backend/ctypestruct.py @@ -17,7 +17,7 @@ class W_CTypeStructOrUnion(W_CType): - _immutable_fields_ = ['alignment?', 'fields_list?', 'fields_dict?', + _immutable_fields_ = ['alignment?', 'fields_list?[*]', 'fields_dict?', 'custom_field_pos?', 'with_var_array?'] # fields added by complete_struct_or_union(): alignment = -1 diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -389,7 +389,7 @@ w_ctype.size = totalsize w_ctype.alignment = totalalignment - w_ctype.fields_list = fields_list + w_ctype.fields_list = fields_list[:] w_ctype.fields_dict = fields_dict w_ctype.custom_field_pos = custom_field_pos w_ctype.with_var_array = with_var_array diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py --- a/pypy/module/_io/interp_stringio.py +++ b/pypy/module/_io/interp_stringio.py @@ -86,7 +86,7 @@ initval = space.unicode_w(w_initval) size = len(initval) self.resize_buffer(size) - self.buf = [c for c in initval] + self.buf = list(initval) pos = space.getindex_w(w_pos, space.w_TypeError) if pos < 0: raise OperationError(space.w_ValueError, diff --git a/pypy/module/_pypyjson/interp_encoder.py b/pypy/module/_pypyjson/interp_encoder.py --- a/pypy/module/_pypyjson/interp_encoder.py +++ b/pypy/module/_pypyjson/interp_encoder.py @@ -1,4 +1,6 @@ from rpython.rlib.rstring import StringBuilder +from rpython.rlib.runicode import str_decode_utf_8 +from pypy.interpreter import unicodehelper HEX = '0123456789abcdef' @@ -17,20 +19,37 @@ def raw_encode_basestring_ascii(space, w_string): if space.isinstance_w(w_string, space.w_str): s = space.str_w(w_string) - for c in s: + for i in range(len(s)): + c = s[i] if c >= ' ' and c <= '~' and c != '"' and c != '\\': pass else: + first = i break else: # the input is a string with only non-special ascii chars return w_string - w_string = space.call_method(w_string, 'decode', space.wrap('utf-8')) + eh = unicodehelper.decode_error_handler(space) + u = str_decode_utf_8( + s, len(s), None, final=True, errorhandler=eh, + allow_surrogates=True)[0] + sb = StringBuilder(len(u)) + sb.append_slice(s, 0, first) + else: + # We used to check if 'u' contains only safe characters, and return + # 'w_string' directly. But this requires an extra pass over all + # characters, and the expected use case of this function, from + # json.encoder, will anyway re-encode a unicode result back to + # a string (with the ascii encoding). This requires two passes + # over the characters. So we may as well directly turn it into a + # string here --- only one pass. + u = space.unicode_w(w_string) + sb = StringBuilder(len(u)) + first = 0 - u = space.unicode_w(w_string) - sb = StringBuilder(len(u)) - for c in u: + for i in range(first, len(u)): + c = u[i] if c <= u'~': if c == u'"' or c == u'\\': sb.append('\\') diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -29,7 +29,7 @@ #define PY_VERSION "2.7.8" /* PyPy version as a string */ -#define PYPY_VERSION "2.4.0-alpha0" +#define PYPY_VERSION "2.5.0-alpha0" /* Subversion Revision number of this file (not of the repository). * Empty since Mercurial migration. */ diff --git a/pypy/module/errno/test/test_errno.py b/pypy/module/errno/test/test_errno.py --- a/pypy/module/errno/test/test_errno.py +++ b/pypy/module/errno/test/test_errno.py @@ -8,7 +8,7 @@ cls.w_errorcode = cls.space.wrap(errno.errorcode) def test_posix(self): - assert self.errno.__file__ + assert not hasattr(self.errno, '__file__') def test_constants(self): for code, name in self.errorcode.iteritems(): diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -96,7 +96,7 @@ need_sparse_files() def test_posix_is_pypy_s(self): - assert self.posix.__file__ + assert hasattr(self.posix, '_statfields') def test_some_posix_basic_operation(self): path = self.path @@ -282,13 +282,8 @@ f = posix.fdopen(fd, "r") f.close() - # Ensure that fcntl is not faked - try: - import fcntl - except ImportError: - pass - else: - assert fcntl.__file__.endswith('pypy/module/fcntl') + # There used to be code here to ensure that fcntl is not faked + # but we can't do that cleanly any more exc = raises(OSError, posix.fdopen, fd) assert exc.value.errno == errno.EBADF diff --git a/pypy/module/posix/test/test_posix_libfile.py b/pypy/module/posix/test/test_posix_libfile.py --- a/pypy/module/posix/test/test_posix_libfile.py +++ b/pypy/module/posix/test/test_posix_libfile.py @@ -19,7 +19,7 @@ cls.w_path = cls.space.wrap(str(path)) def test_posix_is_pypy_s(self): - assert self.posix.__file__ + assert hasattr(self.posix, '_statfields') def test_fdopen(self): path = self.path diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py --- a/pypy/module/pypyjit/test_pypy_c/test_call.py +++ b/pypy/module/pypyjit/test_pypy_c/test_call.py @@ -17,13 +17,18 @@ # now we can inline it as call assembler i = 0 j = 0 - while i < 20: + while i < 25: i += 1 j += rec(100) # ID: call_rec return j # - log = self.run(fn, [], threshold=18) - loop, = log.loops_by_filename(self.filepath) + # NB. the parameters below are a bit ad-hoc. After 16 iterations, + # the we trace from the "while" and reach a "trace too long". Then + # in the next execution, we trace the "rec" function from start; + # that's "functrace" below. Then after one or two extra iterations + # we try again from "while", and this time we succeed. + log = self.run(fn, [], threshold=20) + functrace, loop = log.loops_by_filename(self.filepath) assert loop.match_by_id('call_rec', """ ... p53 = call_assembler(..., descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py --- a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py +++ b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py @@ -1,4 +1,4 @@ -import py, sys +import py, sys, re from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC class TestCProfile(BaseTestPyPyC): @@ -26,10 +26,20 @@ for method in ['append', 'pop']: loop, = log.loops_by_id(method) print loop.ops_by_id(method) - # on 32-bit, there is f1=read_timestamp(); ...; - # f2=read_timestamp(); f3=call(llong_sub,f1,f2) - # which should turn into a single PADDQ/PSUBQ - if sys.maxint != 2147483647: - assert ' call(' not in repr(loop.ops_by_id(method)) + # on 32-bit, there is f1=call(read_timestamp); ...; + # f2=call(read_timestamp); f3=call(llong_sub,f1,f2) + # but all calls can be special-cased by the backend if + # supported. On 64-bit there is only the two calls to + # read_timestamp. + r = re.compile(r" call[(]ConstClass[(](.+?)[)]") + calls = r.findall(repr(loop.ops_by_id(method))) + if sys.maxint == 2147483647: + assert len(calls) == 6 + else: + assert len(calls) == 2 + for x in calls: + assert ('ll_read_timestamp' in x or 'llong_sub' in x + or 'llong_add' in x) + # assert ' call_may_force(' not in repr(loop.ops_by_id(method)) assert ' cond_call(' in repr(loop.ops_by_id(method)) diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py --- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py +++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py @@ -340,30 +340,19 @@ guard_value(p166, ConstPtr(ptr72), descr=...) p167 = call(ConstClass(_ll_0_alloc_with_del___), descr=<Callr . EF=4>) guard_no_exception(descr=...) - i168 = call(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, descr=<Calli . i EF=4 OS=110>) - i169 = int_add(i168, i97) - i170 = int_sub(i160, i106) - setfield_gc(p167, i168, descr=<FieldU pypy.module._cffi_backend.cdataobj.W_CData.inst__cdata .>) + i112 = int_sub(i160, -32768) setfield_gc(p167, ConstPtr(null), descr=<FieldP pypy.module._cffi_backend.cdataobj.W_CData.inst__lifeline_ .+>) - setfield_gc(p167, ConstPtr(ptr89), descr=<FieldP pypy.module._cffi_backend.cdataobj.W_CData.inst_ctype .+>) - i171 = uint_gt(i170, i108) - guard_false(i171, descr=...) - i172 = int_sub(i160, -32768) - i173 = int_and(i172, 65535) - i174 = int_add(i173, -32768) - setarrayitem_raw(i169, 0, i174, descr=<ArrayS 2>) - i175 = int_add(i168, i121) - i176 = int_sub(i160, i130) - i177 = uint_gt(i176, i132) - guard_false(i177, descr=...) - setarrayitem_raw(i175, 0, i174, descr=<ArrayS 2>) - i178 = int_add(i168, i140) - i179 = int_sub(i160, i149) - i180 = uint_gt(i179, i151) - guard_false(i180, descr=...) - setarrayitem_raw(i178, 0, i174, descr=<ArrayS 2>) + setfield_gc(p167, ConstPtr(ptr85), descr=<FieldP pypy.module._cffi_backend.cdataobj.W_CData.inst_ctype .+>) + i114 = uint_gt(i112, 65535) + guard_false(i114, descr=...) + i115 = int_and(i112, 65535) + i116 = int_add(i115, -32768) --TICK-- - i183 = arraylen_gc(p67, descr=<ArrayP .>) - i184 = arraylen_gc(p92, descr=<ArrayP .>) + i119 = call(ConstClass(_ll_1_raw_malloc_varsize__Signed), 6, descr=<Calli . i EF=4 OS=110>) + raw_store(i119, 0, i116, descr=<ArrayS 2>) + raw_store(i119, 2, i116, descr=<ArrayS 2>) + raw_store(i119, 4, i116, descr=<ArrayS 2>) + setfield_gc(p167, i119, descr=<FieldU pypy.module._cffi_backend.cdataobj.W_CData.inst__cdata .+>) + i123 = arraylen_gc(p67, descr=<ArrayP .>) jump(..., descr=...) """) diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py --- a/pypy/module/select/interp_select.py +++ b/pypy/module/select/interp_select.py @@ -98,6 +98,9 @@ for w_f in list_w: fd = space.c_filedescriptor_w(w_f) if fd > nfds: + if _c.MAX_FD_SIZE is not None and fd >= _c.MAX_FD_SIZE: + raise oefmt(space.w_ValueError, + "file descriptor out of range in select()") nfds = fd _c.FD_SET(fd, ll_list) fdlist.append(fd) diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py --- a/pypy/module/select/test/test_select.py +++ b/pypy/module/select/test/test_select.py @@ -198,6 +198,16 @@ finally: writeend.close() + def test_select_descr_out_of_bounds(self): + import sys, select + raises(ValueError, select.select, [-1], [], []) + raises(ValueError, select.select, [], [-2], []) + raises(ValueError, select.select, [], [], [-3]) + if sys.platform != 'win32': + raises(ValueError, select.select, [2000000000], [], []) + raises(ValueError, select.select, [], [2000000000], []) + raises(ValueError, select.select, [], [], [2000000000]) + def test_poll(self): import select if not hasattr(select, 'poll'): diff --git a/pypy/module/sys/initpath.py b/pypy/module/sys/initpath.py --- a/pypy/module/sys/initpath.py +++ b/pypy/module/sys/initpath.py @@ -18,6 +18,13 @@ _WIN32 = sys.platform == 'win32' +def _exists_and_is_executable(fn): + # os.access checks using the user's real uid and gid. + # Since pypy should not be run setuid/setgid, this + # should be sufficient. + return os.path.isfile(fn) and os.access(fn, os.X_OK) + + def find_executable(executable): """ Return the absolute path of the executable, by looking into PATH and @@ -34,14 +41,14 @@ if path: for dir in path.split(os.pathsep): fn = os.path.join(dir, executable) - if os.path.isfile(fn): + if _exists_and_is_executable(fn): executable = fn break executable = rpath.rabspath(executable) # 'sys.executable' should not end up being an non-existing file; # just use '' in this case. (CPython issue #7774) - return executable if os.path.isfile(executable) else '' + return executable if _exists_and_is_executable(executable) else '' def _readlink_maybe(filename): diff --git a/pypy/module/sys/test/test_initpath.py b/pypy/module/sys/test/test_initpath.py --- a/pypy/module/sys/test/test_initpath.py +++ b/pypy/module/sys/test/test_initpath.py @@ -57,6 +57,7 @@ a.join('pypy').ensure(file=True) b.join('pypy').ensure(file=True) # + monkeypatch.setattr(os, 'access', lambda x, y: True) # if there is already a slash, don't do anything monkeypatch.chdir(tmpdir) assert find_executable('a/pypy') == a.join('pypy') @@ -82,7 +83,11 @@ # if pypy is found but it's not a file, ignore it c.join('pypy').ensure(dir=True) assert find_executable('pypy') == a.join('pypy') + # if pypy is found but it's not executable, ignore it + monkeypatch.setattr(os, 'access', lambda x, y: False) + assert find_executable('pypy') == '' # + monkeypatch.setattr(os, 'access', lambda x, y: True) monkeypatch.setattr(initpath, 'we_are_translated', lambda: True) monkeypatch.setattr(initpath, '_WIN32', True) monkeypatch.setenv('PATH', str(a)) diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -10,7 +10,7 @@ #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h -PYPY_VERSION = (2, 4, 0, "alpha", 0) #XXX # sync patchlevel.h +PYPY_VERSION = (2, 5, 0, "alpha", 0) #XXX # sync patchlevel.h if platform.name == 'msvc': COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600) diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py --- a/pypy/module/thread/test/test_thread.py +++ b/pypy/module/thread/test/test_thread.py @@ -13,18 +13,26 @@ def f(): lock.acquire() lock.release() + start = thread._count() try: try: for i in range(1000): thread.start_new_thread(f, ()) finally: lock.release() - # wait a bit to allow most threads to finish now - time.sleep(0.5) except (thread.error, MemoryError): cls.w_can_start_many_threads = space.wrap(False) else: cls.w_can_start_many_threads = space.wrap(True) + # wait a bit to allow all threads to finish now + remaining = thread._count() + retries = 0 + while remaining > start: + retries += 1 + if retries == 200: + raise Exception("the test's threads don't stop!") + time.sleep(0.2) + remaining = thread._count() def test_start_new_thread(self): import thread @@ -227,7 +235,7 @@ import signal def f(): - for x in range(5): + for x in range(40): if waiting: thread.interrupt_main() return @@ -236,7 +244,7 @@ def busy_wait(): waiting.append(None) - for x in range(10): + for x in range(50): print 'tick...', x # <-force the GIL to be released, as time.sleep(0.1) # time.sleep doesn't do non-translated waiting.pop() @@ -245,6 +253,8 @@ signal.signal(signal.SIGINT, signal.default_int_handler) for i in range(100): + print + print "loop", i waiting = [] thread.start_new_thread(f, ()) raises(KeyboardInterrupt, busy_wait) diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -671,6 +671,7 @@ left, right = specialnames errormsg = "unsupported operand type(s) for %s: '%%N' and '%%N'" % ( symbol.replace('%', '%%'),) + seq_bug_compat = (symbol == '+' or symbol == '*') def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) @@ -686,20 +687,16 @@ # __xxx__ and __rxxx__ methods where found by identity. # Note that space.is_w() is potentially not happy if one of them # is None... - if w_left_src is not w_right_src: # XXX - # -- cpython bug compatibility: see objspace/std/test/ - # -- test_unicodeobject.test_str_unicode_concat_overrides. - # -- The following handles "unicode + string subclass" by - # -- pretending that the unicode is a superclass of the - # -- string, thus giving priority to the string subclass' - # -- __radd__() method. The case "string + unicode subclass" - # -- is handled directly by add__String_Unicode(). - if symbol == '+' and space.is_w(w_typ1, space.w_unicode): - w_typ1 = space.w_basestring - # -- end of bug compatibility - if space.is_true(space.issubtype(w_typ2, w_typ1)): - if (w_left_src and w_right_src and - not space.abstract_issubclass_w(w_left_src, w_right_src) and + if w_right_src and (w_left_src is not w_right_src) and w_left_src: + # 'seq_bug_compat' is for cpython bug-to-bug compatibility: + # see objspace/std/test/test_unicodeobject.*concat_overrides + # and objspace/test/test_descrobject.*rmul_overrides. + # For cases like "unicode + string subclass". + if ((seq_bug_compat and w_typ1.flag_sequence_bug_compat + and not w_typ2.flag_sequence_bug_compat) + # the non-bug-compat part is the following check: + or space.is_true(space.issubtype(w_typ2, w_typ1))): + if (not space.abstract_issubclass_w(w_left_src, w_right_src) and not space.abstract_issubclass_w(w_typ1, w_right_src)): w_obj1, w_obj2 = w_obj2, w_obj1 w_left_impl, w_right_impl = w_right_impl, w_left_impl diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -534,7 +534,7 @@ if not e.match(space, space.w_TypeError): raise else: - return [c for c in buf.as_str()] + return list(buf.as_str()) # sequence of bytes w_iter = space.iter(w_source) @@ -1131,6 +1131,7 @@ reverse = interp2app(W_BytearrayObject.descr_reverse, doc=BytearrayDocstrings.reverse.__doc__), ) +W_BytearrayObject.typedef.flag_sequence_bug_compat = True init_signature = Signature(['source', 'encoding', 'errors'], None, None) init_defaults = [None, None, None] diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py --- a/pypy/objspace/std/bytesobject.py +++ b/pypy/objspace/std/bytesobject.py @@ -951,6 +951,7 @@ _formatter_field_name_split = interp2app(W_BytesObject.descr_formatter_field_name_split), ) +W_BytesObject.typedef.flag_sequence_bug_compat = True def string_escape_encode(s, quote): diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -1874,3 +1874,4 @@ insert = interp2app(W_ListObject.descr_insert), remove = interp2app(W_ListObject.descr_remove), ) +W_ListObject.typedef.flag_sequence_bug_compat = True diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py --- a/pypy/objspace/std/stdtypedef.py +++ b/pypy/objspace/std/stdtypedef.py @@ -93,6 +93,8 @@ overridetypedef=overridetypedef) if typedef is not overridetypedef: w_type.w_doc = space.wrap(typedef.doc) + if hasattr(typedef, 'flag_sequence_bug_compat'): + w_type.flag_sequence_bug_compat = typedef.flag_sequence_bug_compat w_type.lazyloaders = lazyloaders return w_type diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -244,6 +244,7 @@ count = interp2app(W_AbstractTupleObject.descr_count), index = interp2app(W_AbstractTupleObject.descr_index) ) +W_AbstractTupleObject.typedef.flag_sequence_bug_compat = True class W_TupleObject(W_AbstractTupleObject): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -67,6 +67,7 @@ _immutable_fields_ = ["flag_heaptype", "flag_cpytype", "flag_abstract?", + "flag_sequence_bug_compat", 'needsdel', 'weakrefable', 'hasdict', @@ -104,6 +105,7 @@ w_self.flag_heaptype = False w_self.flag_cpytype = False w_self.flag_abstract = False + w_self.flag_sequence_bug_compat = False w_self.instancetypedef = overridetypedef if overridetypedef is not None: 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 @@ -1068,6 +1068,7 @@ _formatter_field_name_split = interp2app(W_UnicodeObject.descr_formatter_field_name_split), ) +W_UnicodeObject.typedef.flag_sequence_bug_compat = True _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit