mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix share_open() in py3 on windows
This commit is contained in:
parent
0410b0c4fb
commit
729540cebf
@ -9,7 +9,7 @@ import os, sys
|
||||
|
||||
from polyglot.builtins import reraise
|
||||
|
||||
from calibre.constants import iswindows, plugins
|
||||
from calibre.constants import iswindows
|
||||
|
||||
'''
|
||||
This module defines a share_open() function which is a replacement for
|
||||
@ -28,59 +28,6 @@ directory until all file handles are closed. To get around this, rename the
|
||||
file before deleting it.
|
||||
'''
|
||||
|
||||
speedup, err = plugins['speedup']
|
||||
|
||||
if not speedup:
|
||||
raise RuntimeError('Failed to load the speedup plugin with error: %s' % err)
|
||||
|
||||
valid_modes = {'a', 'a+', 'a+b', 'ab', 'r', 'rb', 'r+', 'r+b', 'w', 'wb', 'w+', 'w+b'}
|
||||
|
||||
|
||||
def validate_mode(mode):
|
||||
return mode in valid_modes
|
||||
|
||||
|
||||
class FlagConstants(object):
|
||||
|
||||
def __init__(self):
|
||||
for x in 'APPEND CREAT TRUNC EXCL RDWR RDONLY WRONLY'.split():
|
||||
x = 'O_' + x
|
||||
setattr(self, x, getattr(os, x))
|
||||
for x in 'RANDOM SEQUENTIAL TEXT BINARY'.split():
|
||||
x = 'O_' + x
|
||||
setattr(self, x, getattr(os, x, 0))
|
||||
|
||||
|
||||
fc = FlagConstants()
|
||||
|
||||
|
||||
def flags_from_mode(mode):
|
||||
if not validate_mode(mode):
|
||||
raise ValueError('The mode is invalid')
|
||||
m = mode[0]
|
||||
random = '+' in mode
|
||||
binary = 'b' in mode
|
||||
if m == 'a':
|
||||
flags = fc.O_APPEND | fc.O_CREAT
|
||||
if random:
|
||||
flags |= fc.O_RDWR | fc.O_RANDOM
|
||||
else:
|
||||
flags |= fc.O_WRONLY | fc.O_SEQUENTIAL
|
||||
elif m == 'r':
|
||||
if random:
|
||||
flags = fc.O_RDWR | fc.O_RANDOM
|
||||
else:
|
||||
flags = fc.O_RDONLY | fc.O_SEQUENTIAL
|
||||
elif m == 'w':
|
||||
if random:
|
||||
flags = fc.O_RDWR | fc.O_RANDOM
|
||||
else:
|
||||
flags = fc.O_WRONLY | fc.O_SEQUENTIAL
|
||||
flags |= fc.O_TRUNC | fc.O_CREAT
|
||||
flags |= (fc.O_BINARY if binary else fc.O_TEXT)
|
||||
return flags
|
||||
|
||||
|
||||
if iswindows:
|
||||
from numbers import Integral
|
||||
import msvcrt
|
||||
@ -127,7 +74,7 @@ if iswindows:
|
||||
reraise(
|
||||
WindowsError,
|
||||
WindowsError(pywinerr.winerror,
|
||||
(pywinerr.funcname or '') + b': ' + (pywinerr.strerror or '')),
|
||||
(pywinerr.funcname or '') + ': ' + (pywinerr.strerror or '')),
|
||||
sys.exc_info()[2])
|
||||
|
||||
def os_open(path, flags, mode=0o777, share_flags=FILE_SHARE_VALID_FLAGS):
|
||||
@ -168,13 +115,12 @@ if iswindows:
|
||||
path, access_flags, share_flags, None, create_flags, attrib_flags, None)
|
||||
except pywintypes.error as e:
|
||||
raise_winerror(e)
|
||||
ans = msvcrt.open_osfhandle(h, flags | os.O_NOINHERIT)
|
||||
h.Detach() # We dont want the handle to be automatically closed when h is deleted
|
||||
ans = msvcrt.open_osfhandle(h.Detach(), flags | os.O_NOINHERIT)
|
||||
return ans
|
||||
|
||||
def share_open(path, mode='r', buffering=-1):
|
||||
flags = flags_from_mode(mode)
|
||||
return speedup.fdopen(os_open(path, flags), path, mode, buffering)
|
||||
def share_open(*a, **kw):
|
||||
kw['opener'] = os_open
|
||||
return open(*a, **kw)
|
||||
|
||||
else:
|
||||
share_open = open
|
||||
@ -214,3 +160,8 @@ def find_tests():
|
||||
eq(f3.read(100), b'b' * 100)
|
||||
|
||||
return unittest.defaultTestLoader.loadTestsFromTestCase(SharedFileTest)
|
||||
|
||||
|
||||
def run_tests():
|
||||
from calibre.utils.run_tests import run_tests
|
||||
run_tests(find_tests)
|
||||
|
@ -127,30 +127,6 @@ speedup_detach(PyObject *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
speedup_fdopen(PyObject *self, PyObject *args) {
|
||||
PyObject *ans = NULL;
|
||||
char *name;
|
||||
#if PY_MAJOR_VERSION == 2
|
||||
FILE *fp;
|
||||
#endif
|
||||
int fd, bufsize = -1;
|
||||
char *mode;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iss|i", &fd, &name, &mode, &bufsize)) return NULL;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
ans = PyFile_FromFd(fd, NULL, mode, bufsize, NULL, NULL, NULL, 1);
|
||||
#else
|
||||
fp = fdopen(fd, mode);
|
||||
if (fp == NULL) return PyErr_SetFromErrno(PyExc_OSError);
|
||||
ans = PyFile_FromFile(fp, name, mode, fclose);
|
||||
if (ans != NULL) {
|
||||
PyFile_SetBufSize(ans, bufsize);
|
||||
}
|
||||
#endif
|
||||
return ans;
|
||||
}
|
||||
|
||||
static void calculate_gaussian_kernel(Py_ssize_t size, double *kernel, double radius) {
|
||||
const double sqr = radius * radius;
|
||||
const double factor = 1.0 / (2 * M_PI * sqr);
|
||||
@ -633,10 +609,6 @@ static PyMethodDef speedup_methods[] = {
|
||||
" This function returns an image (bytestring) in the PPM format as the texture."
|
||||
},
|
||||
|
||||
{"fdopen", speedup_fdopen, METH_VARARGS,
|
||||
"fdopen(fd, name, mode [, bufsize=-1)\n\nCreate a python file object from an OS file descriptor with a name. Note that this does not do any validation of mode, so you must ensure fd already has the correct flags set."
|
||||
},
|
||||
|
||||
{"websocket_mask", speedup_websocket_mask, METH_VARARGS,
|
||||
"websocket_mask(data, mask [, offset=0)\n\nXOR the data (bytestring) with the specified (must be 4-byte bytestring) mask"
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user