Author: Amaury Forgeot d'Arc <[email protected]>
Branch: decimal-libmpdec
Changeset: r73817:8f8d7ad8360d
Date: 2014-10-05 20:21 +0200
http://bitbucket.org/pypy/pypy/changeset/8f8d7ad8360d/
Log: hg merge py3.3
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -60,7 +60,8 @@
skip=None):
self.basename = basename
self._usemodules = usemodules.split() + [
- '_socket', 'binascii', 'rctime', 'select', 'signal']
+ '_socket', 'binascii', 'rctime',
+ 'select', 'signal', 'faulthandler']
if not sys.platform == 'win32':
self._usemodules.extend(['_posixsubprocess', 'fcntl'])
self._compiler = compiler
diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py
--- a/lib_pypy/ctypes_support.py
+++ b/lib_pypy/ctypes_support.py
@@ -22,7 +22,7 @@
def _where_is_errno():
return standard_c_lib._errno()
-elif sys.platform in ('linux2', 'freebsd6'):
+elif sys.platform in ('linux', 'freebsd6'):
standard_c_lib.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
standard_c_lib.__errno_location.argtypes = None
def _where_is_errno():
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -85,10 +85,13 @@
Abridged method (for -Ojit builds using Visual Studio 2008)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Download the versions of all the external packages
-from
+Download the versions of all the external packages from
+https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip
+(for 2.4 release and later) or
https://bitbucket.org/pypy/pypy/downloads/local.zip
-Then expand it into the base directory (base_dir) and modify your environment
to reflect this::
+(for pre-2.4 versions)
+Then expand it into the base directory (base_dir) and modify your environment
+to reflect this::
set PATH=<base_dir>\bin;<base_dir>\tcltk\bin;%PATH%
set INCLUDE=<base_dir>\include;<base_dir>\tcltk\include;%INCLUDE%
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -46,6 +46,7 @@
def cpython_code_signature(code):
"([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)."
argcount = code.co_argcount
+ varnames = code.co_varnames
if we_are_translated():
kwonlyargcount = code.co_kwonlyargcount
else:
@@ -53,16 +54,18 @@
kwonlyargcount = getattr(code, 'co_kwonlyargcount', 0)
assert argcount >= 0 # annotator hint
assert kwonlyargcount >= 0
- argnames = list(code.co_varnames[:argcount])
- kwonlyargs = list(code.co_varnames[argcount:argcount + kwonlyargcount])
+ argnames = list(varnames[:argcount])
+ if argcount < len(varnames):
+ kwonlyargs = list(varnames[argcount:argcount + kwonlyargcount])
+ else:
+ kwonlyargs = None
if code.co_flags & CO_VARARGS:
- varargname = code.co_varnames[argcount]
+ varargname = varnames[argcount]
argcount += 1
else:
varargname = None
if code.co_flags & CO_VARKEYWORDS:
kwargname = code.co_varnames[argcount + kwonlyargcount]
- argcount += 1
else:
kwargname = None
return Signature(argnames, varargname, kwargname, kwonlyargs)
diff --git a/pypy/interpreter/pyparser/test/test_parsestring.py
b/pypy/interpreter/pyparser/test/test_parsestring.py
--- a/pypy/interpreter/pyparser/test/test_parsestring.py
+++ b/pypy/interpreter/pyparser/test/test_parsestring.py
@@ -100,11 +100,11 @@
def test_simple_enc_roundtrip(self):
space = self.space
- s = "'\x81'"
+ s = "'\x81\\t'"
s = s.decode("koi8-u").encode("utf8")
w_ret = parsestring.parsestr(self.space, 'koi8-u', s)
ret = space.unwrap(w_ret)
- assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81'")
+ assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81\\t'")
def test_multiline_unicode_strings_with_backslash(self):
space = self.space
diff --git a/pypy/interpreter/test/test_app_main.py
b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -1064,7 +1064,7 @@
prefix = udir.join('pathtest').ensure(dir=1)
fake_exe = 'bin/pypy-c'
if sys.platform == 'win32':
- fake_exe += '.exe'
+ fake_exe = 'pypy-c.exe'
fake_exe = prefix.join(fake_exe).ensure(file=1)
expected_path = [str(prefix.join(subdir).ensure(dir=1))
for subdir in ('lib_pypy',
@@ -1104,8 +1104,10 @@
assert sys.path == old_sys_path + [self.goal_dir]
app_main.setup_bootstrap_path(self.fake_exe)
- assert sys.executable == '' # not executable!
- assert sys.path == old_sys_path + [self.goal_dir]
+ if not sys.platform == 'win32':
+ # an existing file is always 'executable' on windows
+ assert sys.executable == '' # not executable!
+ assert sys.path == old_sys_path + [self.goal_dir]
os.chmod(self.fake_exe, 0o755)
app_main.setup_bootstrap_path(self.fake_exe)
diff --git a/pypy/interpreter/test/test_code.py
b/pypy/interpreter/test/test_code.py
--- a/pypy/interpreter/test/test_code.py
+++ b/pypy/interpreter/test/test_code.py
@@ -194,3 +194,9 @@
# CO_NESTED
assert d['f'](4).__code__.co_flags & 0x10
assert d['f'].__code__.co_flags & 0x10 == 0
+
+ def test_issue1844(self):
+ import types
+ args = (1, 0, 1, 0, 0, b'', (), (), (), '', 'operator', 0, b'')
+ # previously raised a MemoryError when translated
+ types.CodeType(*args)
diff --git a/pypy/module/_cffi_backend/ctypefunc.py
b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -8,6 +8,7 @@
from rpython.rlib.jit_libffi import (CIF_DESCRIPTION, CIF_DESCRIPTION_P,
FFI_TYPE, FFI_TYPE_P, FFI_TYPE_PP, SIZE_OF_FFI_ARG)
from rpython.rlib.objectmodel import we_are_translated, instantiate
+from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from pypy.interpreter.error import OperationError, oefmt
@@ -160,6 +161,7 @@
raw_cdata = rffi.cast(rffi.CCHARPP, data)[0]
lltype.free(raw_cdata, flavor='raw')
lltype.free(buffer, flavor='raw')
+ keepalive_until_here(args_w)
return w_res
def get_mustfree_flag(data):
diff --git a/pypy/module/operator/app_operator.py
b/pypy/module/operator/app_operator.py
--- a/pypy/module/operator/app_operator.py
+++ b/pypy/module/operator/app_operator.py
@@ -4,7 +4,8 @@
This module exports a set of operators as functions. E.g. operator.add(x,y) is
equivalent to x+y.
'''
-from __pypy__ import builtinify
+
+import types
def countOf(a,b):
@@ -15,51 +16,78 @@
count += 1
return count
+def _resolve_attr_chain(chain, obj, idx=0):
+ obj = getattr(obj, chain[idx])
+ if idx + 1 == len(chain):
+ return obj
+ else:
+ return _resolve_attr_chain(chain, obj, idx + 1)
+
+
+class _simple_attrgetter(object):
+ def __init__(self, attr):
+ self._attr = attr
+
+ def __call__(self, obj):
+ return getattr(obj, self._attr)
+
+
+class _single_attrgetter(object):
+ def __init__(self, attrs):
+ self._attrs = attrs
+
+ def __call__(self, obj):
+ return _resolve_attr_chain(self._attrs, obj)
+
+
+class _multi_attrgetter(object):
+ def __init__(self, attrs):
+ self._attrs = attrs
+
+ def __call__(self, obj):
+ return tuple([
+ _resolve_attr_chain(attrs, obj)
+ for attrs in self._attrs
+ ])
+
+
def attrgetter(attr, *attrs):
+ if (
+ not isinstance(attr, str) or
+ not all(isinstance(a, str) for a in attrs)
+ ):
+ raise TypeError("attribute name must be a string, not %r" %
+ type(attr).__name__)
if attrs:
- getters = [single_attr_getter(a) for a in (attr,) + attrs]
- def getter(obj):
- return tuple([getter(obj) for getter in getters])
+ return _multi_attrgetter([
+ a.split(".") for a in [attr] + list(attrs)
+ ])
+ elif "." not in attr:
+ return _simple_attrgetter(attr)
else:
- getter = single_attr_getter(attr)
- return builtinify(getter)
+ return _single_attrgetter(attr.split("."))
-def single_attr_getter(attr):
- if not isinstance(attr, str):
- raise TypeError("attribute name must be a string, not {!r}".format(
- type(attr).__name__))
- #
- def make_getter(name, prevfn=None):
- if prevfn is None:
- def getter(obj):
- return getattr(obj, name)
+
+class itemgetter(object):
+ def __init__(self, item, *items):
+ self._single = not bool(items)
+ if self._single:
+ self._idx = item
else:
- def getter(obj):
- return getattr(prevfn(obj), name)
- return getter
- #
- last = 0
- getter = None
- while True:
- dot = attr.find(".", last)
- if dot < 0: break
- getter = make_getter(attr[last:dot], getter)
- last = dot + 1
- return make_getter(attr[last:], getter)
+ self._idx = [item] + list(items)
+ def __call__(self, obj):
+ if self._single:
+ return obj[self._idx]
+ else:
+ return tuple([obj[i] for i in self._idx])
-def itemgetter(item, *items):
- if items:
- list_of_indices = [item] + list(items)
- def getter(obj):
- return tuple([obj[i] for i in list_of_indices])
- else:
- def getter(obj):
- return obj[item]
- return builtinify(getter)
+class methodcaller(object):
+ def __init__(self, method_name, *args, **kwargs):
+ self._method_name = method_name
+ self._args = args
+ self._kwargs = kwargs
-def methodcaller(method_name, *args, **kwargs):
- def call(obj):
- return getattr(obj, method_name)(*args, **kwargs)
- return builtinify(call)
+ def __call__(self, obj):
+ return getattr(obj, self._method_name)(*self._args, **self._kwargs)
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -168,6 +168,12 @@
# not visible via os, inconsistency in nt:
if hasattr(posix, '_getfullpathname'):
interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname'
+ if os.name == 'nt':
+ interpleveldefs.update({
+ '_getfileinformation': 'interp_posix._getfileinformation',
+ # XXX: currently broken
+ #'_getfinalpathname': 'interp_posix._getfinalpathname',
+ })
if hasattr(os, 'chroot'):
interpleveldefs['chroot'] = 'interp_posix.chroot'
diff --git a/pypy/module/posix/interp_posix.py
b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -5,8 +5,7 @@
from rpython.rlib.objectmodel import specialize
from rpython.rlib.rarithmetic import r_longlong
from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.module import ll_os_stat
-from rpython.rtyper.module.ll_os import RegisterOs
+from rpython.rtyper.module import ll_os, ll_os_stat
from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
@@ -1234,7 +1233,7 @@
raise wrap_oserror(space, e)
def declare_new_w_star(name):
- if name in RegisterOs.w_star_returning_int:
+ if name in ll_os.RegisterOs.w_star_returning_int:
@unwrap_spec(status=c_int)
def WSTAR(space, status):
return space.wrap(getattr(os, name)(status))
@@ -1246,7 +1245,7 @@
WSTAR.func_name = name
return WSTAR
-for name in RegisterOs.w_star:
+for name in ll_os.RegisterOs.w_star:
if hasattr(os, name):
func = declare_new_w_star(name)
globals()[name] = func
@@ -1412,3 +1411,25 @@
if codeset:
return space.wrap(codeset)
return space.w_None
+
+if _WIN32:
+ @unwrap_spec(fd=c_int)
+ def _getfileinformation(space, fd):
+ try:
+ info = ll_os._getfileinformation(fd)
+ except OSError as e:
+ raise wrap_oserror(space, e)
+ return space.newtuple([space.wrap(info[0]),
+ space.wrap(info[1]),
+ space.wrap(info[2])])
+
+ def _getfinalpathname(space, w_path):
+ path = space.unicode_w(w_path)
+ try:
+ result = ll_os._getfinalpathname(path)
+ except ll_os.LLNotImplemented as e:
+ raise OperationError(space.w_NotImplementedError,
+ space.wrap(e.msg))
+ except OSError as e:
+ raise wrap_oserror2(space, e, w_path)
+ return space.wrap(result)
diff --git a/pypy/module/posix/test/test_posix2.py
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -1069,6 +1069,24 @@
# just ensure it returns something reasonable
assert encoding is None or type(encoding) is str
+ if os.name == 'nt':
+ def test__getfileinformation(self):
+ import os
+ path = os.path.join(self.pdir, 'file1')
+ with open(path) as fp:
+ info = self.posix._getfileinformation(fp.fileno())
+ assert len(info) == 3
+ assert all(isinstance(obj, int) for obj in info)
+
+ def test__getfinalpathname(self):
+ import os
+ path = os.path.join(self.pdir, 'file1')
+ try:
+ result = self.posix._getfinalpathname(path)
+ except NotImplementedError:
+ skip("_getfinalpathname not supported on this platform")
+ assert os.path.exists(result)
+
def test_rtld_constants(self):
# check presence of major RTLD_* constants
self.posix.RTLD_LAZY
@@ -1076,6 +1094,7 @@
self.posix.RTLD_GLOBAL
self.posix.RTLD_LOCAL
+
class AppTestEnvironment(object):
def setup_class(cls):
cls.space = space
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -23,7 +23,7 @@
'__name__' : '(space.wrap("sys"))',
'__doc__' : '(space.wrap("PyPy sys module"))',
- 'platform' : 'space.wrap(sys.platform)',
+ 'platform' : 'space.wrap(system.PLATFORM)',
'maxsize' : 'space.wrap(sys.maxint)',
'byteorder' : 'space.wrap(sys.byteorder)',
'maxunicode' : 'space.wrap(vm.MAXUNICODE)',
diff --git a/pypy/module/sys/system.py b/pypy/module/sys/system.py
--- a/pypy/module/sys/system.py
+++ b/pypy/module/sys/system.py
@@ -1,4 +1,6 @@
"""Information about the current system."""
+import sys
+
from pypy.objspace.std.complexobject import HASH_IMAG
from pypy.objspace.std.floatobject import HASH_INF, HASH_NAN
from pypy.objspace.std.intobject import HASH_MODULUS
@@ -6,6 +8,7 @@
from rpython.rlib import rbigint, rfloat
from rpython.rtyper.lltypesystem import lltype, rffi
+PLATFORM = 'linux' if sys.platform.startswith('linux') else sys.platform
app = gateway.applevel("""
"NOT_RPYTHON"
diff --git a/pypy/module/sys/test/test_sysmodule.py
b/pypy/module/sys/test/test_sysmodule.py
--- a/pypy/module/sys/test/test_sysmodule.py
+++ b/pypy/module/sys/test/test_sysmodule.py
@@ -127,9 +127,9 @@
assert isinstance(sys.__stdin__, io.IOBase)
assert sys.__stderr__.errors == 'backslashreplace'
- assert sys.__stdin__.name == "<stdin>"
- assert sys.__stdout__.name == "<stdout>"
- assert sys.__stderr__.name == "<stderr>"
+ #assert sys.__stdin__.name == "<stdin>"
+ #assert sys.__stdout__.name == "<stdout>"
+ #assert sys.__stderr__.name == "<stderr>"
if self.appdirect and not isinstance(sys.stdin, io.IOBase):
return
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -306,10 +306,16 @@
import imp
argparse = imp.load_source('argparse', 'lib-python/2.7/argparse.py')
if sys.platform == 'win32':
- pypy_exe = 'pypy.exe'
- license_base = os.path.join(basedir, r'..\..\..\local') # as on
buildbot YMMV
+ pypy_exe = 'pypy3.exe'
+ for p in [os.path.join(basedir, r'..\..\..\local'), #buildbot
+ os.path.join(basedir, r'..\local')]: # pypy/doc/windows.rst
+ if os.path.exists(p):
+ license_base = p
+ break
+ else:
+ license_base = 'unkown'
else:
- pypy_exe = 'pypy'
+ pypy_exe = 'pypy3'
license_base = '/usr/share/doc'
parser = argparse.ArgumentParser()
args = list(args)
@@ -380,5 +386,21 @@
if __name__ == '__main__':
import sys
+ if sys.platform == 'win32':
+ # Try to avoid opeing a dialog box if one of the
+ # subprocesses causes a system error
+ import ctypes
+ winapi = ctypes.windll.kernel32
+ SetErrorMode = winapi.SetErrorMode
+ SetErrorMode.argtypes=[ctypes.c_int]
+
+ SEM_FAILCRITICALERRORS = 1
+ SEM_NOGPFAULTERRORBOX = 2
+ SEM_NOOPENFILEERRORBOX = 0x8000
+ flags = SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX
+ #Since there is no GetErrorMode, do a double Set
+ old_mode = SetErrorMode(flags)
+ SetErrorMode(old_mode | flags)
+
retval, _ = package(*sys.argv[1:])
sys.exit(retval)
diff --git a/pypy/tool/release/test/test_package.py
b/pypy/tool/release/test/test_package.py
--- a/pypy/tool/release/test/test_package.py
+++ b/pypy/tool/release/test/test_package.py
@@ -115,15 +115,21 @@
check(pypy, 0755)
def test_generate_license():
- from os.path import dirname, abspath, join
+ from os.path import dirname, abspath, join, exists
class Options(object):
pass
options = Options()
basedir = dirname(dirname(dirname(dirname(dirname(abspath(__file__))))))
options.no_tk = False
if sys.platform == 'win32':
- # as on buildbot YMMV
- options.license_base = join(basedir, r'..\..\..\local')
+ for p in [join(basedir, r'..\..\..\local'), #buildbot
+ join(basedir, r'..\local')]: # pypy/doc/windows.rst
+ if exists(p):
+ license_base = p
+ break
+ else:
+ license_base = 'unkown'
+ options.license_base = license_base
else:
options.license_base = '/usr/share/doc'
license = package.generate_license(py.path.local(basedir), options)
diff --git a/rpython/jit/backend/arm/callbuilder.py
b/rpython/jit/backend/arm/callbuilder.py
--- a/rpython/jit/backend/arm/callbuilder.py
+++ b/rpython/jit/backend/arm/callbuilder.py
@@ -92,7 +92,8 @@
self.mc.LDR_ri(r.r7.value, r.r5.value)
# change 'rpy_fastgil' to 0 (it should be non-zero right now)
- self.mc.DMB()
+ if self.asm.cpu.cpuinfo.arch_version >= 7:
+ self.mc.DMB()
self.mc.gen_load_int(r.r6.value, fastgil)
self.mc.MOV_ri(r.ip.value, 0)
self.mc.STR_ri(r.ip.value, r.r6.value)
@@ -112,7 +113,8 @@
self.mc.STREX(r.r3.value, r.ip.value, r.r6.value, c=c.EQ)
# try to claim the lock
self.mc.CMP_ri(r.r3.value, 0, cond=c.EQ) # did this succeed?
- self.mc.DMB()
+ if self.asm.cpu.cpuinfo.arch_version >= 7:
+ self.mc.DMB()
# the success of the lock acquisition is defined by
# 'EQ is true', or equivalently by 'r3 == 0'.
#
diff --git a/rpython/jit/backend/arm/codebuilder.py
b/rpython/jit/backend/arm/codebuilder.py
--- a/rpython/jit/backend/arm/codebuilder.py
+++ b/rpython/jit/backend/arm/codebuilder.py
@@ -333,6 +333,8 @@
| (rn & 0xF) << 16)
def DMB(self):
+ # ARMv7 only. I guess ARMv6 CPUs cannot be used in symmetric
+ # multi-processing at all? That would make this instruction unneeded.
# note: 'cond' is only permitted on Thumb here, but don't
# write literally 0xf57ff05f, because it's larger than 31 bits
c = cond.AL
diff --git a/rpython/jit/backend/arm/instructions.py
b/rpython/jit/backend/arm/instructions.py
--- a/rpython/jit/backend/arm/instructions.py
+++ b/rpython/jit/backend/arm/instructions.py
@@ -142,6 +142,7 @@
#'VCVT' : {'opc1':0xB, 'opc2':0xE, 'opc3':0x1, 'base': False},
}
+# ARMv7 only
simd_instructions_3regs = {
'VADD_i64': {'A': 0x8, 'B': 0, 'U': 0},
'VSUB_i64': {'A': 0x8, 'B': 0, 'U': 1},
diff --git a/rpython/jit/backend/llsupport/rewrite.py
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -1,3 +1,4 @@
+from rpython.rlib import rgc
from rpython.rlib.rarithmetic import ovfcheck
from rpython.rtyper.lltypesystem import llmemory
from rpython.jit.metainterp import history
@@ -390,8 +391,8 @@
val = op.getarg(0)
if val not in self.write_barrier_applied:
v = op.getarg(1)
- if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
- bool(v.value)): # store a non-NULL
+ if (isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+ rgc.needs_write_barrier(v.value))):
self.gen_write_barrier(val)
#op = op.copy_and_change(rop.SETFIELD_RAW)
self.newops.append(op)
@@ -400,8 +401,8 @@
val = op.getarg(0)
if val not in self.write_barrier_applied:
v = op.getarg(2)
- if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
- bool(v.value)): # store a non-NULL
+ if (isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+ rgc.needs_write_barrier(v.value))):
self.gen_write_barrier_array(val, op.getarg(1))
#op = op.copy_and_change(rop.SET{ARRAYITEM,INTERIORFIELD}_RAW)
self.newops.append(op)
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -158,3 +158,4 @@
return res
LoadLibrary = rwin32.LoadLibrary
+ GetModuleHandle = rwin32.GetModuleHandle
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -86,6 +86,14 @@
collect(i)
i += 1
+def needs_write_barrier(obj):
+ """ We need to emit write barrier if the right hand of assignment
+ is in nursery, used by the JIT for handling set*_gc(Const)
+ """
+ if not obj:
+ return False
+ return can_move(obj)
+
def _heap_stats():
raise NotImplementedError # can't be run directly
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -130,6 +130,7 @@
# is hidden by operations in ll2ctypes. Call it now.
GetLastError()
+ GetModuleHandle = winexternal('GetModuleHandleA', [rffi.CCHARP], HMODULE)
LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], HMODULE)
GetProcAddress = winexternal('GetProcAddress',
[HMODULE, rffi.CCHARP],
diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -361,7 +361,9 @@
functype = ctypes.CFUNCTYPE
if sys.platform == 'win32':
from rpython.rlib.clibffi import FFI_STDCALL, FFI_DEFAULT_ABI
- if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL:
+ # XXX:
+ #if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == FFI_STDCALL:
+ if getattr(T.TO, 'ABI', FFI_DEFAULT_ABI) == 'FFI_STDCALL':
# for win32 system call
functype = ctypes.WINFUNCTYPE
argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
diff --git a/rpython/rtyper/lltypesystem/lltype.py
b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -1,16 +1,17 @@
-from types import NoneType, MethodType
import weakref
+from types import MethodType, NoneType
+
+from rpython.annotator.bookkeeper import analyzer_for, immutablevalue
from rpython.annotator.model import (
- SomeInteger, SomeBool, SomeObject, AnnotatorError)
+ AnnotatorError, SomeBool, SomeInteger, SomeObject)
+from rpython.rlib.objectmodel import Symbolic
from rpython.rlib.rarithmetic import (
- r_int, r_uint, intmask, r_singlefloat, r_ulonglong, r_longlong,
- r_longfloat, r_longlonglong, base_int, normalizedinttype, longlongmask,
- longlonglongmask, maxint, is_valid_int, is_emulated_long)
-from rpython.rlib.objectmodel import Symbolic
+ base_int, intmask, is_emulated_long, is_valid_int, longlonglongmask,
+ longlongmask, maxint, normalizedinttype, r_int, r_longfloat, r_longlong,
+ r_longlonglong, r_singlefloat, r_uint, r_ulonglong)
+from rpython.rtyper.extregistry import ExtRegistryEntry
+from rpython.tool import leakfinder
from rpython.tool.identity_dict import identity_dict
-from rpython.tool import leakfinder
-from rpython.annotator.bookkeeper import analyzer_for, immutablevalue
-from rpython.rtyper.extregistry import ExtRegistryEntry
class State(object):
pass
@@ -313,14 +314,12 @@
except KeyError:
return ContainerType.__getattr__(self, name)
-
def _nofield(self, name):
raise AttributeError('struct %s has no field %r' % (self._name,
name))
def _names_without_voids(self):
- names_without_voids = [name for name in self._names if
self._flds[name] is not Void]
- return names_without_voids
+ return [name for name in self._names if self._flds[name] is not Void]
def _str_fields_without_voids(self):
return ', '.join(['%s: %s' % (name, self._flds[name])
@@ -576,8 +575,10 @@
_gckind = 'raw'
def __init__(self, tag, hints={}):
- """ if hints['render_structure'] is set, the type is internal and not
considered
- to come from somewhere else (it should be rendered as a structure)
"""
+ """If hints['render_structure'] is set, the type is internal and
+ not considered to come from somewhere else (it should be
+ rendered as a structure)
+ """
self.tag = tag
self.__name__ = tag
self.hints = frozendict(hints)
@@ -675,7 +676,8 @@
_numbertypes = {int: Number("Signed", int, intmask)}
_numbertypes[r_int] = _numbertypes[int]
-_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong,
longlonglongmask)
+_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong,
+ longlonglongmask)
if r_longlong is not r_int:
_numbertypes[r_longlong] = Number("SignedLongLong", r_longlong,
longlongmask)
@@ -702,8 +704,8 @@
UnsignedLongLong = build_number("UnsignedLongLong", r_ulonglong)
Float = Primitive("Float", 0.0) # C type 'double'
-SingleFloat = Primitive("SingleFloat", r_singlefloat(0.0)) # C type 'float'
-LongFloat = Primitive("LongFloat", r_longfloat(0.0)) # C type 'long
double'
+SingleFloat = Primitive("SingleFloat", r_singlefloat(0.0)) # 'float'
+LongFloat = Primitive("LongFloat", r_longfloat(0.0)) # 'long double'
r_singlefloat._TYPE = SingleFloat
Char = Primitive("Char", '\x00')
@@ -876,9 +878,11 @@
@analyzer_for(cast_primitive)
def ann_cast_primitive(T, s_v):
- from rpython.rtyper.llannotation import annotation_to_lltype,
ll_to_annotation
+ from rpython.rtyper.llannotation import (
+ annotation_to_lltype, ll_to_annotation)
assert T.is_constant()
- return ll_to_annotation(cast_primitive(T.const,
annotation_to_lltype(s_v)._defl()))
+ return ll_to_annotation(cast_primitive(T.const,
+ annotation_to_lltype(s_v)._defl()))
def _cast_whatever(TGT, value):
@@ -905,7 +909,8 @@
elif TGT == llmemory.Address and isinstance(ORIG, Ptr):
return llmemory.cast_ptr_to_adr(value)
elif TGT == Signed and isinstance(ORIG, Ptr) and ORIG.TO._gckind == 'raw':
- return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(value),
'symbolic')
+ return llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(value),
+ 'symbolic')
raise TypeError("don't know how to cast from %r to %r" % (ORIG, TGT))
@@ -1176,8 +1181,8 @@
except DelayedPointer:
return True # assume it's not a delayed null
- # _setobj, _getobj and _obj0 are really _internal_ implementations details
of _ptr,
- # use _obj if necessary instead !
+ # _setobj, _getobj and _obj0 are really _internal_ implementations
+ # details of _ptr, use _obj if necessary instead !
def _setobj(self, pointing_to, solid=False):
if pointing_to is None:
obj0 = None
@@ -1244,12 +1249,12 @@
if T1 == T2:
setattr(self._obj, field_name, val)
else:
- raise TypeError("%r instance field %r:\n"
- "expects %r\n"
- " got %r" % (self._T, field_name, T1,
T2))
+ raise TypeError(
+ "%r instance field %r:\nexpects %r\n got %r" %
+ (self._T, field_name, T1, T2))
return
- raise AttributeError("%r instance has no field %r" % (self._T,
- field_name))
+ raise AttributeError("%r instance has no field %r" %
+ (self._T, field_name))
def __getitem__(self, i): # ! can only return basic or ptr !
if isinstance(self._T, (Array, FixedSizeArray)):
@@ -1266,7 +1271,8 @@
if isinstance(self._T, (Array, FixedSizeArray)):
T1 = self._T.OF
if isinstance(T1, ContainerType):
- raise TypeError("cannot directly assign to container array
items")
+ raise TypeError("cannot directly assign to container array "
+ "items")
T2 = typeOf(val)
if T2 != T1:
from rpython.rtyper.lltypesystem import rffi
@@ -1316,7 +1322,8 @@
from rpython.rtyper.lltypesystem import rffi
if isinstance(self._T, FuncType):
if len(args) != len(self._T.ARGS):
- raise TypeError("calling %r with wrong argument number: %r" %
(self._T, args))
+ raise TypeError("calling %r with wrong argument number: %r" %
+ (self._T, args))
for i, a, ARG in zip(range(len(self._T.ARGS)), args, self._T.ARGS):
if typeOf(a) != ARG:
# ARG could be Void
@@ -1415,11 +1422,13 @@
raise RuntimeError("widening to trash: %r" % self)
PARENTTYPE = struc._parent_type
if getattr(parent, PARENTTYPE._names[0]) != struc:
- raise InvalidCast(CURTYPE, PTRTYPE) # xxx different exception
perhaps?
+ # xxx different exception perhaps?
+ raise InvalidCast(CURTYPE, PTRTYPE)
struc = parent
u -= 1
if PARENTTYPE != PTRTYPE.TO:
- raise RuntimeError("widening %r inside %r instead of %r" %
(CURTYPE, PARENTTYPE, PTRTYPE.TO))
+ raise RuntimeError("widening %r inside %r instead of %r" %
+ (CURTYPE, PARENTTYPE, PTRTYPE.TO))
return _ptr(PTRTYPE, struc, solid=self._solid)
def _cast_to_int(self, check=True):
@@ -1430,7 +1439,9 @@
return obj # special case for cast_int_to_ptr() results
obj = normalizeptr(self, check)._getobj(check)
if isinstance(obj, int):
- return obj # special case for cast_int_to_ptr() results put
into opaques
+ # special case for cast_int_to_ptr() results put into
+ # opaques
+ return obj
if getattr(obj, '_read_directly_intval', False):
return obj.intval # special case for _llgcopaque
result = intmask(obj._getid())
@@ -1468,7 +1479,8 @@
"""XXX A nice docstring here"""
T = typeOf(val)
if isinstance(T, ContainerType):
- if self._T._gckind == 'gc' and T._gckind == 'raw' and not
isinstance(T, OpaqueType):
+ if (self._T._gckind == 'gc' and T._gckind == 'raw' and
+ not isinstance(T, OpaqueType)):
val = _interior_ptr(T, self._obj, [offset])
else:
val = _ptr(Ptr(T), val, solid=self._solid)
@@ -1531,12 +1543,14 @@
setattr(example, s_attr.const, v_lltype._defl())
def call(self, args):
- from rpython.rtyper.llannotation import annotation_to_lltype,
ll_to_annotation
+ from rpython.rtyper.llannotation import (
+ annotation_to_lltype, ll_to_annotation)
args_s, kwds_s = args.unpack()
if kwds_s:
raise Exception("keyword arguments to call to a low-level fn ptr")
info = 'argument to ll function pointer call'
- llargs = [annotation_to_lltype(s_arg, info)._defl() for s_arg in
args_s]
+ llargs = [annotation_to_lltype(s_arg, info)._defl()
+ for s_arg in args_s]
v = self.ll_ptrtype._example()(*llargs)
return ll_to_annotation(v)
@@ -1593,7 +1607,6 @@
return val
-
assert not '__dict__' in dir(_interior_ptr)
class _container(object):
@@ -1721,11 +1734,13 @@
__slots__ = ('_hash_cache_', '_compilation_info')
- def __new__(self, TYPE, n=None, initialization=None, parent=None,
parentindex=None):
+ def __new__(self, TYPE, n=None, initialization=None, parent=None,
+ parentindex=None):
my_variety = _struct_variety(TYPE._names)
return object.__new__(my_variety)
- def __init__(self, TYPE, n=None, initialization=None, parent=None,
parentindex=None):
+ def __init__(self, TYPE, n=None, initialization=None, parent=None,
+ parentindex=None):
_parentable.__init__(self, TYPE)
if n is not None and TYPE._arrayfld is None:
raise TypeError("%r is not variable-sized" % (TYPE,))
@@ -1734,9 +1749,11 @@
first, FIRSTTYPE = TYPE._first_struct()
for fld, typ in TYPE._flds.items():
if fld == TYPE._arrayfld:
- value = _array(typ, n, initialization=initialization,
parent=self, parentindex=fld)
+ value = _array(typ, n, initialization=initialization,
+ parent=self, parentindex=fld)
else:
- value = typ._allocate(initialization=initialization,
parent=self, parentindex=fld)
+ value = typ._allocate(initialization=initialization,
+ parent=self, parentindex=fld)
setattr(self, fld, value)
if parent is not None:
self._setparentstructure(parent, parentindex)
@@ -1795,7 +1812,8 @@
__slots__ = ('items',)
- def __init__(self, TYPE, n, initialization=None, parent=None,
parentindex=None):
+ def __init__(self, TYPE, n, initialization=None, parent=None,
+ parentindex=None):
if not is_valid_int(n):
raise TypeError("array length must be an int")
if n < 0:
@@ -1964,7 +1982,8 @@
if not key._was_freed():
newcache[key] = value
except RuntimeError:
- pass # ignore "accessing subxxx, but already gc-ed
parent"
+ # ignore "accessing subxxx, but already gc-ed parent"
+ pass
if newcache:
_subarray._cache[T] = newcache
else:
@@ -2020,8 +2039,10 @@
attrs.setdefault('_name', '?')
attrs.setdefault('_callable', None)
self.__dict__.update(attrs)
- if '_callable' in attrs and hasattr(attrs['_callable'],
'_compilation_info'):
- self.__dict__['compilation_info'] =
attrs['_callable']._compilation_info
+ if '_callable' in attrs and hasattr(attrs['_callable'],
+ '_compilation_info'):
+ self.__dict__['compilation_info'] = \
+ attrs['_callable']._compilation_info
def __repr__(self):
return '<%s>' % (self,)
@@ -2126,8 +2147,8 @@
return _ptr(Ptr(T), o, solid)
@analyzer_for(malloc)
-def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None,
s_track_allocation=None,
- s_add_memory_pressure=None):
+def ann_malloc(s_T, s_n=None, s_flavor=None, s_zero=None,
+ s_track_allocation=None, s_add_memory_pressure=None):
assert (s_n is None or s_n.knowntype == int
or issubclass(s_n.knowntype, base_int))
assert s_T.is_constant()
@@ -2303,7 +2324,8 @@
@analyzer_for(runtime_type_info)
def ann_runtime_type_info(s_p):
- assert isinstance(s_p, SomePtr), "runtime_type_info of non-pointer: %r" %
s_p
+ assert isinstance(s_p, SomePtr), \
+ "runtime_type_info of non-pointer: %r" % s_p
return SomePtr(typeOf(runtime_type_info(s_p.ll_ptrtype._example())))
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -105,6 +105,12 @@
_CYGWIN = sys.platform == 'cygwin'
+# plain NotImplementedError is invalid RPython
+class LLNotImplemented(NotImplementedError):
+
+ def __init__(self, msg):
+ self.msg = msg
+
class CConfig:
"""
Definitions for platform integration.
@@ -1179,7 +1185,7 @@
condition=sys.platform=='win32')
def register_posix__getfullpathname(self, traits):
# this nt function is not exposed via os, but needed
- # to get a correct implementation of os.abspath
+ # to get a correct implementation of os.path.abspath
from rpython.rtyper.module.ll_win32file import
make_getfullpathname_impl
getfullpathname_llimpl = make_getfullpathname_impl(traits)
@@ -1963,10 +1969,12 @@
return OsEnvironController()
# ____________________________________________________________
-# Support for the WindowsError exception
+# Support for the WindowsError exception and misc functions
if sys.platform == 'win32':
from rpython.rlib import rwin32
+ from rpython.rtyper.module.ll_win32file import (
+ make__getfileinformation_impl, make__getfinalpathname_impl)
class RegisterFormatError(BaseLazyRegistering):
def __init__(self):
@@ -1977,3 +1985,6 @@
return extdef([lltype.Signed], str,
"rwin32_FormatError",
llimpl=rwin32.llimpl_FormatError)
+
+ _getfileinformation = make__getfileinformation_impl(UnicodeTraits())
+ _getfinalpathname = make__getfinalpathname_impl(UnicodeTraits())
diff --git a/rpython/rtyper/module/ll_os_stat.py
b/rpython/rtyper/module/ll_os_stat.py
--- a/rpython/rtyper/module/ll_os_stat.py
+++ b/rpython/rtyper/module/ll_os_stat.py
@@ -186,7 +186,10 @@
_name_struct_stat = '_stati64'
INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h']
else:
- _name_struct_stat = 'stat'
+ if sys.platform.startswith('linux'):
+ _name_struct_stat = 'stat64'
+ else:
+ _name_struct_stat = 'stat'
INCLUDES = ['sys/types.h', 'sys/stat.h', 'sys/statvfs.h', 'unistd.h']
compilation_info = ExternalCompilationInfo(
diff --git a/rpython/rtyper/module/ll_win32file.py
b/rpython/rtyper/module/ll_win32file.py
--- a/rpython/rtyper/module/ll_win32file.py
+++ b/rpython/rtyper/module/ll_win32file.py
@@ -55,6 +55,15 @@
FILE_TYPE_CHAR = platform.ConstantInteger('FILE_TYPE_CHAR')
FILE_TYPE_PIPE = platform.ConstantInteger('FILE_TYPE_PIPE')
+ FILE_WRITE_ATTRIBUTES = platform.ConstantInteger(
+ 'FILE_WRITE_ATTRIBUTES')
+ OPEN_EXISTING = platform.ConstantInteger(
+ 'OPEN_EXISTING')
+ FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger(
+ 'FILE_FLAG_BACKUP_SEMANTICS')
+ VOLUME_NAME_DOS = platform.ConstantInteger('VOLUME_NAME_DOS')
+ VOLUME_NAME_NT = platform.ConstantInteger('VOLUME_NAME_NT')
+
WIN32_FILE_ATTRIBUTE_DATA = platform.Struct(
'WIN32_FILE_ATTRIBUTE_DATA',
[('dwFileAttributes', rwin32.DWORD),
@@ -67,14 +76,15 @@
BY_HANDLE_FILE_INFORMATION = platform.Struct(
'BY_HANDLE_FILE_INFORMATION',
[('dwFileAttributes', rwin32.DWORD),
+ ('ftCreationTime', rwin32.FILETIME),
+ ('ftLastAccessTime', rwin32.FILETIME),
+ ('ftLastWriteTime', rwin32.FILETIME),
+ ('dwVolumeSerialNumber', rwin32.DWORD),
('nFileSizeHigh', rwin32.DWORD),
('nFileSizeLow', rwin32.DWORD),
('nNumberOfLinks', rwin32.DWORD),
('nFileIndexHigh', rwin32.DWORD),
- ('nFileIndexLow', rwin32.DWORD),
- ('ftCreationTime', rwin32.FILETIME),
- ('ftLastAccessTime', rwin32.FILETIME),
- ('ftLastWriteTime', rwin32.FILETIME)])
+ ('nFileIndexLow', rwin32.DWORD)])
config = platform.configure(CConfig)
@@ -92,6 +102,8 @@
INVALID_FILE_ATTRIBUTES
_S_IFDIR _S_IFREG _S_IFCHR _S_IFIFO
FILE_TYPE_UNKNOWN FILE_TYPE_CHAR FILE_TYPE_PIPE
+ FILE_WRITE_ATTRIBUTES OPEN_EXISTING
FILE_FLAG_BACKUP_SEMANTICS
+ VOLUME_NAME_DOS VOLUME_NAME_NT
ERROR_FILE_NOT_FOUND ERROR_NO_MORE_FILES
ERROR_SHARING_VIOLATION
'''.split():
@@ -163,6 +175,13 @@
[traits.CCHARP, traits.CCHARP],
rwin32.BOOL)
+ CreateFile = external(
+ 'CreateFile' + apisuffix,
+ [traits.CCHARP, rwin32.DWORD, rwin32.DWORD,
+ rwin32.LPSECURITY_ATTRIBUTES, rwin32.DWORD, rwin32.DWORD,
+ rwin32.HANDLE],
+ rwin32.HANDLE)
+
DeleteFile = external(
'DeleteFile' + suffix,
[traits.CCHARP],
@@ -173,7 +192,29 @@
[traits.CCHARP, traits.CCHARP],
rwin32.BOOL)
- return Win32Traits
+ GETFINALPATHNAMEBYHANDLE_TP = lltype.Ptr(lltype.FuncType(
+ [rwin32.HANDLE, traits.CCHARP, rwin32.DWORD, rwin32.DWORD],
+ rwin32.DWORD, abi='FFI_STDCALL'))
+ # dynamically loaded
+ GetFinalPathNameByHandle = lltype.nullptr(
+ GETFINALPATHNAMEBYHANDLE_TP.TO)
+
+ def check_GetFinalPathNameByHandle(self):
+ if self.GetFinalPathNameByHandle:
+ return True
+
+ from rpython.rlib.rdynload import GetModuleHandle, dlsym
+ hKernel32 = GetModuleHandle("KERNEL32")
+ try:
+ func = dlsym(hKernel32, 'GetFinalPathNameByHandle' + suffix)
+ except KeyError:
+ return False
+
+ self.GetFinalPathNameByHandle = rffi.cast(
+ Win32Traits.GETFINALPATHNAMEBYHANDLE_TP, func)
+ return True
+
+ return Win32Traits()
#_______________________________________________________________
# listdir
@@ -336,27 +377,6 @@
win32traits = make_win32_traits(traits)
from rpython.rtyper.module.ll_os_stat import time_t_to_FILE_TIME
- class CConfig:
- _compilation_info_ = ExternalCompilationInfo(
- includes = ['windows.h'],
- )
-
- FILE_WRITE_ATTRIBUTES = platform.ConstantInteger(
- 'FILE_WRITE_ATTRIBUTES')
- OPEN_EXISTING = platform.ConstantInteger(
- 'OPEN_EXISTING')
- FILE_FLAG_BACKUP_SEMANTICS = platform.ConstantInteger(
- 'FILE_FLAG_BACKUP_SEMANTICS')
- globals().update(platform.configure(CConfig))
-
- CreateFile = rffi.llexternal(
- 'CreateFile' + win32traits.apisuffix,
- [traits.CCHARP, rwin32.DWORD, rwin32.DWORD,
- rwin32.LPSECURITY_ATTRIBUTES, rwin32.DWORD, rwin32.DWORD,
- rwin32.HANDLE],
- rwin32.HANDLE,
- calling_conv='win')
-
GetSystemTime = rffi.llexternal(
'GetSystemTime',
[lltype.Ptr(rwin32.SYSTEMTIME)],
@@ -381,10 +401,10 @@
@specialize.argtype(1)
def os_utime_llimpl(path, tp):
- hFile = CreateFile(path,
- FILE_WRITE_ATTRIBUTES, 0,
- None, OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
+ hFile = win32traits.CreateFile(path,
+ win32traits.FILE_WRITE_ATTRIBUTES, 0,
+ None, win32traits.OPEN_EXISTING,
+ win32traits.FILE_FLAG_BACKUP_SEMANTICS,
rwin32.NULL_HANDLE)
if hFile == rwin32.INVALID_HANDLE_VALUE:
raise rwin32.lastWindowsError()
@@ -413,3 +433,68 @@
lltype.free(mtime, flavor='raw')
return os_utime_llimpl
+
+#_______________________________________________________________
+# _getfileinformation (py3)
+
+def make__getfileinformation_impl(traits):
+ from rpython.rlib import rwin32
+ win32traits = make_win32_traits(traits)
+
+ def _getfileinformation_llimpl(fd):
+ hFile = rwin32.get_osfhandle(fd)
+ with lltype.scoped_alloc(
+ win32traits.BY_HANDLE_FILE_INFORMATION) as info:
+ if win32traits.GetFileInformationByHandle(hFile, info) == 0:
+ raise rwin32.lastWindowsError("_getfileinformation")
+ return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber),
+ rffi.cast(lltype.Signed, info.c_nFileIndexHigh),
+ rffi.cast(lltype.Signed, info.c_nFileIndexLow))
+
+ return _getfileinformation_llimpl
+
+#_______________________________________________________________
+# _getfinalpathname (py3)
+
+def make__getfinalpathname_impl(traits):
+ from rpython.rlib import rwin32
+ from rpython.rtyper.module.ll_os import LLNotImplemented
+ assert traits.str is unicode, 'Currently only handles unicode paths'
+ win32traits = make_win32_traits(traits)
+
+ def _getfinalpathname_llimpl(path):
+ if not win32traits.check_GetFinalPathNameByHandle():
+ raise LLNotImplemented("GetFinalPathNameByHandle not available on "
+ "this platform")
+
+ hFile = win32traits.CreateFile(path, 0, 0, None,
+ win32traits.OPEN_EXISTING,
+ win32traits.FILE_FLAG_BACKUP_SEMANTICS,
+ rwin32.NULL_HANDLE)
+ if hFile == rwin32.INVALID_HANDLE_VALUE:
+ raise rwin32.lastWindowsError("CreateFile")
+
+ VOLUME_NAME_DOS = rffi.cast(rwin32.DWORD, win32traits.VOLUME_NAME_DOS)
+ try:
+ size = win32traits.GetFinalPathNameByHandle(
+ hFile,
+ lltype.nullptr(traits.CCHARP.TO),
+ rffi.cast(rwin32.DWORD, 0),
+ VOLUME_NAME_DOS)
+ if size == 0:
+ raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
+
+ with lltype.scoped_alloc(traits.CCHARP.TO, size + 1) as
target_path:
+ result = win32traits.GetFinalPathNameByHandle(
+ hFile,
+ target_path,
+ size,
+ VOLUME_NAME_DOS)
+ if result == 0:
+ raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
+ return traits.charpsize2str(target_path,
+ rffi.cast(lltype.Signed, result))
+ finally:
+ rwin32.CloseHandle(hFile)
+
+ return _getfinalpathname_llimpl
diff --git a/rpython/rtyper/module/support.py b/rpython/rtyper/module/support.py
--- a/rpython/rtyper/module/support.py
+++ b/rpython/rtyper/module/support.py
@@ -49,6 +49,7 @@
CHAR = rffi.CHAR
CCHARP = rffi.CCHARP
charp2str = staticmethod(rffi.charp2str)
+ charpsize2str = staticmethod(rffi.charpsize2str)
scoped_str2charp = staticmethod(rffi.scoped_str2charp)
str2charp = staticmethod(rffi.str2charp)
free_charp = staticmethod(rffi.free_charp)
@@ -68,6 +69,7 @@
CHAR = rffi.WCHAR_T
CCHARP = rffi.CWCHARP
charp2str = staticmethod(rffi.wcharp2unicode)
+ charpsize2str = staticmethod(rffi.wcharpsize2unicode)
str2charp = staticmethod(rffi.unicode2wcharp)
scoped_str2charp = staticmethod(rffi.scoped_unicode2wcharp)
free_charp = staticmethod(rffi.free_wcharp)
diff --git a/rpython/rtyper/module/test/test_ll_win32file.py
b/rpython/rtyper/module/test/test_ll_win32file.py
new file mode 100644
--- /dev/null
+++ b/rpython/rtyper/module/test/test_ll_win32file.py
@@ -0,0 +1,26 @@
+import os
+
+import py
+
+from rpython.rtyper.module import ll_os
+
+if not ll_os._WIN32:
+ py.test.skip("requires Windows")
+
+
+def test__getfileinformation():
+ with open(__file__) as fp:
+ stat = os.fstat(fp.fileno())
+ info = ll_os._getfileinformation(fp.fileno())
+ serial, high, low = info
+ assert type(serial) in (int, long)
+ assert (high << 32) + low == stat.st_ino
+
+
+def test__getfinalpathname():
+ path = __file__.decode('mbcs')
+ try:
+ result = ll_os._getfinalpathname(path)
+ except ll_os.LLNotImplemented:
+ py.test.skip("_getfinalpathname not supported on this platform")
+ assert os.path.exists(result)
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -476,11 +476,12 @@
shutil_copy(str(soname), str(newsoname))
self.log.info("copied: %s" % (newsoname,))
if sys.platform == 'win32':
- # copy the import library as well
- libname = soname.new(ext='lib')
- newlibname = newexename.new(basename=soname.basename)
- shutil.copyfile(str(libname),
str(newlibname.new(ext='lib')))
- self.log.info("copied: %s" % (newlibname,))
+ ext_to_copy = ['lib', 'pdb']
+ for ext in ext_to_copy:
+ name = soname.new(ext=ext)
+ newname = newexename.new(basename=soname.basename)
+ shutil.copyfile(str(name), str(newname.new(ext=ext)))
+ self.log.info("copied: %s" % (newname,))
self.c_entryp = newexename
self.log.info('usession directory: %s' % (udir,))
self.log.info("created: %s" % (self.c_entryp,))
diff --git a/rpython/translator/platform/test/test_makefile.py
b/rpython/translator/platform/test/test_makefile.py
--- a/rpython/translator/platform/test/test_makefile.py
+++ b/rpython/translator/platform/test/test_makefile.py
@@ -44,6 +44,7 @@
assert res.returncode == 0
def test_900_files(self):
+ tmpdir = udir.join('test_900_files').ensure(dir=1)
txt = '#include <stdio.h>\n'
for i in range(900):
txt += 'int func%03d();\n' % i
@@ -52,11 +53,11 @@
txt += ' j += func%03d();\n' % i
txt += ' printf("%d\\n", j);\n'
txt += ' return 0;};\n'
- cfile = udir.join('test_900_files.c')
+ cfile = tmpdir.join('test_900_files.c')
cfile.write(txt)
cfiles = [cfile]
for i in range(900):
- cfile2 = udir.join('implement%03d.c' %i)
+ cfile2 = tmpdir.join('implement%03d.c' %i)
cfile2.write('''
int func%03d()
{
@@ -64,10 +65,10 @@
}
''' % (i, i))
cfiles.append(cfile2)
- mk = self.platform.gen_makefile(cfiles, ExternalCompilationInfo(),
path=udir)
+ mk = self.platform.gen_makefile(cfiles, ExternalCompilationInfo(),
path=tmpdir)
mk.write()
self.platform.execute_makefile(mk)
- res = self.platform.execute(udir.join('test_900_files'))
+ res = self.platform.execute(tmpdir.join('test_900_files'))
self.check_res(res, '%d\n' %sum(range(900)))
def test_precompiled_headers(self):
diff --git a/rpython/translator/platform/windows.py
b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -203,6 +203,9 @@
# the assembler still has the old behavior that all options
# must come first, and after the file name all options are ignored.
# So please be careful with the order of parameters! ;-)
+ pdb_dir = oname.dirname
+ if pdb_dir:
+ compile_args += ['/Fd%s\\' % (pdb_dir,)]
args = ['/nologo', '/c'] + compile_args + ['/Fo%s' % (oname,),
str(cfile)]
self._execute_c_compiler(cc, args, oname)
return oname
@@ -407,7 +410,7 @@
'int main(int argc, char* argv[]) '
'{ return $(PYPY_MAIN_FUNCTION)(argc, argv); } > $@')
m.rule('$(DEFAULT_TARGET)', ['$(TARGET)', 'main.obj'],
- ['$(CC_LINK) /nologo main.obj $(SHARED_IMPORT_LIB) /out:$@
/MANIFEST /MANIFESTFILE:$*.manifest',
+ ['$(CC_LINK) /nologo /debug main.obj $(SHARED_IMPORT_LIB)
/out:$@ /MANIFEST /MANIFESTFILE:$*.manifest',
'mt.exe -nologo -manifest $*.manifest
-outputresource:$@;1',
])
m.rule('debugmode_$(DEFAULT_TARGET)', ['debugmode_$(TARGET)',
'main.obj'],
diff --git a/rpython/translator/sandbox/rsandbox.py
b/rpython/translator/sandbox/rsandbox.py
--- a/rpython/translator/sandbox/rsandbox.py
+++ b/rpython/translator/sandbox/rsandbox.py
@@ -60,8 +60,7 @@
def need_more_data(self):
buflen = self.buflen
- buf = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw')
- try:
+ with lltype.scoped_alloc(rffi.CCHARP.TO, buflen) as buf:
buflen = rffi.cast(rffi.SIZE_T, buflen)
count = ll_read_not_sandboxed(self.fd, buf, buflen)
count = rffi.cast(lltype.Signed, count)
@@ -69,20 +68,15 @@
raise IOError
self.buf += ''.join([buf[i] for i in range(count)])
self.buflen *= 2
- finally:
- lltype.free(buf, flavor='raw')
def sandboxed_io(buf):
STDIN = 0
STDOUT = 1
# send the buffer with the marshalled fnname and input arguments to STDOUT
- p = lltype.malloc(rffi.CCHARP.TO, len(buf), flavor='raw')
- try:
+ with lltype.scoped_alloc(rffi.CCHARP.TO, len(buf)) as p:
for i in range(len(buf)):
p[i] = buf[i]
writeall_not_sandboxed(STDOUT, p, len(buf))
- finally:
- lltype.free(p, flavor='raw')
# build a Loader that will get the answer from STDIN
loader = FdLoader(STDIN)
# check for errors
@@ -108,9 +102,8 @@
@signature(types.str(), returns=types.impossible())
def not_implemented_stub(msg):
STDERR = 2
- buf = rffi.str2charp(msg + '\n')
- writeall_not_sandboxed(STDERR, buf, len(msg) + 1)
- rffi.free_charp(buf)
+ with rffi.scoped_str2charp(msg + '\n') as buf:
+ writeall_not_sandboxed(STDERR, buf, len(msg) + 1)
raise RuntimeError(msg) # XXX in RPython, the msg is ignored at the moment
dump_string = rmarshal.get_marshaller(str)
diff --git a/rpython/translator/test/test_driver.py
b/rpython/translator/test/test_driver.py
--- a/rpython/translator/test/test_driver.py
+++ b/rpython/translator/test/test_driver.py
@@ -55,12 +55,15 @@
src_name = udir.join('src/dydy2.exe')
dll_name = udir.join('src/pypy.dll')
lib_name = udir.join('src/pypy.lib')
+ pdb_name = udir.join('src/pypy.pdb')
src_name.ensure()
src_name.write('exe')
dll_name.ensure()
dll_name.write('dll')
lib_name.ensure()
lib_name.write('lib')
+ pdb_name.ensure()
+ pdb_name.write('pdb')
dst_name.ensure()
class CBuilder(object):
@@ -75,6 +78,8 @@
assert dst_name.new(ext='lib').read() == 'lib'
def test_shutil_copy():
+ if os.name == 'nt':
+ py.test.skip('Windows cannot copy or rename to an in-use file')
a = udir.join('file_a')
b = udir.join('file_a')
a.write('hello')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit