[pypy-commit] pypy kill-rctime: Rename 'rctime' to plain 'time'.

amauryfa noreply at buildbot.pypy.org
Wed Nov 12 00:21:37 CET 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: kill-rctime
Changeset: r74468:d53aec985fd4
Date: 2014-11-12 00:20 +0100
http://bitbucket.org/pypy/pypy/changeset/d53aec985fd4/

Log:	Rename 'rctime' to plain 'time'. Try to remove all references to
	rctime.

diff too long, truncating to 2000 out of 2637 lines

diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -59,7 +59,7 @@
     def __init__(self, basename, core=False, compiler=None, usemodules='',
                  skip=None):
         self.basename = basename
-        self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket']
+        self._usemodules = usemodules.split() + ['signal', 'time', 'itertools', '_socket']
         self._compiler = compiler
         self.core = core
         self.skip = skip
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -29,7 +29,7 @@
 # --allworkingmodules
 working_modules = default_modules.copy()
 working_modules.update([
-    "_socket", "unicodedata", "mmap", "fcntl", "_locale", "pwd", "rctime" ,
+    "_socket", "unicodedata", "mmap", "fcntl", "_locale", "pwd", "time" ,
     "select", "zipimport", "_lsprof", "crypt", "signal", "_rawffi", "termios",
     "zlib", "bz2", "struct", "_hashlib", "_md5", "_sha", "_minimal_curses",
     "cStringIO", "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array",
@@ -40,7 +40,7 @@
 
 translation_modules = default_modules.copy()
 translation_modules.update([
-    "fcntl", "rctime", "select", "signal", "_rawffi", "zlib", "struct", "_md5",
+    "fcntl", "time", "select", "signal", "_rawffi", "zlib", "struct", "_md5",
     "cStringIO", "array", "binascii",
     # the following are needed for pyrepl (and hence for the
     # interactive prompt/pdb)
@@ -65,18 +65,18 @@
 
 if sys.platform == "sunos5":
     working_modules.remove('mmap')   # depend on ctypes, can't get at c-level 'errono'
-    working_modules.remove('rctime') # depend on ctypes, missing tm_zone/tm_gmtoff
+    working_modules.remove('time')   # depend on ctypes, missing tm_zone/tm_gmtoff
     working_modules.remove('signal') # depend on ctypes, can't get at c-level 'errono'
     working_modules.remove('fcntl')  # LOCK_NB not defined
     working_modules.remove("_minimal_curses")
     working_modules.remove("termios")
-    working_modules.remove("_multiprocessing")   # depends on rctime
+    working_modules.remove("_multiprocessing")   # depends on time
     if "cppyy" in working_modules:
         working_modules.remove("cppyy")  # depends on ctypes
 
 
 module_dependencies = {
-    '_multiprocessing': [('objspace.usemodules.rctime', True),
+    '_multiprocessing': [('objspace.usemodules.time', True),
                          ('objspace.usemodules.thread', True)],
     'cpyext': [('objspace.usemodules.array', True)],
     'cppyy': [('objspace.usemodules.cpyext', True)],
diff --git a/pypy/doc/config/objspace.usemodules.rctime.txt b/pypy/doc/config/objspace.usemodules.rctime.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.usemodules.rctime.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Use the 'rctime' module. 
-
-'rctime' is our `rffi`_ based implementation of the builtin 'time' module.
-It supersedes the less complete :config:`objspace.usemodules.time`,
-at least for C-like targets (the C and LLVM backends).
-
-.. _`rffi`: ../rffi.html
diff --git a/pypy/doc/config/objspace.usemodules.time.txt b/pypy/doc/config/objspace.usemodules.time.txt
--- a/pypy/doc/config/objspace.usemodules.time.txt
+++ b/pypy/doc/config/objspace.usemodules.time.txt
@@ -1,5 +1,1 @@
 Use the 'time' module. 
-
-Obsolete; use :config:`objspace.usemodules.rctime` for our up-to-date version
-of the application-level 'time' module, at least for C-like targets (the C
-and LLVM backends).
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -522,11 +522,6 @@
                 if name not in modules:
                     modules.append(name)
 
-        # a bit of custom logic: rctime take precedence over time
-        # XXX this could probably be done as a "requires" in the config
-        if 'rctime' in modules and 'time' in modules:
-            modules.remove('time')
-
         self._builtinmodule_list = modules
         return self._builtinmodule_list
 
diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py
--- a/pypy/module/_file/test/test_file_extra.py
+++ b/pypy/module/_file/test/test_file_extra.py
@@ -221,7 +221,7 @@
     expected_filename = str(udir.join('sample'))
     expected_mode = 'rb'
     extra_args = ()
-    spaceconfig = {'usemodules': ['binascii', 'rctime', 'struct']}
+    spaceconfig = {'usemodules': ['binascii', 'time', 'struct']}
 
     def setup_method(self, method):
         space = self.space
@@ -281,7 +281,7 @@
     expected_filename = '<fdopen>'
     expected_mode = 'rb'
     extra_args = ()
-    spaceconfig = {'usemodules': ['binascii', 'rctime', 'struct']}
+    spaceconfig = {'usemodules': ['binascii', 'time', 'struct']}
 
     def setup_method(self, method):
         space = self.space
@@ -359,7 +359,7 @@
 #  A few extra tests
 
 class AppTestAFewExtra:
-    spaceconfig = {'usemodules': ['_socket', 'array', 'binascii', 'rctime',
+    spaceconfig = {'usemodules': ['_socket', 'array', 'binascii', 'time',
                                   'struct']}
 
     def setup_method(self, method):
diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py
--- a/pypy/module/_lsprof/test/test_cprofile.py
+++ b/pypy/module/_lsprof/test/test_cprofile.py
@@ -1,6 +1,6 @@
 class AppTestCProfile(object):
     spaceconfig = {
-        "usemodules": ['_lsprof', 'rctime'],
+        "usemodules": ['_lsprof', 'time'],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/_md5/test/test_md5.py b/pypy/module/_md5/test/test_md5.py
--- a/pypy/module/_md5/test/test_md5.py
+++ b/pypy/module/_md5/test/test_md5.py
@@ -5,7 +5,7 @@
 
 class AppTestMD5(object):
     spaceconfig = {
-        'usemodules': ['_md5', 'binascii', 'rctime', 'struct'],
+        'usemodules': ['_md5', 'binascii', 'time', 'struct'],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py
--- a/pypy/module/_multiprocessing/interp_semaphore.py
+++ b/pypy/module/_multiprocessing/interp_semaphore.py
@@ -254,7 +254,7 @@
         start = _GetTickCount()
 
         while True:
-            from pypy.module.rctime.interp_time import State
+            from pypy.module.time.interp_time import State
             interrupt_event = space.fromcache(State).get_interrupt_event()
             handles = [self.handle, interrupt_event]
 
diff --git a/pypy/module/_random/test/test_random.py b/pypy/module/_random/test/test_random.py
--- a/pypy/module/_random/test/test_random.py
+++ b/pypy/module/_random/test/test_random.py
@@ -1,6 +1,6 @@
 class AppTestRandom:
     spaceconfig = {
-        "usemodules": ['_random', 'rctime'],
+        "usemodules": ['_random', 'time'],
     }
 
     def test_dict(self):
diff --git a/pypy/module/_sha/test/test_sha.py b/pypy/module/_sha/test/test_sha.py
--- a/pypy/module/_sha/test/test_sha.py
+++ b/pypy/module/_sha/test/test_sha.py
@@ -5,7 +5,7 @@
 
 class AppTestSHA(object):
     spaceconfig = {
-        'usemodules': ['_sha', 'binascii', 'rctime', 'struct'],
+        'usemodules': ['_sha', 'binascii', 'time', 'struct'],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py
--- a/pypy/module/bz2/test/test_bz2_file.py
+++ b/pypy/module/bz2/test/test_bz2_file.py
@@ -53,7 +53,7 @@
 
 class AppTestBZ2File(CheckAllocation):
     spaceconfig = {
-        'usemodules': ['bz2', 'binascii', 'rctime', 'struct']
+        'usemodules': ['bz2', 'binascii', 'time', 'struct']
     }
 
     def setup_class(cls):
diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py
--- a/pypy/module/cpyext/test/conftest.py
+++ b/pypy/module/cpyext/test/conftest.py
@@ -7,7 +7,7 @@
     # it's necessary to run "import time" at least once before any
     # other cpyext test, otherwise the same statement will fail in
     # test_datetime.py.
-    space = gettestobjspace(usemodules=['rctime'])
+    space = gettestobjspace(usemodules=['time'])
     space.getbuiltinmodule("time")
 
 def pytest_ignore_collect(path, config):
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -102,7 +102,7 @@
 class LeakCheckingTest(object):
     """Base class for all cpyext tests."""
     spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array',
-                                   'itertools', 'rctime', 'binascii', 'micronumpy'])
+                                   'itertools', 'time', 'binascii', 'micronumpy'])
     spaceconfig['std.withmethodcache'] = True
 
     enable_leak_checking = True
diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py
--- a/pypy/module/fcntl/test/test_fcntl.py
+++ b/pypy/module/fcntl/test/test_fcntl.py
@@ -12,7 +12,7 @@
 
 class AppTestFcntl:
     spaceconfig = dict(usemodules=('fcntl', 'array', 'struct', 'termios',
-                                   'select', 'rctime'))
+                                   'select', 'time'))
 
     def setup_class(cls):
         tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_'))
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -4,7 +4,7 @@
 
 class AppTestImpModule:
     spaceconfig = {
-        'usemodules': ['binascii', 'imp', 'itertools', 'rctime', 'struct'],
+        'usemodules': ['binascii', 'imp', 'itertools', 'time', 'struct'],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -149,7 +149,7 @@
 
 class AppTestImport:
     spaceconfig = {
-        "usemodules": ['_md5', 'rctime'],
+        "usemodules": ['_md5', 'time'],
     }
 
     def setup_class(cls):
@@ -1044,7 +1044,7 @@
 
 class AppTestImportHooks(object):
     spaceconfig = {
-        "usemodules": ['struct', 'itertools', 'rctime'],
+        "usemodules": ['struct', 'itertools', 'time'],
     }
 
     def setup_class(cls):
@@ -1304,7 +1304,7 @@
 
 
 class AppTestMultithreadedImp(object):
-    spaceconfig = dict(usemodules=['thread', 'rctime'])
+    spaceconfig = dict(usemodules=['thread', 'time'])
 
     def setup_class(cls):
         #if not conftest.option.runappdirect:
diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -7,7 +7,7 @@
 
 class AppTestMath:
     spaceconfig = {
-        "usemodules": ['math', 'struct', 'itertools', 'rctime', 'binascii'],
+        "usemodules": ['math', 'struct', 'itertools', 'time', 'binascii'],
     }
 
     def setup_class(cls):
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
@@ -14,7 +14,7 @@
 import signal
 
 def setup_module(mod):
-    usemodules = ['binascii', 'posix', 'struct', 'rctime']
+    usemodules = ['binascii', 'posix', 'struct', 'time']
     if os.name != 'nt':
         usemodules += ['fcntl']
     else:
diff --git a/pypy/module/posix/test/test_posix_libfile.py b/pypy/module/posix/test/test_posix_libfile.py
--- a/pypy/module/posix/test/test_posix_libfile.py
+++ b/pypy/module/posix/test/test_posix_libfile.py
@@ -10,7 +10,7 @@
 
 class AppTestPosix:
     spaceconfig = {
-        "usemodules": ['posix', 'rctime'],
+        "usemodules": ['posix', 'time'],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -177,7 +177,7 @@
 
 class AppTestPyexpat2:
     spaceconfig = dict(usemodules=['pyexpat', 'itertools', '_socket',
-                                   'rctime', 'struct', 'binascii'])
+                                   'time', 'struct', 'binascii'])
 
     def test_django_bug(self):
         xml_str = '<?xml version="1.0" standalone="no"?><!DOCTYPE example SYSTEM "http://example.com/example.dtd"><root/>'
diff --git a/pypy/module/pypyjit/test/test_policy.py b/pypy/module/pypyjit/test/test_policy.py
--- a/pypy/module/pypyjit/test/test_policy.py
+++ b/pypy/module/pypyjit/test/test_policy.py
@@ -29,7 +29,7 @@
     assert pypypolicy.look_inside_function(get_ident)
 
 def test_time():
-    from pypy.module.rctime.interp_time import time
+    from pypy.module.time.interp_time import time
     assert pypypolicy.look_inside_function(time)
 
 def test_io():
diff --git a/pypy/module/rctime/__init__.py b/pypy/module/rctime/__init__.py
deleted file mode 100644
--- a/pypy/module/rctime/__init__.py
+++ /dev/null
@@ -1,42 +0,0 @@
-
-from pypy.interpreter.mixedmodule import MixedModule
-import os
-
-_WIN = os.name == "nt"
-
-class Module(MixedModule):
-    applevel_name = 'time'
-
-    interpleveldefs = {
-        'time': 'interp_time.time',
-        'clock': 'interp_time.clock',
-        'ctime': 'interp_time.ctime',
-        'asctime': 'interp_time.asctime',
-        'gmtime': 'interp_time.gmtime',
-        'localtime': 'interp_time.localtime',
-        'mktime': 'interp_time.mktime',
-        'strftime': 'interp_time.strftime',
-        'sleep' : 'interp_time.sleep',
-    }
-
-    if os.name == "posix":
-        interpleveldefs['tzset'] = 'interp_time.tzset'
-
-    appleveldefs = {
-        'struct_time': 'app_time.struct_time',
-        '__doc__': 'app_time.__doc__',
-        'strptime': 'app_time.strptime',
-    }
-
-    def startup(self, space):
-        if _WIN:
-            from pypy.module.rctime.interp_time import State
-            space.fromcache(State).startup(space)
-
-        # this machinery is needed to expose constants
-        # that have to be initialized one time only
-        from pypy.module.rctime import interp_time
-
-        interp_time._init_timezone(space)
-        interp_time._init_accept2dyear(space)
-
diff --git a/pypy/module/rctime/interp_time.py b/pypy/module/rctime/interp_time.py
deleted file mode 100644
--- a/pypy/module/rctime/interp_time.py
+++ /dev/null
@@ -1,670 +0,0 @@
-from rpython.rtyper.tool import rffi_platform as platform
-from rpython.rtyper.lltypesystem import rffi
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import unwrap_spec
-from rpython.rtyper.lltypesystem import lltype
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib import rposix
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-import os
-import sys
-import time as pytime
-
-_POSIX = os.name == "posix"
-_WIN = os.name == "nt"
-_CYGWIN = sys.platform == "cygwin"
-
-_time_zones = []
-if _CYGWIN:
-    _time_zones = ["GMT-12", "GMT-11", "GMT-10", "GMT-9", "GMT-8", "GMT-7",
-                   "GMT-6", "GMT-5", "GMT-4", "GMT-3", "GMT-2", "GMT-1",
-                   "GMT",  "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5",
-                   "GMT+6",  "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11",
-                   "GMT+12",  "GMT+13", "GMT+14"]
-
-if _WIN:
-    # Interruptible sleeps on Windows:
-    # We install a specific Console Ctrl Handler which sets an 'event'.
-    # time.sleep() will actually call WaitForSingleObject with the desired
-    # timeout.  On Ctrl-C, the signal handler is called, the event is set,
-    # and the wait function exits.
-    from rpython.rlib import rwin32
-    from pypy.interpreter.error import wrap_windowserror, wrap_oserror
-    from rpython.rlib import rthread as thread
-
-    eci = ExternalCompilationInfo(
-        includes = ['windows.h'],
-        post_include_bits = [
-            "RPY_EXTERN\n"
-            "BOOL pypy_timemodule_setCtrlHandler(HANDLE event);"],
-        separate_module_sources=['''
-            static HANDLE interrupt_event;
-
-            static BOOL WINAPI CtrlHandlerRoutine(
-              DWORD dwCtrlType)
-            {
-                SetEvent(interrupt_event);
-                /* allow other default handlers to be called.
-                 * Default Python handler will setup the
-                 * KeyboardInterrupt exception.
-                 */
-                return 0;
-            }
-
-            BOOL pypy_timemodule_setCtrlHandler(HANDLE event)
-            {
-                interrupt_event = event;
-                return SetConsoleCtrlHandler(CtrlHandlerRoutine, TRUE);
-            }
-
-        '''],
-        )
-    _setCtrlHandlerRoutine = rffi.llexternal(
-        'pypy_timemodule_setCtrlHandler',
-        [rwin32.HANDLE], rwin32.BOOL,
-        compilation_info=eci)
-
-    class GlobalState:
-        def __init__(self):
-            self.init()
-
-        def init(self):
-            self.interrupt_event = rwin32.NULL_HANDLE
-
-        def startup(self, space):
-            # Initialize the event handle used to signal Ctrl-C
-            try:
-                globalState.interrupt_event = rwin32.CreateEvent(
-                    rffi.NULL, True, False, rffi.NULL)
-            except WindowsError, e:
-                raise wrap_windowserror(space, e)
-            if not _setCtrlHandlerRoutine(globalState.interrupt_event):
-                raise wrap_windowserror(
-                    space, rwin32.lastWindowsError("SetConsoleCtrlHandler"))
-
-    globalState = GlobalState()
-
-    class State:
-        def __init__(self, space):
-            self.main_thread = 0
-
-        def _cleanup_(self):
-            self.main_thread = 0
-            globalState.init()
-
-        def startup(self, space):
-            self.main_thread = thread.get_ident()
-            globalState.startup(space)
-
-        def get_interrupt_event(self):
-            return globalState.interrupt_event
-
-
-_includes = ["time.h"]
-if _POSIX:
-    _includes.append('sys/time.h')
-
-class CConfig:
-    _compilation_info_ = ExternalCompilationInfo(
-        includes = _includes
-    )
-    CLOCKS_PER_SEC = platform.ConstantInteger("CLOCKS_PER_SEC")
-    clock_t = platform.SimpleType("clock_t", rffi.ULONG)
-    has_gettimeofday = platform.Has('gettimeofday')
-
-if _POSIX:
-    calling_conv = 'c'
-    CConfig.timeval = platform.Struct("struct timeval",
-                                      [("tv_sec", rffi.INT),
-                                       ("tv_usec", rffi.INT)])
-    if _CYGWIN:
-        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
-            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
-            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
-            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
-    else:
-        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
-            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
-            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
-            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT), ("tm_gmtoff", rffi.LONG),
-            ("tm_zone", rffi.CCHARP)])
-elif _WIN:
-    calling_conv = 'win'
-    CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
-        ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
-        ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
-        ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
-
-class cConfig:
-    pass
-
-for k, v in platform.configure(CConfig).items():
-    setattr(cConfig, k, v)
-cConfig.tm.__name__ = "_tm"
-
-def external(name, args, result, eci=CConfig._compilation_info_):
-    if _WIN and rffi.sizeof(rffi.TIME_T) == 8:
-        # Recent Microsoft compilers use 64bit time_t and
-        # the corresponding functions are named differently
-        if (rffi.TIME_T in args or rffi.TIME_TP in args
-            or result in (rffi.TIME_T, rffi.TIME_TP)):
-            name = '_' + name + '64'
-    return rffi.llexternal(name, args, result,
-                           compilation_info=eci,
-                           calling_conv=calling_conv,
-                           releasegil=False)
-
-if _POSIX:
-    cConfig.timeval.__name__ = "_timeval"
-    timeval = cConfig.timeval
-
-CLOCKS_PER_SEC = cConfig.CLOCKS_PER_SEC
-clock_t = cConfig.clock_t
-tm = cConfig.tm
-glob_buf = lltype.malloc(tm, flavor='raw', zero=True, immortal=True)
-
-if cConfig.has_gettimeofday:
-    c_gettimeofday = external('gettimeofday', [rffi.VOIDP, rffi.VOIDP], rffi.INT)
-TM_P = lltype.Ptr(tm)
-c_clock = external('clock', [rffi.TIME_TP], clock_t)
-c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
-c_ctime = external('ctime', [rffi.TIME_TP], rffi.CCHARP)
-c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P)
-c_mktime = external('mktime', [TM_P], rffi.TIME_T)
-c_asctime = external('asctime', [TM_P], rffi.CCHARP)
-c_localtime = external('localtime', [rffi.TIME_TP], TM_P)
-if _POSIX:
-    c_tzset = external('tzset', [], lltype.Void)
-if _WIN:
-    win_eci = ExternalCompilationInfo(
-        includes = ["time.h"],
-        post_include_bits = ["RPY_EXTERN "
-                             "long pypy_get_timezone();\n"
-                             "RPY_EXTERN "
-                             "int pypy_get_daylight();\n"
-                             "RPY_EXTERN "
-                             "char** pypy_get_tzname();\n"
-                             "RPY_EXTERN "
-                             "void pypy__tzset();"],
-        separate_module_sources = ["""
-        long pypy_get_timezone() { return timezone; }
-        int pypy_get_daylight() { return daylight; }
-        char** pypy_get_tzname() { return tzname; }
-        void pypy__tzset() { _tzset(); }
-        """])
-    # Ensure sure that we use _tzset() and timezone from the same C Runtime.
-    c_tzset = external('pypy__tzset', [], lltype.Void, win_eci)
-    c_get_timezone = external('pypy_get_timezone', [], rffi.LONG, win_eci)
-    c_get_daylight = external('pypy_get_daylight', [], rffi.INT, win_eci)
-    c_get_tzname = external('pypy_get_tzname', [], rffi.CCHARPP, win_eci)
-
-c_strftime = external('strftime', [rffi.CCHARP, rffi.SIZE_T, rffi.CCHARP, TM_P],
-                      rffi.SIZE_T)
-
-def _init_accept2dyear(space):
-    if os.environ.get("PYTHONY2K"):
-        accept2dyear = 0
-    else:
-        accept2dyear = 1
-    _set_module_object(space, "accept2dyear", space.wrap(accept2dyear))
-
-def _init_timezone(space):
-    timezone = daylight = altzone = 0
-    tzname = ["", ""]
-
-    if _WIN:
-        c_tzset()
-        timezone = c_get_timezone()
-        altzone = timezone - 3600
-        daylight = c_get_daylight()
-        tzname_ptr = c_get_tzname()
-        tzname = rffi.charp2str(tzname_ptr[0]), rffi.charp2str(tzname_ptr[1])
-
-    if _POSIX:
-        if _CYGWIN:
-            YEAR = (365 * 24 + 6) * 3600
-
-            # about January 11th
-            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR + 10 * 24 * 3600)
-            # we cannot have reference to stack variable, put it on the heap
-            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-            t_ref[0] = rffi.cast(rffi.TIME_T, t)
-            p = c_localtime(t_ref)
-            q = c_gmtime(t_ref)
-            janzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
-            if janzone < -12:
-                janname = "   "
-            elif janzone > 14:
-                janname = "   "
-            else:
-                janname = _time_zones[janzone - 12]
-            janzone = janzone * 3600
-            # about July 11th
-            tt = t + YEAR / 2
-            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
-            p = c_localtime(t_ref)
-            q = c_gmtime(t_ref)
-            julyzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
-            if julyzone < -12:
-                julyname = "   "
-            elif julyzone > 14:
-                julyname = "   "
-            else:
-                julyname = _time_zones[julyzone - 12]
-            julyzone = julyzone * 3600
-            lltype.free(t_ref, flavor='raw')
-
-            if janzone < julyzone:
-                # DST is reversed in the southern hemisphere
-                timezone = julyzone
-                altzone = janzone
-                daylight = int(janzone != julyzone)
-                tzname = [julyname, janname]
-            else:
-                timezone = janzone
-                altzone = julyzone
-                daylight = int(janzone != julyzone)
-                tzname = [janname, julyname]
-
-        else:
-            YEAR = (365 * 24 + 6) * 3600
-
-            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR)
-            # we cannot have reference to stack variable, put it on the heap
-            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-            t_ref[0] = rffi.cast(rffi.TIME_T, t)
-            p = c_localtime(t_ref)
-            janzone = -p.c_tm_gmtoff
-            tm_zone = rffi.charp2str(p.c_tm_zone)
-            janname = ["   ", tm_zone][bool(tm_zone)]
-            tt = t + YEAR / 2
-            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
-            p = c_localtime(t_ref)
-            lltype.free(t_ref, flavor='raw')
-            tm_zone = rffi.charp2str(p.c_tm_zone)
-            julyzone = -p.c_tm_gmtoff
-            julyname = ["   ", tm_zone][bool(tm_zone)]
-
-            if janzone < julyzone:
-                # DST is reversed in the southern hemisphere
-                timezone = julyzone
-                altzone = janzone
-                daylight = int(janzone != julyzone)
-                tzname = [julyname, janname]
-            else:
-                timezone = janzone
-                altzone = julyzone
-                daylight = int(janzone != julyzone)
-                tzname = [janname, julyname]
-
-    _set_module_object(space, "timezone", space.wrap(timezone))
-    _set_module_object(space, 'daylight', space.wrap(daylight))
-    tzname_w = [space.wrap(tzname[0]), space.wrap(tzname[1])]
-    _set_module_object(space, 'tzname', space.newtuple(tzname_w))
-    _set_module_object(space, 'altzone', space.wrap(altzone))
-
-def _get_error_msg():
-    errno = rposix.get_errno()
-    return os.strerror(errno)
-
-if sys.platform != 'win32':
-    @unwrap_spec(secs=float)
-    def sleep(space, secs):
-        if secs < 0:
-            raise OperationError(space.w_IOError,
-                                 space.wrap("Invalid argument: negative time in sleep"))
-        pytime.sleep(secs)
-else:
-    from rpython.rlib import rwin32
-    from errno import EINTR
-    def _simple_sleep(space, secs, interruptible):
-        if secs == 0.0 or not interruptible:
-            pytime.sleep(secs)
-        else:
-            millisecs = int(secs * 1000)
-            interrupt_event = space.fromcache(State).get_interrupt_event()
-            rwin32.ResetEvent(interrupt_event)
-            rc = rwin32.WaitForSingleObject(interrupt_event, millisecs)
-            if rc == rwin32.WAIT_OBJECT_0:
-                # Yield to make sure real Python signal handler
-                # called.
-                pytime.sleep(0.001)
-                raise wrap_oserror(space,
-                                   OSError(EINTR, "sleep() interrupted"))
-    @unwrap_spec(secs=float)
-    def sleep(space, secs):
-        if secs < 0:
-            raise OperationError(space.w_IOError,
-                                 space.wrap("Invalid argument: negative time in sleep"))
-        # as decreed by Guido, only the main thread can be
-        # interrupted.
-        main_thread = space.fromcache(State).main_thread
-        interruptible = (main_thread == thread.get_ident())
-        MAX = sys.maxint / 1000.0 # > 24 days
-        while secs > MAX:
-            _simple_sleep(space, MAX, interruptible)
-            secs -= MAX
-        _simple_sleep(space, secs, interruptible)
-
-def _get_module_object(space, obj_name):
-    w_module = space.getbuiltinmodule('time')
-    w_obj = space.getattr(w_module, space.wrap(obj_name))
-    return w_obj
-
-def _set_module_object(space, obj_name, w_obj_value):
-    w_module = space.getbuiltinmodule('time')
-    space.setattr(w_module, space.wrap(obj_name), w_obj_value)
-
-def _get_inttime(space, w_seconds):
-    # w_seconds can be a wrapped None (it will be automatically wrapped
-    # in the callers, so we never get a real None here).
-    if space.is_none(w_seconds):
-        seconds = pytime.time()
-    else:
-        seconds = space.float_w(w_seconds)
-    #
-    t = rffi.cast(rffi.TIME_T, seconds)
-    #
-    # Logic from CPython: How much info did we lose?  We assume that
-    # time_t is an integral type.  If we lost a second or more, the
-    # input doesn't fit in a time_t; call it an error.
-    diff = seconds - rffi.cast(lltype.Float, t)
-    if diff <= -1.0 or diff >= 1.0:
-        raise OperationError(space.w_ValueError,
-                      space.wrap("timestamp out of range for platform time_t"))
-    return t
-
-def _tm_to_tuple(space, t):
-    time_tuple = [
-        space.wrap(rffi.getintfield(t, 'c_tm_year') + 1900),
-        space.wrap(rffi.getintfield(t, 'c_tm_mon') + 1), # want january == 1
-        space.wrap(rffi.getintfield(t, 'c_tm_mday')),
-        space.wrap(rffi.getintfield(t, 'c_tm_hour')),
-        space.wrap(rffi.getintfield(t, 'c_tm_min')),
-        space.wrap(rffi.getintfield(t, 'c_tm_sec')),
-        space.wrap((rffi.getintfield(t, 'c_tm_wday') + 6) % 7), # want monday == 0
-        space.wrap(rffi.getintfield(t, 'c_tm_yday') + 1), # want january, 1 == 1
-        space.wrap(rffi.getintfield(t, 'c_tm_isdst'))]
-
-    w_struct_time = _get_module_object(space, 'struct_time')
-    w_time_tuple = space.newtuple(time_tuple)
-    return space.call_function(w_struct_time, w_time_tuple)
-
-def _gettmarg(space, w_tup, allowNone=True):
-    if space.is_none(w_tup):
-        if not allowNone:
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("tuple expected"))
-        # default to the current local time
-        tt = rffi.r_time_t(int(pytime.time()))
-        t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-        t_ref[0] = tt
-        pbuf = c_localtime(t_ref)
-        lltype.free(t_ref, flavor='raw')
-        if not pbuf:
-            raise OperationError(space.w_ValueError,
-                space.wrap(_get_error_msg()))
-        return pbuf
-
-    tup_w = space.fixedview(w_tup)
-    if len(tup_w) != 9:
-        raise oefmt(space.w_TypeError,
-                    "argument must be sequence of length 9, not %d",
-                    len(tup_w))
-
-    y = space.int_w(tup_w[0])
-    tm_mon = space.int_w(tup_w[1])
-    if tm_mon == 0:
-        tm_mon = 1
-    tm_mday = space.int_w(tup_w[2])
-    if tm_mday == 0:
-        tm_mday = 1
-    tm_yday = space.int_w(tup_w[7])
-    if tm_yday == 0:
-        tm_yday = 1
-    rffi.setintfield(glob_buf, 'c_tm_mon', tm_mon)
-    rffi.setintfield(glob_buf, 'c_tm_mday', tm_mday)
-    rffi.setintfield(glob_buf, 'c_tm_hour', space.int_w(tup_w[3]))
-    rffi.setintfield(glob_buf, 'c_tm_min', space.int_w(tup_w[4]))
-    rffi.setintfield(glob_buf, 'c_tm_sec', space.int_w(tup_w[5]))
-    rffi.setintfield(glob_buf, 'c_tm_wday', space.int_w(tup_w[6]))
-    rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday)
-    rffi.setintfield(glob_buf, 'c_tm_isdst', space.int_w(tup_w[8]))
-    if _POSIX:
-        if _CYGWIN:
-            pass
-        else:
-            # actually never happens, but makes annotator happy
-            glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
-            rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
-
-    if y < 1900:
-        w_accept2dyear = _get_module_object(space, "accept2dyear")
-        accept2dyear = space.int_w(w_accept2dyear)
-
-        if not accept2dyear:
-            raise OperationError(space.w_ValueError,
-                space.wrap("year >= 1900 required"))
-
-        if 69 <= y <= 99:
-            y += 1900
-        elif 0 <= y <= 68:
-            y += 2000
-        else:
-            raise OperationError(space.w_ValueError,
-                space.wrap("year out of range"))
-
-    # tm_wday does not need checking of its upper-bound since taking "%
-    #  7" in gettmarg() automatically restricts the range.
-    if rffi.getintfield(glob_buf, 'c_tm_wday') < -1:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of week out of range"))
-
-    rffi.setintfield(glob_buf, 'c_tm_year', y - 1900)
-    rffi.setintfield(glob_buf, 'c_tm_mon',
-                     rffi.getintfield(glob_buf, 'c_tm_mon') - 1)
-    rffi.setintfield(glob_buf, 'c_tm_wday',
-                     (rffi.getintfield(glob_buf, 'c_tm_wday') + 1) % 7)
-    rffi.setintfield(glob_buf, 'c_tm_yday',
-                     rffi.getintfield(glob_buf, 'c_tm_yday') - 1)
-
-    return glob_buf
-
-def time(space):
-    """time() -> floating point number
-
-    Return the current time in seconds since the Epoch.
-    Fractions of a second may be present if the system clock provides them."""
-
-    secs = pytime.time()
-    return space.wrap(secs)
-
-if _WIN:
-    class PCCache:
-        pass
-    pccache = PCCache()
-    pccache.divisor = 0.0
-    pccache.ctrStart = 0
-
-def clock(space):
-    """clock() -> floating point number
-
-    Return the CPU time or real time since the start of the process or since
-    the first call to clock().  This has as much precision as the system
-    records."""
-
-    return space.wrap(pytime.clock())
-
-def ctime(space, w_seconds=None):
-    """ctime([seconds]) -> string
-
-    Convert a time in seconds since the Epoch to a string in local time.
-    This is equivalent to asctime(localtime(seconds)). When the time tuple is
-    not present, current time as returned by localtime() is used."""
-
-    seconds = _get_inttime(space, w_seconds)
-
-    t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-    t_ref[0] = seconds
-    p = c_ctime(t_ref)
-    lltype.free(t_ref, flavor='raw')
-    if not p:
-        raise OperationError(space.w_ValueError,
-            space.wrap("unconvertible time"))
-
-    return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line
-
-# by now w_tup is an optional argument (and not *args)
-# because of the ext. compiler bugs in handling such arguments (*args, **kwds)
-def asctime(space, w_tup=None):
-    """asctime([tuple]) -> string
-
-    Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.
-    When the time tuple is not present, current time as returned by localtime()
-    is used."""
-    buf_value = _gettmarg(space, w_tup)
-    p = c_asctime(buf_value)
-    if not p:
-        raise OperationError(space.w_ValueError,
-            space.wrap("unconvertible time"))
-
-    return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line
-
-def gmtime(space, w_seconds=None):
-    """gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,
-                          tm_sec, tm_wday, tm_yday, tm_isdst)
-
-    Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.
-    GMT).  When 'seconds' is not passed in, convert the current time instead.
-    """
-
-    # rpython does not support that a variable has two incompatible builtins
-    # as value so we have to duplicate the code. NOT GOOD! see localtime() too
-    seconds = _get_inttime(space, w_seconds)
-    t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-    t_ref[0] = seconds
-    p = c_gmtime(t_ref)
-    lltype.free(t_ref, flavor='raw')
-
-    if not p:
-        raise OperationError(space.w_ValueError, space.wrap(_get_error_msg()))
-    return _tm_to_tuple(space, p)
-
-def localtime(space, w_seconds=None):
-    """localtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,
-                             tm_sec, tm_wday, tm_yday, tm_isdst)
-
-    Convert seconds since the Epoch to a time tuple expressing local time.
-    When 'seconds' is not passed in, convert the current time instead."""
-
-    seconds = _get_inttime(space, w_seconds)
-    t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-    t_ref[0] = seconds
-    p = c_localtime(t_ref)
-    lltype.free(t_ref, flavor='raw')
-
-    if not p:
-        raise OperationError(space.w_ValueError, space.wrap(_get_error_msg()))
-    return _tm_to_tuple(space, p)
-
-def mktime(space, w_tup):
-    """mktime(tuple) -> floating point number
-
-    Convert a time tuple in local time to seconds since the Epoch."""
-
-    buf = _gettmarg(space, w_tup, allowNone=False)
-    rffi.setintfield(buf, "c_tm_wday", -1)
-    tt = c_mktime(buf)
-    # A return value of -1 does not necessarily mean an error, but tm_wday
-    # cannot remain set to -1 if mktime succeeds.
-    if tt == -1 and rffi.getintfield(buf, "c_tm_wday") == -1:
-        raise OperationError(space.w_OverflowError,
-            space.wrap("mktime argument out of range"))
-
-    return space.wrap(float(tt))
-
-if _POSIX:
-    def tzset(space):
-        """tzset()
-
-        Initialize, or reinitialize, the local timezone to the value stored in
-        os.environ['TZ']. The TZ environment variable should be specified in
-        standard Unix timezone format as documented in the tzset man page
-        (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently
-        fall back to UTC. If the TZ environment variable is not set, the local
-        timezone is set to the systems best guess of wallclock time.
-        Changing the TZ environment variable without calling tzset *may* change
-        the local timezone used by methods such as localtime, but this behaviour
-        should not be relied on"""
-
-        c_tzset()
-
-        # reset timezone, altzone, daylight and tzname
-        _init_timezone(space)
-
- at unwrap_spec(format=str)
-def strftime(space, format, w_tup=None):
-    """strftime(format[, tuple]) -> string
-
-    Convert a time tuple to a string according to a format specification.
-    See the library reference manual for formatting codes. When the time tuple
-    is not present, current time as returned by localtime() is used."""
-    buf_value = _gettmarg(space, w_tup)
-
-    # Checks added to make sure strftime() does not crash Python by
-    # indexing blindly into some array for a textual representation
-    # by some bad index (fixes bug #897625).
-    # No check for year since handled in gettmarg().
-    if rffi.getintfield(buf_value, 'c_tm_mon') < 0 or rffi.getintfield(buf_value, 'c_tm_mon') > 11:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("month out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_mday') < 1 or rffi.getintfield(buf_value, 'c_tm_mday') > 31:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of month out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_hour') < 0 or rffi.getintfield(buf_value, 'c_tm_hour') > 23:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("hour out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_min') < 0 or rffi.getintfield(buf_value, 'c_tm_min') > 59:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("minute out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_sec') < 0 or rffi.getintfield(buf_value, 'c_tm_sec') > 61:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("seconds out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_yday') < 0 or rffi.getintfield(buf_value, 'c_tm_yday') > 365:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of year out of range"))
-    if rffi.getintfield(buf_value, 'c_tm_isdst') < -1 or rffi.getintfield(buf_value, 'c_tm_isdst') > 1:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("daylight savings flag out of range"))
-
-    if _WIN:
-        # check that the format string contains only valid directives
-        length = len(format)
-        i = 0
-        while i < length:
-            if format[i] == '%':
-                i += 1
-                if i < length and format[i] == '#':
-                    # not documented by python
-                    i += 1
-                if i >= length or format[i] not in "aAbBcdHIjmMpSUwWxXyYzZ%":
-                    raise OperationError(space.w_ValueError,
-                                         space.wrap("invalid format string"))
-            i += 1
-
-    i = 1024
-    while True:
-        outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw')
-        try:
-            buflen = c_strftime(outbuf, i, format, buf_value)
-            if buflen > 0 or i >= 256 * len(format):
-                # if the buffer is 256 times as long as the format,
-                # it's probably not failing for lack of room!
-                # More likely, the format yields an empty result,
-                # e.g. an empty format, or %Z when the timezone
-                # is unknown.
-                result = rffi.charp2strn(outbuf, intmask(buflen))
-                return space.wrap(result)
-        finally:
-            lltype.free(outbuf, flavor='raw')
-        i += i
diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py
deleted file mode 100644
--- a/pypy/module/rctime/test/test_rctime.py
+++ /dev/null
@@ -1,333 +0,0 @@
-class AppTestRCTime:
-    spaceconfig = {
-        "usemodules": ['rctime', 'struct', 'binascii'],
-    }
-
-    def test_attributes(self):
-        import time as rctime
-        assert isinstance(rctime.accept2dyear, int)
-        assert isinstance(rctime.altzone, int)
-        assert isinstance(rctime.daylight, int)
-        assert isinstance(rctime.timezone, int)
-        assert isinstance(rctime.tzname, tuple)
-        assert isinstance(rctime.__doc__, str)
-
-    def test_sleep(self):
-        import time as rctime
-        import sys
-        import os
-        raises(TypeError, rctime.sleep, "foo")
-        rctime.sleep(0.12345)
-        raises(IOError, rctime.sleep, -1.0)
-
-    def test_clock(self):
-        import time as rctime
-        rctime.clock()
-        assert isinstance(rctime.clock(), float)
-
-    def test_time(self):
-        import time as rctime
-        t1 = rctime.time()
-        assert isinstance(rctime.time(), float)
-        assert rctime.time() != 0.0 # 0.0 means failure
-        rctime.sleep(0.02)
-        t2 = rctime.time()
-        assert t1 != t2       # the resolution should be at least 0.01 secs
-
-    def test_ctime(self):
-        import time as rctime
-        raises(TypeError, rctime.ctime, "foo")
-        rctime.ctime(None)
-        rctime.ctime()
-        res = rctime.ctime(0)
-        assert isinstance(res, str)
-        rctime.ctime(rctime.time())
-        raises(ValueError, rctime.ctime, 1E200)
-        raises(OverflowError, rctime.ctime, 10**900)
-
-    def test_gmtime(self):
-        import time as rctime
-        raises(TypeError, rctime.gmtime, "foo")
-        rctime.gmtime()
-        rctime.gmtime(None)
-        rctime.gmtime(0)
-        res = rctime.gmtime(rctime.time())
-        assert isinstance(res, rctime.struct_time)
-        assert res[-1] == 0 # DST is always zero in gmtime()
-        t0 = rctime.mktime(rctime.gmtime())
-        t1 = rctime.mktime(rctime.gmtime(None))
-        assert 0 <= (t1 - t0) < 1.2
-        t = rctime.time()
-        assert rctime.gmtime(t) == rctime.gmtime(t)
-        raises(ValueError, rctime.gmtime, 2**64)
-        raises(ValueError, rctime.gmtime, -2**64)
-
-    def test_localtime(self):
-        import time as rctime
-        import os
-        raises(TypeError, rctime.localtime, "foo")
-        rctime.localtime()
-        rctime.localtime(None)
-        rctime.localtime(0)
-        res = rctime.localtime(rctime.time())
-        assert isinstance(res, rctime.struct_time)
-        t0 = rctime.mktime(rctime.localtime())
-        t1 = rctime.mktime(rctime.localtime(None))
-        assert 0 <= (t1 - t0) < 1.2
-        t = rctime.time()
-        assert rctime.localtime(t) == rctime.localtime(t)
-        if os.name == 'nt':
-            raises(ValueError, rctime.localtime, -1)
-        else:
-            rctime.localtime(-1)
-
-    def test_mktime(self):
-        import time as rctime
-        import os, sys
-        raises(TypeError, rctime.mktime, "foo")
-        raises(TypeError, rctime.mktime, None)
-        raises(TypeError, rctime.mktime, (1, 2))
-        raises(TypeError, rctime.mktime, (1, 2, 3, 4, 5, 6, 'f', 8, 9))
-        res = rctime.mktime(rctime.localtime())
-        assert isinstance(res, float)
-
-        ltime = rctime.localtime()
-        rctime.accept2dyear == 0
-        ltime = list(ltime)
-        ltime[0] = 1899
-        raises(ValueError, rctime.mktime, tuple(ltime))
-        rctime.accept2dyear == 1
-
-        ltime = list(ltime)
-        ltime[0] = 67
-        ltime = tuple(ltime)
-        if os.name != "nt" and sys.maxint < 1<<32:   # time_t may be 64bit
-            raises(OverflowError, rctime.mktime, ltime)
-
-        ltime = list(ltime)
-        ltime[0] = 100
-        raises(ValueError, rctime.mktime, tuple(ltime))
-
-        t = rctime.time()
-        assert long(rctime.mktime(rctime.localtime(t))) == long(t)
-        assert long(rctime.mktime(rctime.gmtime(t))) - rctime.timezone == long(t)
-        ltime = rctime.localtime()
-        assert rctime.mktime(tuple(ltime)) == rctime.mktime(ltime)
-        if os.name != 'nt':
-            assert rctime.mktime(rctime.localtime(-1)) == -1
-
-        res = rctime.mktime((2000, 1, 1, 0, 0, 0, -1, -1, -1))
-        if os.name == 'nt':
-            assert rctime.ctime(res) == 'Sat Jan 01 00:00:00 2000'
-        else:
-            assert rctime.ctime(res) == 'Sat Jan  1 00:00:00 2000'
-
-    def test_asctime(self):
-        import time as rctime
-        rctime.asctime()
-        # raises(TypeError, rctime.asctime, None)
-        raises(TypeError, rctime.asctime, ())
-        raises(TypeError, rctime.asctime, (1,))
-        raises(TypeError, rctime.asctime, range(8))
-        raises(TypeError, rctime.asctime, (1, 2))
-        raises(TypeError, rctime.asctime, (1, 2, 3, 4, 5, 6, 'f', 8, 9))
-        raises(TypeError, rctime.asctime, "foo")
-        res = rctime.asctime()
-        assert isinstance(res, str)
-        rctime.asctime(rctime.localtime())
-        t = rctime.time()
-        assert rctime.ctime(t) == rctime.asctime(rctime.localtime(t))
-        if rctime.timezone:
-            assert rctime.ctime(t) != rctime.asctime(rctime.gmtime(t))
-        ltime = rctime.localtime()
-        assert rctime.asctime(tuple(ltime)) == rctime.asctime(ltime)
-        try:
-            rctime.asctime((12345,) + (0,) * 8)  # assert this doesn't crash
-        except ValueError:
-            pass  # some OS (ie POSIXes besides Linux) reject year > 9999
-
-    def test_accept2dyear_access(self):
-        import time as rctime
-
-        accept2dyear = rctime.accept2dyear
-        del rctime.accept2dyear
-        try:
-            # with year >= 1900 this shouldn't need to access accept2dyear
-            assert rctime.asctime((2000,) + (0,) * 8).split()[-1] == '2000'
-        finally:
-            rctime.accept2dyear = accept2dyear
-
-    def test_struct_time(self):
-        import time as rctime
-        raises(TypeError, rctime.struct_time)
-        raises(TypeError, rctime.struct_time, "foo")
-        raises(TypeError, rctime.struct_time, (1, 2, 3))
-        tup = (1, 2, 3, 4, 5, 6, 7, 8, 9)
-        st_time = rctime.struct_time(tup)
-        assert str(st_time).startswith('time.struct_time(tm_year=1, ')
-        assert len(st_time) == len(tup)
-
-    def test_tzset(self):
-        import time as rctime
-        import os
-
-        if not os.name == "posix":
-            skip("tzset available only under Unix")
-
-        # epoch time of midnight Dec 25th 2002. Never DST in northern
-        # hemisphere.
-        xmas2002 = 1040774400.0
-
-        # these formats are correct for 2002, and possibly future years
-        # this format is the 'standard' as documented at:
-        # http://www.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap08.html
-        # They are also documented in the tzset(3) man page on most Unix
-        # systems.
-        eastern = 'EST+05EDT,M4.1.0,M10.5.0'
-        victoria = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
-        utc = 'UTC+0'
-
-        org_TZ = os.environ.get('TZ', None)
-        try:
-            # Make sure we can switch to UTC time and results are correct
-            # Note that unknown timezones default to UTC.
-            # Note that altzone is undefined in UTC, as there is no DST
-            os.environ['TZ'] = eastern
-            rctime.tzset()
-            os.environ['TZ'] = utc
-            rctime.tzset()
-            assert rctime.gmtime(xmas2002) == rctime.localtime(xmas2002)
-            assert rctime.daylight == 0
-            assert rctime.timezone == 0
-            assert rctime.localtime(xmas2002).tm_isdst == 0
-
-            # make sure we can switch to US/Eastern
-            os.environ['TZ'] = eastern
-            rctime.tzset()
-            assert rctime.gmtime(xmas2002) != rctime.localtime(xmas2002)
-            assert rctime.tzname == ('EST', 'EDT')
-            assert len(rctime.tzname) == 2
-            assert rctime.daylight == 1
-            assert rctime.timezone == 18000
-            assert rctime.altzone == 14400
-            assert rctime.localtime(xmas2002).tm_isdst == 0
-
-            # now go to the southern hemisphere.
-            os.environ['TZ'] = victoria
-            rctime.tzset()
-            assert rctime.gmtime(xmas2002) != rctime.localtime(xmas2002)
-            assert rctime.tzname[0] == 'AEST'
-            assert rctime.tzname[1] == 'AEDT'
-            assert len(rctime.tzname) == 2
-            assert rctime.daylight == 1
-            assert rctime.timezone == -36000
-            assert rctime.altzone == -39600
-            assert rctime.localtime(xmas2002).tm_isdst == 1
-        finally:
-            # repair TZ environment variable in case any other tests
-            # rely on it.
-            if org_TZ is not None:
-                os.environ['TZ'] = org_TZ
-            elif os.environ.has_key('TZ'):
-                del os.environ['TZ']
-            rctime.tzset()
-
-    def test_strftime(self):
-        import time as rctime
-        import os, sys
-
-        t = rctime.time()
-        tt = rctime.gmtime(t)
-        for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
-                          'j', 'm', 'M', 'p', 'S',
-                          'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
-            format = ' %' + directive
-            rctime.strftime(format, tt)
-
-        raises(TypeError, rctime.strftime, ())
-        raises(TypeError, rctime.strftime, (1,))
-        raises(TypeError, rctime.strftime, range(8))
-        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')
-        elif sys.platform == 'darwin' or 'bsd' in sys.platform:
-            # darwin strips % of unknown format codes
-            # http://bugs.python.org/issue9811
-            assert rctime.strftime('%f') == 'f'
-        else:
-            assert rctime.strftime('%f') == '%f'
-
-    def test_strftime_ext(self):
-        import time as rctime
-
-        tt = rctime.gmtime()
-        try:
-            result = rctime.strftime('%D', tt)
-        except ValueError:
-            pass
-        else:
-            assert result == rctime.strftime('%m/%d/%y', tt)
-
-    def test_strftime_bounds_checking(self):
-        import time as rctime
-
-        # make sure that strftime() checks the bounds of the various parts
-        # of the time tuple.
-
-        # check year
-        raises(ValueError, rctime.strftime, '', (1899, 1, 1, 0, 0, 0, 0, 1, -1))
-        if rctime.accept2dyear:
-            raises(ValueError, rctime.strftime, '', (-1, 1, 1, 0, 0, 0, 0, 1, -1))
-            raises(ValueError, rctime.strftime, '', (100, 1, 1, 0, 0, 0, 0, 1, -1))
-        # check month
-        raises(ValueError, rctime.strftime, '', (1900, 13, 1, 0, 0, 0, 0, 1, -1))
-        # check day of month
-        raises(ValueError, rctime.strftime, '', (1900, 1, 32, 0, 0, 0, 0, 1, -1))
-        # check hour
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, -1, 0, 0, 0, 1, -1))
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 24, 0, 0, 0, 1, -1))
-        # check minute
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, -1, 0, 0, 1, -1))
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 60, 0, 0, 1, -1))
-        # check second
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, -1, 0, 1, -1))
-        # C99 only requires allowing for one leap second, but Python's docs say
-        # allow two leap seconds (0..61)
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 62, 0, 1, -1))
-        # no check for upper-bound day of week;
-        #  value forced into range by a "% 7" calculation.
-        # start check at -2 since gettmarg() increments value before taking
-        #  modulo.
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, -2, 1, -1))
-        # check day of the year
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 367, -1))
-        # check daylight savings flag
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, -2))
-        raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, 2))
-
-    def test_strptime(self):
-        import time as rctime
-
-        t = rctime.time()
-        tt = rctime.gmtime(t)
-        assert isinstance(rctime.strptime("", ""), type(tt))
-
-        for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
-                          'j', 'm', 'M', 'p', 'S',
-                          'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
-            format = ' %' + directive
-            print format
-            rctime.strptime(rctime.strftime(format, tt), format)
-
-    def test_pickle(self):
-        import pickle
-        import time as rctime
-        now = rctime.localtime()
-        new = pickle.loads(pickle.dumps(now))
-        assert new == now
-        assert type(new) is type(now)
diff --git a/pypy/module/select/test/test_epoll.py b/pypy/module/select/test/test_epoll.py
--- a/pypy/module/select/test/test_epoll.py
+++ b/pypy/module/select/test/test_epoll.py
@@ -7,7 +7,7 @@
 
 class AppTestEpoll(object):
     spaceconfig = {
-        "usemodules": ["select", "_socket", "posix", "rctime"],
+        "usemodules": ["select", "_socket", "posix", "time"],
     }
 
     def setup_class(cls):
diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py
--- a/pypy/module/select/test/test_kqueue.py
+++ b/pypy/module/select/test/test_kqueue.py
@@ -4,7 +4,7 @@
 import sys
 
 class AppTestKqueue(object):
-    spaceconfig = dict(usemodules=["select", "_socket", "posix", "rctime"])
+    spaceconfig = dict(usemodules=["select", "_socket", "posix", "time"])
 
     def setup_class(cls):
         if not 'bsd' in sys.platform and \
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -249,7 +249,7 @@
 class AppTestSelectWithPipes(_AppTestSelect):
     "Use a pipe to get pairs of file descriptors"
     spaceconfig = {
-        "usemodules": ["select", "rctime", "thread"]
+        "usemodules": ["select", "time", "thread"]
     }
 
     def setup_class(cls):
@@ -325,7 +325,7 @@
     so we start our own server.
     """
     spaceconfig = {
-        "usemodules": ["select", "_socket", "rctime", "thread"],
+        "usemodules": ["select", "_socket", "time", "thread"],
     }
 
     def w_make_server(self):
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -36,7 +36,7 @@
 
 class AppTestSignal:
     spaceconfig = {
-        "usemodules": ['signal', 'rctime'] + (['fcntl'] if os.name != 'nt' else []),
+        "usemodules": ['signal', 'time'] + (['fcntl'] if os.name != 'nt' else []),
     }
 
     def setup_class(cls):
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
@@ -619,7 +619,7 @@
 
 class AppTestCurrentFramesWithThread(AppTestCurrentFrames):
     spaceconfig = {
-        "usemodules": ["rctime", "thread"],
+        "usemodules": ["time", "thread"],
     }
 
     def test_current_frames(self):
diff --git a/pypy/module/thread/test/support.py b/pypy/module/thread/test/support.py
--- a/pypy/module/thread/test/support.py
+++ b/pypy/module/thread/test/support.py
@@ -41,7 +41,7 @@
 
 
 class GenericTestThread:
-    spaceconfig = dict(usemodules=('thread', 'rctime', 'signal'))
+    spaceconfig = dict(usemodules=('thread', 'time', 'signal'))
 
     def setup_class(cls):
         cls.w_runappdirect = cls.space.wrap(cls.runappdirect)
diff --git a/pypy/module/time/__init__.py b/pypy/module/time/__init__.py
--- a/pypy/module/time/__init__.py
+++ b/pypy/module/time/__init__.py
@@ -1,13 +1,42 @@
+
 from pypy.interpreter.mixedmodule import MixedModule
+import os
+
+_WIN = os.name == "nt"
 
 class Module(MixedModule):
-    """time module"""
+    applevel_name = 'time'
+
+    interpleveldefs = {
+        'time': 'interp_time.time',
+        'clock': 'interp_time.clock',
+        'ctime': 'interp_time.ctime',
+        'asctime': 'interp_time.asctime',
+        'gmtime': 'interp_time.gmtime',
+        'localtime': 'interp_time.localtime',
+        'mktime': 'interp_time.mktime',
+        'strftime': 'interp_time.strftime',
+        'sleep' : 'interp_time.sleep',
+    }
+
+    if os.name == "posix":
+        interpleveldefs['tzset'] = 'interp_time.tzset'
 
     appleveldefs = {
+        'struct_time': 'app_time.struct_time',
+        '__doc__': 'app_time.__doc__',
+        'strptime': 'app_time.strptime',
     }
 
-    interpleveldefs = {
-        'clock'    : 'interp_time.clock',
-        'time'     : 'interp_time.time_',
-        'sleep'    : 'interp_time.sleep',
-    }
+    def startup(self, space):
+        if _WIN:
+            from pypy.module.time.interp_time import State
+            space.fromcache(State).startup(space)
+
+        # this machinery is needed to expose constants
+        # that have to be initialized one time only
+        from pypy.module.time import interp_time
+
+        interp_time._init_timezone(space)
+        interp_time._init_accept2dyear(space)
+
diff --git a/pypy/module/rctime/app_time.py b/pypy/module/time/app_time.py
rename from pypy/module/rctime/app_time.py
rename to pypy/module/time/app_time.py
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -1,20 +1,670 @@
-import time
+from rpython.rtyper.tool import rffi_platform as platform
+from rpython.rtyper.lltypesystem import rffi
+from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import unwrap_spec
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rlib.rarithmetic import intmask
+from rpython.rlib import rposix
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+import os
+import sys
+import time as pytime
 
+_POSIX = os.name == "posix"
+_WIN = os.name == "nt"
+_CYGWIN = sys.platform == "cygwin"
+
+_time_zones = []
+if _CYGWIN:
+    _time_zones = ["GMT-12", "GMT-11", "GMT-10", "GMT-9", "GMT-8", "GMT-7",
+                   "GMT-6", "GMT-5", "GMT-4", "GMT-3", "GMT-2", "GMT-1",
+                   "GMT",  "GMT+1", "GMT+2", "GMT+3", "GMT+4", "GMT+5",
+                   "GMT+6",  "GMT+7", "GMT+8", "GMT+9", "GMT+10", "GMT+11",
+                   "GMT+12",  "GMT+13", "GMT+14"]
+
+if _WIN:
+    # Interruptible sleeps on Windows:
+    # We install a specific Console Ctrl Handler which sets an 'event'.
+    # time.sleep() will actually call WaitForSingleObject with the desired
+    # timeout.  On Ctrl-C, the signal handler is called, the event is set,
+    # and the wait function exits.
+    from rpython.rlib import rwin32
+    from pypy.interpreter.error import wrap_windowserror, wrap_oserror
+    from rpython.rlib import rthread as thread
+
+    eci = ExternalCompilationInfo(
+        includes = ['windows.h'],
+        post_include_bits = [
+            "RPY_EXTERN\n"
+            "BOOL pypy_timemodule_setCtrlHandler(HANDLE event);"],
+        separate_module_sources=['''
+            static HANDLE interrupt_event;
+
+            static BOOL WINAPI CtrlHandlerRoutine(
+              DWORD dwCtrlType)
+            {
+                SetEvent(interrupt_event);
+                /* allow other default handlers to be called.
+                 * Default Python handler will setup the
+                 * KeyboardInterrupt exception.
+                 */
+                return 0;
+            }
+
+            BOOL pypy_timemodule_setCtrlHandler(HANDLE event)
+            {
+                interrupt_event = event;
+                return SetConsoleCtrlHandler(CtrlHandlerRoutine, TRUE);
+            }
+
+        '''],
+        )
+    _setCtrlHandlerRoutine = rffi.llexternal(
+        'pypy_timemodule_setCtrlHandler',
+        [rwin32.HANDLE], rwin32.BOOL,
+        compilation_info=eci)
+
+    class GlobalState:
+        def __init__(self):
+            self.init()
+
+        def init(self):
+            self.interrupt_event = rwin32.NULL_HANDLE
+
+        def startup(self, space):
+            # Initialize the event handle used to signal Ctrl-C
+            try:
+                globalState.interrupt_event = rwin32.CreateEvent(
+                    rffi.NULL, True, False, rffi.NULL)
+            except WindowsError, e:
+                raise wrap_windowserror(space, e)
+            if not _setCtrlHandlerRoutine(globalState.interrupt_event):
+                raise wrap_windowserror(
+                    space, rwin32.lastWindowsError("SetConsoleCtrlHandler"))
+
+    globalState = GlobalState()
+
+    class State:
+        def __init__(self, space):
+            self.main_thread = 0
+
+        def _cleanup_(self):
+            self.main_thread = 0
+            globalState.init()
+
+        def startup(self, space):
+            self.main_thread = thread.get_ident()
+            globalState.startup(space)
+
+        def get_interrupt_event(self):
+            return globalState.interrupt_event
+
+
+_includes = ["time.h"]
+if _POSIX:
+    _includes.append('sys/time.h')
+
+class CConfig:
+    _compilation_info_ = ExternalCompilationInfo(
+        includes = _includes
+    )
+    CLOCKS_PER_SEC = platform.ConstantInteger("CLOCKS_PER_SEC")
+    clock_t = platform.SimpleType("clock_t", rffi.ULONG)
+    has_gettimeofday = platform.Has('gettimeofday')
+
+if _POSIX:
+    calling_conv = 'c'
+    CConfig.timeval = platform.Struct("struct timeval",
+                                      [("tv_sec", rffi.INT),
+                                       ("tv_usec", rffi.INT)])
+    if _CYGWIN:
+        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
+            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
+            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
+            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
+    else:
+        CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
+            ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
+            ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
+            ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT), ("tm_gmtoff", rffi.LONG),
+            ("tm_zone", rffi.CCHARP)])
+elif _WIN:
+    calling_conv = 'win'
+    CConfig.tm = platform.Struct("struct tm", [("tm_sec", rffi.INT),
+        ("tm_min", rffi.INT), ("tm_hour", rffi.INT), ("tm_mday", rffi.INT),
+        ("tm_mon", rffi.INT), ("tm_year", rffi.INT), ("tm_wday", rffi.INT),
+        ("tm_yday", rffi.INT), ("tm_isdst", rffi.INT)])
+
+class cConfig:
+    pass
+
+for k, v in platform.configure(CConfig).items():
+    setattr(cConfig, k, v)
+cConfig.tm.__name__ = "_tm"
+
+def external(name, args, result, eci=CConfig._compilation_info_):
+    if _WIN and rffi.sizeof(rffi.TIME_T) == 8:
+        # Recent Microsoft compilers use 64bit time_t and
+        # the corresponding functions are named differently
+        if (rffi.TIME_T in args or rffi.TIME_TP in args
+            or result in (rffi.TIME_T, rffi.TIME_TP)):
+            name = '_' + name + '64'
+    return rffi.llexternal(name, args, result,
+                           compilation_info=eci,
+                           calling_conv=calling_conv,
+                           releasegil=False)
+
+if _POSIX:
+    cConfig.timeval.__name__ = "_timeval"
+    timeval = cConfig.timeval
+
+CLOCKS_PER_SEC = cConfig.CLOCKS_PER_SEC
+clock_t = cConfig.clock_t
+tm = cConfig.tm
+glob_buf = lltype.malloc(tm, flavor='raw', zero=True, immortal=True)
+
+if cConfig.has_gettimeofday:
+    c_gettimeofday = external('gettimeofday', [rffi.VOIDP, rffi.VOIDP], rffi.INT)
+TM_P = lltype.Ptr(tm)
+c_clock = external('clock', [rffi.TIME_TP], clock_t)
+c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
+c_ctime = external('ctime', [rffi.TIME_TP], rffi.CCHARP)
+c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P)
+c_mktime = external('mktime', [TM_P], rffi.TIME_T)
+c_asctime = external('asctime', [TM_P], rffi.CCHARP)
+c_localtime = external('localtime', [rffi.TIME_TP], TM_P)
+if _POSIX:
+    c_tzset = external('tzset', [], lltype.Void)
+if _WIN:
+    win_eci = ExternalCompilationInfo(
+        includes = ["time.h"],
+        post_include_bits = ["RPY_EXTERN "
+                             "long pypy_get_timezone();\n"
+                             "RPY_EXTERN "
+                             "int pypy_get_daylight();\n"
+                             "RPY_EXTERN "
+                             "char** pypy_get_tzname();\n"
+                             "RPY_EXTERN "
+                             "void pypy__tzset();"],
+        separate_module_sources = ["""
+        long pypy_get_timezone() { return timezone; }
+        int pypy_get_daylight() { return daylight; }
+        char** pypy_get_tzname() { return tzname; }
+        void pypy__tzset() { _tzset(); }
+        """])
+    # Ensure sure that we use _tzset() and timezone from the same C Runtime.
+    c_tzset = external('pypy__tzset', [], lltype.Void, win_eci)
+    c_get_timezone = external('pypy_get_timezone', [], rffi.LONG, win_eci)
+    c_get_daylight = external('pypy_get_daylight', [], rffi.INT, win_eci)
+    c_get_tzname = external('pypy_get_tzname', [], rffi.CCHARPP, win_eci)
+
+c_strftime = external('strftime', [rffi.CCHARP, rffi.SIZE_T, rffi.CCHARP, TM_P],
+                      rffi.SIZE_T)
+
+def _init_accept2dyear(space):
+    if os.environ.get("PYTHONY2K"):
+        accept2dyear = 0
+    else:
+        accept2dyear = 1
+    _set_module_object(space, "accept2dyear", space.wrap(accept2dyear))
+
+def _init_timezone(space):
+    timezone = daylight = altzone = 0
+    tzname = ["", ""]
+
+    if _WIN:
+        c_tzset()
+        timezone = c_get_timezone()
+        altzone = timezone - 3600
+        daylight = c_get_daylight()
+        tzname_ptr = c_get_tzname()
+        tzname = rffi.charp2str(tzname_ptr[0]), rffi.charp2str(tzname_ptr[1])
+
+    if _POSIX:
+        if _CYGWIN:
+            YEAR = (365 * 24 + 6) * 3600
+
+            # about January 11th
+            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR + 10 * 24 * 3600)
+            # we cannot have reference to stack variable, put it on the heap
+            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
+            t_ref[0] = rffi.cast(rffi.TIME_T, t)
+            p = c_localtime(t_ref)
+            q = c_gmtime(t_ref)
+            janzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
+            if janzone < -12:
+                janname = "   "
+            elif janzone > 14:
+                janname = "   "
+            else:
+                janname = _time_zones[janzone - 12]
+            janzone = janzone * 3600
+            # about July 11th
+            tt = t + YEAR / 2
+            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
+            p = c_localtime(t_ref)
+            q = c_gmtime(t_ref)
+            julyzone = (p.c_tm_hour + 24 * p.c_tm_mday) - (q.c_tm_hour + 24 * q.c_tm_mday)
+            if julyzone < -12:
+                julyname = "   "
+            elif julyzone > 14:
+                julyname = "   "
+            else:
+                julyname = _time_zones[julyzone - 12]
+            julyzone = julyzone * 3600
+            lltype.free(t_ref, flavor='raw')
+
+            if janzone < julyzone:
+                # DST is reversed in the southern hemisphere
+                timezone = julyzone
+                altzone = janzone
+                daylight = int(janzone != julyzone)
+                tzname = [julyname, janname]
+            else:
+                timezone = janzone
+                altzone = julyzone
+                daylight = int(janzone != julyzone)
+                tzname = [janname, julyname]
+
+        else:
+            YEAR = (365 * 24 + 6) * 3600
+
+            t = (((c_time(lltype.nullptr(rffi.TIME_TP.TO))) / YEAR) * YEAR)
+            # we cannot have reference to stack variable, put it on the heap
+            t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
+            t_ref[0] = rffi.cast(rffi.TIME_T, t)
+            p = c_localtime(t_ref)
+            janzone = -p.c_tm_gmtoff
+            tm_zone = rffi.charp2str(p.c_tm_zone)
+            janname = ["   ", tm_zone][bool(tm_zone)]
+            tt = t + YEAR / 2
+            t_ref[0] = rffi.cast(rffi.TIME_T, tt)
+            p = c_localtime(t_ref)
+            lltype.free(t_ref, flavor='raw')
+            tm_zone = rffi.charp2str(p.c_tm_zone)
+            julyzone = -p.c_tm_gmtoff
+            julyname = ["   ", tm_zone][bool(tm_zone)]
+
+            if janzone < julyzone:
+                # DST is reversed in the southern hemisphere
+                timezone = julyzone
+                altzone = janzone
+                daylight = int(janzone != julyzone)
+                tzname = [julyname, janname]
+            else:
+                timezone = janzone
+                altzone = julyzone
+                daylight = int(janzone != julyzone)
+                tzname = [janname, julyname]
+
+    _set_module_object(space, "timezone", space.wrap(timezone))
+    _set_module_object(space, 'daylight', space.wrap(daylight))
+    tzname_w = [space.wrap(tzname[0]), space.wrap(tzname[1])]
+    _set_module_object(space, 'tzname', space.newtuple(tzname_w))
+    _set_module_object(space, 'altzone', space.wrap(altzone))
+
+def _get_error_msg():
+    errno = rposix.get_errno()
+    return os.strerror(errno)
+
+if sys.platform != 'win32':
+    @unwrap_spec(secs=float)
+    def sleep(space, secs):
+        if secs < 0:
+            raise OperationError(space.w_IOError,
+                                 space.wrap("Invalid argument: negative time in sleep"))
+        pytime.sleep(secs)
+else:
+    from rpython.rlib import rwin32
+    from errno import EINTR
+    def _simple_sleep(space, secs, interruptible):
+        if secs == 0.0 or not interruptible:
+            pytime.sleep(secs)
+        else:
+            millisecs = int(secs * 1000)
+            interrupt_event = space.fromcache(State).get_interrupt_event()
+            rwin32.ResetEvent(interrupt_event)
+            rc = rwin32.WaitForSingleObject(interrupt_event, millisecs)
+            if rc == rwin32.WAIT_OBJECT_0:
+                # Yield to make sure real Python signal handler
+                # called.
+                pytime.sleep(0.001)
+                raise wrap_oserror(space,
+                                   OSError(EINTR, "sleep() interrupted"))
+    @unwrap_spec(secs=float)
+    def sleep(space, secs):
+        if secs < 0:
+            raise OperationError(space.w_IOError,
+                                 space.wrap("Invalid argument: negative time in sleep"))
+        # as decreed by Guido, only the main thread can be
+        # interrupted.
+        main_thread = space.fromcache(State).main_thread
+        interruptible = (main_thread == thread.get_ident())
+        MAX = sys.maxint / 1000.0 # > 24 days
+        while secs > MAX:
+            _simple_sleep(space, MAX, interruptible)
+            secs -= MAX
+        _simple_sleep(space, secs, interruptible)
+
+def _get_module_object(space, obj_name):
+    w_module = space.getbuiltinmodule('time')
+    w_obj = space.getattr(w_module, space.wrap(obj_name))
+    return w_obj
+
+def _set_module_object(space, obj_name, w_obj_value):
+    w_module = space.getbuiltinmodule('time')
+    space.setattr(w_module, space.wrap(obj_name), w_obj_value)
+
+def _get_inttime(space, w_seconds):
+    # w_seconds can be a wrapped None (it will be automatically wrapped
+    # in the callers, so we never get a real None here).
+    if space.is_none(w_seconds):
+        seconds = pytime.time()
+    else:
+        seconds = space.float_w(w_seconds)
+    #
+    t = rffi.cast(rffi.TIME_T, seconds)
+    #
+    # Logic from CPython: How much info did we lose?  We assume that
+    # time_t is an integral type.  If we lost a second or more, the
+    # input doesn't fit in a time_t; call it an error.
+    diff = seconds - rffi.cast(lltype.Float, t)
+    if diff <= -1.0 or diff >= 1.0:
+        raise OperationError(space.w_ValueError,
+                      space.wrap("timestamp out of range for platform time_t"))
+    return t
+
+def _tm_to_tuple(space, t):
+    time_tuple = [
+        space.wrap(rffi.getintfield(t, 'c_tm_year') + 1900),
+        space.wrap(rffi.getintfield(t, 'c_tm_mon') + 1), # want january == 1
+        space.wrap(rffi.getintfield(t, 'c_tm_mday')),
+        space.wrap(rffi.getintfield(t, 'c_tm_hour')),
+        space.wrap(rffi.getintfield(t, 'c_tm_min')),
+        space.wrap(rffi.getintfield(t, 'c_tm_sec')),
+        space.wrap((rffi.getintfield(t, 'c_tm_wday') + 6) % 7), # want monday == 0
+        space.wrap(rffi.getintfield(t, 'c_tm_yday') + 1), # want january, 1 == 1
+        space.wrap(rffi.getintfield(t, 'c_tm_isdst'))]
+
+    w_struct_time = _get_module_object(space, 'struct_time')
+    w_time_tuple = space.newtuple(time_tuple)
+    return space.call_function(w_struct_time, w_time_tuple)
+
+def _gettmarg(space, w_tup, allowNone=True):
+    if space.is_none(w_tup):
+        if not allowNone:
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("tuple expected"))
+        # default to the current local time
+        tt = rffi.r_time_t(int(pytime.time()))
+        t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
+        t_ref[0] = tt
+        pbuf = c_localtime(t_ref)
+        lltype.free(t_ref, flavor='raw')
+        if not pbuf:
+            raise OperationError(space.w_ValueError,
+                space.wrap(_get_error_msg()))
+        return pbuf
+
+    tup_w = space.fixedview(w_tup)
+    if len(tup_w) != 9:
+        raise oefmt(space.w_TypeError,
+                    "argument must be sequence of length 9, not %d",
+                    len(tup_w))
+
+    y = space.int_w(tup_w[0])
+    tm_mon = space.int_w(tup_w[1])
+    if tm_mon == 0:
+        tm_mon = 1
+    tm_mday = space.int_w(tup_w[2])
+    if tm_mday == 0:
+        tm_mday = 1
+    tm_yday = space.int_w(tup_w[7])
+    if tm_yday == 0:
+        tm_yday = 1
+    rffi.setintfield(glob_buf, 'c_tm_mon', tm_mon)
+    rffi.setintfield(glob_buf, 'c_tm_mday', tm_mday)
+    rffi.setintfield(glob_buf, 'c_tm_hour', space.int_w(tup_w[3]))
+    rffi.setintfield(glob_buf, 'c_tm_min', space.int_w(tup_w[4]))
+    rffi.setintfield(glob_buf, 'c_tm_sec', space.int_w(tup_w[5]))
+    rffi.setintfield(glob_buf, 'c_tm_wday', space.int_w(tup_w[6]))
+    rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday)
+    rffi.setintfield(glob_buf, 'c_tm_isdst', space.int_w(tup_w[8]))
+    if _POSIX:
+        if _CYGWIN:
+            pass
+        else:
+            # actually never happens, but makes annotator happy
+            glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
+            rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
+
+    if y < 1900:
+        w_accept2dyear = _get_module_object(space, "accept2dyear")
+        accept2dyear = space.int_w(w_accept2dyear)
+
+        if not accept2dyear:
+            raise OperationError(space.w_ValueError,
+                space.wrap("year >= 1900 required"))
+
+        if 69 <= y <= 99:
+            y += 1900
+        elif 0 <= y <= 68:
+            y += 2000
+        else:
+            raise OperationError(space.w_ValueError,
+                space.wrap("year out of range"))
+
+    # tm_wday does not need checking of its upper-bound since taking "%
+    #  7" in gettmarg() automatically restricts the range.
+    if rffi.getintfield(glob_buf, 'c_tm_wday') < -1:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("day of week out of range"))
+
+    rffi.setintfield(glob_buf, 'c_tm_year', y - 1900)
+    rffi.setintfield(glob_buf, 'c_tm_mon',
+                     rffi.getintfield(glob_buf, 'c_tm_mon') - 1)
+    rffi.setintfield(glob_buf, 'c_tm_wday',
+                     (rffi.getintfield(glob_buf, 'c_tm_wday') + 1) % 7)
+    rffi.setintfield(glob_buf, 'c_tm_yday',
+                     rffi.getintfield(glob_buf, 'c_tm_yday') - 1)
+


More information about the pypy-commit mailing list