Commit 2cfffde3 authored by Jason Madden's avatar Jason Madden

We no longer need to gc before getting a libuv io object on PyPy: everything...

We no longer need to gc before getting a libuv io object on PyPy: everything is deterministically closed (or should be).
parent 509c1d66
...@@ -26,10 +26,11 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -26,10 +26,11 @@ class GreenFileDescriptorIO(RawIOBase):
_read_event = None _read_event = None
_write_event = None _write_event = None
_closed = False
_seekable = None
def __init__(self, fileno, mode='r', closefd=True): def __init__(self, fileno, mode='r', closefd=True):
RawIOBase.__init__(self) # Python 2: pylint:disable=no-member,non-parent-init-called RawIOBase.__init__(self) # Python 2: pylint:disable=no-member,non-parent-init-called
self._closed = False
self._closefd = closefd self._closefd = closefd
self._fileno = fileno self._fileno = fileno
make_nonblocking(fileno) make_nonblocking(fileno)
...@@ -44,8 +45,6 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -44,8 +45,6 @@ class GreenFileDescriptorIO(RawIOBase):
if writable: if writable:
self._write_event = io_watcher(fileno, 2) self._write_event = io_watcher(fileno, 2)
self._seekable = None
def readable(self): def readable(self):
return self._read_event is not None return self._read_event is not None
...@@ -81,11 +80,9 @@ class GreenFileDescriptorIO(RawIOBase): ...@@ -81,11 +80,9 @@ class GreenFileDescriptorIO(RawIOBase):
self._read_event = self._write_event = None self._read_event = self._write_event = None
if read_event is not None: if read_event is not None:
self.hub.cancel_wait(read_event, cancel_wait_ex) self.hub.cancel_wait(read_event, cancel_wait_ex, True)
read_event.close()
if write_event is not None: if write_event is not None:
self.hub.cancel_wait(write_event, cancel_wait_ex) self.hub.cancel_wait(write_event, cancel_wait_ex, True)
write_event.close()
fileno = self._fileno fileno = self._fileno
if self._closefd: if self._closefd:
......
...@@ -11,7 +11,6 @@ from operator import delitem ...@@ -11,7 +11,6 @@ from operator import delitem
import signal import signal
from gevent._ffi import _dbg # pylint: disable=unused-import from gevent._ffi import _dbg # pylint: disable=unused-import
from gevent._compat import PYPY
from gevent._ffi.loop import AbstractLoop from gevent._ffi.loop import AbstractLoop
from gevent.libuv import _corecffi # pylint:disable=no-name-in-module,import-error from gevent.libuv import _corecffi # pylint:disable=no-name-in-module,import-error
from gevent._ffi.loop import assign_standard_callbacks from gevent._ffi.loop import assign_standard_callbacks
...@@ -62,19 +61,6 @@ def get_header_version(): ...@@ -62,19 +61,6 @@ def get_header_version():
def supported_backends(): def supported_backends():
return ['default'] return ['default']
if PYPY:
def gcBefore(f):
import functools
import gc
@functools.wraps(f)
def m(self, *args):
gc.collect()
return f(self, *args)
return m
else:
def gcBefore(f):
return f
class loop(AbstractLoop): class loop(AbstractLoop):
...@@ -447,7 +433,6 @@ class loop(AbstractLoop): ...@@ -447,7 +433,6 @@ class loop(AbstractLoop):
watcher._set_status(status) watcher._set_status(status)
@gcBefore
def io(self, fd, events, ref=True, priority=None): def io(self, fd, events, ref=True, priority=None):
# We rely on hard references here and explicit calls to # We rely on hard references here and explicit calls to
# close() on the returned object to correctly manage # close() on the returned object to correctly manage
......
...@@ -54,7 +54,7 @@ class libuv_error_wrapper(object): ...@@ -54,7 +54,7 @@ class libuv_error_wrapper(object):
str(ffi.string(libuv.uv_err_name(res)).decode('ascii') str(ffi.string(libuv.uv_err_name(res)).decode('ascii')
+ ' ' + ' '
+ ffi.string(libuv.uv_strerror(res)).decode('ascii')) + ffi.string(libuv.uv_strerror(res)).decode('ascii'))
+ "Args: " + repr(args) + "KWARGS: " + repr(kwargs) + " Args: " + repr(args) + " KWARGS: " + repr(kwargs)
) )
return res return res
......
...@@ -291,5 +291,5 @@ class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})): ...@@ -291,5 +291,5 @@ class TestCase(TestCaseMetaClass("NewBase", (BaseTestCase,), {})):
except AssertionError: except AssertionError:
flaky.reraiseFlakyTestRaceCondition() flaky.reraiseFlakyTestRaceCondition()
if not hasattr(TestCase, 'assertRaisesRegex'): assertRaisesRegex = getattr(BaseTestCase, 'assertRaisesRegex',
TestCase.assertRaisesRegex = TestCase.assertRaisesRegexp getattr(BaseTestCase, 'assertRaisesRegexp'))
...@@ -3,13 +3,13 @@ import os ...@@ -3,13 +3,13 @@ import os
import sys import sys
import tempfile import tempfile
import gc import gc
import greentest
import gevent import gevent
from gevent.fileobject import FileObject, FileObjectThread from gevent.fileobject import FileObject, FileObjectThread
import greentest
PYPY = hasattr(sys, 'pypy_version_info') from greentest.sysinfo import PY3
from greentest.flaky import reraiseFlakyTestRaceConditionLibuv
class Test(greentest.TestCase): class Test(greentest.TestCase):
...@@ -41,18 +41,14 @@ class Test(greentest.TestCase): ...@@ -41,18 +41,14 @@ class Test(greentest.TestCase):
gc.collect() # PyPy gc.collect() # PyPy
if kwargs.get("close", True): if kwargs.get("close", True):
try: with self.assertRaises((OSError, IOError)):
# expected, because FileObject already closed it
os.close(w) os.close(w)
except (OSError, IOError):
pass # expected, because FileObject already closed it
else:
raise AssertionError('os.close(%r) must not succeed on %r' % (w, ts))
else: else:
os.close(w) os.close(w)
fobj = FileObject(r, 'rb') with FileObject(r, 'rb') as fobj:
self.assertEqual(fobj.read(), b'x') self.assertEqual(fobj.read(), b'x')
fobj.close()
def test_del(self): def test_del(self):
# Close should be true by default # Close should be true by default
...@@ -69,11 +65,9 @@ class Test(greentest.TestCase): ...@@ -69,11 +65,9 @@ class Test(greentest.TestCase):
self._test_del(close=False) self._test_del(close=False)
else: else:
def test_del_noclose(self): def test_del_noclose(self):
try: with self.assertRaisesRegex(TypeError,
'FileObjectThread does not support close=False on an fd.'):
self._test_del(close=False) self._test_del(close=False)
self.fail("Shouldn't be able to create a FileObjectThread with close=False")
except TypeError as e:
self.assertEqual(str(e), 'FileObjectThread does not support close=False on an fd.')
def test_newlines(self): def test_newlines(self):
r, w = os.pipe() r, w = os.pipe()
...@@ -101,10 +95,17 @@ class Test(greentest.TestCase): ...@@ -101,10 +95,17 @@ class Test(greentest.TestCase):
native_data = f.read(1024) native_data = f.read(1024)
with open(path, 'rb') as f_raw: with open(path, 'rb') as f_raw:
print("Opened", f_raw) try:
f = FileObject(f_raw, 'rb') f = FileObject(f_raw, 'rb')
if hasattr(f, 'seekable'): except ValueError:
# Py3 # libuv on Travis can raise EPERM
# from FileObjectPosix. I can't produce it on mac os locally,
# don't know what the issue is. This started happening on Jan 19,
# in the branch that caused all watchers to be explicitly closed.
# That shouldn't have any effect on io watchers, though, which were
# already being explicitly closed.
reraiseFlakyTestRaceConditionLibuv()
if PY3 or FileObject is not FileObjectThread:
self.assertTrue(f.seekable()) self.assertTrue(f.seekable())
f.seek(15) f.seek(15)
self.assertEqual(15, f.tell()) self.assertEqual(15, f.tell())
...@@ -126,9 +127,9 @@ class Test(greentest.TestCase): ...@@ -126,9 +127,9 @@ class Test(greentest.TestCase):
r, w = os.pipe() r, w = os.pipe()
x = FileObject(r) x = FileObject(r)
y = FileObject(w, 'w') y = FileObject(w, 'w')
assert hasattr(x, 'read1'), x self._close_on_teardown(x)
x.close() self._close_on_teardown(y)
y.close() self.assertTrue(hasattr(x, 'read1'))
#if FileObject is not FileObjectThread: #if FileObject is not FileObjectThread:
def test_bufsize_0(self): def test_bufsize_0(self):
...@@ -136,6 +137,8 @@ class Test(greentest.TestCase): ...@@ -136,6 +137,8 @@ class Test(greentest.TestCase):
r, w = os.pipe() r, w = os.pipe()
x = FileObject(r, 'rb', bufsize=0) x = FileObject(r, 'rb', bufsize=0)
y = FileObject(w, 'wb', bufsize=0) y = FileObject(w, 'wb', bufsize=0)
self._close_on_teardown(x)
self._close_on_teardown(y)
y.write(b'a') y.write(b'a')
b = x.read(1) b = x.read(1)
self.assertEqual(b, b'a') self.assertEqual(b, b'a')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment