Attach numerical code to Qt OSErrors and fix tests.
This fixes tests with tox < 2.0.0 on systems with a non-english locale, as it's no longer the errorString which gets compared. Fixes #806.
This commit is contained in:
parent
0037b0db7e
commit
ca5a78dfc7
@ -50,6 +50,26 @@ MINVALS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class QtOSError(OSError):
|
||||||
|
|
||||||
|
"""An OSError triggered by a QFileDevice.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
qt_errno: The error attribute of the given QFileDevice, if applicable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, dev, msg=None):
|
||||||
|
if msg is None:
|
||||||
|
msg = dev.errorString()
|
||||||
|
|
||||||
|
super().__init__(msg)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.qt_errno = dev.error()
|
||||||
|
except AttributeError:
|
||||||
|
self.qt_errno = None
|
||||||
|
|
||||||
|
|
||||||
def version_check(version, op=operator.ge):
|
def version_check(version, op=operator.ge):
|
||||||
"""Check if the Qt runtime version is the version supplied or newer.
|
"""Check if the Qt runtime version is the version supplied or newer.
|
||||||
|
|
||||||
@ -183,7 +203,7 @@ def savefile_open(filename, binary=False, encoding='utf-8'):
|
|||||||
try:
|
try:
|
||||||
ok = f.open(QIODevice.WriteOnly)
|
ok = f.open(QIODevice.WriteOnly)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise OSError(f.errorString())
|
raise QtOSError(f)
|
||||||
if binary:
|
if binary:
|
||||||
new_f = PyQIODevice(f)
|
new_f = PyQIODevice(f)
|
||||||
else:
|
else:
|
||||||
@ -198,7 +218,7 @@ def savefile_open(filename, binary=False, encoding='utf-8'):
|
|||||||
finally:
|
finally:
|
||||||
commit_ok = f.commit()
|
commit_ok = f.commit()
|
||||||
if not commit_ok and not cancelled:
|
if not commit_ok and not cancelled:
|
||||||
raise OSError("Commit failed!")
|
raise QtOSError(f, msg="Commit failed!")
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
@ -266,7 +286,7 @@ class PyQIODevice(io.BufferedIOBase):
|
|||||||
"""
|
"""
|
||||||
ok = self.dev.open(mode)
|
ok = self.dev.open(mode)
|
||||||
if not ok:
|
if not ok:
|
||||||
raise OSError(self.dev.errorString())
|
raise QtOSError(self.dev)
|
||||||
return contextlib.closing(self)
|
return contextlib.closing(self)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
@ -289,7 +309,7 @@ class PyQIODevice(io.BufferedIOBase):
|
|||||||
raise io.UnsupportedOperation("whence = {} is not "
|
raise io.UnsupportedOperation("whence = {} is not "
|
||||||
"supported!".format(whence))
|
"supported!".format(whence))
|
||||||
if not ok:
|
if not ok:
|
||||||
raise OSError("seek failed!")
|
raise QtOSError(self.dev, msg="seek failed!")
|
||||||
|
|
||||||
def truncate(self, size=None): # pylint: disable=unused-argument
|
def truncate(self, size=None): # pylint: disable=unused-argument
|
||||||
raise io.UnsupportedOperation
|
raise io.UnsupportedOperation
|
||||||
@ -329,7 +349,7 @@ class PyQIODevice(io.BufferedIOBase):
|
|||||||
buf = self.dev.read(size)
|
buf = self.dev.read(size)
|
||||||
|
|
||||||
if buf is None:
|
if buf is None:
|
||||||
raise OSError(self.dev.errorString())
|
raise QtOSError(self.dev)
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def seekable(self):
|
def seekable(self):
|
||||||
@ -348,7 +368,7 @@ class PyQIODevice(io.BufferedIOBase):
|
|||||||
self._check_writable()
|
self._check_writable()
|
||||||
num = self.dev.write(b)
|
num = self.dev.write(b)
|
||||||
if num == -1 or num < len(b):
|
if num == -1 or num < len(b):
|
||||||
raise OSError(self.dev.errorString())
|
raise QtOSError(self.dev)
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def read(self, size=-1):
|
def read(self, size=-1):
|
||||||
@ -359,7 +379,7 @@ class PyQIODevice(io.BufferedIOBase):
|
|||||||
else:
|
else:
|
||||||
buf = self.dev.read(size)
|
buf = self.dev.read(size)
|
||||||
if buf is None:
|
if buf is None:
|
||||||
raise OSError(self.dev.errorString())
|
raise QtOSError(self.dev)
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import pytest
|
|||||||
import unittest
|
import unittest
|
||||||
import unittest.mock
|
import unittest.mock
|
||||||
from PyQt5.QtCore import (QDataStream, QPoint, QUrl, QByteArray, QIODevice,
|
from PyQt5.QtCore import (QDataStream, QPoint, QUrl, QByteArray, QIODevice,
|
||||||
QTimer, QBuffer, QFile, QProcess)
|
QTimer, QBuffer, QFile, QProcess, QFileDevice)
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
from qutebrowser import qutebrowser
|
from qutebrowser import qutebrowser
|
||||||
@ -700,11 +700,9 @@ class TestPyQIODevice:
|
|||||||
"""Test open() which fails (because it's an existant directory)."""
|
"""Test open() which fails (because it's an existant directory)."""
|
||||||
qf = QFile(str(tmpdir))
|
qf = QFile(str(tmpdir))
|
||||||
dev = qtutils.PyQIODevice(qf)
|
dev = qtutils.PyQIODevice(qf)
|
||||||
with pytest.raises(OSError) as excinfo:
|
with pytest.raises(qtutils.QtOSError) as excinfo:
|
||||||
dev.open(QIODevice.WriteOnly)
|
dev.open(QIODevice.WriteOnly)
|
||||||
errors = ['Access is denied.', # Linux/OS X
|
assert excinfo.value.qt_errno == QFileDevice.OpenError
|
||||||
'Is a directory'] # Windows
|
|
||||||
assert str(excinfo.value) in errors
|
|
||||||
assert dev.closed
|
assert dev.closed
|
||||||
|
|
||||||
def test_fileno(self, pyqiodev):
|
def test_fileno(self, pyqiodev):
|
||||||
|
Loading…
Reference in New Issue
Block a user