Commits

Hakan Ardo committed a40f788 Merge

merge default

Comments (0)

Files changed (71)

lib-python/2.7/ctypes/__init__.py

File contents unchanged.

lib-python/2.7/mailbox.py

File contents unchanged.

lib-python/2.7/tarfile.py

File contents unchanged.

lib-python/2.7/test/test_mailbox.py

File contents unchanged.

lib-python/2.7/test/test_old_mailbox.py

File contents unchanged.

lib-python/2.7/test/test_os.py

File contents unchanged.

lib-python/2.7/test/test_tarfile.py

File contents unchanged.

lib-python/2.7/test/test_zipfile.py

File contents unchanged.

lib-python/2.7/zipfile.py

File contents unchanged.

lib-python/conftest.py

 
 from pypy.tool.pytest import appsupport 
 from pypy.tool.pytest.confpath import pypydir, testdir, testresultdir
+from pypy.config.parse import parse_info
 
 pytest_plugins = "resultlog",
 rsyncdirs = ['.', '../pypy/']
 
             # check modules
             info = py.process.cmdexec("%s --info" % execpath)
+            info = parse_info(info)
             for mod in regrtest.usemodules:
-                if "objspace.usemodules.%s: False" % mod in info:
+                if info.get('objspace.usemodules.%s' % mod) is not True:
                     py.test.skip("%s module not included in %s" % (mod,
                                                                    execpath))
                     

lib_pypy/_ctypes_test.py

File contents unchanged.

lib_pypy/_testcapi.py

File contents unchanged.

pypy/config/parse.py

+
+
+def parse_info(text):
+    """See test_parse.py."""
+    text = text.lstrip()
+    result = {}
+    if (text+':').index(':') > (text+'=').index('='):
+        # found a '=' before a ':' means that we have the new format
+        current = {0: ''}
+        indentation_prefix = None
+        for line in text.splitlines():
+            line = line.rstrip()
+            if not line:
+                continue
+            realline = line.lstrip()
+            indent = len(line) - len(realline)
+            #
+            # 'indentation_prefix' is set when the previous line was a [group]
+            if indentation_prefix is not None:
+                assert indent > max(current)     # missing indent?
+                current[indent] = indentation_prefix
+                indentation_prefix = None
+                #
+            else:
+                # in case of dedent, must kill the extra items from 'current'
+                for n in current.keys():
+                    if n > indent:
+                        del current[n]
+            #
+            prefix = current[indent]      # KeyError if bad dedent
+            #
+            if realline.startswith('[') and realline.endswith(']'):
+                indentation_prefix = prefix + realline[1:-1] + '.'
+            else:
+                # build the whole dotted key and evaluate the value
+                i = realline.index(' = ')
+                key = prefix + realline[:i]
+                value = realline[i+3:]
+                value = eval(value, {})
+                result[key] = value
+        #
+    else:
+        # old format
+        for line in text.splitlines():
+            i = line.index(':')
+            key = line[:i].strip()
+            value = line[i+1:].strip()
+            try:
+                value = int(value)
+            except ValueError:
+                if value in ('True', 'False', 'None'):
+                    value = eval(value, {})
+            result[key] = value
+        #
+    return result

pypy/config/test/test_parse.py

+from pypy.config.parse import parse_info
+
+
+def test_parse_new_format():
+    assert (parse_info("[foo]\n"
+                       "    bar = True\n")
+            == {'foo.bar': True})
+    
+    assert (parse_info("[objspace]\n"
+                       "    x = 'hello'\n"
+                       "[translation]\n"
+                       "    bar = 42\n"
+                       "    [egg]\n"
+                       "        something = None\n"
+                       "    foo = True\n")
+            == {
+        'translation.foo': True,
+        'translation.bar': 42,
+        'translation.egg.something': None,
+        'objspace.x': 'hello',
+        })
+
+    assert parse_info("simple = 43\n") == {'simple': 43}
+
+
+def test_parse_old_format():
+    assert (parse_info("                          objspace.allworkingmodules: True\n"
+                       "                    objspace.disable_call_speedhacks: False\n"
+                       "                                 objspace.extmodules: None\n"
+                       "                                       objspace.name: std\n"
+                       "                        objspace.std.prebuiltintfrom: -5\n")
+            == {
+        'objspace.allworkingmodules': True,
+        'objspace.disable_call_speedhacks': False,
+        'objspace.extmodules': None,
+        'objspace.name': 'std',
+        'objspace.std.prebuiltintfrom': -5,
+        })

pypy/interpreter/astcompiler/assemble.py

 
     ops.WITH_CLEANUP : -1,
     ops.POP_BLOCK : 0,
-    ops.END_FINALLY : -3,
+    ops.END_FINALLY : -1,
     ops.SETUP_WITH : 1,
     ops.SETUP_FINALLY : 0,
     ops.SETUP_EXCEPT : 0,

pypy/interpreter/astcompiler/codegen.py

             self.visit_sequence(handler.body)
             self.emit_jump(ops.JUMP_FORWARD, end)
             self.use_next_block(next_except)
-        self.emit_op(ops.END_FINALLY)
+        self.emit_op(ops.END_FINALLY)   # this END_FINALLY will always re-raise
+        self.is_dead_code()
         self.use_next_block(otherwise)
         self.visit_sequence(te.orelse)
         self.use_next_block(end)

pypy/interpreter/baseobjspace.py

         return obj
     interp_w._annspecialcase_ = 'specialize:arg(1)'
 
+    def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj):
+        """
+        This method should NOT be called unless you are really sure about
+        it. It is used inside the implementation of end_finally() in
+        pyopcode.py, and it's there so that it can be overridden by the
+        FlowObjSpace.
+        """
+        if self.is_w(w_obj, self.w_None):
+            return True
+        obj = self.interpclass_w(w_obj)
+        return isinstance(obj, RequiredClass)
+
     def unpackiterable(self, w_iterable, expected_length=-1):
         """Unpack an iterable object into a real (interpreter-level) list.
         Raise an OperationError(w_ValueError) if the length is wrong."""

pypy/interpreter/pyopcode.py

         block.cleanup(self)  # the block knows how to clean up the value stack
 
     def end_finally(self):
-        # unlike CPython, when we reach this opcode the value stack has
-        # always been set up as follows (topmost first):
-        #   [exception type  or None]
-        #   [exception value or None]
-        #   [wrapped stack unroller ]
-        self.popvalue()   # ignore the exception type
-        self.popvalue()   # ignore the exception value
-        w_unroller = self.popvalue()
-        unroller = self.space.interpclass_w(w_unroller)
-        return unroller
+        # unlike CPython, there are two statically distinct cases: the
+        # END_FINALLY might be closing an 'except' block or a 'finally'
+        # block.  In the first case, the stack contains three items:
+        #   [exception type we are now handling]
+        #   [exception value we are now handling]
+        #   [wrapped SApplicationException]
+        # In the case of a finally: block, the stack contains only one
+        # item (unlike CPython which can have 1, 2 or 3 items):
+        #   [wrapped subclass of SuspendedUnroller]
+        w_top = self.popvalue()
+        # the following logic is a mess for the flow objspace,
+        # so we hide it specially in the space :-/
+        if self.space._check_constant_interp_w_or_w_None(SuspendedUnroller, w_top):
+            # case of a finally: block
+            unroller = self.space.interpclass_w(w_top)
+            return unroller
+        else:
+            # case of an except: block.  We popped the exception type
+            self.popvalue()        #     Now we pop the exception value
+            unroller = self.space.interpclass_w(self.popvalue())
+            assert unroller is not None
+            return unroller
 
     def BUILD_CLASS(self, oparg, next_instr):
         w_methodsdict = self.popvalue()
             # Implementation since 2.7a0: 62191 (introduce SETUP_WITH)
             or self.pycode.magic >= 0xa0df2d1):
             # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization)
-            self.popvalue()
-            self.popvalue()
             w_unroller = self.popvalue()
             w_exitfunc = self.popvalue()
             self.pushvalue(w_unroller)
-            self.pushvalue(self.space.w_None)
-            self.pushvalue(self.space.w_None)
         elif self.pycode.magic >= 0xa0df28c:
             # Implementation since 2.5a0: 62092 (changed WITH_CLEANUP opcode)
             w_exitfunc = self.popvalue()
-            w_unroller = self.peekvalue(2)
+            w_unroller = self.peekvalue(0)
         else:
             raise NotImplementedError("WITH_CLEANUP for CPython <= 2.4")
 
                 w_traceback)
             if self.space.is_true(w_suppress):
                 # __exit__() returned True -> Swallow the exception.
-                self.settopvalue(self.space.w_None, 2)
+                self.settopvalue(self.space.w_None)
         else:
             self.call_contextmanager_exit_function(
                 w_exitfunc,
     _opname = 'SETUP_FINALLY'
     handling_mask = -1     # handles every kind of SuspendedUnroller
 
-    def cleanup(self, frame):
-        # upon normal entry into the finally: part, the standard Python
-        # bytecode pushes a single None for END_FINALLY.  In our case we
-        # always push three values into the stack: the wrapped ctlflowexc,
-        # the exception value and the exception type (which are all None
-        # here).
-        self.cleanupstack(frame)
-        # one None already pushed by the bytecode
-        frame.pushvalue(frame.space.w_None)
-        frame.pushvalue(frame.space.w_None)
-
     def handle(self, frame, unroller):
         # any abnormal reason for unrolling a finally: triggers the end of
         # the block unrolling and the entering the finally: handler.
         # see comments in cleanup().
         self.cleanupstack(frame)
         frame.pushvalue(frame.space.wrap(unroller))
-        frame.pushvalue(frame.space.w_None)
-        frame.pushvalue(frame.space.w_None)
         return r_uint(self.handlerposition)   # jump to the handler
 
 

pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py

         self.optimize_strunicode_loop(ops, expected)
 
     def test_call_pure_vstring_const(self):
+        py.test.skip("implement me")
         ops = """
         []
         p0 = newstr(3)

pypy/module/__pypy__/interp_time.py

 from __future__ import with_statement
-import sys
+import os
 
 from pypy.interpreter.error import exception_from_errno
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
+if os.name == 'nt':
+    libraries = []
+else:
+    libraries = ["rt"]
 
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(
         includes=["time.h"],
-        libraries=["rt"],
+        libraries=libraries,
     )
 
     HAS_CLOCK_GETTIME = rffi_platform.Has('clock_gettime')
     CLOCK_PROCESS_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_PROCESS_CPUTIME_ID")
     CLOCK_THREAD_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_THREAD_CPUTIME_ID")
 
-    TIMESPEC = rffi_platform.Struct("struct timespec", [
-        ("tv_sec", rffi.TIME_T),
-        ("tv_nsec", rffi.LONG),
-    ])
-
 cconfig = rffi_platform.configure(CConfig)
 
 HAS_CLOCK_GETTIME = cconfig["HAS_CLOCK_GETTIME"]
 CLOCK_PROCESS_CPUTIME_ID = cconfig["CLOCK_PROCESS_CPUTIME_ID"]
 CLOCK_THREAD_CPUTIME_ID = cconfig["CLOCK_THREAD_CPUTIME_ID"]
 
-TIMESPEC = cconfig["TIMESPEC"]
+if HAS_CLOCK_GETTIME:
+    #redo it for timespec
+    CConfig.TIMESPEC = rffi_platform.Struct("struct timespec", [
+        ("tv_sec", rffi.TIME_T),
+        ("tv_nsec", rffi.LONG),
+    ])
+    cconfig = rffi_platform.configure(CConfig)
+    TIMESPEC = cconfig['TIMESPEC']
 
-c_clock_gettime = rffi.llexternal("clock_gettime",
-    [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
-    compilation_info=CConfig._compilation_info_, threadsafe=False
-)
-c_clock_getres = rffi.llexternal("clock_getres",
-    [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
-    compilation_info=CConfig._compilation_info_, threadsafe=False
-)
+    c_clock_gettime = rffi.llexternal("clock_gettime",
+        [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+        compilation_info=CConfig._compilation_info_, threadsafe=False
+    )
+    c_clock_getres = rffi.llexternal("clock_getres",
+        [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+        compilation_info=CConfig._compilation_info_, threadsafe=False
+    )
 
-@unwrap_spec(clk_id="c_int")
-def clock_gettime(space, clk_id):
-    with lltype.scoped_alloc(TIMESPEC) as tp:
-        ret = c_clock_gettime(clk_id, tp)
-        if ret != 0:
-            raise exception_from_errno(space, space.w_IOError)
-        return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
+    @unwrap_spec(clk_id="c_int")
+    def clock_gettime(space, clk_id):
+        with lltype.scoped_alloc(TIMESPEC) as tp:
+            ret = c_clock_gettime(clk_id, tp)
+            if ret != 0:
+                raise exception_from_errno(space, space.w_IOError)
+            return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
 
-@unwrap_spec(clk_id="c_int")
-def clock_getres(space, clk_id):
-    with lltype.scoped_alloc(TIMESPEC) as tp:
-        ret = c_clock_getres(clk_id, tp)
-        if ret != 0:
-            raise exception_from_errno(space, space.w_IOError)
-        return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
+    @unwrap_spec(clk_id="c_int")
+    def clock_getres(space, clk_id):
+        with lltype.scoped_alloc(TIMESPEC) as tp:
+            ret = c_clock_getres(clk_id, tp)
+            if ret != 0:
+                raise exception_from_errno(space, space.w_IOError)
+            return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)

pypy/module/_file/interp_file.py

File contents unchanged.

pypy/module/_file/test/test_file.py

 
         if option.runappdirect:
             py.test.skip("works with internals of _file impl on py.py")
-        import platform
-        if platform.system() == 'Windows':
-            # XXX This test crashes until someone implements something like
-            # XXX verify_fd from
-            # XXX http://hg.python.org/cpython/file/80ddbd822227/Modules/posixmodule.c#l434
-            # XXX and adds it to fopen
-            assert False
-
         state = [0]
         def read(fd, n=None):
             if fd != 42:
             return ''
         os.read = read
         stdin = W_File(cls.space)
-        stdin.file_fdopen(42, "r", 1)
+        stdin.file_fdopen(42, 'rb', 1)
         stdin.name = '<stdin>'
         cls.w_stream = stdin
 

pypy/module/_socket/test/test_sock_app.py

                 cli.send('foobar' * 70)
         except timeout:
             pass
-        # test sendall() timeout
-        raises(timeout, cli.sendall, 'foobar' * 70)
+        # test sendall() timeout, be sure to send data larger than the
+        # socket buffer
+        raises(timeout, cli.sendall, 'foobar' * 7000)
         # done
         cli.close()
         t.close()

pypy/module/_weakref/interp__weakref.py

 from pypy.interpreter.gateway import interp2app, ObjSpace
 from pypy.interpreter.typedef import TypeDef
 from pypy.rlib import jit
+from pypy.rlib.rshrinklist import AbstractShrinkList
+from pypy.rlib.objectmodel import specialize
 import weakref
 
 
+class WRefShrinkList(AbstractShrinkList):
+    def must_keep(self, wref):
+        return wref() is not None
+
+
 class WeakrefLifeline(W_Root):
-    cached_weakref_index = -1
-    cached_proxy_index = -1
+    cached_weakref  = None
+    cached_proxy    = None
+    other_refs_weak = None
 
     def __init__(self, space):
         self.space = space
-        self.refs_weak = []
+
+    def append_wref_to(self, w_ref):
+        if self.other_refs_weak is None:
+            self.other_refs_weak = WRefShrinkList()
+        self.other_refs_weak.append(weakref.ref(w_ref))
+
+    @specialize.arg(1)
+    def traverse(self, callback, arg=None):
+        if self.cached_weakref is not None:
+            arg = callback(self, self.cached_weakref, arg)
+        if self.cached_proxy is not None:
+            arg = callback(self, self.cached_proxy, arg)
+        if self.other_refs_weak is not None:
+            for ref_w_ref in self.other_refs_weak.items():
+                arg = callback(self, ref_w_ref, arg)
+        return arg
+
+    def _clear_wref(self, wref, _):
+        w_ref = wref()
+        if w_ref is not None:
+            w_ref.clear()
 
     def clear_all_weakrefs(self):
         """Clear all weakrefs.  This is called when an app-level object has
         a __del__, just before the app-level __del__ method is called.
         """
-        for ref_w_ref in self.refs_weak:
-            w_ref = ref_w_ref()
-            if w_ref is not None:
-                w_ref.clear()
+        self.traverse(WeakrefLifeline._clear_wref)
         # Note that for no particular reason other than convenience,
         # weakref callbacks are not invoked eagerly here.  They are
         # invoked by self.__del__() anyway.
     def get_or_make_weakref(self, w_subtype, w_obj):
         space = self.space
         w_weakreftype = space.gettypeobject(W_Weakref.typedef)
-        is_weakreftype = space.is_w(w_weakreftype, w_subtype)
-        if is_weakreftype and self.cached_weakref_index >= 0:
-            w_cached = self.refs_weak[self.cached_weakref_index]()
-            if w_cached is not None:
-                return w_cached
-            else:
-                self.cached_weakref_index = -1
-        w_ref = space.allocate_instance(W_Weakref, w_subtype)
-        index = len(self.refs_weak)
-        W_Weakref.__init__(w_ref, space, w_obj, None)
-        self.refs_weak.append(weakref.ref(w_ref))
-        if is_weakreftype:
-            self.cached_weakref_index = index
+        #
+        if space.is_w(w_weakreftype, w_subtype):
+            if self.cached_weakref is not None:
+                w_cached = self.cached_weakref()
+                if w_cached is not None:
+                    return w_cached
+            w_ref = W_Weakref(space, w_obj, None)
+            self.cached_weakref = weakref.ref(w_ref)
+        else:
+            # subclass: cannot cache
+            w_ref = space.allocate_instance(W_Weakref, w_subtype)
+            W_Weakref.__init__(w_ref, space, w_obj, None)
+            self.append_wref_to(w_ref)
         return w_ref
 
     def get_or_make_proxy(self, w_obj):
         space = self.space
-        if self.cached_proxy_index >= 0:
-            w_cached = self.refs_weak[self.cached_proxy_index]()
+        if self.cached_proxy is not None:
+            w_cached = self.cached_proxy()
             if w_cached is not None:
                 return w_cached
-            else:
-                self.cached_proxy_index = -1
-        index = len(self.refs_weak)
         if space.is_true(space.callable(w_obj)):
             w_proxy = W_CallableProxy(space, w_obj, None)
         else:
             w_proxy = W_Proxy(space, w_obj, None)
-        self.refs_weak.append(weakref.ref(w_proxy))
-        self.cached_proxy_index = index
+        self.cached_proxy = weakref.ref(w_proxy)
         return w_proxy
 
     def get_any_weakref(self, space):
-        if self.cached_weakref_index != -1:
-            w_ref = self.refs_weak[self.cached_weakref_index]()
+        if self.cached_weakref is not None:
+            w_ref = self.cached_weakref()
             if w_ref is not None:
                 return w_ref
-        w_weakreftype = space.gettypeobject(W_Weakref.typedef)
-        for i in range(len(self.refs_weak)):
-            w_ref = self.refs_weak[i]()
-            if (w_ref is not None and
-                space.is_true(space.isinstance(w_ref, w_weakreftype))):
-                return w_ref
+        if self.other_refs_weak is not None:
+            w_weakreftype = space.gettypeobject(W_Weakref.typedef)
+            for wref in self.other_refs_weak.items():
+                w_ref = wref()
+                if (w_ref is not None and
+                    space.is_true(space.isinstance(w_ref, w_weakreftype))):
+                    return w_ref
         return space.w_None
 
 
 
     def __init__(self, space, oldlifeline=None):
         self.space = space
-        if oldlifeline is None:
-            self.refs_weak = []
-        else:
-            self.refs_weak = oldlifeline.refs_weak
+        if oldlifeline is not None:
+            self.cached_weakref  = oldlifeline.cached_weakref
+            self.cached_proxy    = oldlifeline.cached_proxy
+            self.other_refs_weak = oldlifeline.other_refs_weak
 
     def __del__(self):
         """This runs when the interp-level object goes away, and allows
         callbacks even if there is no __del__ method on the interp-level
         W_Root subclass implementing the object.
         """
-        for i in range(len(self.refs_weak) - 1, -1, -1):
-            w_ref = self.refs_weak[i]()
+        if self.other_refs_weak is None:
+            return
+        items = self.other_refs_weak.items()
+        for i in range(len(items)-1, -1, -1):
+            w_ref = items[i]()
             if w_ref is not None and w_ref.w_callable is not None:
                 w_ref.enqueue_for_destruction(self.space,
                                               W_WeakrefBase.activate_callback,
         space = self.space
         w_ref = space.allocate_instance(W_Weakref, w_subtype)
         W_Weakref.__init__(w_ref, space, w_obj, w_callable)
-        self.refs_weak.append(weakref.ref(w_ref))
+        self.append_wref_to(w_ref)
         return w_ref
 
     def make_proxy_with_callback(self, w_obj, w_callable):
             w_proxy = W_CallableProxy(space, w_obj, w_callable)
         else:
             w_proxy = W_Proxy(space, w_obj, w_callable)
-        self.refs_weak.append(weakref.ref(w_proxy))
+        self.append_wref_to(w_proxy)
         return w_proxy
 
 # ____________________________________________________________
 )
 
 
+def _weakref_count(lifeline, wref, count):
+    if wref() is not None:
+        count += 1
+    return count
+
 def getweakrefcount(space, w_obj):
     """Return the number of weak references to 'obj'."""
     lifeline = w_obj.getweakref()
     if lifeline is None:
         return space.wrap(0)
     else:
-        result = 0
-        for i in range(len(lifeline.refs_weak)):
-            if lifeline.refs_weak[i]() is not None:
-                result += 1
+        result = lifeline.traverse(_weakref_count, 0)
         return space.wrap(result)
 
+def _get_weakrefs(lifeline, wref, result):
+    w_ref = wref()
+    if w_ref is not None:
+        result.append(w_ref)
+    return result
+
 def getweakrefs(space, w_obj):
     """Return a list of all weak reference objects that point to 'obj'."""
+    result = []
     lifeline = w_obj.getweakref()
-    if lifeline is None:
-        return space.newlist([])
-    else:
-        result = []
-        for i in range(len(lifeline.refs_weak)):
-            w_ref = lifeline.refs_weak[i]()
-            if w_ref is not None:
-                result.append(w_ref)
-        return space.newlist(result)
+    if lifeline is not None:
+        lifeline.traverse(_get_weakrefs, result)
+    return space.newlist(result)
 
 #_________________________________________________________________
 # Proxy

pypy/module/cpyext/api.py

 from pypy.module.__builtin__.interp_classobj import W_ClassObject
 from pypy.module.__builtin__.interp_memoryview import W_MemoryView
 from pypy.rlib.entrypoint import entrypoint
+from pypy.rlib.rposix import is_valid_fd, validate_fd
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.objectmodel import specialize
 from pypy.rlib.exports import export_struct
 
 # FILE* interface
 FILEP = rffi.COpaquePtr('FILE')
-fopen = rffi.llexternal('fopen', [CONST_STRING, CONST_STRING], FILEP)
-fclose = rffi.llexternal('fclose', [FILEP], rffi.INT)
-fwrite = rffi.llexternal('fwrite',
-                         [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
-                         rffi.SIZE_T)
-fread = rffi.llexternal('fread',
-                        [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
-                        rffi.SIZE_T)
-feof = rffi.llexternal('feof', [FILEP], rffi.INT)
+
 if sys.platform == 'win32':
     fileno = rffi.llexternal('_fileno', [FILEP], rffi.INT)
 else:
     fileno = rffi.llexternal('fileno', [FILEP], rffi.INT)
 
+fopen = rffi.llexternal('fopen', [CONST_STRING, CONST_STRING], FILEP)
+
+_fclose = rffi.llexternal('fclose', [FILEP], rffi.INT)
+def fclose(fp):
+    if not is_valid_fd(fileno(fp)):
+        return -1
+    return _fclose(fp)
+
+_fwrite = rffi.llexternal('fwrite',
+                         [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
+                         rffi.SIZE_T)
+def fwrite(buf, sz, n, fp):
+    validate_fd(fileno(fp))
+    return _fwrite(buf, sz, n, fp)
+
+_fread = rffi.llexternal('fread',
+                        [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, FILEP],
+                        rffi.SIZE_T)
+def fread(buf, sz, n, fp):
+    validate_fd(fileno(fp))
+    return _fread(buf, sz, n, fp)
+
+_feof = rffi.llexternal('feof', [FILEP], rffi.INT)
+def feof(fp):
+    validate_fd(fileno(fp))
+    return _feof(fp)
+
 
 constant_names = """
 Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER

pypy/module/cpyext/eval.py

File contents unchanged.

pypy/module/math/test/test_math.py

         assert math.trunc(foo()) == "truncated"
 
     def test_copysign_nan(self):
+        skip('sign of nan is undefined')
         import math
         assert math.copysign(1.0, float('-nan')) == -1.0

pypy/module/micronumpy/test/test_ufuncs.py

         assert a[1] == 0
 
     def test_signbit(self):
-        from _numpypy import signbit, copysign
+        from _numpypy import signbit
 
-        assert (signbit([0, 0.0, 1, 1.0, float('inf'), float('nan')]) ==
-            [False, False, False, False, False, False]).all()
-        assert (signbit([-0, -0.0, -1, -1.0, float('-inf'), -float('nan'), float('-nan')]) ==
-            [False,  True,  True,  True,  True,  True, True]).all()
+        assert (signbit([0, 0.0, 1, 1.0, float('inf')]) ==
+            [False, False, False, False, False]).all()
+        assert (signbit([-0, -0.0, -1, -1.0, float('-inf')]) ==
+            [False,  True,  True,  True,  True]).all()
+        skip('sign of nan is non-determinant')
+        assert (signbit([float('nan'), float('-nan'), -float('nan')]) ==
+            [False, True, True]).all()    
 
     def test_reciporocal(self):
         from _numpypy import array, reciprocal
         assert ([ninf, -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 1.0, inf] == ceil(a)).all()
         assert ([ninf, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 0.0, inf] == trunc(a)).all()
         assert all([math.isnan(f(float("nan"))) for f in floor, ceil, trunc])
-        assert all([math.copysign(1, f(float("nan"))) == 1 for f in floor, ceil, trunc])
-        assert all([math.copysign(1, f(float("-nan"))) == -1 for f in floor, ceil, trunc])
+        assert all([math.copysign(1, f(abs(float("nan")))) == 1 for f in floor, ceil, trunc])
+        assert all([math.copysign(1, f(-abs(float("nan")))) == -1 for f in floor, ceil, trunc])
 
     def test_copysign(self):
         from _numpypy import array, copysign

pypy/module/mmap/test/test_mmap.py

         assert len(b) == 6
         assert b[3] == "b"
         assert b[:] == "foobar"
+        m.close()
+        f.close()
 
     def test_offset(self):
         from mmap import mmap, ALLOCATIONGRANULARITY

pypy/module/pyexpat/interp_pyexpat.py

File contents unchanged.

pypy/module/rctime/interp_time.py

File contents unchanged.

pypy/module/rctime/test/test_rctime.py

 
     def test_strftime(self):
         import time as rctime
+        import os
 
         t = rctime.time()
         tt = rctime.gmtime(t)
         exp = '2000 01 01 00 00 00 1 001'
         assert rctime.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) == exp
 
+        # Guard against invalid/non-supported format string
+        # so that Python don't crash (Windows crashes when the format string
+        # input to [w]strftime is not kosher.
+        if os.name == 'nt':
+            raises(ValueError, rctime.strftime, '%f')
+        else:
+            assert rctime.strftime('%f') == '%f'
+
     def test_strftime_ext(self):
         import time as rctime
 

pypy/module/select/__init__.py

File contents unchanged.

pypy/module/select/interp_select.py

File contents unchanged.

pypy/module/select/test/test_select.py

File contents unchanged.

pypy/module/signal/interp_signal.py

 
 def setup():
     for key, value in cpy_signal.__dict__.items():
-        if key.startswith('SIG') and is_valid_int(value):
+        if (key.startswith('SIG') or key.startswith('CTRL_')) and \
+                is_valid_int(value):
             globals()[key] = value
             yield key
 
 SIG_DFL = cpy_signal.SIG_DFL
 SIG_IGN = cpy_signal.SIG_IGN
 signal_names = list(setup())
+signal_values = [globals()[key] for key in signal_names]
+signal_values = {}
+for key in signal_names:
+    signal_values[globals()[key]] = None
 
 includes = ['stdlib.h', 'src/signals.h']
 if sys.platform != 'win32':
     return space.w_None
 
 def check_signum(space, signum):
-    if signum < 1 or signum >= NSIG:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("signal number out of range"))
+    if signum in signal_values:
+        return
+    raise OperationError(space.w_ValueError,
+                         space.wrap("invalid signal value"))
+
 
 @jit.dont_look_inside
 @unwrap_spec(signum=int)

pypy/module/signal/test/test_interp_signal.py

 def setup_module(mod):
     if not hasattr(os, 'kill') or not hasattr(os, 'getpid'):
         py.test.skip("requires os.kill() and os.getpid()")
+    if not hasattr(interp_signal, 'SIGUSR1'):
+        py.test.skip("requires SIGUSR1 in signal")
 
 
 def check(expected):

pypy/module/signal/test/test_signal.py

     def setup_class(cls):
         if not hasattr(os, 'kill') or not hasattr(os, 'getpid'):
             py.test.skip("requires os.kill() and os.getpid()")
+        if not hasattr(cpy_signal, 'SIGUSR1'):    
+            py.test.skip("requires SIGUSR1 in signal")
         cls.space = gettestobjspace(usemodules=['signal'])
 
     def test_checksignals(self):
 class AppTestSignal:
 
     def setup_class(cls):
-        if not hasattr(os, 'kill') or not hasattr(os, 'getpid'):
-            py.test.skip("requires os.kill() and os.getpid()")
         space = gettestobjspace(usemodules=['signal'])
         cls.space = space
         cls.w_signal = space.appexec([], "(): import signal; return signal")
     def test_exported_names(self):
         self.signal.__dict__   # crashes if the interpleveldefs are invalid
 
-    def test_usr1(self):
-        import types, posix
+    def test_basics(self):
+        import types, os
+        if not hasattr(os, 'kill') or not hasattr(os, 'getpid'):
+            skip("requires os.kill() and os.getpid()")
         signal = self.signal   # the signal module to test
+        if hasattr(signal,'SIGUSR1'):
+            signum = signal.SIGUSR1
+        else:
+            signum = signal.CTRL_BREAK_EVENT
 
         received = []
         def myhandler(signum, frame):
             assert isinstance(frame, types.FrameType)
             received.append(signum)
-        signal.signal(signal.SIGUSR1, myhandler)
+        signal.signal(signum, myhandler)
 
-        posix.kill(posix.getpid(), signal.SIGUSR1)
+        print dir(os)
+
+        os.kill(os.getpid(), signum)
         # the signal should be delivered to the handler immediately
-        assert received == [signal.SIGUSR1]
+        assert received == [signum]
         del received[:]
 
-        posix.kill(posix.getpid(), signal.SIGUSR1)
+        os.kill(os.getpid(), signum)
         # the signal should be delivered to the handler immediately
-        assert received == [signal.SIGUSR1]
+        assert received == [signum]
         del received[:]
 
-        signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+        signal.signal(signum, signal.SIG_IGN)
 
-        posix.kill(posix.getpid(), signal.SIGUSR1)
+        os.kill(os.getpid(), signum)
         for i in range(10000):
             # wait a bit - signal should not arrive
             if received:
                 break
         assert received == []
 
-        signal.signal(signal.SIGUSR1, signal.SIG_DFL)
+        signal.signal(signum, signal.SIG_DFL)
 
 
     def test_default_return(self):
         """
         Test that signal.signal returns SIG_DFL if that is the current handler.
         """
-        from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+        from signal import signal, SIGINT, SIG_DFL, SIG_IGN
 
         try:
             for handler in SIG_DFL, SIG_IGN, lambda *a: None:
-                signal(SIGUSR1, SIG_DFL)
-                assert signal(SIGUSR1, handler) == SIG_DFL
+                signal(SIGINT, SIG_DFL)
+                assert signal(SIGINT, handler) == SIG_DFL
         finally:
-            signal(SIGUSR1, SIG_DFL)
+            signal(SIGINT, SIG_DFL)
 
 
     def test_ignore_return(self):
         """
         Test that signal.signal returns SIG_IGN if that is the current handler.
         """
-        from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+        from signal import signal, SIGINT, SIG_DFL, SIG_IGN
 
         try:
             for handler in SIG_DFL, SIG_IGN, lambda *a: None:
-                signal(SIGUSR1, SIG_IGN)
-                assert signal(SIGUSR1, handler) == SIG_IGN
+                signal(SIGINT, SIG_IGN)
+                assert signal(SIGINT, handler) == SIG_IGN
         finally:
-            signal(SIGUSR1, SIG_DFL)
+            signal(SIGINT, SIG_DFL)
 
 
     def test_obj_return(self):
         Test that signal.signal returns a Python object if one is the current
         handler.
         """
-        from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+        from signal import signal, SIGINT, SIG_DFL, SIG_IGN
         def installed(*a):
             pass
 
         try:
             for handler in SIG_DFL, SIG_IGN, lambda *a: None:
-                signal(SIGUSR1, installed)
-                assert signal(SIGUSR1, handler) is installed
+                signal(SIGINT, installed)
+                assert signal(SIGINT, handler) is installed
         finally:
-            signal(SIGUSR1, SIG_DFL)
+            signal(SIGINT, SIG_DFL)
 
 
     def test_getsignal(self):
         """
         Test that signal.getsignal returns the currently installed handler.
         """
-        from signal import getsignal, signal, SIGUSR1, SIG_DFL, SIG_IGN
+        from signal import getsignal, signal, SIGINT, SIG_DFL, SIG_IGN
 
         def handler(*a):
             pass
 
         try:
-            assert getsignal(SIGUSR1) == SIG_DFL
-            signal(SIGUSR1, SIG_DFL)
-            assert getsignal(SIGUSR1) == SIG_DFL
-            signal(SIGUSR1, SIG_IGN)
-            assert getsignal(SIGUSR1) == SIG_IGN
-            signal(SIGUSR1, handler)
-            assert getsignal(SIGUSR1) is handler
+            assert getsignal(SIGINT) == SIG_DFL
+            signal(SIGINT, SIG_DFL)
+            assert getsignal(SIGINT) == SIG_DFL
+            signal(SIGINT, SIG_IGN)
+            assert getsignal(SIGINT) == SIG_IGN
+            signal(SIGINT, handler)
+            assert getsignal(SIGINT) is handler
         finally:
-            signal(SIGUSR1, SIG_DFL)
+            signal(SIGINT, SIG_DFL)
 
         raises(ValueError, getsignal, 4444)
         raises(ValueError, signal, 4444, lambda *args: None)
+        raises(ValueError, signal, 42, lambda *args: None)
 
     def test_alarm(self):
-        from signal import alarm, signal, SIG_DFL, SIGALRM
+        try:
+            from signal import alarm, signal, SIG_DFL, SIGALRM
+        except:
+            skip('no alarm on this platform')
         import time
         l = []
         def handler(*a):
             signal(SIGALRM, SIG_DFL)
 
     def test_set_wakeup_fd(self):
-        import signal, posix, fcntl
+        try:
+            import signal, posix, fcntl
+        except ImportError:
+            skip('cannot import posix or fcntl')
         def myhandler(signum, frame):
             pass
-        signal.signal(signal.SIGUSR1, myhandler)
+        signal.signal(signal.SIGINT, myhandler)
         #
         def cannot_read():
             try:
         old_wakeup = signal.set_wakeup_fd(fd_write)
         try:
             cannot_read()
-            posix.kill(posix.getpid(), signal.SIGUSR1)
+            posix.kill(posix.getpid(), signal.SIGINT)
             res = posix.read(fd_read, 1)
             assert res == '\x00'
             cannot_read()
         finally:
             old_wakeup = signal.set_wakeup_fd(old_wakeup)
         #
-        signal.signal(signal.SIGUSR1, signal.SIG_DFL)
+        signal.signal(signal.SIGINT, signal.SIG_DFL)
 
     def test_siginterrupt(self):
         import signal, os, time
+        if not hasattr(signal, 'siginterrupt'):
+            skip('non siginterrupt in signal')
         signum = signal.SIGUSR1
         def readpipe_is_not_interrupted():
             # from CPython's test_signal.readpipe_interrupted()

pypy/module/thread/__init__.py

         'allocate_lock':          'os_lock.allocate_lock',
         'allocate':               'os_lock.allocate_lock',  # obsolete synonym
         'LockType':               'os_lock.Lock',
-        #'_local':                'os_local.Local',   # only if 'rweakref'
+        '_local':                 'os_local.Local',
         'error':                  'space.fromcache(error.Cache).w_error',
     }
 
         from pypy.module.posix.interp_posix import add_fork_hook
         from pypy.module.thread.os_thread import reinit_threads
         add_fork_hook('child', reinit_threads)
-
-    def setup_after_space_initialization(self):
-        """NOT_RPYTHON"""
-        if self.space.config.translation.rweakref:
-            self.extra_interpdef('_local', 'os_local.Local')

pypy/module/thread/os_local.py

-from pypy.rlib.rweakref import RWeakKeyDictionary
+import weakref
+from pypy.rlib import jit
 from pypy.interpreter.baseobjspace import Wrappable, W_Root
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.typedef import (TypeDef, interp2app, GetSetProperty,
     descr_get_dict)
+from pypy.rlib.rshrinklist import AbstractShrinkList
+
+class WRefShrinkList(AbstractShrinkList):
+    def must_keep(self, wref):
+        return wref() is not None
+
+
+ExecutionContext._thread_local_objs = None
 
 
 class Local(Wrappable):
     """Thread-local data"""
 
+    @jit.dont_look_inside
     def __init__(self, space, initargs):
         self.initargs = initargs
-        self.dicts = RWeakKeyDictionary(ExecutionContext, W_Root)
+        self.dicts = {}   # mapping ExecutionContexts to the wraped dict
         # The app-level __init__() will be called by the general
         # instance-creation logic.  It causes getdict() to be
         # immediately called.  If we don't prepare and set a w_dict
         # to call __init__() a second time.
         ec = space.getexecutioncontext()
         w_dict = space.newdict(instance=True)
-        self.dicts.set(ec, w_dict)
+        self.dicts[ec] = w_dict
+        self._register_in_ec(ec)
+
+    def _register_in_ec(self, ec):
+        if not ec.space.config.translation.rweakref:
+            return    # without weakrefs, works but 'dicts' is never cleared
+        if ec._thread_local_objs is None:
+            ec._thread_local_objs = WRefShrinkList()
+        ec._thread_local_objs.append(weakref.ref(self))
+
+    @jit.dont_look_inside
+    def create_new_dict(self, ec):
+        # create a new dict for this thread
+        space = ec.space
+        w_dict = space.newdict(instance=True)
+        self.dicts[ec] = w_dict
+        # call __init__
+        try:
+            w_self = space.wrap(self)
+            w_type = space.type(w_self)
+            w_init = space.getattr(w_type, space.wrap("__init__"))
+            space.call_obj_args(w_init, w_self, self.initargs)
+        except:
+            # failed, forget w_dict and propagate the exception
+            del self.dicts[ec]
+            raise
+        # ready
+        self._register_in_ec(ec)
+        return w_dict
 
     def getdict(self, space):
         ec = space.getexecutioncontext()
-        w_dict = self.dicts.get(ec)
-        if w_dict is None:
-            # create a new dict for this thread
-            w_dict = space.newdict(instance=True)
-            self.dicts.set(ec, w_dict)
-            # call __init__
-            try:
-                w_self = space.wrap(self)
-                w_type = space.type(w_self)
-                w_init = space.getattr(w_type, space.wrap("__init__"))
-                space.call_obj_args(w_init, w_self, self.initargs)
-            except:
-                # failed, forget w_dict and propagate the exception
-                self.dicts.set(ec, None)
-                raise
-            # ready
+        try:
+            w_dict = self.dicts[ec]
+        except KeyError:
+            w_dict = self.create_new_dict(ec)
         return w_dict
 
     def descr_local__new__(space, w_subtype, __args__):
                         __init__ = interp2app(Local.descr_local__init__),
                         __dict__ = GetSetProperty(descr_get_dict, cls=Local),
                         )
+
+def thread_is_stopping(ec):
+    tlobjs = ec._thread_local_objs
+    if tlobjs is None:
+        return
+    ec._thread_local_objs = None
+    for wref in tlobjs.items():
+        local = wref()
+        if local is not None:
+            del local.dicts[ec]

pypy/module/thread/threadlocals.py

 
     def leave_thread(self, space):
         "Notification that the current thread is about to stop."
-        self.setvalue(None)
+        from pypy.module.thread.os_local import thread_is_stopping
+        try:
+            thread_is_stopping(self.getvalue())
+        finally:
+            self.setvalue(None)

pypy/objspace/flow/objspace.py

             return obj
         return None
 
+    def _check_constant_interp_w_or_w_None(self, RequiredClass, w_obj):
+        """
+        WARNING: this implementation is not complete at all. It's just enough
+        to be used by end_finally() inside pyopcode.py.
+        """
+        return w_obj == self.w_None or (isinstance(w_obj, Constant) and
+                                        isinstance(w_obj.value, RequiredClass))
+
     def getexecutioncontext(self):
         return getattr(self, 'executioncontext', None)
 

pypy/rlib/clibffi.py

File contents unchanged.
     'retrace_limit': 'how many times we can try retracing before giving up',
     'max_retrace_guards': 'number of extra guards a retrace can cause',
     'max_unroll_loops': 'number of extra unrollings a loop can cause',
-    'enable_opts': 'INTERNAL USE ONLY: optimizations to enable, or all = %s' %
-                       ENABLE_ALL_OPTS,
+    'enable_opts': 'INTERNAL USE ONLY (MAY NOT WORK OR LEAD TO CRASHES): '
+                   'optimizations to enable, or all = %s' % ENABLE_ALL_OPTS,
     }
 
 PARAMETERS = {'threshold': 1039, # just above 1024, prime

pypy/rlib/rarithmetic.py

 
 # used in tests for ctypes and for genc and friends
 # to handle the win64 special case:
-is_emulated_long = _long_typecode <> 'l'
+is_emulated_long = _long_typecode != 'l'
     
 LONG_BIT = _get_long_bit()
 LONG_MASK = (2**LONG_BIT)-1

pypy/rlib/rmmap.py

         # assume -1 and 0 both mean invalid file descriptor
         # to 'anonymously' map memory.
         if fileno != -1 and fileno != 0:
-            fh = rwin32._get_osfhandle(fileno)
-            if fh == INVALID_HANDLE:
-                errno = rposix.get_errno()
-                raise OSError(errno, os.strerror(errno))
+            fh = rwin32.get_osfhandle(fileno)
             # Win9x appears to need us seeked to zero
             # SEEK_SET = 0
             # libc._lseek(fileno, 0, SEEK_SET)
 
+            # check file size
+            try:
+                low, high = _get_file_size(fh)
+            except OSError:
+                pass     # ignore non-seeking files and errors and trust map_size
+            else:
+                if not high and low <= sys.maxint:
+                   size = low
+                else:   
+                    # not so sure if the signed/unsigned strictness is a good idea:
+                    high = rffi.cast(lltype.Unsigned, high)
+                    low = rffi.cast(lltype.Unsigned, low)
+                    size = (high << 32) + low
+                    size = rffi.cast(lltype.Signed, size)
+                if map_size == 0:
+                    if offset > size:
+                        raise RValueError(
+                            "mmap offset is greater than file size")
+                    map_size = int(size - offset)
+                    if map_size != size - offset:
+                        raise RValueError("mmap length is too large")
+                elif offset + map_size > size:
+                    raise RValueError("mmap length is greater than file size")
+
         m = MMap(access, offset)
         m.file_handle = INVALID_HANDLE
         m.map_handle = INVALID_HANDLE

pypy/rlib/rposix.py

     _set_errno(rffi.cast(INT, errno))
 
 if os.name == 'nt':
-    _validate_fd = rffi.llexternal(
+    is_valid_fd = rffi.llexternal(
         "_PyVerify_fd", [rffi.INT], rffi.INT,
         compilation_info=errno_eci,
         )
     @jit.dont_look_inside
     def validate_fd(fd):
-        if not _validate_fd(fd):
+        if not is_valid_fd(fd):
             raise OSError(get_errno(), 'Bad file descriptor')
 else:
-    def _validate_fd(fd):
+    def is_valid_fd(fd):
         return 1
 
     def validate_fd(fd):
     # this behaves like os.closerange() from Python 2.6.
     for fd in xrange(fd_low, fd_high):
         try:
-            os.close(fd)
+            if is_valid_fd(fd):
+                os.close(fd)
         except OSError:
             pass
 

pypy/rlib/rshrinklist.py

+
+class AbstractShrinkList(object):
+    """A mixin base class.  You should subclass it and add a method
+    must_keep().  Behaves like a list with the method append(), and
+    you can read *for reading* the list of items by calling items().
+    The twist is that occasionally append() will throw away the
+    items for which must_keep() returns False.  (It does so without
+    changing the order.)
+    """
+    _mixin_ = True
+
+    def __init__(self):
+        self._list = []
+        self._next_shrink = 16
+
+    def append(self, x):
+        self._do_shrink()
+        self._list.append(x)
+
+    def items(self):
+        return self._list
+
+    def _do_shrink(self):
+        if len(self._list) >= self._next_shrink:
+            rest = 0
+            for x in self._list:
+                if self.must_keep(x):
+                    self._list[rest] = x
+                    rest += 1
+            del self._list[rest:]
+            self._next_shrink = 16 + 2 * rest
+
+    def must_keep(self, x):
+        raise NotImplementedError

pypy/rlib/rwin32.py

 from pypy.translator.platform import CompilationError
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rposix import validate_fd
 from pypy.rlib import jit
 import os, sys, errno
 
         for name in """FORMAT_MESSAGE_ALLOCATE_BUFFER FORMAT_MESSAGE_FROM_SYSTEM
                        MAX_PATH
                        WAIT_OBJECT_0 WAIT_TIMEOUT INFINITE
+                       ERROR_INVALID_HANDLE
                     """.split():
             locals()[name] = rffi_platform.ConstantInteger(name)
 
 
     _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], HANDLE)
 
+    def get_osfhandle(fd):
+        validate_fd(fd)
+        handle = _get_osfhandle(fd)
+        if handle == INVALID_HANDLE_VALUE:
+            raise WindowsError(ERROR_INVALID_HANDLE, "Invalid file handle")
+        return handle
+
     def build_winerror_to_errno():
         """Build a dictionary mapping windows error numbers to POSIX errno.
         The function returns the dict, and the default value for codes not

pypy/rlib/streamio.py

 
 
 if sys.platform == "win32":
-    from pypy.rlib import rwin32
+    from pypy.rlib.rwin32 import BOOL, HANDLE, get_osfhandle, GetLastError
     from pypy.translator.tool.cbuild import ExternalCompilationInfo
     from pypy.rpython.lltypesystem import rffi
-    import errno
 
     _eci = ExternalCompilationInfo()
-    _get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], rffi.LONG,
-                                     compilation_info=_eci)
     _setmode = rffi.llexternal('_setmode', [rffi.INT, rffi.INT], rffi.INT,
                                compilation_info=_eci)
-    SetEndOfFile = rffi.llexternal('SetEndOfFile', [rffi.LONG], rwin32.BOOL,
+    SetEndOfFile = rffi.llexternal('SetEndOfFile', [HANDLE], BOOL,
                                    compilation_info=_eci)
 
     # HACK: These implementations are specific to MSVCRT and the C backend.
     # When generating on CLI or JVM, these are patched out.
     # See PyPyTarget.target() in targetpypystandalone.py
     def _setfd_binary(fd):
-        _setmode(fd, os.O_BINARY)
+        #Allow this to succeed on invalid fd's
+        if rposix.is_valid_fd(fd):
+            _setmode(fd, os.O_BINARY)
 
     def ftruncate_win32(fd, size):
         curpos = os.lseek(fd, 0, 1)
             # move to the position to be truncated
             os.lseek(fd, size, 0)
             # Truncate.  Note that this may grow the file!
-            handle = _get_osfhandle(fd)
-            if handle == -1:
-                raise OSError(errno.EBADF, "Invalid file handle")
+            handle = get_osfhandle(fd)
             if not SetEndOfFile(handle):
-                raise WindowsError(rwin32.GetLastError(),
+                raise WindowsError(GetLastError(),
                                    "Could not truncate file")
         finally:
             # we restore the file pointer position in any case

pypy/rlib/test/test_rmmap.py

         interpret(f, [])
 
     def test_file_size(self):
-        if os.name == "nt":
-            skip("Only Unix checks file size")
         def func(no):
 
             try:
     def test_windows_crasher_1(self):
         if sys.platform != "win32":
             skip("Windows-only test")
-
-        m = mmap.mmap(-1, 1000, tagname="foo")
-        # same tagname, but larger size
-        try:
-            m2 = mmap.mmap(-1, 5000, tagname="foo")
-            m2.getitem(4500)
-        except WindowsError:
-            pass
-        m.close()
+        def func():
+            m = mmap.mmap(-1, 1000, tagname="foo")
+            # same tagname, but larger size
+            try:
+                m2 = mmap.mmap(-1, 5000, tagname="foo")
+                m2.getitem(4500)
+            except WindowsError:
+                pass
+            m.close()
+        interpret(func, [])
 
     def test_windows_crasher_2(self):
         if sys.platform != "win32":

pypy/rlib/test/test_rposix.py

             except Exception:
                 pass
 
-    def test_validate_fd(self):
+    def test_is_valid_fd(self):
         if os.name != 'nt':
             skip('relevant for windows only')
-        assert rposix._validate_fd(0) == 1
+        assert rposix.is_valid_fd(0) == 1
         fid = open(str(udir.join('validate_test.txt')), 'w')
         fd = fid.fileno()
-        assert rposix._validate_fd(fd) == 1
+        assert rposix.is_valid_fd(fd) == 1
         fid.close()
-        assert rposix._validate_fd(fd) == 0
-
-
+        assert rposix.is_valid_fd(fd) == 0

pypy/rlib/test/test_rshrinklist.py

+from pypy.rlib.rshrinklist import AbstractShrinkList
+
+class Item:
+    alive = True
+
+class ItemList(AbstractShrinkList):
+    def must_keep(self, x):
+        return x.alive
+
+def test_simple():
+    l = ItemList()
+    l2 = [Item() for i in range(150)]
+    for x in l2:
+        l.append(x)
+    assert l.items() == l2
+    #
+    for x in l2[::2]:
+        x.alive = False
+    l3 = [Item() for i in range(150 + 16)]
+    for x in l3:
+        l.append(x)
+    assert l.items() == l2[1::2] + l3   # keeps the order
+
+def test_append_dead_items():
+    l = ItemList()
+    for i in range(150):
+        x = Item()
+        l.append(x)
+        x.alive = False
+    assert len(l.items()) <= 16

pypy/rlib/test/test_rweakkeydict.py

             d = RWeakKeyDictionary(KX, VY)
         d.set(KX(), VX())
     py.test.raises(Exception, interpret, g, [1])
+
+
+def test_rpython_free_values():
+    import py; py.test.skip("XXX not implemented, messy")
+    class VXDel:
+        def __del__(self):
+            state.freed.append(1)
+    class State:
+        pass
+    state = State()
+    state.freed = []
+    #
+    def add_me():
+        k = KX()
+        v = VXDel()
+        d = RWeakKeyDictionary(KX, VXDel)
+        d.set(k, v)
+        return d
+    def f():
+        del state.freed[:]
+        d = add_me()
+        rgc.collect()
+        # we want the dictionary to be really empty here.  It's hard to
+        # ensure in the current implementation after just one collect(),
+        # but at least two collects should be enough.
+        rgc.collect()
+        return len(state.freed)
+    assert f() == 1
+    assert interpret(f, []) == 1

pypy/rlib/test/test_rwin32.py

+import os
+if os.name != 'nt':
+    skip('tests for win32 only')
+
+from pypy.rlib import rwin32
+from pypy.tool.udir import udir
+
+
+def test_get_osfhandle():
+    fid = open(str(udir.join('validate_test.txt')), 'w')
+    fd = fid.fileno()
+    rwin32.get_osfhandle(fd)
+    fid.close()
+    raises(OSError, rwin32.get_osfhandle, fd)
+    rwin32.get_osfhandle(0)
+
+def test_get_osfhandle_raising():
+    #try to test what kind of exception get_osfhandle raises w/out fd validation
+    skip('Crashes python')
+    fid = open(str(udir.join('validate_test.txt')), 'w')
+    fd = fid.fileno()
+    fid.close()
+    def validate_fd(fd):
+        return 1
+    _validate_fd = rwin32.validate_fd
+    rwin32.validate_fd = validate_fd
+    raises(WindowsError, rwin32.get_osfhandle, fd)
+    rwin32.validate_fd = _validate_fd

pypy/rpython/llinterp.py

             etype = frame.op_direct_call(exdata.fn_type_of_exc_inst, evalue)
             if etype == klass:
                 return cls
-        raise ValueError, "couldn't match exception"
+        raise ValueError("couldn't match exception, maybe it"
+                      " has RPython attributes like OSError?")
 
     def get_transformed_exc_data(self, graph):
         if hasattr(graph, 'exceptiontransformed'):

pypy/rpython/module/ll_os.py

         os_dup = self.llexternal(underscore_on_windows+'dup', [rffi.INT], rffi.INT)
 
         def dup_llimpl(fd):
+            rposix.validate_fd(fd)
             newfd = rffi.cast(lltype.Signed, os_dup(rffi.cast(rffi.INT, fd)))
             if newfd == -1:
                 raise OSError(rposix.get_errno(), "dup failed")
                                   [rffi.INT, rffi.INT], rffi.INT)
 
         def dup2_llimpl(fd, newfd):
+            rposix.validate_fd(fd)
             error = rffi.cast(lltype.Signed, os_dup2(rffi.cast(rffi.INT, fd),
                                              rffi.cast(rffi.INT, newfd)))
             if error == -1:
         def os_read_llimpl(fd, count):
             if count < 0:
                 raise OSError(errno.EINVAL, None)
+            rposix.validate_fd(fd)
             raw_buf, gc_buf = rffi.alloc_buffer(count)
             try:
                 void_buf = rffi.cast(rffi.VOIDP, raw_buf)
 
         def os_write_llimpl(fd, data):
             count = len(data)
+            rposix.validate_fd(fd)
             buf = rffi.get_nonmovingbuffer(data)
             try:
                 written = rffi.cast(lltype.Signed, os_write(
                                    rffi.INT, threadsafe=False)
         
         def close_llimpl(fd):
+            rposix.validate_fd(fd)
             error = rffi.cast(lltype.Signed, os_close(rffi.cast(rffi.INT, fd)))
             if error == -1:
                 raise OSError(rposix.get_errno(), "close failed")
 
         os_lseek = self.llexternal(funcname,
                                    [rffi.INT, rffi.LONGLONG, rffi.INT],
-                                   rffi.LONGLONG)
+                                   rffi.LONGLONG, macro=True)
 
         def lseek_llimpl(fd, pos, how):
+            rposix.validate_fd(fd)
             how = fix_seek_arg(how)
             res = os_lseek(rffi.cast(rffi.INT,      fd),
                            rffi.cast(rffi.LONGLONG, pos),
                                        [rffi.INT, rffi.LONGLONG], rffi.INT)
 
         def ftruncate_llimpl(fd, length):
+            rposix.validate_fd(fd)
             res = rffi.cast(rffi.LONG,
                             os_ftruncate(rffi.cast(rffi.INT, fd),
                                          rffi.cast(rffi.LONGLONG, length)))
             os_fsync = self.llexternal('_commit', [rffi.INT], rffi.INT)
 
         def fsync_llimpl(fd):
+            rposix.validate_fd(fd)
             res = rffi.cast(rffi.SIGNED, os_fsync(rffi.cast(rffi.INT, fd)))
             if res < 0:
                 raise OSError(rposix.get_errno(), "fsync failed")
         os_fdatasync = self.llexternal('fdatasync', [rffi.INT], rffi.INT)
 
         def fdatasync_llimpl(fd):
+            rposix.validate_fd(fd)
             res = rffi.cast(rffi.SIGNED, os_fdatasync(rffi.cast(rffi.INT, fd)))
             if res < 0:
                 raise OSError(rposix.get_errno(), "fdatasync failed")
         os_fchdir = self.llexternal('fchdir', [rffi.INT], rffi.INT)
 
         def fchdir_llimpl(fd):
+            rposix.validate_fd(fd)
             res = rffi.cast(rffi.SIGNED, os_fchdir(rffi.cast(rffi.INT, fd)))
             if res < 0:
                 raise OSError(rposix.get_errno(), "fchdir failed")
         os_isatty = self.llexternal(underscore_on_windows+'isatty', [rffi.INT], rffi.INT)
 
         def isatty_llimpl(fd):
+            rposix.validate_fd(fd)
             res = rffi.cast(lltype.Signed, os_isatty(rffi.cast(rffi.INT, fd)))
             return res != 0
 
         os_umask = self.llexternal(underscore_on_windows+'umask', [rffi.MODE_T], rffi.MODE_T)
 
         def umask_llimpl(fd):
+            rposix.validate_fd(fd)
             res = os_umask(rffi.cast(rffi.MODE_T, fd))
             return rffi.cast(lltype.Signed, res)
 

pypy/rpython/module/ll_os_stat.py

             lltype.free(data, flavor='raw')
 
     def win32_fstat_llimpl(fd):
-        handle = rwin32._get_osfhandle(fd)
-
+        handle = rwin32.get_osfhandle(fd)
         filetype = win32traits.GetFileType(handle)
         if filetype == win32traits.FILE_TYPE_CHAR:
             # console or LPT device

pypy/rpython/module/test/test_ll_os.py

         if (len == 0) and "WINGDB_PYTHON" in os.environ:
             # the ctypes call seems not to work in the Wing debugger
             return
-        assert str(buf.value).lower() == pwd
-        # ctypes returns the drive letter in uppercase, os.getcwd does not
+        assert str(buf.value).lower() == pwd.lower()
+        # ctypes returns the drive letter in uppercase, 
+        # os.getcwd does not, 
+        # but there may be uppercase in os.getcwd path
 
     pwd = os.getcwd()
     try:
         OSError, ll_execve, "/etc/passwd", [], {})
     assert info.value.errno == errno.EACCES
 
+def test_os_write():
+    #Same as test in rpython/test/test_rbuiltin
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
+    assert fd >= 0
+    f = getllimpl(os.write)
+    f(fd, 'Hello world')
+    os.close(fd)
+    with open(fname) as fid:
+        assert fid.read() == "Hello world"
+    fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
+    os.close(fd)
+    raises(OSError, f, fd, 'Hello world')
 
+def test_os_close():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
+    assert fd >= 0
+    os.write(fd, 'Hello world')
+    f = getllimpl(os.close)
+    f(fd)
+    raises(OSError, f, fd)
+
+def test_os_lseek():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_RDWR|os.O_CREAT, 0777)
+    assert fd >= 0
+    os.write(fd, 'Hello world')
+    f = getllimpl(os.lseek)
+    f(fd,0,0)
+    assert os.read(fd, 11) == 'Hello world'
+    os.close(fd)
+    raises(OSError, f, fd, 0, 0)
+
+def test_os_fsync():
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
+    assert fd >= 0
+    os.write(fd, 'Hello world')
+    f = getllimpl(os.fsync)
+    f(fd)
+    os.close(fd)
+    fid = open(fname)
+    assert fid.read() == 'Hello world'
+    fid.close()
+    raises(OSError, f, fd)
+
+def test_os_fdatasync():
+    try:
+        f = getllimpl(os.fdatasync)
+    except:
+        skip('No fdatasync in os')
+    fname = str(udir.join('os_test.txt'))
+    fd = os.open(fname, os.O_WRONLY|os.O_CREAT, 0777)
+    assert fd >= 0
+    os.write(fd, 'Hello world')
+    f(fd)
+    fid = open(fname)
+    assert fid.read() == 'Hello world'
+    os.close(fd)
+    raises(OSError, f, fd)
 
 class ExpectTestOs:
     def setup_class(cls):

pypy/rpython/test/test_llinterp.py

     #start = time.time()
     res = call(*args, **kwds) 
     #elapsed = time.time() - start 
-    #print "%.2f secs" %(elapsed,)
+    #print "%.2f secs" % (elapsed,)
     return res 
 
 def gengraph(func, argtypes=[], viewbefore='auto', policy=None,
     info = py.test.raises(LLException, "interp.eval_graph(graph, values)")
     try:
         got = interp.find_exception(info.value)
-    except ValueError:
-        got = None
-    assert got is exc, "wrong exception type"
+    except ValueError as message:
+        got = 'None %r' % message
+    assert got is exc, "wrong exception type, expected %r got %r" % (exc, got)
 
 #__________________________________________________________________
 # tests

pypy/rpython/test/test_rbuiltin.py

         os.close(res)
         hello = open(tmpdir).read()
         assert hello == "hello world"
+        fd = os.open(tmpdir, os.O_WRONLY|os.O_CREAT, 777)
+        os.close(fd)
+        raises(OSError, os.write, fd, "hello world")    
 
     def test_os_write_single_char(self):
         tmpdir = str(udir.udir.join("os_write_test_char"))

pypy/translator/c/primitive.py

File contents unchanged.

pypy/translator/c/src/ll_math.c

File contents unchanged.

pypy/translator/c/src/main.h

 #define PYPY_MAIN_FUNCTION main
 #endif
 
-#ifdef MS_WINDOWS
-#include "src/winstuff.c"
-#endif
-
 #ifdef __GNUC__
 /* Hack to prevent this function from being inlined.  Helps asmgcc
    because the main() function has often a different prologue/epilogue. */
     }
 #endif
 
-#ifdef MS_WINDOWS
-    pypy_Windows_startup();
-#endif
-
     errmsg = RPython_StartupCode();
     if (errmsg) goto error;
 

pypy/translator/c/src/winstuff.c

-
-/************************************************************/
- /*****  Windows-specific stuff.                         *****/
-
-
-/* copied from CPython. */
-
-#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
-/* crt variable checking in VisualStudio .NET 2005 */
-#include <crtdbg.h>
-
-/* Invalid parameter handler.  Sets a ValueError exception */
-static void
-InvalidParameterHandler(
-    const wchar_t * expression,
-    const wchar_t * function,
-    const wchar_t * file,
-    unsigned int line,
-    uintptr_t pReserved)
-{
-    /* Do nothing, allow execution to continue.  Usually this
-     * means that the CRT will set errno to EINVAL