Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r95194:248ed5fa4ded Date: 2018-10-08 20:30 +0200 http://bitbucket.org/pypy/pypy/changeset/248ed5fa4ded/
Log: hg merge default diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py --- a/pypy/module/_codecs/test/test_codecs.py +++ b/pypy/module/_codecs/test/test_codecs.py @@ -761,6 +761,26 @@ assert b"\\u3042\u3xxx".decode("unicode-escape", "test.handler1") == \ u"\u3042[<92><117><51>]xxx" + def test_unicode_internal_error_handler_infinite_loop(self): + import codecs + class MyException(Exception): + pass + seen = [0] + def handler_unicodeinternal(exc): + if not isinstance(exc, UnicodeDecodeError): + raise TypeError("don't know how to handle %r" % exc) + seen[0] += 1 + if seen[0] == 20: # stop the 20th time this is called + raise MyException + return (u"\x01", 4) # 4 < len(input), so will try and fail again + codecs.register_error("test.inf", handler_unicodeinternal) + try: + b"\x00\x00\x00\x00\x00".decode("unicode-internal", "test.inf") + except MyException: + pass + else: + raise AssertionError("should have gone into infinite loop") + def test_encode_error_bad_handler(self): import codecs codecs.register_error("test.bad_handler", lambda e: (repl, 1)) 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,8 +93,11 @@ if sys.platform == 'win32': dash = '_' + WIN32 = True else: dash = '' + WIN32 = False + def fclose(fp): try: @@ -610,7 +613,7 @@ 'PyObject_CallMethod', 'PyObject_CallFunctionObjArgs', 'PyObject_CallMethodObjArgs', '_PyObject_CallFunction_SizeT', '_PyObject_CallMethod_SizeT', - 'PyObject_GetBuffer', 'PyBuffer_Release', + 'PyObject_DelItemString', 'PyObject_GetBuffer', 'PyBuffer_Release', '_Py_setfilesystemdefaultencoding', 'PyCapsule_New', 'PyCapsule_IsValid', 'PyCapsule_GetPointer', @@ -1664,7 +1667,11 @@ try: ll_libname = rffi.str2charp(path) try: - dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags) + if WIN32: + # Allow other DLLs in the same directory with "path" + dll = rdynload.dlopenex(ll_libname) + else: + dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags) finally: lltype.free(ll_libname, flavor='raw') except rdynload.DLOpenError as e: diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py --- a/pypy/module/cpyext/eval.py +++ b/pypy/module/cpyext/eval.py @@ -9,6 +9,7 @@ from pypy.module.cpyext.pyobject import PyObject from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno from pypy.module.cpyext.funcobject import PyCodeObject +from pypy.module.cpyext.frameobject import PyFrameObject from pypy.module.__builtin__ import compiling PyCompilerFlags = cpython_struct( @@ -58,6 +59,11 @@ return None return caller.get_w_globals() # borrowed ref +@cpython_api([], PyFrameObject, error=CANNOT_FAIL, result_borrowed=True) +def PyEval_GetFrame(space): + caller = space.getexecutioncontext().gettopframe_nohidden() + return caller # borrowed ref, may be null + @cpython_api([PyCodeObject, PyObject, PyObject], PyObject) def PyEval_EvalCode(space, w_code, w_globals, w_locals): """This is a simplified interface to PyEval_EvalCodeEx(), with just diff --git a/pypy/module/cpyext/include/abstract.h b/pypy/module/cpyext/include/abstract.h --- a/pypy/module/cpyext/include/abstract.h +++ b/pypy/module/cpyext/include/abstract.h @@ -4,6 +4,15 @@ extern "C" { #endif + PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key); + + /* + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ + + /* new buffer API */ #define PyObject_CheckBuffer(obj) \ @@ -27,6 +36,27 @@ /* Releases a Py_buffer obtained from getbuffer ParseTuple's s*. */ +/* Mapping protocol:*/ + + /* implemented as a macro: + + int PyMapping_DelItemString(PyObject *o, char *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) + + /* implemented as a macro: + + int PyMapping_DelItem(PyObject *o, PyObject *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) #ifdef __cplusplus } diff --git a/pypy/module/cpyext/src/abstract.c b/pypy/module/cpyext/src/abstract.c --- a/pypy/module/cpyext/src/abstract.c +++ b/pypy/module/cpyext/src/abstract.c @@ -23,6 +23,23 @@ /* Operations on any object */ int +PyObject_DelItemString(PyObject *o, char *key) +{ + PyObject *okey; + int ret; + + if (o == NULL || key == NULL) { + null_error(); + return -1; + } + okey = PyUnicode_FromString(key); + if (okey == NULL) + return -1; + ret = PyObject_DelItem(o, okey); + Py_DECREF(okey); + return ret; +} +int PyObject_CheckReadBuffer(PyObject *obj) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; @@ -96,6 +113,20 @@ return 0; } +/* Buffer C-API for Python 3.0 */ + +int +PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) +{ + if (!PyObject_CheckBuffer(obj)) { + PyErr_Format(PyExc_TypeError, + "'%100s' does not have the buffer interface", + Py_TYPE(obj)->tp_name); + return -1; + } + return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); +} + void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) { @@ -111,6 +142,7 @@ return (void*)pointer; } + void _Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape) { @@ -253,19 +285,6 @@ -/* Buffer C-API for Python 3.0 */ - -int -PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) -{ - if (!PyObject_CheckBuffer(obj)) { - PyErr_Format(PyExc_TypeError, - "'%100s' does not have the buffer interface", - Py_TYPE(obj)->tp_name); - return -1; - } - return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); -} void PyBuffer_Release(Py_buffer *view) @@ -427,6 +446,7 @@ return retval; } + static PyObject * objargs_mktuple(va_list va) { diff --git a/pypy/module/cpyext/stubs-find-implemented.py b/pypy/module/cpyext/stubs-find-implemented.py new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/stubs-find-implemented.py @@ -0,0 +1,21 @@ +import re +import os + + +for line in open('stubs.py'): + if not line.strip(): + continue + if line.startswith(' '): + continue + if line.startswith('#'): + continue + if line.startswith('@cpython_api'): + continue + if line.endswith(' = rffi.VOIDP\n'): + continue + + #print line.rstrip() + m = re.match(r"def ([\w\d_]+)[(]", line) + assert m, line + funcname = m.group(1) + os.system('grep -w %s [a-r]*.py s[a-s]*.py str*.py stubsa*.py sy*.py [t-z]*.py' % funcname) diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py --- a/pypy/module/cpyext/stubs.py +++ b/pypy/module/cpyext/stubs.py @@ -1,29 +1,10 @@ -from pypy.module.cpyext.api import ( - cpython_api, PyObject, PyObjectP, CANNOT_FAIL - ) -from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex -from rpython.rtyper.lltypesystem import rffi, lltype +#----this file is not imported, only here for reference---- -CWCHARPP = lltype.Ptr(lltype.Array(rffi.CWCHARP, hints={'nolength': True})) - -# we don't really care -PyTypeObjectPtr = rffi.VOIDP -Py_ssize_t = rffi.SSIZE_T -PyModuleDef = rffi.VOIDP -PyMethodDef = rffi.VOIDP -PyGetSetDef = rffi.VOIDP -PyMemberDef = rffi.VOIDP -va_list = rffi.VOIDP -wrapperbase = rffi.VOIDP -FILE = rffi.VOIDP -PyFrameObject = rffi.VOIDP -_inittab = rffi.VOIDP -PyThreadState = rffi.VOIDP -PyInterpreterState = rffi.VOIDP -Py_UNICODE = lltype.UniChar -PyCompilerFlags = rffi.VOIDP -struct_node = rffi.VOIDP -Py_tracefunc = rffi.VOIDP +#from pypy.module.cpyext.api import ( +# cpython_api, PyObject, PyObjectP, CANNOT_FAIL +# ) +#from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex +#from rpython.rtyper.lltypesystem import rffi, lltype @cpython_api([rffi.CCHARP], Py_ssize_t, error=-1) @@ -228,39 +209,6 @@ this method returns zero and sets errno to EDOM.""" raise NotImplementedError -@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, rffi.INTP], rffi.CCHARP) -def PyOS_double_to_string(space, val, format_code, precision, flags, ptype): - """Convert a double val to a string using supplied - format_code, precision, and flags. - - format_code must be one of 'e', 'E', 'f', 'F', - 'g', 'G' or 'r'. For 'r', the supplied precision - must be 0 and is ignored. The 'r' format code specifies the - standard repr() format. - - flags can be zero or more of the values Py_DTSF_SIGN, - Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together: - - Py_DTSF_SIGN means to always precede the returned string with a sign - character, even if val is non-negative. - - Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look - like an integer. - - Py_DTSF_ALT means to apply "alternate" formatting rules. See the - documentation for the PyOS_snprintf() '#' specifier for - details. - - If ptype is non-NULL, then the value it points to will be set to one of - Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that - val is a finite number, an infinite number, or not a number, respectively. - - The return value is a pointer to buffer with the converted string or - NULL if the conversion failed. The caller is responsible for freeing the - returned string by calling PyMem_Free(). - """ - raise NotImplementedError - @cpython_api([rffi.CCHARP, rffi.CCHARP], rffi.CCHARP) def PyOS_stricmp(space, s1, s2): """Case insensitive comparison of strings. The function works almost @@ -275,24 +223,6 @@ """ raise NotImplementedError -@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PyTZInfo_Check(space, ob): - """Return true if ob is of type PyDateTime_TZInfoType or a subtype of - PyDateTime_TZInfoType. ob must not be NULL. - """ - raise NotImplementedError - -@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) -def PyTZInfo_CheckExact(space, ob): - """Return true if ob is of type PyDateTime_TZInfoType. ob must not be - NULL. - """ - raise NotImplementedError - -@cpython_api([PyTypeObjectPtr, PyGetSetDef], PyObject) -def PyDescr_NewGetSet(space, type, getset): - raise NotImplementedError - @cpython_api([PyTypeObjectPtr, PyMemberDef], PyObject) def PyDescr_NewMember(space, type, meth): raise NotImplementedError @@ -483,31 +413,6 @@ 0 on success, -1 on failure.""" raise NotImplementedError -@cpython_api([PyObject], rffi.INT_real, error=-1) -def Py_ReprEnter(space, object): - """Called at the beginning of the tp_repr implementation to - detect cycles. - - If the object has already been processed, the function returns a - positive integer. In that case the tp_repr implementation - should return a string object indicating a cycle. As examples, - dict objects return {...} and list objects - return [...]. - - The function will return a negative integer if the recursion limit - is reached. In that case the tp_repr implementation should - typically return NULL. - - Otherwise, the function returns zero and the tp_repr - implementation can continue normally.""" - raise NotImplementedError - -@cpython_api([PyObject], lltype.Void) -def Py_ReprLeave(space, object): - """Ends a Py_ReprEnter(). Must be called once for each - invocation of Py_ReprEnter() that returns zero.""" - raise NotImplementedError - @cpython_api([rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.INT_real, rffi.CCHARP, rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject) def PyFile_FromFd(space, fd, name, mode, buffering, encoding, errors, newline, closefd): """Create a Python file object from the file descriptor of an already @@ -1295,39 +1200,6 @@ """ raise NotImplementedError -@cpython_api([PyObject], rffi.VOIDP) -def PyModule_GetState(space, module): - """Return the "state" of the module, that is, a pointer to the block of memory - allocated at module creation time, or NULL. See - PyModuleDef.m_size.""" - raise NotImplementedError - -@cpython_api([PyObject], PyModuleDef) -def PyModule_GetDef(space, module): - """Return a pointer to the PyModuleDef struct from which the module was - created, or NULL if the module wasn't created with - PyModule_Create().""" - raise NotImplementedError - - -@cpython_api([PyModuleDef], PyObject) -def PyModule_Create(space, module): - """Create a new module object, given the definition in module. This behaves - like PyModule_Create2() with module_api_version set to - PYTHON_API_VERSION.""" - raise NotImplementedError - - -@cpython_api([PyModuleDef, rffi.INT_real], PyObject) -def PyModule_Create2(space, module, module_api_version): - """Create a new module object, given the definition in module, assuming the - API version module_api_version. If that version does not match the version - of the running interpreter, a RuntimeWarning is emitted. - - Most uses of this function should be using PyModule_Create() - instead; only use this if you are sure you need it.""" - raise NotImplementedError - @cpython_api([PyObject, rffi.INT_real], PyObject) def PyNumber_ToBase(space, n, base): """Returns the integer n converted to base base as a string. The base @@ -1337,23 +1209,6 @@ PyNumber_Index() first.""" raise NotImplementedError -@cpython_api([PyObject], PyObject) -def PyObject_Bytes(space, o): - """ - Compute a bytes representation of object o. NULL is returned on - failure and a bytes object on success. This is equivalent to the Python - expression bytes(o), when o is not an integer. Unlike bytes(o), - a TypeError is raised when o is an integer instead of a zero-initialized - bytes object.""" - raise NotImplementedError - -@cpython_api([], PyFrameObject) -def PyEval_GetFrame(space): - """Return the current thread state's frame, which is NULL if no frame is - currently executing.""" - raise NotImplementedError - borrow_from() - @cpython_api([PyFrameObject], rffi.INT_real, error=-1) def PyFrame_GetLineNumber(space, frame): """Return the line number that frame is currently executing.""" diff --git a/pypy/module/cpyext/test/test_eval.py b/pypy/module/cpyext/test/test_eval.py --- a/pypy/module/cpyext/test/test_eval.py +++ b/pypy/module/cpyext/test/test_eval.py @@ -510,3 +510,15 @@ assert run_async(list1()) == ([], [0, 1, 2]) assert run_async(list2()) == ([], [0, 1, 2]) """ + + def test_getframe(self): + import sys + module = self.import_extension('foo', [ + ("getframe1", "METH_NOARGS", + """ + PyFrameObject *x = PyEval_GetFrame(); + Py_INCREF(x); + return (PyObject *)x; + """),], prologue="#include <frameobject.h>\n") + res = module.getframe1() + assert res is sys._getframe(0) diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -151,7 +151,7 @@ if getattr(func, '_elidable_function_', False): raise TypeError("it does not make sense for %s to be both elidable and unroll_safe" % func) if not getattr(func, '_jit_look_inside_', True): - raise TypeError("it does not make sense for %s to be both elidable and dont_look_inside" % func) + raise TypeError("it does not make sense for %s to be both unroll_safe and dont_look_inside" % func) func._jit_unroll_safe_ = True return func diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py --- a/rpython/rlib/rdynload.py +++ b/rpython/rlib/rdynload.py @@ -233,6 +233,15 @@ raise DLOpenError(ustr.encode('utf-8')) return res + def dlopenex(name): + res = rwin32.LoadLibraryExA(name) + if not res: + err = rwin32.GetLastError_saved() + ustr = rwin32.FormatErrorW(err) + # DLOpenError unicode msg breaks translation of cpyext create_extension_module + raise DLOpenError(ustr.encode('utf-8')) + return res + def dlclose(handle): res = rwin32.FreeLibrary(handle) if res: diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -730,16 +730,21 @@ length = rwin32.MAX_PATH + 1 traits = _preferred_traits(path) win32traits = make_win32_traits(traits) - with traits.scoped_alloc_buffer(length) as buf: - res = win32traits.GetFullPathName( - traits.as_str0(path), rffi.cast(rwin32.DWORD, length), - buf.raw, lltype.nullptr(win32traits.LPSTRP.TO)) - if res == 0: - raise rwin32.lastSavedWindowsError("_getfullpathname failed") - result = buf.str(intmask(res)) - assert result is not None - result = rstring.assert_str0(result) - return result + while True: # should run the loop body maximum twice + with traits.scoped_alloc_buffer(length) as buf: + res = win32traits.GetFullPathName( + traits.as_str0(path), rffi.cast(rwin32.DWORD, length), + buf.raw, lltype.nullptr(win32traits.LPSTRP.TO)) + res = intmask(res) + if res == 0: + raise rwin32.lastSavedWindowsError("_getfullpathname failed") + if res >= length: + length = res + 1 + continue + result = buf.str(res) + assert result is not None + result = rstring.assert_str0(result) + return result c_getcwd = external(UNDERSCORE_ON_WIN32 + 'getcwd', [rffi.CCHARP, rffi.SIZE_T], rffi.CCHARP, diff --git a/rpython/rlib/runicode.py b/rpython/rlib/runicode.py --- a/rpython/rlib/runicode.py +++ b/rpython/rlib/runicode.py @@ -1775,8 +1775,6 @@ "truncated input", s, pos, size) result.append(res) - if pos > size - unicode_bytes: - break continue t = r_uint(0) h = 0 diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -113,6 +113,7 @@ MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE STD_ERROR_HANDLE HANDLE_FLAG_INHERIT FILE_TYPE_CHAR + LOAD_WITH_ALTERED_SEARCH_PATH """ from rpython.translator.platform import host_factory static_platform = host_factory() @@ -195,6 +196,22 @@ GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE) LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE, save_err=rffi.RFFI_SAVE_LASTERROR) + def wrap_loadlibraryex(func): + def loadlibrary(name, handle=None, flags=LOAD_WITH_ALTERED_SEARCH_PATH): + # Requires a full path name with '/' -> '\\' + return func(name, handle, flags) + return loadlibrary + + _LoadLibraryExA = winexternal('LoadLibraryExA', + [rffi.CCHARP, HANDLE, DWORD], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + LoadLibraryExA = wrap_loadlibraryex(_LoadLibraryExA) + LoadLibraryW = winexternal('LoadLibraryW', [rffi.CWCHARP], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + _LoadLibraryExW = winexternal('LoadLibraryExW', + [rffi.CWCHARP, HANDLE, DWORD], HMODULE, + save_err=rffi.RFFI_SAVE_LASTERROR) + LoadLibraryExW = wrap_loadlibraryex(_LoadLibraryExW) GetProcAddress = winexternal('GetProcAddress', [HMODULE, rffi.CCHARP], rffi.VOIDP) diff --git a/rpython/rlib/test/loadtest/loadtest0.dll b/rpython/rlib/test/loadtest/loadtest0.dll new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9bdcc33a1902f8e989d349c49c2cc08e633aa32b GIT binary patch [cut] diff --git a/rpython/rlib/test/loadtest/loadtest1.dll b/rpython/rlib/test/loadtest/loadtest1.dll new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb83854875c876717371bdf90488eed9c6571f03 GIT binary patch [cut] diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -83,6 +83,14 @@ # the most intriguing failure of ntpath.py should not repeat, here: assert not data.endswith(stuff) + @win_only + def test__getfullpathname_long(self): + stuff = "C:" + "\\abcd" * 100 + py.test.raises(WindowsError, rposix.getfullpathname, stuff) + ustuff = u"C:" + u"\\abcd" * 100 + res = rposix.getfullpathname(ustuff) + assert res == ustuff + def test_getcwd(self): assert rposix.getcwd() == os.getcwd() diff --git a/rpython/rlib/test/test_rwin32.py b/rpython/rlib/test/test_rwin32.py --- a/rpython/rlib/test/test_rwin32.py +++ b/rpython/rlib/test/test_rwin32.py @@ -6,6 +6,44 @@ from rpython.rlib import rwin32 from rpython.tool.udir import udir +loadtest_dir = os.path.dirname(__file__) + '/loadtest' +test1 = os.path.abspath(loadtest_dir + '/loadtest1.dll') +test0 = os.path.abspath(loadtest_dir + '/loadtest0.dll') + +if not os.path.exists(test1) or not os.path.exists(test0): + # This is how the files, which are checked into the repo, were created + from rpython.translator.tool.cbuild import ExternalCompilationInfo + from rpython.translator.platform import platform + from rpython.translator import cdir + if not os.path.exists(loadtest_dir): + os.mkdir(loadtest_dir) + c_file = udir.ensure("test_rwin32", dir=1).join("test0.c") + c_file.write(py.code.Source(''' + #include "src/precommondefs.h" + RPY_EXPORTED + int internal_sum(int a, int b) { + return a + b; + } + ''')) + eci = ExternalCompilationInfo(include_dirs=[cdir]) + lib_name = str(platform.compile([c_file], eci, test0[:-4], + standalone=False)) + assert os.path.abspath(lib_name) == os.path.abspath(test0) + + c_file = udir.ensure("test_rwin32", dir=1).join("test1.c") + c_file.write(py.code.Source(''' + #include "src/precommondefs.h" + int internal_sum(int a, int b); + RPY_EXPORTED + int sum(int a, int b) { + return internal_sum(a, b); + } + ''')) + eci = ExternalCompilationInfo(include_dirs=[cdir], + libraries=[loadtest_dir + '/loadtest0']) + lib_name = str(platform.compile([c_file], eci, test1[:-4], + standalone=False, )) + assert os.path.abspath(lib_name) == os.path.abspath(test1) def test_get_osfhandle(): fid = open(str(udir.join('validate_test.txt')), 'w') @@ -28,13 +66,13 @@ "import time;" "time.sleep(10)", ], - ) + ) print proc.pid handle = rwin32.OpenProcess(rwin32.PROCESS_ALL_ACCESS, False, proc.pid) assert rwin32.TerminateProcess(handle, signal.SIGTERM) == 1 rwin32.CloseHandle(handle) assert proc.wait() == signal.SIGTERM - + @py.test.mark.dont_track_allocations('putenv intentionally keeps strings alive') def test_wenviron(): name, value = u'PYPY_TEST_日本', u'foobar日本' @@ -55,3 +93,48 @@ msg = rwin32.FormatErrorW(34) assert type(msg) is unicode assert u'%2' in msg + +def test_loadlibraryA(): + # test0 can be loaded alone, but test1 requires the modified search path + hdll = rwin32.LoadLibrary(test0) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'internal_sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + + hdll = rwin32.LoadLibrary(test1) + assert not hdll + + assert os.path.exists(test1) + + hdll = rwin32.LoadLibraryExA(test1) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + +def test_loadlibraryW(): + # test0 can be loaded alone, but test1 requires the modified search path + hdll = rwin32.LoadLibraryW(unicode(test0)) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'internal_sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + + hdll = rwin32.LoadLibraryW(unicode(test1)) + assert not hdll + + assert os.path.exists(unicode(test1)) + + hdll = rwin32.LoadLibraryExW(unicode(test1)) + assert hdll + faddr = rwin32.GetProcAddress(hdll, 'sum') + assert faddr + assert rwin32.FreeLibrary(hdll) + +def test_loadlibrary_unicode(): + import shutil + test0u = unicode(udir.join(u'load\u03betest.dll')) + shutil.copyfile(test0, test0u) + hdll = rwin32.LoadLibraryW(test0u) + assert hdll _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit