Author: andrewjlawrence
Branch: winconsoleio
Changeset: r97558:9210c8d4569e
Date: 2019-09-20 06:58 +0100
http://bitbucket.org/pypy/pypy/changeset/9210c8d4569e/
Log: Added some more tests
diff --git a/pypy/module/_io/interp_win32consoleio.py
b/pypy/module/_io/interp_win32consoleio.py
--- a/pypy/module/_io/interp_win32consoleio.py
+++ b/pypy/module/_io/interp_win32consoleio.py
@@ -12,6 +12,7 @@
from rpython.rlib._os_support import _preferred_traits
from rpython.rlib import rwin32
from rpython.rlib.rwin32file import make_win32_traits
+
from rpython.rtyper.tool import rffi_platform as platform
import unicodedata
@@ -164,9 +165,6 @@
self.writable = False
self.closehandle = False
self.blksize = 0
-
- # def _internal_close(self, space):
- # pass
def _copyfrombuf(self, buf, len):
n = 0
@@ -200,6 +198,9 @@
try:
if space.isinstance_w(w_nameobj, space.w_int):
self.fd = space.int_w(w_nameobj)
+ if self.fd < 0:
+ raise oefmt(space.w_ValueError,
+ "negative file descriptor")
# make the flow analysis happy,otherwise it thinks w_path
# is undefined later
@@ -325,11 +326,13 @@
return space.newtext("<%s name=%s>" % (typename, name_repr))
def fileno_w(self, space):
+ traits = _preferred_traits(u"")
+ win32traits = make_win32_traits(traits)
if self.fd < 0 and self.handle != rwin32.INVALID_HANDLE_VALUE:
if self.writable:
- self.fd = rwin32.open_osfhandle(self.handle, rwin32._O_WRONLY
| rwin32._O_BINARY)
+ self.fd = rwin32.open_osfhandle(self.handle,
win32traits._O_WRONLY | win32traits._O_BINARY)
else:
- self.fd = rwin32.open_osfhandle(self.handle, rwin32._O_RDONLY
| rwin32._O_BINARY)
+ self.fd = rwin32.open_osfhandle(self.handle,
win32traits._O_RDONLY | win32traits._O_BINARY)
if self.fd < 0:
return err_mode(space, "fileno")
return space.newint(self.fd)
@@ -438,9 +441,9 @@
err_closed(space)
bufsize = BUFSIZ
- buf = lltype.malloc(rffi.CWCHARP, bufsize + 1, flavor='raw')
+ buf = lltype.malloc(rffi.CWCHARP.TO, bufsize + 1, flavor='raw')
len = 0
- n = lltype.malloc(rffi.CWCHARP, 1, flavor='raw')
+ n = lltype.malloc(rwin32.LPDWORD.TO, 1, flavor='raw')
n[0] = 0
try:
@@ -456,7 +459,7 @@
"than a Python bytes object can hold")
bufsize = newsize
lltype.free(buf, flavor='raw')
- buf = lltype.malloc(rffi.CWCHARP, bufsize + 1,
flavor='raw')
+ buf = lltype.malloc(rffi.CWCHARP.TO, bufsize + 1,
flavor='raw')
subbuf = read_console_w(self.handle, bufsize - len, n)
if n > 0:
@@ -485,7 +488,7 @@
bytes_size += self._buflen()
# Create destination buffer and convert the bytes
- bytes = lltype.malloc(rffi.CCHARP, bytes_size, flavor='raw')
+ bytes = lltype.malloc(rffi.CCHARP.TO, bytes_size, flavor='raw')
rn = self._copyfrombuf(bytes, bytes_size)
if len:
@@ -509,60 +512,60 @@
def write_w(self, space, w_data):
buffer = space.charbuf_w(w_data)
- n = lltype.malloc(rwin32.LPDWORD.TO, 0, flavor='raw')
+ with lltype.scoped_alloc(rwin32.LPDWORD.TO, 1) as n:
- if self.handle == rwin32.INVALID_HANDLE_VALUE:
- return err_closed(space)
+ if self.handle == rwin32.INVALID_HANDLE_VALUE:
+ return err_closed(space)
- if not self.writable:
- return err_mode(space,"writing")
+ if not self.writable:
+ return err_mode(space,"writing")
- if not len(buffer):
- return 0
+ if not len(buffer):
+ lltype.free(n, flavor='raw')
+ return space.newint(0)
- if len(buffer) > BUFMAX:
- buflen = BUFMAX
- else:
- buflen = len(buffer)
+ if len(buffer) > BUFMAX:
+ buflen = BUFMAX
+ else:
+ buflen = len(buffer)
- wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer, buflen,
rffi.NULL, 0)
+ wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer,
buflen, rffi.NULL, 0)
- while wlen > (32766 / rffi.sizeof(rffi.CWCHARP)):
- buflen /= 2
- wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer,
buflen, rffi.NULL, 0)
+ while wlen > (32766 / rffi.sizeof(rffi.CWCHARP)):
+ buflen /= 2
+ wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer,
buflen, rffi.NULL, 0)
- if not wlen:
- lltype.free(n, flavor='raw')
- raise WindowsError("Failed to convert bytes to wide characters")
+ if not wlen:
+ lltype.free(n, flavor='raw')
+ raise WindowsError("Failed to convert bytes to wide
characters")
- with lltype.scoped_alloc(rffi.CWCHARP, wlen) as wbuf:
- wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer,
buflen, wbuf, wlen)
- if wlen:
- res = rwin32.WriteConsoleW(self.handle, wbuf, wlen, n ,
rffi.NULL)
+ with lltype.scoped_alloc(rffi.CWCHARP.TO, wlen) as wbuf:
+ wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0 , buffer,
buflen, wbuf, wlen)
+ if wlen:
+ res = rwin32.WriteConsoleW(self.handle,
rffi.cast(rwin32.LPVOID, wbuf), wlen, n , rffi.NULL)
- if res and n < wlen:
- buflen = rwin32.WideCharToMultiByte(rwin32.CP_UTF8, 0,
wbuf, n,
- rffi.NULL, 0, rffi.NULL, rffi.NULL)
+ if res and n < wlen:
+ buflen = rwin32.WideCharToMultiByte(rwin32.CP_UTF8, 0,
wbuf, n,
+ rffi.NULL, 0, rffi.NULL, rffi.NULL)
- if buflen:
- wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8, 0,
buffer,
- buflen, rffi.NULL, 0)
- assert len == wlen
+ if buflen:
+ wlen = rwin32.MultiByteToWideChar(rwin32.CP_UTF8,
0, buffer,
+ buflen, rffi.NULL, 0)
+ assert buflen == wlen
- else:
- res = 0
+ else:
+ res = 0
- if not res:
- err = rwin32.GetLastError_saved()
- lltype.free(n, flavor='raw')
- raise WindowsError(err, "Failed to convert multi byte string
to wide characters")
+ if not res:
+ err = rwin32.GetLastError_saved()
+ raise WindowsError(err, "Failed to convert multi byte
string to wide characters")
- lltype.free(n, flavor='raw')
- return space.newint(len)
+ return space.newint(buflen)
def get_blksize(self,space):
return space.newint(self.blksize)
+
W_WinConsoleIO.typedef = TypeDef(
'_io.WinConsoleIO', W_RawIOBase.typedef,
__new__ = generic_new_descr(W_WinConsoleIO),
@@ -574,7 +577,8 @@
isatty = interp2app(W_WinConsoleIO.isatty_w),
read = interp2app(W_WinConsoleIO.read_w),
readall = interp2app(W_WinConsoleIO.readall_w),
- readinto = interp2app(W_WinConsoleIO.readinto_w),
+ readinto = interp2app(W_WinConsoleIO.readinto_w),
+ fileno = interp2app(W_WinConsoleIO.fileno_w),
write = interp2app(W_WinConsoleIO.write_w),
_blksize = GetSetProperty(W_WinConsoleIO.get_blksize),
)
diff --git a/pypy/module/_io/test/test_win32consoleio.py
b/pypy/module/_io/test/test_win32consoleio.py
--- a/pypy/module/_io/test/test_win32consoleio.py
+++ b/pypy/module/_io/test/test_win32consoleio.py
@@ -1,32 +1,32 @@
+from rpython.tool.udir import udir
+
class AppTestWinConsoleIO:
- spaceconfig = dict(usemodules=['_io', '_locale', 'array'])
+ spaceconfig = dict(usemodules=['_io'])
- def setup_class(cls):
- from rpython.rlib.rarithmetic import INT_MAX, UINT_MAX
- space = cls.space
- cls.w_INT_MAX = space.wrap(INT_MAX)
- cls.w_UINT_MAX = space.wrap(UINT_MAX)
+ def setup_method(self, meth):
+ tmpfile = udir.join('tmpfile')
+ tmpfile.write("a\nb\nc", mode='wb')
+ self.tmpfile = tmpfile
+ self.conout_path = self.space.wrap(str(udir.join('CONOUT$')))
def test_open_fd(self):
import _io
+
+ w_fd = self.fileno()
+ # Windows 10: "Cannot open non-console file"
+ # Earlier: "Cannot open console output buffer for reading"
+ raises(ValueError, _io._WindowsConsoleIO, fd)
+
raises(ValueError, _io._WindowsConsoleIO, -1)
- fd, _ = tempfile.mkstemp()
- try:
- # Windows 10: "Cannot open non-console file"
- # Earlier: "Cannot open console output buffer for reading"
- raises(ValueError, _io._WindowsConsoleIO, fd)
- finally:
- os.close(fd)
-
try:
f = _io._WindowsConsoleIO(0)
except ValueError:
# cannot open console because it's not a real console
pass
else:
- assert f.readable() == True
- assert f.writable() == False
+ assert f.readable()
+ assert not f.writable()
assert 0 == f.fileno()
f.close() # multiple close should not crash
f.close()
@@ -37,8 +37,8 @@
# cannot open console because it's not a real console
pass
else:
- assert f.readable() == False
- assert True == f.writable()
+ assert not f.readable()
+ assert f.writable()
assert 1 == f.fileno()
f.close()
f.close()
@@ -49,12 +49,57 @@
# cannot open console because it's not a real console
pass
else:
- assert False == f.readable()
- assert True == f.writable()
+ assert not f.readable()
+ assert f.writable()
assert 2 == f.fileno()
f.close()
f.close()
def test_constructor(self):
import _io
- t = _io._WindowsConsoleIO("CONIN$")
+
+ f = _io._WindowsConsoleIO("CON")
+ assert f.readable()
+ assert not f.writable()
+ assert f.fileno() != None
+ f.close() # multiple close should not crash
+ f.close()
+
+ f = _io._WindowsConsoleIO('CONIN$')
+ assert f.readable()
+ assert not f.writable()
+ assert f.fileno() != None
+ f.close()
+ f.close()
+
+ f = _io._WindowsConsoleIO('CONOUT$', 'w')
+ assert not f.readable()
+ assert f.writable()
+ assert f.fileno() != None
+ f.close()
+ f.close()
+
+ f = open('C:/con', 'rb', buffering=0)
+ assert f is _io._WindowsConsoleIO
+ f.close()
+
+ def test_conin_conout_names(self):
+ import _io
+ f = open(r'\\.\conin$', 'rb', buffering=0)
+ assert type(f) is _io._WindowsConsoleIO
+ f.close()
+
+ f = open('//?/conout$', 'wb', buffering=0)
+ assert type(f) is _io._WindowsConsoleIO
+ f.close()
+
+ def test_conout_path(self):
+ import _io
+
+ with open(self.conout_path, 'wb', buffering=0) as f:
+ assert type(f) is _io._WindowsConsoleIO
+
+ def test_write_empty_data(self):
+ import _io
+ with _io._WindowsConsoleIO('CONOUT$', 'w') as f:
+ assert f.write(b'') == 0
\ No newline at end of file
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -252,6 +252,7 @@
_open_osfhandle = rffi.llexternal('_open_osfhandle', [rffi.INTP,
rffi.INT], rffi.INT)
def open_osfhandle(handle, flags):
+ from rpython.rlib.rposix import FdValidator
fd = _open_osfhandle(handle, flags)
with FdValidator(fd):
return fd
diff --git a/rpython/rlib/rwin32file.py b/rpython/rlib/rwin32file.py
--- a/rpython/rlib/rwin32file.py
+++ b/rpython/rlib/rwin32file.py
@@ -46,6 +46,7 @@
_O_RDWR = platform.ConstantInteger('_O_RDWR')
_O_TRUNC = platform.ConstantInteger('_O_TRUNC')
_O_WRONLY = platform.ConstantInteger('_O_WRONLY')
+ _O_BINARY = platform.ConstantInteger('_O_BINARY')
FILE_TYPE_UNKNOWN = platform.ConstantInteger('FILE_TYPE_UNKNOWN')
FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR')
FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE')
@@ -140,6 +141,7 @@
ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES
ERROR_SHARING_VIOLATION MOVEFILE_REPLACE_EXISTING
ERROR_ACCESS_DENIED
+ _O_RDONLY _O_WRONLY _O_BINARY
'''.split():
locals()[name] = config[name]
LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit