Author: Amaury Forgeot d'Arc <[email protected]>
Branch: stdlib-2.7.9
Changeset: r75749:0005ffa6a65b
Date: 2015-02-06 23:58 +0100
http://bitbucket.org/pypy/pypy/changeset/0005ffa6a65b/
Log: hg merge default + update interp_ssl to use the new
rposix.get_saved_errno
diff too long, truncating to 2000 out of 10699 lines
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -7,10 +7,7 @@
9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
ab0dd631c22015ed88e583d9fdd4c43eebf0be21 pypy-2.1-beta1-arm
20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0
-20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0
-0000000000000000000000000000000000000000 release-2.3.0
394146e9bb673514c61f0150ab2013ccf78e8de7 release-2.3
32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1
-32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
-0000000000000000000000000000000000000000 release-2.2=3.1
+10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -42,19 +42,19 @@
Amaury Forgeot d'Arc
Samuele Pedroni
Alex Gaynor
+ Brian Kearns
+ Matti Picus
+ Philip Jenvey
Michael Hudson
David Schneider
- Matti Picus
- Brian Kearns
- Philip Jenvey
Holger Krekel
Christian Tismer
Hakan Ardo
Benjamin Peterson
Manuel Jacob
+ Ronan Lamy
Anders Chrigstrom
Eric van Riet Paap
- Ronan Lamy
Wim Lavrijsen
Richard Emslie
Alexander Schremmer
@@ -68,9 +68,9 @@
Camillo Bruni
Laura Creighton
Toon Verwaest
+ Romain Guillebert
Leonardo Santagada
Seo Sanghyeon
- Romain Guillebert
Justin Peel
Ronny Pfannschmidt
David Edelsohn
@@ -91,15 +91,16 @@
Michal Bendowski
Jan de Mooij
stian
+ Tyler Wade
Michael Foord
Stephan Diehl
- Tyler Wade
Stefan Schwarzer
Valentino Volonghi
Tomek Meka
Patrick Maupin
Bob Ippolito
Bruno Gola
+ David Malcolm
Jean-Paul Calderone
Timo Paulssen
Squeaky
@@ -108,18 +109,19 @@
Marius Gedminas
Martin Matusiak
Konstantin Lopuhin
+ Wenzhu Man
John Witulski
- Wenzhu Man
+ Laurence Tratt
+ Ivan Sichmann Freitas
Greg Price
Dario Bertini
Mark Pearse
Simon Cross
- Ivan Sichmann Freitas
Andreas Stührk
+ Stefano Rivera
Jean-Philippe St. Pierre
Guido van Rossum
Pavel Vinogradov
- Stefano Rivera
Paweł Piotr Przeradowski
Paul deGrandis
Ilya Osadchiy
@@ -129,7 +131,6 @@
tav
Taavi Burns
Georg Brandl
- Laurence Tratt
Bert Freudenberg
Stian Andreassen
Wanja Saatkamp
@@ -141,13 +142,12 @@
Jeremy Thurgood
Rami Chowdhury
Tobias Pape
- David Malcolm
Eugene Oden
Henry Mason
Vasily Kuznetsov
Preston Timmons
+ David Ripton
Jeff Terrace
- David Ripton
Dusty Phillips
Lukas Renggli
Guenter Jantzen
@@ -166,13 +166,16 @@
Gintautas Miliauskas
Michael Twomey
Lucian Branescu Mihaila
+ Yichao Yu
Gabriel Lavoie
Olivier Dormond
Jared Grubb
Karl Bartel
+ Wouter van Heyst
Brian Dorsey
Victor Stinner
Andrews Medina
+ anatoly techtonik
Stuart Williams
Jasper Schulz
Christian Hudon
@@ -182,12 +185,11 @@
Michael Cheng
Justas Sadzevicius
Gasper Zejn
- anatoly techtonik
Neil Shepperd
+ Stanislaw Halik
Mikael Schönenberg
Elmo M?ntynen
Jonathan David Riehl
- Stanislaw Halik
Anders Qvist
Corbin Simpson
Chirag Jadwani
@@ -196,10 +198,13 @@
Vincent Legoll
Alan McIntyre
Alexander Sedov
+ Attila Gobi
Christopher Pope
Christian Tismer
Marc Abramowitz
Dan Stromberg
+ Arjun Naik
+ Valentina Mukhamedzhanova
Stefano Parmesan
Alexis Daboville
Jens-Uwe Mager
@@ -213,8 +218,6 @@
Sylvain Thenault
Nathan Taylor
Vladimir Kryachko
- Arjun Naik
- Attila Gobi
Jacek Generowicz
Alejandro J. Cura
Jacob Oscarson
@@ -222,22 +225,23 @@
Ryan Gonzalez
Ian Foote
Kristjan Valur Jonsson
+ David Lievens
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
+ Toni Mattis
+ Lucas Stadler
roberto@goyle
Yury V. Zaytsev
Anna Katrina Dominguez
@@ -265,23 +269,30 @@
Stephan Busemann
Rafał Gałczyński
Christian Muirhead
+ Berker Peksag
James Lan
shoma hosaka
- Daniel Neuh?user
- Matthew Miller
+ Daniel Neuhäuser
+ Ben Mather
+ halgari
+ Boglarka Vezer
+ Chris Pressey
Buck Golemon
Konrad Delong
Dinu Gherman
Chris Lambacher
[email protected]
+ Jim Baker
Rodrigo Araújo
- Jim Baker
+ Nikolaos-Digenis Karagiannis
James Robert
Armin Ronacher
Brett Cannon
+ Donald Stufft
yrttyr
aliceinwire
OlivierBlanvillain
+ Dan Sanders
Zooko Wilcox-O Hearn
Tomer Chachamu
Christopher Groskopf
@@ -295,6 +306,7 @@
Markus Unterwaditzer
Even Wiik Thomassen
jbs
+ squeaky
soareschen
Kurt Griffiths
Mike Bayer
@@ -306,6 +318,7 @@
Anna Ravencroft
Dan Crosta
Julien Phalip
+ Roman Podoliaka
Dan Loewenherz
Heinrich-Heine University, Germany
diff --git a/lib-python/2.7/ctypes/test/test_frombuffer.py
b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -2,7 +2,6 @@
import array
import gc
import unittest
-from ctypes.test import xfail
class X(Structure):
_fields_ = [("c_int", c_int)]
@@ -11,7 +10,6 @@
self._init_called = True
class Test(unittest.TestCase):
- @xfail
def test_fom_buffer(self):
a = array.array("i", range(16))
x = (c_int * 16).from_buffer(a)
@@ -34,10 +32,9 @@
del a; gc.collect(); gc.collect(); gc.collect()
self.assertEqual(x[:], expected)
- self.assertRaises(TypeError,
+ self.assertRaises((TypeError, ValueError),
(c_char * 16).from_buffer, "a" * 16)
- @xfail
def test_fom_buffer_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer(a, sizeof(c_int))
@@ -46,7 +43,6 @@
self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a,
sizeof(c_int)))
self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 *
sizeof(c_int)))
- @xfail
def test_from_buffer_copy(self):
a = array.array("i", range(16))
x = (c_int * 16).from_buffer_copy(a)
@@ -71,7 +67,6 @@
x = (c_char * 16).from_buffer_copy("a" * 16)
self.assertEqual(x[:], "a" * 16)
- @xfail
def test_fom_buffer_copy_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -83,6 +83,37 @@
def in_dll(self, dll, name):
return self.from_address(dll._handle.getaddressindll(name))
+ def from_buffer(self, obj, offset=0):
+ size = self._sizeofinstances()
+ buf = buffer(obj, offset, size)
+ if len(buf) < size:
+ raise ValueError(
+ "Buffer size too small (%d instead of at least %d bytes)"
+ % (len(buf) + offset, size + offset))
+ raw_addr = buf._pypy_raw_address()
+ result = self.from_address(raw_addr)
+ result._ensure_objects()['ffffffff'] = obj
+ return result
+
+ def from_buffer_copy(self, obj, offset=0):
+ size = self._sizeofinstances()
+ buf = buffer(obj, offset, size)
+ if len(buf) < size:
+ raise ValueError(
+ "Buffer size too small (%d instead of at least %d bytes)"
+ % (len(buf) + offset, size + offset))
+ result = self()
+ dest = result._buffer.buffer
+ try:
+ raw_addr = buf._pypy_raw_address()
+ except ValueError:
+ _rawffi.rawstring2charp(dest, buf)
+ else:
+ from ctypes import memmove
+ memmove(dest, raw_addr, size)
+ return result
+
+
class CArgObject(object):
""" simple wrapper around buffer, just for the case of freeing
it afterwards
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -1,3 +1,4 @@
+import sys
import _rawffi
from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
store_reference, ensure_objects, CArgObject
@@ -178,6 +179,8 @@
instance = StructOrUnion.__new__(self)
if isinstance(address, _rawffi.StructureInstance):
address = address.buffer
+ # fix the address: turn it into as unsigned, in case it is negative
+ address = address & (sys.maxint * 2 + 1)
instance.__dict__['_buffer'] = self._ffistruct.fromaddress(address)
return instance
diff --git a/lib_pypy/greenlet.egg-info b/lib_pypy/greenlet.egg-info
--- a/lib_pypy/greenlet.egg-info
+++ b/lib_pypy/greenlet.egg-info
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: greenlet
-Version: 0.4.0
+Version: 0.4.5
Summary: Lightweight in-process concurrent programming
Home-page: https://github.com/python-greenlet/greenlet
Author: Ralf Schmitt (for CPython), PyPy team
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,7 +1,7 @@
import sys
import _continuation
-__version__ = "0.4.0"
+__version__ = "0.4.5"
# ____________________________________________________________
# Exceptions
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.4'
+version = '2.5'
# The full version, including alpha/beta/rc tags.
-release = '2.4.0'
+release = '2.5.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
@@ -12,19 +12,19 @@
Amaury Forgeot d'Arc
Samuele Pedroni
Alex Gaynor
+ Brian Kearns
+ Matti Picus
+ Philip Jenvey
Michael Hudson
David Schneider
- Matti Picus
- Brian Kearns
- Philip Jenvey
Holger Krekel
Christian Tismer
Hakan Ardo
Benjamin Peterson
Manuel Jacob
+ Ronan Lamy
Anders Chrigstrom
Eric van Riet Paap
- Ronan Lamy
Wim Lavrijsen
Richard Emslie
Alexander Schremmer
@@ -38,9 +38,9 @@
Camillo Bruni
Laura Creighton
Toon Verwaest
+ Romain Guillebert
Leonardo Santagada
Seo Sanghyeon
- Romain Guillebert
Justin Peel
Ronny Pfannschmidt
David Edelsohn
@@ -61,15 +61,16 @@
Michal Bendowski
Jan de Mooij
stian
+ Tyler Wade
Michael Foord
Stephan Diehl
- Tyler Wade
Stefan Schwarzer
Valentino Volonghi
Tomek Meka
Patrick Maupin
Bob Ippolito
Bruno Gola
+ David Malcolm
Jean-Paul Calderone
Timo Paulssen
Squeaky
@@ -78,18 +79,19 @@
Marius Gedminas
Martin Matusiak
Konstantin Lopuhin
+ Wenzhu Man
John Witulski
- Wenzhu Man
+ Laurence Tratt
+ Ivan Sichmann Freitas
Greg Price
Dario Bertini
Mark Pearse
Simon Cross
- Ivan Sichmann Freitas
Andreas Stührk
+ Stefano Rivera
Jean-Philippe St. Pierre
Guido van Rossum
Pavel Vinogradov
- Stefano Rivera
Paweł Piotr Przeradowski
Paul deGrandis
Ilya Osadchiy
@@ -99,7 +101,6 @@
tav
Taavi Burns
Georg Brandl
- Laurence Tratt
Bert Freudenberg
Stian Andreassen
Wanja Saatkamp
@@ -111,13 +112,12 @@
Jeremy Thurgood
Rami Chowdhury
Tobias Pape
- David Malcolm
Eugene Oden
Henry Mason
Vasily Kuznetsov
Preston Timmons
+ David Ripton
Jeff Terrace
- David Ripton
Dusty Phillips
Lukas Renggli
Guenter Jantzen
@@ -136,13 +136,16 @@
Gintautas Miliauskas
Michael Twomey
Lucian Branescu Mihaila
+ Yichao Yu
Gabriel Lavoie
Olivier Dormond
Jared Grubb
Karl Bartel
+ Wouter van Heyst
Brian Dorsey
Victor Stinner
Andrews Medina
+ anatoly techtonik
Stuart Williams
Jasper Schulz
Christian Hudon
@@ -152,12 +155,11 @@
Michael Cheng
Justas Sadzevicius
Gasper Zejn
- anatoly techtonik
Neil Shepperd
+ Stanislaw Halik
Mikael Schönenberg
Elmo M?ntynen
Jonathan David Riehl
- Stanislaw Halik
Anders Qvist
Corbin Simpson
Chirag Jadwani
@@ -166,10 +168,13 @@
Vincent Legoll
Alan McIntyre
Alexander Sedov
+ Attila Gobi
Christopher Pope
Christian Tismer
Marc Abramowitz
Dan Stromberg
+ Arjun Naik
+ Valentina Mukhamedzhanova
Stefano Parmesan
Alexis Daboville
Jens-Uwe Mager
@@ -183,8 +188,6 @@
Sylvain Thenault
Nathan Taylor
Vladimir Kryachko
- Arjun Naik
- Attila Gobi
Jacek Generowicz
Alejandro J. Cura
Jacob Oscarson
@@ -192,22 +195,23 @@
Ryan Gonzalez
Ian Foote
Kristjan Valur Jonsson
+ David Lievens
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
+ Toni Mattis
+ Lucas Stadler
roberto@goyle
Yury V. Zaytsev
Anna Katrina Dominguez
@@ -235,23 +239,30 @@
Stephan Busemann
Rafał Gałczyński
Christian Muirhead
+ Berker Peksag
James Lan
shoma hosaka
- Daniel Neuh?user
- Matthew Miller
+ Daniel Neuhäuser
+ Ben Mather
+ halgari
+ Boglarka Vezer
+ Chris Pressey
Buck Golemon
Konrad Delong
Dinu Gherman
Chris Lambacher
[email protected]
+ Jim Baker
Rodrigo Araújo
- Jim Baker
+ Nikolaos-Digenis Karagiannis
James Robert
Armin Ronacher
Brett Cannon
+ Donald Stufft
yrttyr
aliceinwire
OlivierBlanvillain
+ Dan Sanders
Zooko Wilcox-O Hearn
Tomer Chachamu
Christopher Groskopf
@@ -265,6 +276,7 @@
Markus Unterwaditzer
Even Wiik Thomassen
jbs
+ squeaky
soareschen
Kurt Griffiths
Mike Bayer
@@ -276,5 +288,6 @@
Anna Ravencroft
Dan Crosta
Julien Phalip
+ Roman Podoliaka
Dan Loewenherz
diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst
--- a/pypy/doc/cppyy.rst
+++ b/pypy/doc/cppyy.rst
@@ -74,7 +74,9 @@
See the :doc:`backend documentation <cppyy_backend>`.
A standalone version of Reflex that also provides the dynamically loadable
-backend is available for `download`_.
+backend is available for `download`_. Note this is currently the only way to
+get the dynamically loadable backend, so use this first.
+
That version, as well as any other distribution of Reflex (e.g. the one that
comes with `ROOT`_, which may be part of your Linux distribution as part of
the selection of scientific software) will also work for a build with the
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -3,6 +3,13 @@
.. contents::
+See also: `Frequently ask questions about RPython.`__
+
+.. __: http://rpython.readthedocs.org/en/latest/faq.html
+
+---------------------------
+
+
What is PyPy?
-------------
@@ -190,6 +197,55 @@
(now-dead) object are still true about the new object.
+
+Would type annotations help PyPy's performance?
+-----------------------------------------------
+
+Two examples of type annotations that are being proposed for improved
+performance are `Cython types`__ and `PEP 484 - Type Hints`__.
+
+.. __:
http://docs.cython.org/src/reference/language_basics.html#declaring-data-types
+.. __: https://www.python.org/dev/peps/pep-0484/
+
+**Cython types** are, by construction, similar to C declarations. For
+example, a local variable or an instance attribute can be declared
+``"cdef int"`` to force a machine word to be used. This changes the
+usual Python semantics (e.g. no overflow checks, and errors when
+trying to write other types of objects there). It gives some extra
+performance, but the exact benefits are unclear: right now
+(January 2015) for example we are investigating a technique that would
+store machine-word integers directly on instances, giving part of the
+benefits without the user-supplied ``"cdef int"``.
+
+**PEP 484 - Type Hints,** on the other hand, is almost entirely
+useless if you're looking at performance. First, as the name implies,
+they are *hints:* they must still be checked at runtime, like PEP 484
+says. Or maybe you're fine with a mode in which you get very obscure
+crashes when the type annotations are wrong; but even in that case the
+speed benefits would be extremely minor.
+
+There are several reasons for why. One of them is that annotations
+are at the wrong level (e.g. a PEP 484 "int" corresponds to Python 3's
+int type, which does not necessarily fits inside one machine word;
+even worse, an "int" annotation allows arbitrary int subclasses).
+Another is that a lot more information is needed to produce good code
+(e.g. "this ``f()`` called here really means this function there, and
+will never be monkey-patched" -- same with ``len()`` or ``list()``,
+btw). The third reason is that some "guards" in PyPy's JIT traces
+don't really have an obvious corresponding type (e.g. "this dict is so
+far using keys which don't override ``__hash__`` so a more efficient
+implementation was used"). Many guards don't even have any correspondence
+with types at all ("this class attribute was not modified"; "the loop
+counter did not reach zero so we don't need to release the GIL"; and
+so on).
+
+As PyPy works right now, it is able to derive far more useful
+information than can ever be given by PEP 484, and it works
+automatically. As far as we know, this is true even if we would add
+other techniques to PyPy, like a fast first-pass JIT.
+
+
+
.. _`prolog and javascript`:
Can I use PyPy's translation toolchain for other languages besides Python?
diff --git a/pypy/doc/getting-started-dev.rst b/pypy/doc/getting-started-dev.rst
--- a/pypy/doc/getting-started-dev.rst
+++ b/pypy/doc/getting-started-dev.rst
@@ -4,6 +4,93 @@
.. contents::
+Using Mercurial
+---------------
+
+PyPy development is based on Mercurial (hg). If you are not used to
+version control, the cycle for a new PyPy contributor goes typically
+like this:
+
+* Make an account on bitbucket_.
+
+* Go to https://bitbucket.org/pypy/pypy/ and click "fork" (left
+ icons). You get a fork of the repository, e.g. in
+ https://bitbucket.org/yourname/pypy/.
+
+* Clone this new repo (i.e. the fork) to your local machine with the command
+ ``hg clone ssh://[email protected]/yourname/pypy``. It is a very slow
+ operation but only ever needs to be done once. If you already cloned
+ ``https://bitbucket.org/pypy/pypy`` before, even if some time ago,
+ then you can reuse the same clone by editing the file ``.hg/hgrc`` in
+ your clone to contain the line ``default =
+ ssh://[email protected]/yourname/pypy``, and then do ``hg pull && hg
+ up``. If you already have such a clone but don't want to change it,
+ you can clone that copy with ``hg clone /path/to/other/copy``, and
+ then edit ``.hg/hgrc`` as above and do ``hg pull && hg up``.
+
+* Now you have a complete copy of the PyPy repo. Make a branch
+ with a command like ``hg branch name_of_your_branch``.
+
+* Edit things. Use ``hg diff`` to see what you changed. Use ``hg add``
+ to make Mercurial aware of new files you added, e.g. new test files.
+ Use ``hg status`` to see if there are such files. Run tests! (See
+ the rest of this page.)
+
+* Commit regularly with ``hg commit``. A one-line commit message is
+ fine. We love to have tons of commits; make one as soon as you have
+ some progress, even if it is only some new test that doesn't pass yet,
+ or fixing things even if not all tests pass. Step by step, you are
+ building the history of your changes, which is the point of a version
+ control system. (There are commands like ``hg log`` and ``hg up``
+ that you should read about later, to learn how to navigate this
+ history.)
+
+* The commits stay on your machine until you do ``hg push`` to "push"
+ them back to the repo named in the file ``.hg/hgrc``. Repos are
+ basically just collections of commits (a commit is also called a
+ changeset): there is one repo per url, plus one for each local copy on
+ each local machine. The commands ``hg push`` and ``hg pull`` copy
+ commits around, with the goal that all repos in question end up with
+ the exact same set of commits. By opposition, ``hg up`` only updates
+ the "working copy" by reading the local repository, i.e. it makes the
+ files that you see correspond to the latest (or any other) commit
+ locally present.
+
+* You should push often; there is no real reason not to. Remember that
+ even if they are pushed, with the setup above, the commits are (1)
+ only in ``bitbucket.org/yourname/pypy``, and (2) in the branch you
+ named. Yes, they are publicly visible, but don't worry about someone
+ walking around the thousands of repos on bitbucket saying "hah, look
+ at the bad coding style of that guy". Try to get into the mindset
+ that your work is not secret and it's fine that way. We might not
+ accept it as is for PyPy, asking you instead to improve some things,
+ but we are not going to judge you.
+
+* The final step is to open a pull request, so that we know that you'd
+ like to merge that branch back to the original ``pypy/pypy`` repo.
+ This can also be done several times if you have interesting
+ intermediate states, but if you get there, then we're likely to
+ proceed to the next stage, which is...
+
+* Get a regular account for pushing directly to
+ ``bitbucket.org/pypy/pypy`` (just ask and you'll get it, basically).
+ Once you have it you can rewrite your file ``.hg/hgrc`` to contain
+ ``default = ssh://[email protected]/pypy/pypy``. Your changes will
+ then be pushed directly to the official repo, but (if you follow these
+ rules) they are still on a branch, and we can still review the
+ branches you want to merge.
+
+* If you get closer to the regular day-to-day development, you'll notice
+ that we generally push small changes as one or a few commits directly
+ to the branch ``default``. Also, we often collaborate even if we are
+ on other branches, which do not really "belong" to anyone. At this
+ point you'll need ``hg merge`` and learn how to resolve conflicts that
+ sometimes occur when two people try to push different commits in
+ parallel on the same branch. But it is likely an issue for later ``:-)``
+
+.. _bitbucket: https://bitbucket.org/
+
+
Running PyPy's unit tests
-------------------------
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -22,12 +22,12 @@
will capture the revision number of this change for the release;
some of the next updates may be done before or after branching; make
sure things are ported back to the trunk and to the branch as
- necessary; also update the version number in pypy/doc/conf.py,
- and in pypy/doc/index.rst
+ necessary; also update the version number in pypy/doc/conf.py.
* update pypy/doc/contributor.rst (and possibly LICENSE)
pypy/doc/tool/makecontributor.py generates the list of contributors
* rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst
- and create a fresh whatsnew_head.rst after the release
+ create a fresh whatsnew_head.rst after the release
+ and add the new file to pypy/doc/index-of-whatsnew.rst
* go to pypy/tool/release and run:
force-builds.py <release branch>
* wait for builds to complete, make sure there are no failures
@@ -38,10 +38,14 @@
no JIT: windows, linux, os/x
sandbox: linux, os/x
-* repackage and upload source tar.bz2 to bitbucket and to cobra, as some
packagers
- prefer a clearly labeled source package
+* repackage and upload source "-src.tar.bz2" to bitbucket and to cobra, as some
+ packagers prefer a clearly labeled source package (download e.g.
+ https://bitbucket.org/pypy/pypy/get/release-2.5.x.tar.bz2, unpack,
+ rename the top-level directory to "pypy-2.5.0-src", repack, and upload)
+
* write release announcement pypy/doc/release-x.y(.z).txt
the release announcement should contain a direct link to the download page
+ and add new files to pypy/doc/index-of-release-notes.rst
* update pypy.org (under extradoc/pypy.org), rebuild and commit
* post announcement on morepypy.blogspot.com
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.5.0.rst
release-2.4.0.rst
release-2.3.1.rst
release-2.3.0.rst
diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst
--- a/pypy/doc/index-of-whatsnew.rst
+++ b/pypy/doc/index-of-whatsnew.rst
@@ -7,6 +7,7 @@
.. toctree::
whatsnew-head.rst
+ whatsnew-2.5.0.rst
whatsnew-2.4.0.rst
whatsnew-2.3.1.rst
whatsnew-2.3.0.rst
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -1,14 +1,23 @@
Potential project list
======================
-===========================
-Simple tasks for newcomers:
-===========================
+==========================
+Simple tasks for newcomers
+==========================
-Optimize random
----------------
+* Tkinter module missing support for threads:
+
https://bitbucket.org/pypy/pypy/issue/1929/tkinter-broken-for-threaded-python-on-both
-https://bitbucket.org/pypy/pypy/issue/1901/try-using-a-different-implementation-of
+* Optimize random:
+
https://bitbucket.org/pypy/pypy/issue/1901/try-using-a-different-implementation-of
+
+* Implement AF_XXX packet types of sockets:
+ https://bitbucket.org/pypy/pypy/issue/1942/support-for-af_xxx-sockets
+
+
+==================
+Mid-to-large tasks
+==================
Below is a list of projects that are interesting for potential contributors
who are seriously interested in the PyPy project. They mostly share common
@@ -33,15 +42,8 @@
------------------------
PyPy's bytearray type is very inefficient. It would be an interesting
-task to look into possible optimizations on this.
-
-Implement AF_XXX packet types for PyPy
---------------------------------------
-
-PyPy is missing AF_XXX types of sockets. Implementing it is easy-to-medium
-task. `bug report`_
-
-.. _`bug report`:
https://bitbucket.org/pypy/pypy/issue/1942/support-for-af_xxx-sockets#more
+task to look into possible optimizations on this. (XXX current status
+unknown; ask on #pypy for updates on this.)
Implement copy-on-write list slicing
------------------------------------
@@ -106,6 +108,8 @@
Translation Toolchain
---------------------
+(XXX this is unlikely to be feasible.)
+
* Incremental or distributed translation.
* Allow separate compilation of extension modules.
@@ -187,3 +191,37 @@
to make them work at all if they currently don't. A part of this work would
be to get cpyext into a shape where it supports running Cython generated
extensions.
+
+======================================
+Make more python modules pypy-friendly
+======================================
+
+Work has been started on a few popular python packages. Here is a partial
+list of good work that needs to be finished:
+
+**matplotlib** https://github.com/mattip/matplotlib
+
+ Status: the repo is an older version of matplotlib adapted to pypy and
cpyext
+
+ TODO: A suggested first step would be to merge the differences into
+ matplotlib/HEAD. The major problem is the use of a generic view into a
+ numpy ndarray. The int* fields would need to be converted into
int[MAX_DIMS]
+ c-arrays and filled in.
+
+**wxPython** https://bitbucket.org/waedt/wxpython_cffi
+
+ Status: A GSOC 2013 project to adapt the Phoenix sip build system to cffi
+
+ TODO: Merge the latest version of the wrappers and finish the sip
conversion
+
+**pygame** https://github.com/CTPUG/pygame_cffi
+
+ Status: see blog post
<http://morepypy.blogspot.com/2014/03/pygamecffi-pygame-on-pypy.html>
+
+ TODO: see the end of the blog post
+
+**pyopengl** https://bitbucket.org/duangle/pyopengl-cffi
+
+ Status: unknown
+
+
diff --git a/pypy/doc/release-2.5.0.rst b/pypy/doc/release-2.5.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.5.0.rst
@@ -0,0 +1,104 @@
+==============================
+PyPy 2.5.0 - Pincushion Protea
+==============================
+
+We're pleased to announce PyPy 2.5, which contains significant performance
+enhancements and bug fixes.
+
+You can download the PyPy 2.5.0 release here:
+
+ 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, as well as our
+volunteers and contributors (10 new commiters joined PyPy since the last
+release).
+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:
+
+* `Py3k`_ (supporting Python 3.x): We have released a Python 3.2.5 compatible
version
+ we call PyPy3 2.4.0, and are working toward a Python 3.3 compatible version
+
+* `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`_
+
+.. _`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
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy and cpython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+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 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
+==========
+
+* The past months have seen pypy mature and grow, as rpython becomes the goto
+ solution for writing fast dynamic language interpreters. Our separation of
+ rpython and the python interpreter PyPy is now much clearer in the
+ `PyPy documentation`_ and we now have seperate `RPython documentation`_.
+
+* We have improved warmup time as well as jitted code performance: more than
10%
+ compared to pypy-2.4.0, due to internal cleanup and gc nursery improvements.
+ We no longer zero-out memory allocated in the gc nursery by default, work
that
+ was started during a GSoC.
+
+* Passing objects between C and PyPy has been improved. We are now able to pass
+ raw pointers to C (without copying) using **pinning**. This improves I/O;
+ benchmarks that use networking intensively improved by about 50%. File()
+ operations still need some refactoring but are already showing a 20%
+ improvement on our benchmarks. Let us know if you see similar improvements.
+
+* Our integrated numpy support gained much of the GenericUfunc api in order to
+ support the lapack/blas linalg module of numpy. This dovetails with work in
the
+ pypy/numpy repository to support linalg both through the (slower) cpyext capi
+ interface and also via (the faster) pure python cffi interface, using an
+ extended frompyfunc() api. We will soon post a seperate blog post
specifically
+ about linalg and PyPy.
+
+* Dictionaries are now ordered by default, see the `blog post`_
+
+* Our nightly translations use --shared by default, including on OS/X and linux
+
+* We now more carefully handle errno (and GetLastError, WSAGetLastError) tying
+ the handlers as close as possible to the external function call, in
non-jitted
+ as well as jitted code.
+
+* 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.
+
+.. _`PyPy documentation`: http://doc.pypy.org
+.. _`RPython documentation`: http://rpython.readthedocs.org
+.. _`blog post`:
http://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html
+.. _resolved: http://doc.pypy.org/en/latest/whatsnew-2.5.0.html
+
+We have further improvements on the way: rpython file handling,
+finishing numpy linalg compatibility, numpy object dtypes, a better profiler,
+as well as support for Python stdlib 2.7.9.
+
+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!
+
+Cheers
+
+The PyPy Team
diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py
--- a/pypy/doc/test/test_whatsnew.py
+++ b/pypy/doc/test/test_whatsnew.py
@@ -38,7 +38,11 @@
current_branch, current_branch)
cmd = r'hg log -R "%s" -r "%s" --template "{branches}\n"' % (path, revset)
out = getoutput(cmd)
- branches = set(map(str.strip, out.splitlines()))
+ branches = set()
+ for item in out.splitlines():
+ item = item.strip()
+ if not item.startswith('release-'):
+ branches.add(item)
branches.discard("default")
return branches, current_branch
diff --git a/pypy/doc/whatsnew-2.5.0.rst b/pypy/doc/whatsnew-2.5.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-2.5.0.rst
@@ -0,0 +1,139 @@
+=======================
+What's new in PyPy 2.5
+=======================
+
+.. this is a revision shortly after release-2.4.x
+.. startrev: 7026746cbb1b
+
+.. branch: win32-fixes5
+
+Fix c code generation for msvc so empty "{ }" are avoided in unions,
+Avoid re-opening files created with NamedTemporaryFile,
+Allocate by 4-byte chunks in rffi_platform,
+Skip testing objdump if it does not exist,
+and other small adjustments in own tests
+
+.. branch: rtyper-stuff
+
+Small internal refactorings in the rtyper.
+
+.. branch: var-in-Some
+
+Store annotations on the Variable objects, rather than in a big dict.
+Introduce a new framework for double-dispatched annotation implementations.
+
+.. branch: ClassRepr
+
+Refactor ClassRepr and make normalizecalls independent of the rtyper.
+
+.. branch: remove-remaining-smm
+
+Remove all remaining multimethods.
+
+.. branch: improve-docs
+
+Split RPython documentation from PyPy documentation and clean up. There now is
+a clearer separation between documentation for users, developers and people
+interested in background information.
+
+.. branch: kill-multimethod
+
+Kill multimethod machinery, all multimethods were removed earlier.
+
+.. branch nditer-external_loop
+
+Implement `external_loop` arguement to numpy's nditer
+
+.. branch kill-rctime
+
+Rename pypy/module/rctime to pypy/module/time, since it contains the
implementation of the 'time' module.
+
+.. branch: ssa-flow
+
+Use SSA form for flow graphs inside build_flow() and part of simplify_graph()
+
+.. branch: ufuncapi
+
+Implement most of the GenericUfunc api to support numpy linalg. The strategy is
+to encourage use of pure python or cffi ufuncs by extending frompyfunc().
+See the docstring of frompyfunc for more details. This dovetails with a branch
+of pypy/numpy - cffi-linalg which is a rewrite of the _umath_linalg module in
+python, calling lapack from cffi. The branch also support traditional use of
+cpyext GenericUfunc definitions in c.
+
+.. branch: all_ordered_dicts
+
+This makes ordered dicts the default dictionary implementation in
+RPython and in PyPy. It polishes the basic idea of rordereddict.py
+and then fixes various things, up to simplifying
+collections.OrderedDict.
+
+Note: Python programs can rely on the guaranteed dict order in PyPy
+now, but for compatibility with other Python implementations they
+should still use collections.OrderedDict where that really matters.
+Also, support for reversed() was *not* added to the 'dict' class;
+use OrderedDict.
+
+Benchmark results: in the noise. A few benchmarks see good speed
+improvements but the average is very close to parity.
+
+.. branch: berkerpeksag/fix-broken-link-in-readmerst-1415127402066
+.. branch: bigint-with-int-ops
+.. branch: dstufft/update-pip-bootstrap-location-to-the-new-1420760611527
+.. branch: float-opt
+.. branch: gc-incminimark-pinning
+
+This branch adds an interface rgc.pin which would (very temporarily)
+make object non-movable. That's used by rffi.alloc_buffer and
+rffi.get_nonmovable_buffer and improves performance considerably for
+IO operations.
+
+.. branch: gc_no_cleanup_nursery
+
+A branch started by Wenzhu Man (SoC'14) and then done by fijal. It
+removes the clearing of the nursery. The drawback is that new objects
+are not automatically filled with zeros any longer, which needs some
+care, mostly for GC references (which the GC tries to follow, so they
+must not contain garbage). The benefit is a quite large speed-up.
+
+.. branch: improve-gc-tracing-hooks
+.. branch: improve-ptr-conv-error
+.. branch: intern-not-immortal
+
+Fix intern() to return mortal strings, like in CPython.
+
+.. branch: issue1922-take2
+.. branch: kill-exported-symbols-list
+.. branch: kill-rctime
+.. branch: kill_ll_termios
+.. branch: look-into-all-modules
+.. branch: nditer-external_loop
+.. branch: numpy-generic-item
+.. branch: osx-shared
+
+``--shared`` support on OS/X (thanks wouter)
+
+.. branch: portable-threadlocal
+.. branch: pypy-dont-copy-ops
+.. branch: recursion_and_inlining
+.. branch: slim-down-resumedescr
+.. branch: squeaky/use-cflags-for-compiling-asm
+.. branch: unicode-fix
+.. branch: zlib_zdict
+
+.. branch: errno-again
+
+Changes how errno, GetLastError, and WSAGetLastError are handled.
+The idea is to tie reading the error status as close as possible to
+the external function call. This fixes some bugs, both of the very
+rare kind (e.g. errno on Linux might in theory be overwritten by
+mmap(), called rarely during major GCs, if such a major GC occurs at
+exactly the wrong time), and some of the less rare kind
+(particularly on Windows tests).
+
+.. branch: osx-package.py
+.. branch: package.py-helpful-error-message
+
+.. branch: typed-cells
+
+Improve performance of integer globals and class attributes.
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
@@ -2,121 +2,6 @@
What's new in PyPy 2.5+
=======================
-.. this is a revision shortly after release-2.4.x
-.. startrev: 7026746cbb1b
+.. this is a revision shortly after release-2.5.x
+.. startrev: 397b96217b85
-.. branch: win32-fixes5
-
-Fix c code generation for msvc so empty "{ }" are avoided in unions,
-Avoid re-opening files created with NamedTemporaryFile,
-Allocate by 4-byte chunks in rffi_platform,
-Skip testing objdump if it does not exist,
-and other small adjustments in own tests
-
-.. branch: rtyper-stuff
-
-Small internal refactorings in the rtyper.
-
-.. branch: var-in-Some
-
-Store annotations on the Variable objects, rather than in a big dict.
-Introduce a new framework for double-dispatched annotation implementations.
-
-.. branch: ClassRepr
-
-Refactor ClassRepr and make normalizecalls independent of the rtyper.
-
-.. branch: remove-remaining-smm
-
-Remove all remaining multimethods.
-
-.. branch: improve-docs
-
-Split RPython documentation from PyPy documentation and clean up. There now is
-a clearer separation between documentation for users, developers and people
-interested in background information.
-
-.. branch: kill-multimethod
-
-Kill multimethod machinery, all multimethods were removed earlier.
-
-.. branch nditer-external_loop
-
-Implement `external_loop` arguement to numpy's nditer
-
-.. branch kill-rctime
-
-Rename pypy/module/rctime to pypy/module/time, since it contains the
implementation of the 'time' module.
-
-.. branch: ssa-flow
-
-Use SSA form for flow graphs inside build_flow() and part of simplify_graph()
-
-.. branch: ufuncapi
-
-Implement most of the GenericUfunc api to support numpy linalg. The strategy is
-to encourage use of pure python or cffi ufuncs by extending frompyfunc().
-See the docstring of frompyfunc for more details. This dovetails with a branch
-of pypy/numpy - cffi-linalg which is a rewrite of the _umath_linalg module in
-python, calling lapack from cffi. The branch also support traditional use of
-cpyext GenericUfunc definitions in c.
-
-.. branch: all_ordered_dicts
-
-This makes ordered dicts the default dictionary implementation in
-RPython and in PyPy. It polishes the basic idea of rordereddict.py
-and then fixes various things, up to simplifying
-collections.OrderedDict.
-
-Note: Python programs can rely on the guaranteed dict order in PyPy
-now, but for compatibility with other Python implementations they
-should still use collections.OrderedDict where that really matters.
-Also, support for reversed() was *not* added to the 'dict' class;
-use OrderedDict.
-
-Benchmark results: in the noise. A few benchmarks see good speed
-improvements but the average is very close to parity.
-
-.. branch: berkerpeksag/fix-broken-link-in-readmerst-1415127402066
-.. branch: bigint-with-int-ops
-.. branch: dstufft/update-pip-bootstrap-location-to-the-new-1420760611527
-.. branch: float-opt
-.. branch: gc-incminimark-pinning
-
-This branch adds an interface rgc.pin which would (very temporarily)
-make object non-movable. That's used by rffi.alloc_buffer and
-rffi.get_nonmovable_buffer and improves performance considerably for
-IO operations.
-
-.. branch: gc_no_cleanup_nursery
-
-A branch started by Wenzhu Man (SoC'14) and then done by fijal. It
-removes the clearing of the nursery. The drawback is that new objects
-are not automatically filled with zeros any longer, which needs some
-care, mostly for GC references (which the GC tries to follow, so they
-must not contain garbage). The benefit is a quite large speed-up.
-
-.. branch: improve-gc-tracing-hooks
-.. branch: improve-ptr-conv-error
-.. branch: intern-not-immortal
-
-Fix intern() to return mortal strings, like in CPython.
-
-.. branch: issue1922-take2
-.. branch: kill-exported-symbols-list
-.. branch: kill-rctime
-.. branch: kill_ll_termios
-.. branch: look-into-all-modules
-.. branch: nditer-external_loop
-.. branch: numpy-generic-item
-.. branch: osx-shared
-
-``--shared`` support on OS/X (thanks wouter)
-
-.. branch: portable-threadlocal
-.. branch: pypy-dont-copy-ops
-.. branch: recursion_and_inlining
-.. branch: slim-down-resumedescr
-.. branch: squeaky/use-cflags-for-compiling-asm
-.. branch: unicode-fix
-.. branch: zlib_zdict
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -235,6 +235,11 @@
config.translation.suggest(check_str_without_nul=True)
config.translation.suggest(shared=True)
+ if config.translation.shared:
+ if config.translation.output is not None:
+ raise Exception("Cannot use the --output option with PyPy "
+ "when --shared is on (it is by default). "
+ "See issue #1971.")
if config.translation.thread:
config.objspace.usemodules.thread = True
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1017,6 +1017,9 @@
def newlist_unicode(self, list_u):
return self.newlist([self.wrap(u) for u in list_u])
+ def newlist_int(self, list_i):
+ return self.newlist([self.wrap(i) for i in list_i])
+
def newlist_hint(self, sizehint):
from pypy.objspace.std.listobject import make_empty_list_with_size
return make_empty_list_with_size(self, sizehint)
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -486,10 +486,10 @@
w_exception_class=w_exception_class)
wrap_oserror._annspecialcase_ = 'specialize:arg(3)'
-def exception_from_errno(space, w_type):
- from rpython.rlib.rposix import get_errno
+def exception_from_saved_errno(space, w_type):
+ from rpython.rlib.rposix import get_saved_errno
- errno = get_errno()
+ errno = get_saved_errno()
msg = os.strerror(errno)
w_error = space.call_function(w_type, space.wrap(errno), space.wrap(msg))
return OperationError(w_type, w_error)
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -445,7 +445,10 @@
f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True)
new_frame.f_backref = jit.non_virtual_ref(f_back)
- new_frame.builtin = space.interp_w(Module, w_builtin)
+ if space.config.objspace.honor__builtins__:
+ new_frame.builtin = space.interp_w(Module, w_builtin)
+ else:
+ assert space.interp_w(Module, w_builtin) is space.builtin
new_frame.set_blocklist([unpickle_block(space, w_blk)
for w_blk in
space.unpackiterable(w_blockstack)])
values_w = maker.slp_from_tuple_with_nulls(space, w_valuestack)
@@ -530,9 +533,10 @@
# cellvars are values exported to inner scopes
# freevars are values coming from outer scopes
- freevarnames = list(self.pycode.co_cellvars)
+ # (see locals2fast for why CO_OPTIMIZED)
+ freevarnames = self.pycode.co_cellvars
if self.pycode.co_flags & consts.CO_OPTIMIZED:
- freevarnames.extend(self.pycode.co_freevars)
+ freevarnames = freevarnames + self.pycode.co_freevars
for i in range(len(freevarnames)):
name = freevarnames[i]
cell = self.cells[i]
@@ -561,7 +565,16 @@
self.setfastscope(new_fastlocals_w)
- freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars
+ freevarnames = self.pycode.co_cellvars
+ if self.pycode.co_flags & consts.CO_OPTIMIZED:
+ freevarnames = freevarnames + self.pycode.co_freevars
+ # If the namespace is unoptimized, then one of the
+ # following cases applies:
+ # 1. It does not contain free variables, because it
+ # uses import * or is a top-level namespace.
+ # 2. It is a class namespace.
+ # We don't want to accidentally copy free variables
+ # into the locals dict used by the class.
for i in range(len(freevarnames)):
name = freevarnames[i]
cell = self.cells[i]
diff --git a/pypy/interpreter/test/test_pyframe.py
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -516,3 +516,21 @@
assert seen == [(1, f, firstline + 6, 'line', None),
(1, f, firstline + 7, 'line', None),
(1, f, firstline + 8, 'line', None)]
+
+ def test_locals2fast_freevar_bug(self):
+ import sys
+ def f(n):
+ class A(object):
+ def g(self):
+ return n
+ n = 42
+ return A()
+ res = f(10).g()
+ assert res == 10
+ #
+ def trace(*args):
+ return trace
+ sys.settrace(trace)
+ res = f(10).g()
+ sys.settrace(None)
+ assert res == 10
diff --git a/pypy/module/__pypy__/interp_time.py
b/pypy/module/__pypy__/interp_time.py
--- a/pypy/module/__pypy__/interp_time.py
+++ b/pypy/module/__pypy__/interp_time.py
@@ -1,7 +1,7 @@
from __future__ import with_statement
import sys
-from pypy.interpreter.error import exception_from_errno
+from pypy.interpreter.error import exception_from_saved_errno
from pypy.interpreter.gateway import unwrap_spec
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rtyper.tool import rffi_platform
@@ -48,11 +48,13 @@
c_clock_gettime = rffi.llexternal("clock_gettime",
[lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
- compilation_info=CConfig._compilation_info_, releasegil=False
+ compilation_info=CConfig._compilation_info_, releasegil=False,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
c_clock_getres = rffi.llexternal("clock_getres",
[lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
- compilation_info=CConfig._compilation_info_, releasegil=False
+ compilation_info=CConfig._compilation_info_, releasegil=False,
+ save_err=rffi.RFFI_SAVE_ERRNO
)
@unwrap_spec(clk_id="c_int")
@@ -60,7 +62,7 @@
with lltype.scoped_alloc(TIMESPEC) as tp:
ret = c_clock_gettime(clk_id, tp)
if ret != 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(int(tp.c_tv_sec) + 1e-9 * int(tp.c_tv_nsec))
@unwrap_spec(clk_id="c_int")
@@ -68,5 +70,5 @@
with lltype.scoped_alloc(TIMESPEC) as tp:
ret = c_clock_getres(clk_id, tp)
if ret != 0:
- raise exception_from_errno(space, space.w_IOError)
+ raise exception_from_saved_errno(space, space.w_IOError)
return space.wrap(int(tp.c_tv_sec) + 1e-9 * int(tp.c_tv_nsec))
diff --git a/pypy/module/_cffi_backend/ccallback.py
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -160,7 +160,7 @@
@jit.jit_callback("CFFI")
-def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
+def _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
""" Callback specification.
ffi_cif - something ffi specific, don't care
ll_args - rffi.VOIDPP - pointer to array of pointers to args
@@ -168,7 +168,6 @@
ll_userdata - a special structure which holds necessary information
(what the real callback is for example), casted to VOIDP
"""
- e = cerrno.get_real_errno()
ll_res = rffi.cast(rffi.CCHARP, ll_res)
unique_id = rffi.cast(lltype.Signed, ll_userdata)
callback = global_callback_mapping.get(unique_id)
@@ -185,12 +184,9 @@
return
#
must_leave = False
- ec = None
space = callback.space
try:
must_leave = space.threadlocals.try_enter_thread(space)
- ec = cerrno.get_errno_container(space)
- cerrno.save_errno_into(ec, e)
extra_line = ''
try:
w_res = callback.invoke(ll_args)
@@ -212,5 +208,8 @@
callback.write_error_return_value(ll_res)
if must_leave:
space.threadlocals.leave_thread(space)
- if ec is not None:
- cerrno.restore_errno_from(ec)
+
+def invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata):
+ cerrno._errno_after(rffi.RFFI_ERR_ALL)
+ _invoke_callback(ffi_cif, ll_res, ll_args, ll_userdata)
+ cerrno._errno_before(rffi.RFFI_ERR_ALL)
diff --git a/pypy/module/_cffi_backend/cerrno.py
b/pypy/module/_cffi_backend/cerrno.py
--- a/pypy/module/_cffi_backend/cerrno.py
+++ b/pypy/module/_cffi_backend/cerrno.py
@@ -2,7 +2,6 @@
from rpython.rlib import rposix
-from pypy.interpreter.executioncontext import ExecutionContext
from pypy.interpreter.gateway import unwrap_spec
WIN32 = sys.platform == 'win32'
@@ -10,43 +9,22 @@
from rpython.rlib import rwin32
-ExecutionContext._cffi_saved_errno = 0
-ExecutionContext._cffi_saved_LastError = 0
-
-
-def get_errno_container(space):
- return space.getexecutioncontext()
-
-get_real_errno = rposix.get_errno
-
-
-def restore_errno_from(ec):
- if WIN32:
- rwin32.SetLastError(ec._cffi_saved_LastError)
- rposix.set_errno(ec._cffi_saved_errno)
-
-def save_errno_into(ec, errno):
- ec._cffi_saved_errno = errno
- if WIN32:
- ec._cffi_saved_LastError = rwin32.GetLastError()
-
+_errno_before = rposix._errno_before
+_errno_after = rposix._errno_after
def get_errno(space):
- ec = get_errno_container(space)
- return space.wrap(ec._cffi_saved_errno)
+ return space.wrap(rposix.get_saved_errno())
@unwrap_spec(errno=int)
def set_errno(space, errno):
- ec = get_errno_container(space)
- ec._cffi_saved_errno = errno
+ rposix.set_saved_errno(errno)
# ____________________________________________________________
@unwrap_spec(code=int)
def getwinerror(space, code=-1):
- from rpython.rlib.rwin32 import FormatError
+ from rpython.rlib.rwin32 import GetLastError_saved, FormatError
if code == -1:
- ec = get_errno_container(space)
- code = ec._cffi_saved_LastError
+ code = GetLastError_saved()
message = FormatError(code)
return space.newtuple([space.wrap(code), space.wrap(message)])
diff --git a/pypy/module/_cffi_backend/ctypefunc.py
b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -155,13 +155,9 @@
# argtype is a pointer type, and w_obj a list/tuple/str
mustfree_max_plus_1 = i + 1
- ec = cerrno.get_errno_container(space)
- cerrno.restore_errno_from(ec)
jit_libffi.jit_ffi_call(cif_descr,
rffi.cast(rffi.VOIDP, funcaddr),
buffer)
- e = cerrno.get_real_errno()
- cerrno.save_errno_into(ec, e)
resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
w_res = self.ctitem.copy_and_convert_to_object(resultdata)
diff --git a/pypy/module/_cffi_backend/ctypeptr.py
b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -347,7 +347,8 @@
# ____________________________________________________________
-rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP)
+rffi_fdopen = rffi.llexternal("fdopen", [rffi.INT, rffi.CCHARP], rffi.CCHARP,
+ save_err=rffi.RFFI_SAVE_ERRNO)
rffi_setbuf = rffi.llexternal("setbuf", [rffi.CCHARP, rffi.CCHARP],
lltype.Void)
rffi_fclose = rffi.llexternal("fclose", [rffi.CCHARP], rffi.INT)
@@ -357,7 +358,7 @@
def __init__(self, fd, mode):
self.llf = rffi_fdopen(fd, mode)
if not self.llf:
- raise OSError(rposix.get_errno(), "fdopen failed")
+ raise OSError(rposix.get_saved_errno(), "fdopen failed")
rffi_setbuf(self.llf, lltype.nullptr(rffi.CCHARP.TO))
def close(self):
diff --git a/pypy/module/_io/interp_bufferedio.py
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -19,10 +19,16 @@
def make_write_blocking_error(space, written):
+ # XXX CPython reads 'errno' here. I *think* it doesn't make sense,
+ # because we might reach this point after calling a write() method
+ # that may be overridden by the user, if that method returns None.
+ # In that case what we get is a potentially nonsense errno. But
+ # we'll use get_saved_errno() anyway, and hope (like CPython does)
+ # that we're getting a reasonable value at this point.
w_type = space.gettypeobject(W_BlockingIOError.typedef)
w_value = space.call_function(
w_type,
- space.wrap(rposix.get_errno()),
+ space.wrap(rposix.get_saved_errno()),
space.wrap("write could not complete without blocking"),
space.wrap(written))
return OperationError(w_type, w_value)
diff --git a/pypy/module/_locale/interp_locale.py
b/pypy/module/_locale/interp_locale.py
--- a/pypy/module/_locale/interp_locale.py
+++ b/pypy/module/_locale/interp_locale.py
@@ -300,7 +300,8 @@
return space.wrap(result)
_bindtextdomain = rlocale.external('bindtextdomain', [rffi.CCHARP,
rffi.CCHARP],
- rffi.CCHARP)
+ rffi.CCHARP,
+ save_err=rffi.RFFI_SAVE_ERRNO)
@unwrap_spec(domain=str)
def bindtextdomain(space, domain, w_dir):
@@ -325,7 +326,7 @@
rffi.free_charp(dir_c)
if not dirname:
- errno = rposix.get_errno()
+ errno = rposix.get_saved_errno()
raise OperationError(space.w_OSError, space.wrap(errno))
return space.wrap(rffi.charp2str(dirname))
diff --git a/pypy/module/_multiprocessing/interp_connection.py
b/pypy/module/_multiprocessing/interp_connection.py
--- a/pypy/module/_multiprocessing/interp_connection.py
+++ b/pypy/module/_multiprocessing/interp_connection.py
@@ -406,7 +406,7 @@
size, written_ptr, rffi.NULL)
if (result == 0 and
- rwin32.GetLastError() == ERROR_NO_SYSTEM_RESOURCES):
+ rwin32.GetLastError_saved() == ERROR_NO_SYSTEM_RESOURCES):
raise oefmt(space.w_ValueError,
"Cannot send %d bytes over connection", size)
finally:
@@ -430,7 +430,7 @@
if result:
return intmask(read_ptr[0]), lltype.nullptr(rffi.CCHARP.TO)
- err = rwin32.GetLastError()
+ err = rwin32.GetLastError_saved()
if err == ERROR_BROKEN_PIPE:
raise OperationError(space.w_EOFError, space.w_None)
elif err != ERROR_MORE_DATA:
@@ -441,7 +441,7 @@
lltype.nullptr(rwin32.LPDWORD.TO),
lltype.nullptr(rwin32.LPDWORD.TO),
left_ptr):
- raise wrap_windowserror(space, rwin32.lastWindowsError())
+ raise wrap_windowserror(space, rwin32.lastSavedWindowsError())
length = intmask(read_ptr[0] + left_ptr[0])
if length > maxlength: # bad message, close connection
@@ -460,7 +460,7 @@
read_ptr, rffi.NULL)
if not result:
rffi.free_charp(newbuf)
- raise wrap_windowserror(space, rwin32.lastWindowsError())
+ raise wrap_windowserror(space, rwin32.lastSavedWindowsError())
assert read_ptr[0] == left_ptr[0]
return length, newbuf
@@ -480,7 +480,7 @@
lltype.nullptr(rwin32.LPDWORD.TO),
bytes_ptr,
lltype.nullptr(rwin32.LPDWORD.TO)):
- raise wrap_windowserror(space, rwin32.lastWindowsError())
+ raise wrap_windowserror(space, rwin32.lastSavedWindowsError())
bytes = bytes_ptr[0]
finally:
lltype.free(bytes_ptr, flavor='raw')
@@ -506,7 +506,8 @@
lltype.nullptr(rwin32.LPDWORD.TO),
bytes_ptr,
lltype.nullptr(rwin32.LPDWORD.TO)):
- raise wrap_windowserror(space, rwin32.lastWindowsError())
+ raise wrap_windowserror(space,
+ rwin32.lastSavedWindowsError())
bytes = bytes_ptr[0]
finally:
lltype.free(bytes_ptr, flavor='raw')
diff --git a/pypy/module/_multiprocessing/interp_semaphore.py
b/pypy/module/_multiprocessing/interp_semaphore.py
--- a/pypy/module/_multiprocessing/interp_semaphore.py
+++ b/pypy/module/_multiprocessing/interp_semaphore.py
@@ -26,12 +26,14 @@
_CreateSemaphore = rwin32.winexternal(
'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR],
- rwin32.HANDLE)
- _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE],
+ rwin32.HANDLE,
+ save_err=rffi.RFFI_FULL_LASTERROR)
+ _CloseHandle_no_errno = rwin32.winexternal('CloseHandle', [rwin32.HANDLE],
rwin32.BOOL, releasegil=False)
_ReleaseSemaphore = rwin32.winexternal(
'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP],
- rwin32.BOOL)
+ rwin32.BOOL,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
else:
from rpython.rlib import rposix
@@ -81,51 +83,61 @@
_sem_open = external('sem_open',
[rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT],
- SEM_T)
+ SEM_T, save_err=rffi.RFFI_SAVE_ERRNO)
# sem_close is releasegil=False to be able to use it in the __del__
- _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False)
- _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT)
- _sem_wait = external('sem_wait', [SEM_T], rffi.INT)
- _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT)
- _sem_post = external('sem_post', [SEM_T], rffi.INT)
- _sem_getvalue = external('sem_getvalue', [SEM_T, rffi.INTP], rffi.INT)
+ _sem_close_no_errno = external('sem_close', [SEM_T], rffi.INT,
+ releasegil=False)
+ _sem_close = external('sem_close', [SEM_T], rffi.INT, releasegil=False,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ _sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ _sem_wait = external('sem_wait', [SEM_T], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ _sem_trywait = external('sem_trywait', [SEM_T], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ _sem_post = external('sem_post', [SEM_T], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
+ _sem_getvalue = external('sem_getvalue', [SEM_T, rffi.INTP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
- _gettimeofday = external('gettimeofday', [TIMEVALP, rffi.VOIDP], rffi.INT)
+ _gettimeofday = external('gettimeofday', [TIMEVALP, rffi.VOIDP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
_select = external('select', [rffi.INT, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP,
- TIMEVALP], rffi.INT)
+ TIMEVALP], rffi.INT,
+ save_err=rffi.RFFI_SAVE_ERRNO)
@jit.dont_look_inside
def sem_open(name, oflag, mode, value):
res = _sem_open(name, oflag, mode, value)
if res == rffi.cast(SEM_T, SEM_FAILED):
- raise OSError(rposix.get_errno(), "sem_open failed")
+ raise OSError(rposix.get_saved_errno(), "sem_open failed")
return res
def sem_close(handle):
res = _sem_close(handle)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_close failed")
+ raise OSError(rposix.get_saved_errno(), "sem_close failed")
def sem_unlink(name):
res = _sem_unlink(name)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_unlink failed")
+ raise OSError(rposix.get_saved_errno(), "sem_unlink failed")
def sem_wait(sem):
res = _sem_wait(sem)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_wait failed")
+ raise OSError(rposix.get_saved_errno(), "sem_wait failed")
def sem_trywait(sem):
res = _sem_trywait(sem)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_trywait failed")
+ raise OSError(rposix.get_saved_errno(), "sem_trywait failed")
def sem_timedwait(sem, deadline):
res = _sem_timedwait(sem, deadline)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_timedwait failed")
+ raise OSError(rposix.get_saved_errno(), "sem_timedwait failed")
def _sem_timedwait_save(sem, deadline):
delay = 0
@@ -135,7 +147,7 @@
# poll
if _sem_trywait(sem) == 0:
return 0
- elif rposix.get_errno() != errno.EAGAIN:
+ elif rposix.get_saved_errno() != errno.EAGAIN:
return -1
now = gettimeofday()
@@ -143,7 +155,7 @@
c_tv_nsec = rffi.getintfield(deadline[0], 'c_tv_nsec')
if (c_tv_sec < now[0] or
(c_tv_sec == now[0] and c_tv_nsec <= now[1])):
- rposix.set_errno(errno.ETIMEDOUT)
+ rposix.set_saved_errno(errno.ETIMEDOUT)
return -1
@@ -166,21 +178,21 @@
if SEM_TIMED_WAIT:
_sem_timedwait = external('sem_timedwait', [SEM_T, TIMESPECP],
- rffi.INT)
+ rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO)
else:
_sem_timedwait = _sem_timedwait_save
def sem_post(sem):
res = _sem_post(sem)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_post failed")
+ raise OSError(rposix.get_saved_errno(), "sem_post failed")
def sem_getvalue(sem):
sval_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
try:
res = _sem_getvalue(sem, sval_ptr)
if res < 0:
- raise OSError(rposix.get_errno(), "sem_getvalue failed")
+ raise OSError(rposix.get_saved_errno(), "sem_getvalue failed")
return rffi.cast(lltype.Signed, sval_ptr[0])
finally:
lltype.free(sval_ptr, flavor='raw')
@@ -190,7 +202,7 @@
try:
res = _gettimeofday(now, None)
if res < 0:
- raise OSError(rposix.get_errno(), "gettimeofday failed")
+ raise OSError(rposix.get_saved_errno(), "gettimeofday failed")
return (rffi.getintfield(now[0], 'c_tv_sec'),
rffi.getintfield(now[0], 'c_tv_usec'))
finally:
@@ -216,18 +228,16 @@
if sys.platform == 'win32':
def create_semaphore(space, name, val, max):
- rwin32.SetLastError(0)
+ rwin32.SetLastError_saved(0)
handle = _CreateSemaphore(rffi.NULL, val, max, rffi.NULL)
# On Windows we should fail on ERROR_ALREADY_EXISTS
- err = rwin32.GetLastError()
+ err = rwin32.GetLastError_saved()
if err != 0:
raise WindowsError(err, "CreateSemaphore")
return handle
def delete_semaphore(handle):
- if not _CloseHandle(handle):
- err = rwin32.GetLastError()
- raise WindowsError(err, "CloseHandle")
+ _CloseHandle_no_errno(handle)
def semlock_acquire(self, space, block, w_timeout):
if not block:
@@ -286,7 +296,7 @@
def semlock_release(self, space):
if not _ReleaseSemaphore(self.handle, 1,
lltype.nullptr(rffi.LONGP.TO)):
- err = rwin32.GetLastError()
+ err = rwin32.GetLastError_saved()
if err == 0x0000012a: # ERROR_TOO_MANY_POSTS
raise OperationError(
space.w_ValueError,
@@ -300,7 +310,7 @@
previous_ptr = lltype.malloc(rffi.LONGP.TO, 1, flavor='raw')
try:
if not _ReleaseSemaphore(self.handle, 1, previous_ptr):
- raise rwin32.lastWindowsError("ReleaseSemaphore")
+ raise rwin32.lastSavedWindowsError("ReleaseSemaphore")
return previous_ptr[0] + 1
finally:
lltype.free(previous_ptr, flavor='raw')
@@ -320,7 +330,7 @@
return sem
def delete_semaphore(handle):
- sem_close(handle)
+ _sem_close_no_errno(handle)
def semlock_acquire(self, space, block, w_timeout):
if not block:
diff --git a/pypy/module/_multiprocessing/interp_win32.py
b/pypy/module/_multiprocessing/interp_win32.py
--- a/pypy/module/_multiprocessing/interp_win32.py
+++ b/pypy/module/_multiprocessing/interp_win32.py
@@ -41,20 +41,24 @@
rwin32.DWORD, rwin32.DWORD, rwin32.DWORD,
rwin32.DWORD, rwin32.DWORD, rwin32.DWORD,
rffi.VOIDP],
- rwin32.HANDLE)
+ rwin32.HANDLE,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
_ConnectNamedPipe = rwin32.winexternal(
- 'ConnectNamedPipe', [rwin32.HANDLE, rffi.VOIDP], rwin32.BOOL)
+ 'ConnectNamedPipe', [rwin32.HANDLE, rffi.VOIDP], rwin32.BOOL,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
_SetNamedPipeHandleState = rwin32.winexternal(
'SetNamedPipeHandleState', [
rwin32.HANDLE,
rwin32.LPDWORD, rwin32.LPDWORD, rwin32.LPDWORD],
- rwin32.BOOL)
+ rwin32.BOOL,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
_WaitNamedPipe = rwin32.winexternal(
'WaitNamedPipeA', [rwin32.LPCSTR, rwin32.DWORD],
- rwin32.BOOL)
+ rwin32.BOOL,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
_PeekNamedPipe = rwin32.winexternal(
'PeekNamedPipe', [
@@ -62,31 +66,36 @@
rffi.VOIDP,
rwin32.DWORD,
rwin32.LPDWORD, rwin32.LPDWORD, rwin32.LPDWORD],
- rwin32.BOOL)
+ rwin32.BOOL,
+ save_err=rffi.RFFI_SAVE_LASTERROR)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit