Author: mattip <[email protected]>
Branch: cpyext-ext
Changeset: r83391:a280f13c5a2f
Date: 2016-03-27 18:08 +0300
http://bitbucket.org/pypy/pypy/changeset/a280f13c5a2f/
Log: test, implement PyFile_FromFile (mostly), PyFile_AsFile
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -93,6 +93,8 @@
fileno = rffi.llexternal('fileno', [FILEP], rffi.INT)
fopen = rffi.llexternal('fopen', [CONST_STRING, CONST_STRING], FILEP)
+fdopen = rffi.llexternal('fdopen', [rffi.INT, CONST_STRING], FILEP,
+ save_err=rffi.RFFI_SAVE_ERRNO)
_fclose = rffi.llexternal('fclose', [FILEP], rffi.INT)
def fclose(fp):
diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -1,9 +1,10 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers)
+ cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers, fdopen,
+ fileno)
from pypy.module.cpyext.pyobject import PyObject
from pypy.module.cpyext.object import Py_PRINT_RAW
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError, oefmt
from pypy.module._file.interp_file import W_File
PyFile_Check, PyFile_CheckExact = build_type_checkers("File", W_File)
@@ -22,9 +23,8 @@
try:
w_readline = space.getattr(w_obj, space.wrap('readline'))
except OperationError:
- raise OperationError(
- space.w_TypeError, space.wrap(
- "argument must be a file, or have a readline() method."))
+ raise oefmt(space.w_TypeError,
+ "argument must be a file, or have a readline() method.")
n = rffi.cast(lltype.Signed, n)
if space.is_true(space.gt(space.wrap(n), space.wrap(0))):
@@ -52,14 +52,23 @@
If the caller will ever use the returned FILE* object while
the GIL is released it must also call the PyFile_IncUseCount() and
PyFile_DecUseCount() functions as appropriate."""
- raise NotImplementedError
+ assert isinstance(w_p, W_File)
+ return fdopen(space.int_w(space.call_method(w_p, 'fileno')),
+ w_p.mode)
@cpython_api([FILEP, CONST_STRING, CONST_STRING, rffi.VOIDP], PyObject)
def PyFile_FromFile(space, fp, name, mode, close):
"""Create a new PyFileObject from the already-open standard C file
pointer, fp. The function close will be called when the file should be
closed. Return NULL on failure."""
- raise NotImplementedError
+ if close:
+ raise oefmt(space.w_NotImplementedError,
+ 'PyFromFile(..., close) with close function not implemented')
+ w_ret = space.allocate_instance(W_File, space.gettypefor(W_File))
+ w_ret.w_name = space.wrap(rffi.charp2str(name))
+ w_ret.check_mode_ok(rffi.charp2str(mode))
+ w_ret.fp = fp
+ return w_ret
@cpython_api([PyObject, rffi.INT_real], lltype.Void)
def PyFile_SetBufSize(space, w_file, n):
diff --git a/pypy/module/cpyext/test/test_pyfile.py
b/pypy/module/cpyext/test/test_pyfile.py
--- a/pypy/module/cpyext/test/test_pyfile.py
+++ b/pypy/module/cpyext/test/test_pyfile.py
@@ -61,7 +61,16 @@
assert space.str_w(api.PyFile_Name(w_file)) == name
def test_file_fromfile(self, space, api):
- api.PyFile_FromFile()
+ name = str(udir / "_test_file")
+ with rffi.scoped_str2charp(name) as filename:
+ with rffi.scoped_str2charp("wb") as mode:
+ w_file = api.PyFile_FromString(filename, mode)
+ fp = api.PyFile_AsFile(w_file)
+ assert fp is not None
+ w_file2 = api.PyFile_FromFile(fp, filename, mode, None)
+ assert w_file2 is not None
+ assert api.PyFile_Check(w_file2)
+ assert space.str_w(api.PyFile_Name(w_file2)) == name
@pytest.mark.xfail
def test_file_setbufsize(self, space, api):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit