[pypy-commit] extradoc extradoc: PEP 475 done

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r5758:8bbdf2ea8e81
Date: 2016-12-05 08:52 +0100
http://bitbucket.org/pypy/extradoc/changeset/8bbdf2ea8e81/

Log:PEP 475 done

diff --git a/planning/py3.5/cpython-crashers.rst 
b/planning/py3.5/cpython-crashers.rst
--- a/planning/py3.5/cpython-crashers.rst
+++ b/planning/py3.5/cpython-crashers.rst
@@ -234,3 +234,8 @@
 * if you write ``from .a import b`` inside the Python prompt, or in
   a module not in any package, then you get a SystemError(!) with an
   error message that is unlikely to help newcomers.
+
+* pep 475: unclear why 'os.fchmod(fd)' retries automatically when
+  it gets EINTR but the otherwise-equivalent 'os.chmod(fd)' does not.
+  (The documentation says they are fully equivalent, so someone is
+  wrong.)
diff --git a/planning/py3.5/milestone-1-progress.rst 
b/planning/py3.5/milestone-1-progress.rst
--- a/planning/py3.5/milestone-1-progress.rst
+++ b/planning/py3.5/milestone-1-progress.rst
@@ -37,7 +37,7 @@
 * "except pyopcode.Return:" in pyframe can't be there, because that's
   outside the JIT and it gives terrible performance
   
-* PEP 475: Retry system calls failing with EINTR
+* PEP 475: Retry system calls failing with EINTR (DONE)
 
 * ast compiler: clean up POP_EXCEPT: either remove them, or use it to clean up
   the "finally: name = None; del name" nonsense at the end of any except block
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: Py3.5 always adds these three names to all new modules (thanks Tiberium)

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5
Changeset: r8:5e500ed90cd8
Date: 2016-12-04 23:30 +0100
http://bitbucket.org/pypy/pypy/changeset/5e500ed90cd8/

Log:Py3.5 always adds these three names to all new modules (thanks
Tiberium)

diff --git a/pypy/interpreter/module.py b/pypy/interpreter/module.py
--- a/pypy/interpreter/module.py
+++ b/pypy/interpreter/module.py
@@ -22,11 +22,9 @@
 self.w_name = w_name
 if w_name is not None:
 space.setitem(w_dict, space.new_interned_str('__name__'), w_name)
-if add_package:
-# add the __package__ attribute only when created from internal
-# code, but not when created from Python code (as in CPython)
-space.setitem(w_dict, space.new_interned_str('__package__'),
-  space.w_None)
+# add these three attributes always ('add_package' is no longer used)
+for extra in ['__package__', '__loader__', '__spec__']:
+space.setitem(w_dict, space.new_interned_str(extra), space.w_None)
 self.startup_called = False
 
 def _cleanup_(self):
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
@@ -181,7 +181,7 @@
 
 assert sys.__package__ == ''
 assert os.__package__ == ''
-assert not hasattr(type(sys)('foo'), '__package__')
+assert type(sys)('foo').__package__ is None
 
 def test_name_nonascii(self):
 import sys
@@ -206,3 +206,12 @@
 def test_weakrefable(self):
 import weakref
 weakref.ref(weakref)
+
+def test_all_dict_content(self):
+import sys
+m = type(sys)('foo')
+assert m.__dict__ == {'__name__': 'foo',
+  '__doc__': None,
+  '__package__': None,
+  '__loader__': None,
+  '__spec__': None}
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: Test and fix

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5
Changeset: r6:2b00c209938d
Date: 2016-12-04 22:00 +0100
http://bitbucket.org/pypy/pypy/changeset/2b00c209938d/

Log:Test and fix

diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -90,11 +90,15 @@
 as_int = bigint.toint()
 except OverflowError:
 from pypy.objspace.std.longobject import newbigint
+if space.is_w(w_inttype, space.w_bool):
+return space.w_True  # extremely obscure case
 return newbigint(space, w_inttype, bigint)
 else:
 if space.is_w(w_inttype, space.w_int):
 # common case
 return wrapint(space, as_int)
+if space.is_w(w_inttype, space.w_bool):
+return space.newbool(as_int) # extremely obscure case
 w_obj = space.allocate_instance(W_IntObject, w_inttype)
 W_IntObject.__init__(w_obj, as_int)
 return w_obj
diff --git a/pypy/objspace/std/test/test_boolobject.py 
b/pypy/objspace/std/test/test_boolobject.py
--- a/pypy/objspace/std/test/test_boolobject.py
+++ b/pypy/objspace/std/test/test_boolobject.py
@@ -84,3 +84,7 @@
 def __bool__(self):
 return 1
 raises(TypeError, bool, Spam())
+
+def test_from_bytes(self):
+assert bool.from_bytes(b"", 'little') is False
+assert bool.from_bytes(b"dasijldjs" * 157, 'little') is True
diff --git a/pypy/objspace/std/test/test_intobject.py 
b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -607,6 +607,16 @@
 assert int(bytearray(b'100'), 2) == 4
 raises(TypeError, int, memoryview(b'100'), 2)
 
+def test_from_bytes(self):
+class X(int):
+pass
+x = X.from_bytes(b"", 'little')
+assert type(x) is X and x == 0
+x = X.from_bytes(b"*" * 100, 'little')
+assert type(x) is X
+expected = sum(256 ** i for i in range(100))
+assert x == expected * ord('*')
+
 
 class AppTestIntShortcut(AppTestInt):
 spaceconfig = {"objspace.std.intshortcut": True}
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: fix?

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5
Changeset: r7:ea86f82696e3
Date: 2016-12-04 22:03 +0100
http://bitbucket.org/pypy/pypy/changeset/ea86f82696e3/

Log:fix?

diff --git a/lib-python/3/test/test_ordered_dict.py 
b/lib-python/3/test/test_ordered_dict.py
--- a/lib-python/3/test/test_ordered_dict.py
+++ b/lib-python/3/test/test_ordered_dict.py
@@ -12,7 +12,7 @@
 
 
 py_coll = support.import_fresh_module('collections', blocked=['_collections'])
-c_coll = import_fresh_module('_collections', fresh=['_collections'])
+c_coll = support.import_fresh_module('_collections', fresh=['_collections'])
 
 
 @contextlib.contextmanager
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: close branch, ready to merge

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r4:7c7067888d91
Date: 2016-12-04 21:43 +0100
http://bitbucket.org/pypy/pypy/changeset/7c7067888d91/

Log:close branch, ready to merge

___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5: hg merge py3.5-eintr-pep475

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5
Changeset: r5:b5eaea946a6b
Date: 2016-12-04 21:44 +0100
http://bitbucket.org/pypy/pypy/changeset/b5eaea946a6b/

Log:hg merge py3.5-eintr-pep475

Implement PEP475, which makes a number of os-, file-, select- and
socket-related functions no longer raise OSError/IOError on getting
EINTR, but instead automatically retry.

There are a few functions mentioned in the PEP too which are not
present in PyPy so far.

diff too long, truncating to 2000 out of 2118 lines

diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py
--- a/lib_pypy/_pypy_wait.py
+++ b/lib_pypy/_pypy_wait.py
@@ -1,3 +1,5 @@
+import os
+from errno import EINTR
 from resource import ffi, lib, _make_struct_rusage
 
 __all__ = ["wait3", "wait4"]
@@ -6,7 +8,13 @@
 def wait3(options):
 status = ffi.new("int *")
 ru = ffi.new("struct rusage *")
-pid = lib.wait3(status, options, ru)
+while True:
+pid = lib.wait3(status, options, ru)
+if pid != -1:
+break
+errno = ffi.errno
+if errno != EINTR:
+raise OSError(errno, os.strerror(errno))
 
 rusage = _make_struct_rusage(ru)
 
@@ -15,7 +23,13 @@
 def wait4(pid, options):
 status = ffi.new("int *")
 ru = ffi.new("struct rusage *")
-pid = lib.wait4(pid, status, options, ru)
+while True:
+pid = lib.wait4(pid, status, options, ru)
+if pid != -1:
+break
+errno = ffi.errno
+if errno != EINTR:
+raise OSError(errno, os.strerror(errno))
 
 rusage = _make_struct_rusage(ru)
 
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -543,6 +543,7 @@
 _WINDOWS = True
 
 def wrap_windowserror(space, e, w_filename=None):
+XXX# WindowsError no longer exists in Py3.5
 from rpython.rlib import rwin32
 
 winerror = e.winerror
@@ -559,43 +560,72 @@
   space.wrap(msg))
 return OperationError(exc, w_error)
 
-@specialize.arg(3)
+@specialize.arg(3, 6)
 def wrap_oserror2(space, e, w_filename=None, exception_name='w_OSError',
-  w_exception_class=None, w_filename2=None):
+  w_exception_class=None, w_filename2=None, eintr_retry=False):
+"""A double API here:
+
+* if eintr_retry is False, always return the OperationError to
+  be raised by the caller.  It can possibly be about EINTR
+  (checksignals() is still called here).
+
+* if eintr_retry is True (PEP 475 compliant API for retrying
+  system calls failing with EINTR), then this function raises
+  the OperationError directly, or for EINTR it calls
+  checksignals() and returns None in case the original
+  operation should be retried.
+"""
 assert isinstance(e, OSError)
 
 if _WINDOWS and isinstance(e, WindowsError):
 return wrap_windowserror(space, e, w_filename)
 
+if w_exception_class is None:
+w_exc = getattr(space, exception_name)
+else:
+w_exc = w_exception_class
+operror = _wrap_oserror2_impl(space, e, w_filename, w_filename2, w_exc,
+  eintr_retry)
+if eintr_retry:
+assert operror is None   # otherwise, _wrap_oserror2_impl() has raised
+else:
+assert operror is not None   # tell the annotator we don't return None
+return operror
+
+def _wrap_oserror2_impl(space, e, w_filename, w_filename2, w_exc, eintr_retry):
+# move the common logic in its own function, instead of having it
+# duplicated 4 times in all 4 specialized versions of wrap_oserror2()
 errno = e.errno
 
 if errno == EINTR:
 space.getexecutioncontext().checksignals()
+if eintr_retry:
+return None
 
 try:
 msg = strerror(errno)
 except ValueError:
 msg = u'error %d' % errno
-if w_exception_class is None:
-exc = getattr(space, exception_name)
-else:
-exc = w_exception_class
 if w_filename is not None:
 if w_filename2 is not None:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg), w_filename,
   space.w_None, w_filename2)
 else:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg), w_filename)
 else:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg))
-return OperationError(exc, w_error)
+operror = OperationError(w_exc, 

[pypy-commit] pypy missing-tp_new: move tests and add one for tp_hash

2016-12-04 Thread mattip
Author: Matti Picus 
Branch: missing-tp_new
Changeset: r1:7fe5dcdd537f
Date: 2016-11-26 21:06 +0200
http://bitbucket.org/pypy/pypy/changeset/7fe5dcdd537f/

Log:move tests and add one for tp_hash

diff --git a/pypy/module/cpyext/test/test_typeobject.py 
b/pypy/module/cpyext/test/test_typeobject.py
--- a/pypy/module/cpyext/test/test_typeobject.py
+++ b/pypy/module/cpyext/test/test_typeobject.py
@@ -452,48 +452,6 @@
 ref = make_ref(space, w_obj)
 api.Py_DecRef(ref)
 
-def test_nb_add_from_python(self, space, api):
-w_date = space.appexec([], """():
-class DateType(object):
-def __add__(self, other):
-return 'sum!'
-return DateType()
-""")
-w_datetype = space.type(w_date)
-py_date = make_ref(space, w_date)
-py_datetype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_datetype))
-assert py_datetype.c_tp_as_number
-assert py_datetype.c_tp_as_number.c_nb_add
-w_obj = generic_cpy_call(space, py_datetype.c_tp_as_number.c_nb_add,
- py_date, py_date)
-assert space.str_w(w_obj) == 'sum!'
-
-def test_tp_new_from_python(self, space, api):
-w_date = space.appexec([], """():
-class Date(object):
-def __new__(cls, year, month, day):
-self = object.__new__(cls)
-self.year = year
-self.month = month
-self.day = day
-return self
-return Date
-""")
-py_datetype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_date))
-one = space.newint(1)
-arg = space.newtuple([one, one, one])
-# call w_date.__new__
-w_obj = space.call_function(w_date, one, one, one)
-w_year = space.getattr(w_obj, space.newbytes('year'))
-assert space.int_w(w_year) == 1
-
-# currently fails with "object() takse no parameters,
-# from the tp_new of space.w_object
-w_obj = generic_cpy_call(space, py_datetype.c_tp_new, py_datetype, 
- arg, space.newdict({}))
-w_year = space.getattr(w_obj, space.newbytes('year'))
-assert space.int_w(w_year) == 1
-
 class AppTestSlots(AppTestCpythonExtensionBase):
 def setup_class(cls):
 AppTestCpythonExtensionBase.setup_class.im_func(cls)
diff --git a/pypy/module/cpyext/test/test_userslots.py 
b/pypy/module/cpyext/test/test_userslots.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_userslots.py
@@ -0,0 +1,63 @@
+from pypy.module.cpyext.test.test_api import BaseApiTest
+from rpython.rtyper.lltypesystem import rffi
+from pypy.module.cpyext.pyobject import make_ref, from_ref
+from pypy.module.cpyext.api import generic_cpy_call
+from pypy.module.cpyext.typeobject import PyTypeObjectPtr
+
+
+class TestAppLevelObject(BaseApiTest):
+def test_nb_add_from_python(self, space, api):
+w_date = space.appexec([], """():
+class DateType(object):
+def __add__(self, other):
+return 'sum!'
+return DateType()
+""")
+w_datetype = space.type(w_date)
+py_date = make_ref(space, w_date)
+py_datetype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_datetype))
+assert py_datetype.c_tp_as_number
+assert py_datetype.c_tp_as_number.c_nb_add
+w_obj = generic_cpy_call(space, py_datetype.c_tp_as_number.c_nb_add,
+ py_date, py_date)
+assert space.str_w(w_obj) == 'sum!'
+
+def test_tp_hash_from_python(self, space, api):
+w_c = space.appexec([], """():
+class C:
+def __hash__(self):
+return -23
+return C()
+""")
+w_ctype = space.type(w_c)
+py_c = make_ref(space, w_c)
+py_ctype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_ctype))
+assert py_ctype.c_tp_hash
+val = generic_cpy_call(space, py_ctype.c_tp_hash, py_c)
+assert val == -23
+
+def test_tp_new_from_python(self, space, api):
+w_date = space.appexec([], """():
+class Date(object):
+def __new__(cls, year, month, day):
+self = object.__new__(cls)
+self.year = year
+self.month = month
+self.day = day
+return self
+return Date
+""")
+py_datetype = rffi.cast(PyTypeObjectPtr, make_ref(space, w_date))
+one = space.newint(1)
+arg = space.newtuple([one, one, one])
+# call w_date.__new__
+w_obj = space.call_function(w_date, one, one, one)
+w_year = space.getattr(w_obj, space.newbytes('year'))
+assert space.int_w(w_year) == 1
+
+w_obj = generic_cpy_call(space, 

[pypy-commit] pypy missing-tp_new: change algo to fish the function to call, still ininitely recurses on pandas' Timestamp class

2016-12-04 Thread mattip
Author: Matti Picus 
Branch: missing-tp_new
Changeset: r2:cea545b4e5bc
Date: 2016-11-28 22:32 +0200
http://bitbucket.org/pypy/pypy/changeset/cea545b4e5bc/

Log:change algo to fish the function to call, still ininitely recurses
on pandas' Timestamp class

diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -504,18 +504,24 @@
 this_func_ptr = llhelper(subtype_dealloc.api_func.functype,
 subtype_dealloc.api_func.get_wrapper(space))
 w_obj = from_ref(space, rffi.cast(PyObject, base))
-obj_not_cpytype = not w_obj.is_cpytype()
-# see comment in userslot.slot_tp_new, this call can infinitely recurse
-# We can only get into this function if tp_dealloc is being called on 
-# a non-cpytype, which could or could not inherit from a cpytype
-# So if the original obj is non-cpytype, climb the mro to the first 
non-cpytype,
-# otherwise just make sure we are not calling ourselves again
-#
-# This logic might fail for complicated inheritance schemes.
-while base.c_tp_dealloc == this_func_ptr or (obj_not_cpytype and 
w_obj.is_cpytype()):
+# This wrapper is created on a specific type, call it w_A. 
+# We wish to call the dealloc function from one of the base classes of w_A,
+# the first of which is not this function itself.
+# w_obj is an instance of w_A or one of its subclasses. So climb up the
+# inheritance chain until base.c_tp_dealloc is exactly this_func, and then
+# continue on up until they differ.
+print 'subtype_dealloc, start from', rffi.charp2str(base)
+while base.c_tp_dealloc != this_func_ptr:
 base = base.c_tp_base
 assert base
+print ' ne move to', rffi.charp2str(base)
 w_obj = from_ref(space, rffi.cast(PyObject, base))
+while base.c_tp_dealloc == this_func_ptr:
+base = base.c_tp_base
+assert base
+print ' eq move to', rffi.charp2str(base)
+w_obj = from_ref(space, rffi.cast(PyObject, base))
+print '   end with', rffi.charp2str(base)
 dealloc = base.c_tp_dealloc
 # XXX call tp_del if necessary
 generic_cpy_call(space, dealloc, obj)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy better-PyDict_Next: try to identify and convert a GetSetProperty to a W_GetSetPropertyEx

2016-12-04 Thread mattip
Author: Matti Picus 
Branch: better-PyDict_Next
Changeset: r3:e012751a80df
Date: 2016-12-04 22:25 +0200
http://bitbucket.org/pypy/pypy/changeset/e012751a80df/

Log:try to identify and convert a GetSetProperty to a W_GetSetPropertyEx

diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -1,4 +1,8 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rlib.objectmodel import specialize
+from pypy.interpreter.error import OperationError
+from pypy.objspace.std.classdict import ClassDictStrategy
+from pypy.interpreter.typedef import GetSetProperty
 from pypy.module.cpyext.api import (
 cpython_api, CANNOT_FAIL, build_type_checkers, Py_ssize_t,
 Py_ssize_tP, CONST_STRING, PyObjectFields, cpython_struct,
@@ -7,8 +11,7 @@
 make_typedescr, track_reference, create_ref, from_ref, Py_DecRef,
 Py_IncRef)
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
-from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import specialize
+from pypy.module.cpyext.typeobject import W_GetSetPropertyEx
 
 PyDictObjectStruct = lltype.ForwardReference()
 PyDictObject = lltype.Ptr(PyDictObjectStruct)
@@ -258,6 +261,10 @@
 return 0
 w_key = space.listview(w_keys)[pos]
 w_value = space.getitem(w_dict, w_key)
+if isinstance(w_value, GetSetProperty):
+# XXX doesn't quite work, need to convert GetSetProperty
+# to PyGetSetDef, with c_name, c_get, c_set, c_doc, c_closure
+w_value = W_GetSetPropertyEx(w_value, w_dict.dstorage._x)
 if pkey:
 pkey[0]   = as_pyobj(space, w_key)
 if pvalue:
diff --git a/pypy/module/cpyext/test/test_dictobject.py 
b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -1,7 +1,7 @@
 import py
 from rpython.rtyper.lltypesystem import rffi, lltype
 from pypy.module.cpyext.test.test_api import BaseApiTest
-from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP
+from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP, PyTypeObjectPtr
 from pypy.module.cpyext.pyobject import make_ref, from_ref
 from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
@@ -182,8 +182,8 @@
 assert api.PyDictProxy_Check(w_proxy)
 
 def test_typedict(self, space, api):
-py_type = make_ref(space, space.w_type)
-py_dict = py_type.c_ob_type.c_tp_dict
+py_type = make_ref(space, space.w_int)
+py_dict = rffi.cast(PyTypeObjectPtr, py_type).c_tp_dict
 ppos = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
 
 ppos[0] = 0
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: pep475ify the socket objects

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r0:dbc5c6b1041f
Date: 2016-12-04 20:14 +0100
http://bitbucket.org/pypy/pypy/changeset/dbc5c6b1041f/

Log:pep475ify the socket objects

diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -1,5 +1,6 @@
-import sys
+import sys, errno
 from rpython.rlib import rsocket, rweaklist
+from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.rsocket import (
 RSocket, AF_INET, SOCK_STREAM, SocketError, SocketErrorWithErrno,
@@ -227,12 +228,13 @@
 representing the connection, and the address of the client.
 For IP sockets, the address info is a pair (hostaddr, port).
 """
-try:
-fd, addr = self.sock.accept(inheritable=False)
-return space.newtuple([space.wrap(fd),
-   addr_as_object(addr, fd, space)])
-except SocketError as e:
-raise converted_error(space, e)
+while True:
+try:
+fd, addr = self.sock.accept(inheritable=False)
+return space.newtuple([space.wrap(fd),
+   addr_as_object(addr, fd, space)])
+except SocketError as e:
+converted_error(space, e, eintr_retry=True)
 
 # convert an Address into an app-level object
 def addr_as_object(self, space, address):
@@ -274,10 +276,12 @@
 Connect the socket to a remote address.  For IP sockets, the address
 is a pair (host, port).
 """
-try:
-self.sock.connect(self.addr_from_object(space, w_addr))
-except SocketError as e:
-raise converted_error(space, e)
+while True:
+try:
+self.sock.connect(self.addr_from_object(space, w_addr))
+break
+except SocketError as e:
+converted_error(space, e, eintr_retry=True)
 
 def connect_ex_w(self, space, w_addr):
 """connect_ex(address) -> errno
@@ -289,7 +293,11 @@
 addr = self.addr_from_object(space, w_addr)
 except SocketError as e:
 raise converted_error(space, e)
-error = self.sock.connect_ex(addr)
+while True:
+error = self.sock.connect_ex(addr)
+if error != errno.EINTR:
+break
+space.getexecutioncontext().checksignals()
 return space.wrap(error)
 
 def fileno_w(self, space):
@@ -384,10 +392,12 @@
 at least one byte is available or until the remote end is closed.  When
 the remote end is closed and all data is read, return the empty string.
 """
-try:
-data = self.sock.recv(buffersize, flags)
-except SocketError as e:
-raise converted_error(space, e)
+while True:
+try:
+data = self.sock.recv(buffersize, flags)
+break
+except SocketError as e:
+converted_error(space, e, eintr_retry=True)
 return space.newbytes(data)
 
 @unwrap_spec(buffersize='nonnegint', flags=int)
@@ -396,15 +406,17 @@
 
 Like recv(buffersize, flags) but also return the sender's address info.
 """
-try:
-data, addr = self.sock.recvfrom(buffersize, flags)
-if addr:
-w_addr = addr_as_object(addr, self.sock.fd, space)
-else:
-w_addr = space.w_None
-return space.newtuple([space.newbytes(data), w_addr])
-except SocketError as e:
-raise converted_error(space, e)
+while True:
+try:
+data, addr = self.sock.recvfrom(buffersize, flags)
+if addr:
+w_addr = addr_as_object(addr, self.sock.fd, space)
+else:
+w_addr = space.w_None
+break
+except SocketError as e:
+converted_error(space, e, eintr_retry=True)
+return space.newtuple([space.newbytes(data), w_addr])
 
 @unwrap_spec(data='bufferstr', flags=int)
 def send_w(self, space, data, flags=0):
@@ -414,10 +426,12 @@
 argument, see the Unix manual.  Return the number of bytes
 sent; this may be less than len(data) if the network is busy.
 """
-try:
-count = self.sock.send(data, flags)
-except SocketError as e:
-raise converted_error(space, e)
+while True:
+try:
+count = self.sock.send(data, flags)
+break
+except SocketError as e:
+converted_error(space, e, eintr_retry=True)
 return space.wrap(count)
 
 @unwrap_spec(data='bufferstr', flags=int)
@@ -450,11 +464,13 @@
 # 

[pypy-commit] pypy py3.5-eintr-pep475: select.*() functions (the subset of the ones available on Linux)

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88879:98fd8574f000
Date: 2016-12-04 19:29 +0100
http://bitbucket.org/pypy/pypy/changeset/98fd8574f000/

Log:select.*() functions (the subset of the ones available on Linux)

diff --git a/pypy/module/select/interp_epoll.py 
b/pypy/module/select/interp_epoll.py
--- a/pypy/module/select/interp_epoll.py
+++ b/pypy/module/select/interp_epoll.py
@@ -7,6 +7,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.error import exception_from_saved_errno
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter import timeutils
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.tool import rffi_platform
 from rpython.rlib._rsocket_rffi import socketclose, FD_SETSIZE
@@ -156,9 +157,11 @@
 def descr_poll(self, space, timeout=-1.0, maxevents=-1):
 self.check_closed(space)
 if timeout < 0:
-timeout = -1.0
+end_time = 0.0
+itimeout = -1
 else:
-timeout *= 1000.0
+end_time = timeutils.monotonic(space) + timeout
+itimeout = int(timeout * 1000.0 + 0.999)
 
 if maxevents == -1:
 maxevents = FD_SETSIZE - 1
@@ -167,9 +170,18 @@
 "maxevents must be greater than 0, not %d", maxevents)
 
 with lltype.scoped_alloc(rffi.CArray(epoll_event), maxevents) as evs:
-nfds = epoll_wait(self.epfd, evs, maxevents, int(timeout))
-if nfds < 0:
-raise exception_from_saved_errno(space, space.w_IOError)
+while True:
+nfds = epoll_wait(self.epfd, evs, maxevents, itimeout)
+if nfds < 0:
+if get_saved_errno() == errno.EINTR:
+space.getexecutioncontext().checksignals()
+if itimeout >= 0:
+timeout = end_time - timeutils.monotonic(space)
+timeout = max(timeout, 0.0)
+itimeout = int(timeout * 1000.0 + 0.999)
+continue
+raise exception_from_saved_errno(space, space.w_IOError)
+break
 
 elist_w = [None] * nfds
 for i in xrange(nfds):
diff --git a/pypy/module/select/interp_kqueue.py 
b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -180,6 +180,7 @@
 raise oefmt(space.w_ValueError,
 "Timeout must be None or >= 0, got %s",
 str(_timeout))
+XXX   # fix test_select_signal.py first, for PEP475!
 sec = int(_timeout)
 nsec = int(1e9 * (_timeout - sec))
 rffi.setintfield(timeout, 'c_tv_sec', sec)
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
@@ -10,6 +10,7 @@
 from pypy.interpreter.gateway import (
 Unwrapper, WrappedDefault, interp2app, unwrap_spec)
 from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter import timeutils
 
 defaultevents = rpoll.POLLIN | rpoll.POLLOUT | rpoll.POLLPRI
 
@@ -49,8 +50,10 @@
 
 @unwrap_spec(w_timeout=WrappedDefault(None))
 def poll(self, space, w_timeout):
+"""WARNING: the timeout parameter is in **milliseconds**!"""
 if space.is_w(w_timeout, space.w_None):
 timeout = -1
+end_time = 0
 else:
 # we want to be compatible with cpython and also accept things
 # that can be casted to integer (I think)
@@ -61,19 +64,29 @@
 raise oefmt(space.w_TypeError,
 "timeout must be an integer or None")
 timeout = space.c_int_w(w_timeout)
+end_time = timeutils.monotonic(space) + timeout * 0.001
 
 if self.running:
 raise oefmt(space.w_RuntimeError, "concurrent poll() invocation")
-self.running = True
-try:
-retval = rpoll.poll(self.fddict, timeout)
-except rpoll.PollError as e:
-message = e.get_msg()
-raise OperationError(space.w_OSError,
- space.newtuple([space.wrap(e.errno),
- space.wrap(message)]))
-finally:
-self.running = False
+while True:
+self.running = True
+try:
+retval = rpoll.poll(self.fddict, timeout)
+except rpoll.PollError as e:
+if e.errno == errno.EINTR:
+space.getexecutioncontext().checksignals()
+timeout = int((end_time - timeutils.monotonic(space))
+   

[pypy-commit] pypy.org extradoc: update the values

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: extradoc
Changeset: r828:5a234313e695
Date: 2016-12-04 14:45 +0100
http://bitbucket.org/pypy/pypy.org/changeset/5a234313e695/

Log:update the values

diff --git a/don1.html b/don1.html
--- a/don1.html
+++ b/don1.html
@@ -15,7 +15,7 @@
 
 

-   $66367 of $105000 (63.2%)
+   $66386 of $105000 (63.2%)


 
@@ -23,7 +23,7 @@
   
   This donation goes towards supporting Python 3 in 
PyPy.
   Current status:
-we have $2218 left
+we have $2235 left
   in the account. Read proposal
   
   
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: pep475ify time.sleep()

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88878:b98fafbb5f1c
Date: 2016-12-04 12:40 +0100
http://bitbucket.org/pypy/pypy/changeset/b98fafbb5f1c/

Log:pep475ify time.sleep()

diff --git a/pypy/interpreter/timeutils.py b/pypy/interpreter/timeutils.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/timeutils.py
@@ -0,0 +1,11 @@
+"""
+Access to the time module's high-resolution monotonic clock
+"""
+
+def monotonic(space):
+from pypy.module.time import interp_time
+if interp_time.HAS_MONOTONIC:
+w_res = interp_time.monotonic(space)
+else:
+w_res = interp_time.gettimeofday(space)
+return space.float_w(w_res)   # xxx back and forth
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -2,6 +2,7 @@
 from rpython.rtyper.lltypesystem import rffi
 from pypy.interpreter.error import OperationError, oefmt, strerror as 
_strerror, exception_from_saved_errno
 from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter import timeutils
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rlib.rarithmetic import intmask, r_ulonglong, r_longfloat, widen
 from rpython.rlib.rtime import (GETTIMEOFDAY_NO_TZ, TIMEVAL,
@@ -438,12 +439,31 @@
 return _strerror(errno)
 
 if sys.platform != 'win32':
+from errno import EINTR
+from rpython.rlib.rtime import c_select
+
 @unwrap_spec(secs=float)
 def sleep(space, secs):
 if secs < 0:
 raise oefmt(space.w_ValueError,
 "sleep length must be non-negative")
-rtime.sleep(secs)
+end_time = timeutils.monotonic(space) + secs
+while True:
+void = lltype.nullptr(rffi.VOIDP.TO)
+with lltype.scoped_alloc(TIMEVAL) as t:
+frac = math.fmod(secs, 1.0)
+rffi.setintfield(t, 'c_tv_sec', int(secs))
+rffi.setintfield(t, 'c_tv_usec', int(frac*100.0))
+
+res = rffi.cast(rffi.LONG, c_select(0, void, void, void, t))
+if res == 0:
+break# normal path
+if rposix.get_saved_errno() != EINTR:
+raise exception_from_saved_errno(space, space.w_OSError)
+secs = end_time - timeutils.monotonic(space)   # retry
+if secs <= 0.0:
+break
+
 else:
 from rpython.rlib import rwin32
 from errno import EINTR
@@ -463,6 +483,7 @@
OSError(EINTR, "sleep() interrupted"))
 @unwrap_spec(secs=float)
 def sleep(space, secs):
+XXX   # review for EINTR / PEP475
 if secs < 0:
 raise oefmt(space.w_ValueError,
 "sleep length must be non-negative")
diff --git a/pypy/module/time/test/test_time.py 
b/pypy/module/time/test/test_time.py
--- a/pypy/module/time/test/test_time.py
+++ b/pypy/module/time/test/test_time.py
@@ -1,6 +1,6 @@
 class AppTestTime:
 spaceconfig = {
-"usemodules": ['time', 'struct', 'binascii'],
+"usemodules": ['time', 'struct', 'binascii', 'signal'],
 }
 
 def test_attributes(self):
@@ -394,3 +394,23 @@
 assert info.resolution > 0.0
 assert info.resolution <= 1.0
 assert isinstance(info.adjustable, bool)
+
+def test_pep475_retry_sleep(self):
+import time
+import _signal as signal
+signalled = []
+
+def foo(*args):
+signalled.append("ALARM")
+
+signal.signal(signal.SIGALRM, foo)
+try:
+t1 = time.time()
+signal.alarm(1)
+time.sleep(3.0)
+t2 = time.time()
+finally:
+signal.signal(signal.SIGALRM, signal.SIG_DFL)
+
+assert signalled != []
+assert t2 - t1 > 2.99
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: translation fix

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88877:dab6fcde4713
Date: 2016-12-04 11:58 +0100
http://bitbucket.org/pypy/pypy/changeset/dab6fcde4713/

Log:translation fix

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -543,6 +543,7 @@
 _WINDOWS = True
 
 def wrap_windowserror(space, e, w_filename=None):
+XXX# WindowsError no longer exists in Py3.5
 from rpython.rlib import rwin32
 
 winerror = e.winerror
@@ -559,13 +560,13 @@
   space.wrap(msg))
 return OperationError(exc, w_error)
 
-@specialize.arg(3)
+@specialize.arg(3, 6)
 def wrap_oserror2(space, e, w_filename=None, exception_name='w_OSError',
   w_exception_class=None, w_filename2=None, eintr_retry=False):
 """A double API here:
 
 * if eintr_retry is False, always return the OperationError to
-  be raised by the caller, which might be about EINTR
+  be raised by the caller.  It can possibly be about EINTR
   (checksignals() is still called here).
 
 * if eintr_retry is True (PEP 475 compliant API for retrying
@@ -579,6 +580,21 @@
 if _WINDOWS and isinstance(e, WindowsError):
 return wrap_windowserror(space, e, w_filename)
 
+if w_exception_class is None:
+w_exc = getattr(space, exception_name)
+else:
+w_exc = w_exception_class
+operror = _wrap_oserror2_impl(space, e, w_filename, w_filename2, w_exc,
+  eintr_retry)
+if eintr_retry:
+assert operror is None   # otherwise, _wrap_oserror2_impl() has raised
+else:
+assert operror is not None   # tell the annotator we don't return None
+return operror
+
+def _wrap_oserror2_impl(space, e, w_filename, w_filename2, w_exc, eintr_retry):
+# move the common logic in its own function, instead of having it
+# duplicated 4 times in all 4 specialized versions of wrap_oserror2()
 errno = e.errno
 
 if errno == EINTR:
@@ -590,27 +606,24 @@
 msg = strerror(errno)
 except ValueError:
 msg = u'error %d' % errno
-if w_exception_class is None:
-exc = getattr(space, exception_name)
-else:
-exc = w_exception_class
 if w_filename is not None:
 if w_filename2 is not None:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg), w_filename,
   space.w_None, w_filename2)
 else:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg), w_filename)
 else:
-w_error = space.call_function(exc, space.wrap(errno),
+w_error = space.call_function(w_exc, space.wrap(errno),
   space.wrap(msg))
-operr = OperationError(exc, w_error)
+operror = OperationError(w_exc, w_error)
 if eintr_retry:
-raise operr
-return operr
+raise operror
+return operror
+_wrap_oserror2_impl._dont_inline_ = True
 
-@specialize.arg(3)
+@specialize.arg(3, 6)
 def wrap_oserror(space, e, filename=None, exception_name='w_OSError',
  w_exception_class=None, filename2=None, eintr_retry=False):
 w_filename = None
@@ -624,6 +637,7 @@
  w_exception_class=w_exception_class,
  w_filename2=w_filename2,
  eintr_retry=eintr_retry)
+wrap_oserror._dont_inline_ = True
 
 def exception_from_saved_errno(space, w_type):
 from rpython.rlib.rposix import get_saved_errno
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: hg merge py3.5

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88875:1613a0094a88
Date: 2016-12-04 11:39 +0100
http://bitbucket.org/pypy/pypy/changeset/1613a0094a88/

Log:hg merge py3.5

diff too long, truncating to 2000 out of 28117 lines

diff --git a/lib-python/3/_collections_abc.py b/lib-python/3/_collections_abc.py
--- a/lib-python/3/_collections_abc.py
+++ b/lib-python/3/_collections_abc.py
@@ -156,7 +156,7 @@
 __slots__ = ()
 
 @abstractmethod
-async def __aiter__(self):
+def __aiter__(self):
 return AsyncIterator()
 
 @classmethod
@@ -176,7 +176,7 @@
 """Return the next item or raise StopAsyncIteration when exhausted."""
 raise StopAsyncIteration
 
-async def __aiter__(self):
+def __aiter__(self):
 return self
 
 @classmethod
diff --git a/lib-python/3/_compat_pickle.py b/lib-python/3/_compat_pickle.py
--- a/lib-python/3/_compat_pickle.py
+++ b/lib-python/3/_compat_pickle.py
@@ -177,6 +177,13 @@
 'DocXMLRPCServer': 'xmlrpc.server',
 'SimpleHTTPServer': 'http.server',
 'CGIHTTPServer': 'http.server',
+# For compatibility with broken pickles saved in old Python 3 versions
+'UserDict': 'collections',
+'UserList': 'collections',
+'UserString': 'collections',
+'whichdb': 'dbm',
+'StringIO':  'io',
+'cStringIO': 'io',
 })
 
 REVERSE_IMPORT_MAPPING.update({
diff --git a/lib-python/3/_osx_support.py b/lib-python/3/_osx_support.py
--- a/lib-python/3/_osx_support.py
+++ b/lib-python/3/_osx_support.py
@@ -151,13 +151,13 @@
 #can only be found inside Xcode.app if the "Command Line Tools"
 #are not installed.
 #
-#Futhermore, the compiler that can be used varies between
+#Furthermore, the compiler that can be used varies between
 #Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2'
 #as the compiler, after that 'clang' should be used because
 #gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
 #miscompiles Python.
 
-# skip checks if the compiler was overriden with a CC env variable
+# skip checks if the compiler was overridden with a CC env variable
 if 'CC' in os.environ:
 return _config_vars
 
@@ -193,7 +193,7 @@
 if cc != oldcc:
 # Found a replacement compiler.
 # Modify config vars using new compiler, if not already explicitly
-# overriden by an env variable, preserving additional arguments.
+# overridden by an env variable, preserving additional arguments.
 for cv in _COMPILER_CONFIG_VARS:
 if cv in _config_vars and cv not in os.environ:
 cv_split = _config_vars[cv].split()
@@ -207,7 +207,7 @@
 """Remove all universal build arguments from config vars"""
 
 for cv in _UNIVERSAL_CONFIG_VARS:
-# Do not alter a config var explicitly overriden by env var
+# Do not alter a config var explicitly overridden by env var
 if cv in _config_vars and cv not in os.environ:
 flags = _config_vars[cv]
 flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII)
@@ -228,7 +228,7 @@
 # build extensions on OSX 10.7 and later with the prebuilt
 # 32-bit installer on the python.org website.
 
-# skip checks if the compiler was overriden with a CC env variable
+# skip checks if the compiler was overridden with a CC env variable
 if 'CC' in os.environ:
 return _config_vars
 
@@ -244,7 +244,7 @@
 # across Xcode and compiler versions, there is no reliable way
 # to be sure why it failed.  Assume here it was due to lack of
 # PPC support and remove the related '-arch' flags from each
-# config variables not explicitly overriden by an environment
+# config variables not explicitly overridden by an environment
 # variable.  If the error was for some other reason, we hope the
 # failure will show up again when trying to compile an extension
 # module.
@@ -292,7 +292,7 @@
 sdk = m.group(1)
 if not os.path.exists(sdk):
 for cv in _UNIVERSAL_CONFIG_VARS:
-# Do not alter a config var explicitly overriden by env var
+# Do not alter a config var explicitly overridden by env var
 if cv in _config_vars and cv not in os.environ:
 flags = _config_vars[cv]
 flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
diff --git a/lib-python/3/_pydecimal.py b/lib-python/3/_pydecimal.py
--- a/lib-python/3/_pydecimal.py
+++ b/lib-python/3/_pydecimal.py
@@ -252,7 +252,7 @@
 class ConversionSyntax(InvalidOperation):
 """Trying to convert badly formed string.
 
-This occurs and signals invalid-operation if an string is being
+This occurs and signals invalid-operation if a string is being
 converted to a number and it does not conform to the numeric string
 

[pypy-commit] pypy py3.5-eintr-pep475: close fd's in case of error

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88873:de02c97af766
Date: 2016-12-04 11:39 +0100
http://bitbucket.org/pypy/pypy/changeset/de02c97af766/

Log:close fd's in case of error

diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -1302,11 +1302,16 @@
 
 def openpty(space):
 "Open a pseudo-terminal, returning open fd's for both master and slave 
end."
+master_fd = slave_fd = -1
 try:
 master_fd, slave_fd = os.openpty()
 rposix.set_inheritable(master_fd, False)
 rposix.set_inheritable(slave_fd, False)
 except OSError as e:
+if master_fd >= 0:
+rposix.c_close(master_fd)
+if slave_fd >= 0:
+rposix.c_close(slave_fd)
 raise wrap_oserror(space, e, eintr_retry=False)
 return space.newtuple([space.wrap(master_fd), space.wrap(slave_fd)])
 
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: first try at the _io module

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88874:c9e018812658
Date: 2016-12-04 11:39 +0100
http://bitbucket.org/pypy/pypy/changeset/c9e018812658/

Log:first try at the _io module

diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -175,46 +175,48 @@
 "Cannot use closefd=False with file name")
 
 from pypy.module.posix.interp_posix import dispatch_filename
-try:
-self.fd = dispatch_filename(rposix.open)(
-space, w_name, flags, 0666)
-except OSError as e:
-raise wrap_oserror2(space, e, w_name,
-exception_name='w_IOError')
-finally:
-fd_is_own = True
+while True:
+try:
+self.fd = dispatch_filename(rposix.open)(
+space, w_name, flags, 0666)
+fd_is_own = True
+break
+except OSError as e:
+wrap_oserror2(space, e, w_name,
+  exception_name='w_IOError',
+  eintr_retry=True)
 if not rposix._WIN32:
 try:
 _open_inhcache.set_non_inheritable(self.fd)
 except OSError as e:
-raise wrap_oserror2(space, e, w_name)
+raise wrap_oserror2(space, e, w_name, 
eintr_retry=False)
 else:
 w_fd = space.call_function(w_opener, w_name, space.wrap(flags))
 try:
 self.fd = space.int_w(w_fd)
+fd_is_own = True
 except OperationError as e:
 if not e.match(space, space.w_TypeError):
 raise
 raise oefmt(space.w_TypeError,
 "expected integer from opener")
-finally:
-fd_is_own = True
 if not rposix._WIN32:
 try:
 rposix.set_inheritable(self.fd, False)
 except OSError as e:
-raise wrap_oserror2(space, e, w_name)
+raise wrap_oserror2(space, e, w_name, 
eintr_retry=False)
 
 try:
 st = os.fstat(self.fd)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 # On Unix, fopen will succeed for directories.
 # In Python, there should be no file objects referring to
 # directories, so we need a check.
 if stat.S_ISDIR(st.st_mode):
 raise wrap_oserror2(space, OSError(errno.EISDIR, "fstat"),
-w_name, exception_name='w_IOError')
+w_name, exception_name='w_IOError',
+eintr_retry=False)
 self.blksize = DEFAULT_BUFFER_SIZE
 if HAS_BLKSIZE and st.st_blksize > 1:
 self.blksize = st.st_blksize
@@ -227,7 +229,8 @@
 try:
 os.lseek(self.fd, 0, os.SEEK_END)
 except OSError as e:
-raise wrap_oserror(space, e, exception_name='w_IOError')
+raise wrap_oserror(space, e, exception_name='w_IOError',
+   eintr_retry=False)
 except:
 if not fd_is_own:
 self.fd = -1
@@ -285,7 +288,8 @@
 os.close(fd)
 except OSError as e:
 raise wrap_oserror(space, e,
-   exception_name='w_IOError')
+   exception_name='w_IOError',
+   eintr_retry=False)
 
 def close_w(self, space):
 try:
@@ -319,7 +323,8 @@
 pos = os.lseek(self.fd, pos, whence)
 except OSError as e:
 raise wrap_oserror(space, e,
-   exception_name='w_IOError')
+   exception_name='w_IOError',
+   eintr_retry=False)
 return space.wrap(pos)
 
 def tell_w(self, space):
@@ -328,7 +333,8 @@
 pos = os.lseek(self.fd, 0, 1)
 except OSError as e:
 raise wrap_oserror(space, e,
-   exception_name='w_IOError')
+   exception_name='w_IOError',
+   eintr_retry=False)
 return space.wrap(pos)
 
 def readable_w(self, space):
@@ -361,7 +367,8 @@
 try:
 res = 

[pypy-commit] pypy py3.5-eintr-pep475: fix

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88876:a5c104036e0e
Date: 2016-12-04 11:46 +0100
http://bitbucket.org/pypy/pypy/changeset/a5c104036e0e/

Log:fix

diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -464,6 +464,7 @@
 return space.w_None
 wrap_oserror(space, e, exception_name='w_IOError',
  eintr_retry=True)
+continue
 if not chunk:
 break
 builder.append(chunk)
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: ah bah

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88872:4899480d8be8
Date: 2016-12-04 10:38 +0100
http://bitbucket.org/pypy/pypy/changeset/4899480d8be8/

Log:ah bah

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -622,7 +622,8 @@
 return wrap_oserror2(space, e, w_filename,
  exception_name=exception_name,
  w_exception_class=w_exception_class,
- w_filename2=w_filename2)
+ w_filename2=w_filename2,
+ eintr_retry=eintr_retry)
 
 def exception_from_saved_errno(space, w_type):
 from rpython.rlib.rposix import get_saved_errno
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy py3.5-eintr-pep475: Add eintr_retry=False systematically (the goal would be to remove

2016-12-04 Thread arigo
Author: Armin Rigo 
Branch: py3.5-eintr-pep475
Changeset: r88871:63df1181a419
Date: 2016-12-04 10:19 +0100
http://bitbucket.org/pypy/pypy/changeset/63df1181a419/

Log:Add eintr_retry=False systematically (the goal would be to remove
the default value of the argument, to be sure we're complete)

diff --git a/pypy/module/posix/interp_posix.py 
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -251,7 +251,7 @@
 try:
 pos = os.lseek(fd, position, how)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.wrap(pos)
 
@@ -262,7 +262,7 @@
 try:
 res = os.isatty(fd)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.wrap(res)
 
@@ -300,7 +300,7 @@
 try:
 os.close(fd)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 
 @unwrap_spec(fd_low=c_int, fd_high=c_int)
 def closerange(fd_low, fd_high):
@@ -487,7 +487,7 @@
 raise oefmt(space.w_NotImplementedError,
 "%s: unsupported argument combination", funcname)
 except OSError as e:
-raise wrap_oserror2(space, e, path.w_path)
+raise wrap_oserror2(space, e, path.w_path, eintr_retry=False)
 else:
 return build_stat_result(space, st)
 
@@ -546,7 +546,7 @@
 rposix_stat.statvfs,
 allow_fd_fn=rposix_stat.fstatvfs)(space, w_path)
 except OSError as e:
-raise wrap_oserror2(space, e, w_path)
+raise wrap_oserror2(space, e, w_path, eintr_retry=False)
 else:
 return build_statvfs_result(space, st)
 
@@ -558,17 +558,19 @@
 try:
 newfd = rposix.dup(fd, inheritable=False)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.wrap(newfd)
 
 @unwrap_spec(fd=c_int, fd2=c_int, inheritable=bool)
 def dup2(space, fd, fd2, inheritable=1):
 """Duplicate a file descriptor."""
+# like os.close(), this can still raise EINTR to app-level in
+# CPython 3.5.2
 try:
 rposix.dup2(fd, fd2, inheritable)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 
 @unwrap_spec(mode=c_int,
 dir_fd=DirFD(rposix.HAVE_FACCESSAT), effective_ids=bool,
@@ -613,7 +615,7 @@
 else:
 ok = dispatch_filename(rposix.access)(space, w_path, mode)
 except OSError as e:
-raise wrap_oserror2(space, e, w_path)
+raise wrap_oserror2(space, e, w_path, eintr_retry=False)
 else:
 return space.wrap(ok)
 
@@ -627,7 +629,7 @@
 try:
 times = os.times()
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.newtuple([space.wrap(times[0]),
space.wrap(times[1]),
@@ -641,7 +643,7 @@
 try:
 rc = os.system(command)
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.wrap(rc)
 
@@ -662,7 +664,7 @@
 else:
 dispatch_filename(rposix.unlink)(space, w_path)
 except OSError as e:
-raise wrap_oserror2(space, e, w_path)
+raise wrap_oserror2(space, e, w_path, eintr_retry=False)
 
 @unwrap_spec(dir_fd=DirFD(rposix.HAVE_UNLINKAT))
 def remove(space, w_path, __kwonly__, dir_fd=DEFAULT_DIR_FD):
@@ -681,7 +683,7 @@
 else:
 dispatch_filename(rposix.unlink)(space, w_path)
 except OSError as e:
-raise wrap_oserror2(space, e, w_path)
+raise wrap_oserror2(space, e, w_path, eintr_retry=False)
 
 def _getfullpathname(space, w_path):
 """helper for ntpath.abspath """
@@ -695,7 +697,7 @@
 fullpath = rposix.getfullpathname(path)
 w_fullpath = space.newbytes(fullpath)
 except OSError as e:
-raise wrap_oserror2(space, e, w_path)
+raise wrap_oserror2(space, e, w_path, eintr_retry=False)
 else:
 return w_fullpath
 
@@ -704,7 +706,7 @@
 try:
 cur = os.getcwd()
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.newbytes(cur)
 
@@ -714,7 +716,7 @@
 try:
 cur = os.getcwdu()
 except OSError as e:
-raise wrap_oserror(space, e)
+raise wrap_oserror(space, e, eintr_retry=False)
 else:
 return space.wrap(cur)
 else:
@@ -731,7 +733,7 @@
 else:
 dispatch_filename(rposix.chdir)(space, w_path)
 except OSError as e:
-