[pypy-svn] rev 2280 - in pypy/trunk/src/pypy: annotation appspace module module/test

rocco at codespeak.net rocco at codespeak.net
Sun Nov 30 18:53:13 CET 2003


Author: rocco
Date: Sun Nov 30 18:53:12 2003
New Revision: 2280

Added:
   pypy/trunk/src/pypy/appspace/copy_reg.py   (contents, props changed)
   pypy/trunk/src/pypy/appspace/os.py   (contents, props changed)
   pypy/trunk/src/pypy/module/_randommodule.py   (contents, props changed)
   pypy/trunk/src/pypy/module/_sremodule.py   (contents, props changed)
   pypy/trunk/src/pypy/module/cStringIOmodule.py   (contents, props changed)
   pypy/trunk/src/pypy/module/itertoolsmodule.py   (contents, props changed)
   pypy/trunk/src/pypy/module/mathmodule.py   (contents, props changed)
Modified:
   pypy/trunk/src/pypy/annotation/   (props changed)
   pypy/trunk/src/pypy/appspace/types.py
   pypy/trunk/src/pypy/module/__init__.py
   pypy/trunk/src/pypy/module/builtin.py
   pypy/trunk/src/pypy/module/sysmodule.py
   pypy/trunk/src/pypy/module/test/test_builtin.py
   pypy/trunk/src/pypy/module/test/test_sysmodule.py
Log:
Add functionality on the way towards getting CPython regression tests to run

M      module\sysmodule.py
M      module\test\test_sysmodule.py

Add missing items

M      module\builtin.py
M      module\test\test_builtin.py

Add missing item and fix execfile() so that tracebacks have proper filenames
 
M      module\__init__.py
A      module\itertoolsmodule.py
A      module\_sremodule.py
A      module\mathmodule.py
A      module\_randommodule.py
A      module\cStringIOmodule.py

Add some missing builtin modules - (Note that these probably should get
rewritten at some point when we get a functioning RPython implementation,
but for now ...

M      appspace\types.py

Add copyright notice, and some missing 2.3 items, while we're at it.

A      appspace\os.py

dir() doesn't work, so we work around it for now
Changed line 40:
       return [n for n in module.__dict__.keys() if n[0] != '_']

A      appspace\copy_reg.py

Remove irrelevant and harmful assertion
Changed lines 18&19:
##    if type(ob_type) is _ClassType:
##        raise TypeError("copy_reg is not intended for use with classes") 

 M     annotation

Ignore *.pyc files

Added: pypy/trunk/src/pypy/appspace/copy_reg.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/appspace/copy_reg.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,192 @@
+"""Helper to provide extensibility for pickle/cPickle.
+
+!! This file has been copied practicaly verbatim from the CPython source.
+!! See http://www.python.org/2.3.2/license.html for licensing info.
+
+This is only useful to add pickle support for extension types defined in
+C, not for instances of user-defined classes.
+"""
+
+from types import ClassType as _ClassType
+
+__all__ = ["pickle", "constructor",
+           "add_extension", "remove_extension", "clear_extension_cache"]
+
+dispatch_table = {}
+
+def pickle(ob_type, pickle_function, constructor_ob=None):
+##    if type(ob_type) is _ClassType:
+##        raise TypeError("copy_reg is not intended for use with classes")
+
+    if not callable(pickle_function):
+        raise TypeError("reduction functions must be callable")
+    dispatch_table[ob_type] = pickle_function
+
+    # The constructor_ob function is a vestige of safe for unpickling.
+    # There is no reason for the caller to pass it anymore.
+    if constructor_ob is not None:
+        constructor(constructor_ob)
+
+def constructor(object):
+    if not callable(object):
+        raise TypeError("constructors must be callable")
+
+# Example: provide pickling support for complex numbers.
+
+try:
+    complex
+except NameError:
+    pass
+else:
+
+    def pickle_complex(c):
+        return complex, (c.real, c.imag)
+
+    pickle(complex, pickle_complex, complex)
+
+# Support for pickling new-style objects
+
+def _reconstructor(cls, base, state):
+    if base is object:
+        obj = object.__new__(cls)
+    else:
+        obj = base.__new__(cls, state)
+        base.__init__(obj, state)
+    return obj
+
+_HEAPTYPE = 1<<9
+
+# Python code for object.__reduce_ex__ for protocols 0 and 1
+
+def _reduce_ex(self, proto):
+    assert proto < 2
+    for base in self.__class__.__mro__:
+        if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
+            break
+    else:
+        base = object # not really reachable
+    if base is object:
+        state = None
+    else:
+        if base is self.__class__:
+            raise TypeError, "can't pickle %s objects" % base.__name__
+        state = base(self)
+    args = (self.__class__, base, state)
+    try:
+        getstate = self.__getstate__
+    except AttributeError:
+        if getattr(self, "__slots__", None):
+            raise TypeError("a class that defines __slots__ without "
+                            "defining __getstate__ cannot be pickled")
+        try:
+            dict = self.__dict__
+        except AttributeError:
+            dict = None
+    else:
+        dict = getstate()
+    if dict:
+        return _reconstructor, args, dict
+    else:
+        return _reconstructor, args
+
+# Helper for __reduce_ex__ protocol 2
+
+def __newobj__(cls, *args):
+    return cls.__new__(cls, *args)
+
+def _slotnames(cls):
+    """Return a list of slot names for a given class.
+
+    This needs to find slots defined by the class and its bases, so we
+    can't simply return the __slots__ attribute.  We must walk down
+    the Method Resolution Order and concatenate the __slots__ of each
+    class found there.  (This assumes classes don't modify their
+    __slots__ attribute to misrepresent their slots after the class is
+    defined.)
+    """
+
+    # Get the value from a cache in the class if possible
+    names = cls.__dict__.get("__slotnames__")
+    if names is not None:
+        return names
+
+    # Not cached -- calculate the value
+    names = []
+    if not hasattr(cls, "__slots__"):
+        # This class has no slots
+        pass
+    else:
+        # Slots found -- gather slot names from all base classes
+        for c in cls.__mro__:
+            if "__slots__" in c.__dict__:
+                names += [name for name in c.__dict__["__slots__"]
+                               if name not in ("__dict__", "__weakref__")]
+
+    # Cache the outcome in the class if at all possible
+    try:
+        cls.__slotnames__ = names
+    except:
+        pass # But don't die if we can't
+
+    return names
+
+# A registry of extension codes.  This is an ad-hoc compression
+# mechanism.  Whenever a global reference to <module>, <name> is about
+# to be pickled, the (<module>, <name>) tuple is looked up here to see
+# if it is a registered extension code for it.  Extension codes are
+# universal, so that the meaning of a pickle does not depend on
+# context.  (There are also some codes reserved for local use that
+# don't have this restriction.)  Codes are positive ints; 0 is
+# reserved.
+
+_extension_registry = {}                # key -> code
+_inverted_registry = {}                 # code -> key
+_extension_cache = {}                   # code -> object
+# Don't ever rebind those names:  cPickle grabs a reference to them when
+# it's initialized, and won't see a rebinding.
+
+def add_extension(module, name, code):
+    """Register an extension code."""
+    code = int(code)
+    if not 1 <= code <= 0x7fffffff:
+        raise ValueError, "code out of range"
+    key = (module, name)
+    if (_extension_registry.get(key) == code and
+        _inverted_registry.get(code) == key):
+        return # Redundant registrations are benign
+    if key in _extension_registry:
+        raise ValueError("key %s is already registered with code %s" %
+                         (key, _extension_registry[key]))
+    if code in _inverted_registry:
+        raise ValueError("code %s is already in use for key %s" %
+                         (code, _inverted_registry[code]))
+    _extension_registry[key] = code
+    _inverted_registry[code] = key
+
+def remove_extension(module, name, code):
+    """Unregister an extension code.  For testing only."""
+    key = (module, name)
+    if (_extension_registry.get(key) != code or
+        _inverted_registry.get(code) != key):
+        raise ValueError("key %s is not registered with code %s" %
+                         (key, code))
+    del _extension_registry[key]
+    del _inverted_registry[code]
+    if code in _extension_cache:
+        del _extension_cache[code]
+
+def clear_extension_cache():
+    _extension_cache.clear()
+
+# Standard extension code assignments
+
+# Reserved ranges
+
+# First  Last Count  Purpose
+#     1   127   127  Reserved for Python standard library
+#   128   191    64  Reserved for Zope
+#   192   239    48  Reserved for 3rd parties
+#   240   255    16  Reserved for private use (will never be assigned)
+#   256   Inf   Inf  Reserved for future assignment
+
+# Extension codes are assigned by the Python Software Foundation.

Added: pypy/trunk/src/pypy/appspace/os.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/appspace/os.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,659 @@
+r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
+
+!! This file has been copied practicaly verbatim from the CPython source.
+!! See http://www.python.org/2.3.2/license.html for licensing info.
+
+This exports:
+  - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc.
+  - os.path is one of the modules posixpath, ntpath, or macpath
+  - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos'
+  - os.curdir is a string representing the current directory ('.' or ':')
+  - os.pardir is a string representing the parent directory ('..' or '::')
+  - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
+  - os.extsep is the extension separator ('.' or '/')
+  - os.altsep is the alternate pathname separator (None or '/')
+  - os.pathsep is the component separator used in $PATH etc
+  - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
+  - os.defpath is the default search path for executables
+
+Programs that import and use 'os' stand a better chance of being
+portable between different platforms.  Of course, they must then
+only use functions that are defined by all platforms (e.g., unlink
+and opendir), and leave all pathname manipulation to os.path
+(e.g., split and join).
+"""
+
+#'
+
+import sys
+
+_names = sys.builtin_module_names
+
+# Note:  more names are added to __all__ later.
+__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
+           "defpath", "name", "path"]
+
+def _get_exports_list(module):
+    try:
+        return list(module.__all__)
+    except AttributeError:
+        return [n for n in module.__dict__.keys() if n[0] != '_']
+
+if 'posix' in _names:
+    name = 'posix'
+    linesep = '\n'
+    from posix import *
+    try:
+        from posix import _exit
+    except ImportError:
+        pass
+    import posixpath as path
+
+    import posix
+    __all__.extend(_get_exports_list(posix))
+    del posix
+
+elif 'nt' in _names:
+    name = 'nt'
+    linesep = '\r\n'
+    from nt import *
+    try:
+        from nt import _exit
+    except ImportError:
+        pass
+    import ntpath as path
+
+    import nt
+    __all__.extend(_get_exports_list(nt))
+    del nt
+
+elif 'os2' in _names:
+    name = 'os2'
+    linesep = '\r\n'
+    from os2 import *
+    try:
+        from os2 import _exit
+    except ImportError:
+        pass
+    if sys.version.find('EMX GCC') == -1:
+        import ntpath as path
+    else:
+        import os2emxpath as path
+
+    import os2
+    __all__.extend(_get_exports_list(os2))
+    del os2
+
+elif 'mac' in _names:
+    name = 'mac'
+    linesep = '\r'
+    from mac import *
+    try:
+        from mac import _exit
+    except ImportError:
+        pass
+    import macpath as path
+
+    import mac
+    __all__.extend(_get_exports_list(mac))
+    del mac
+
+elif 'ce' in _names:
+    name = 'ce'
+    linesep = '\r\n'
+    from ce import *
+    try:
+        from ce import _exit
+    except ImportError:
+        pass
+    # We can use the standard Windows path.
+    import ntpath as path
+
+    import ce
+    __all__.extend(_get_exports_list(ce))
+    del ce
+
+elif 'riscos' in _names:
+    name = 'riscos'
+    linesep = '\n'
+    from riscos import *
+    try:
+        from riscos import _exit
+    except ImportError:
+        pass
+    import riscospath as path
+
+    import riscos
+    __all__.extend(_get_exports_list(riscos))
+    del riscos
+
+else:
+    raise ImportError, 'no os specific module found'
+
+sys.modules['os.path'] = path
+from os.path import curdir, pardir, sep, pathsep, defpath, extsep, altsep
+
+del _names
+
+#'
+
+# Super directory utilities.
+# (Inspired by Eric Raymond; the doc strings are mostly his)
+
+def makedirs(name, mode=0777):
+    """makedirs(path [, mode=0777])
+
+    Super-mkdir; create a leaf directory and all intermediate ones.
+    Works like mkdir, except that any intermediate path segment (not
+    just the rightmost) will be created if it does not exist.  This is
+    recursive.
+
+    """
+    head, tail = path.split(name)
+    if not tail:
+        head, tail = path.split(head)
+    if head and tail and not path.exists(head):
+        makedirs(head, mode)
+    mkdir(name, mode)
+
+def removedirs(name):
+    """removedirs(path)
+
+    Super-rmdir; remove a leaf directory and empty all intermediate
+    ones.  Works like rmdir except that, if the leaf directory is
+    successfully removed, directories corresponding to rightmost path
+    segments will be pruned away until either the whole path is
+    consumed or an error occurs.  Errors during this latter phase are
+    ignored -- they generally mean that a directory was not empty.
+
+    """
+    rmdir(name)
+    head, tail = path.split(name)
+    if not tail:
+        head, tail = path.split(head)
+    while head and tail:
+        try:
+            rmdir(head)
+        except error:
+            break
+        head, tail = path.split(head)
+
+def renames(old, new):
+    """renames(old, new)
+
+    Super-rename; create directories as necessary and delete any left
+    empty.  Works like rename, except creation of any intermediate
+    directories needed to make the new pathname good is attempted
+    first.  After the rename, directories corresponding to rightmost
+    path segments of the old name will be pruned way until either the
+    whole path is consumed or a nonempty directory is found.
+
+    Note: this function can fail with the new directory structure made
+    if you lack permissions needed to unlink the leaf directory or
+    file.
+
+    """
+    head, tail = path.split(new)
+    if head and tail and not path.exists(head):
+        makedirs(head)
+    rename(old, new)
+    head, tail = path.split(old)
+    if head and tail:
+        try:
+            removedirs(head)
+        except error:
+            pass
+
+__all__.extend(["makedirs", "removedirs", "renames"])
+
+def walk(top, topdown=True, onerror=None):
+    """Directory tree generator.
+
+    For each directory in the directory tree rooted at top (including top
+    itself, but excluding '.' and '..'), yields a 3-tuple
+
+        dirpath, dirnames, filenames
+
+    dirpath is a string, the path to the directory.  dirnames is a list of
+    the names of the subdirectories in dirpath (excluding '.' and '..').
+    filenames is a list of the names of the non-directory files in dirpath.
+    Note that the names in the lists are just names, with no path components.
+    To get a full path (which begins with top) to a file or directory in
+    dirpath, do os.path.join(dirpath, name).
+
+    If optional arg 'topdown' is true or not specified, the triple for a
+    directory is generated before the triples for any of its subdirectories
+    (directories are generated top down).  If topdown is false, the triple
+    for a directory is generated after the triples for all of its
+    subdirectories (directories are generated bottom up).
+
+    When topdown is true, the caller can modify the dirnames list in-place
+    (e.g., via del or slice assignment), and walk will only recurse into the
+    subdirectories whose names remain in dirnames; this can be used to prune
+    the search, or to impose a specific order of visiting.  Modifying
+    dirnames when topdown is false is ineffective, since the directories in
+    dirnames have already been generated by the time dirnames itself is
+    generated.
+
+    By default errors from the os.listdir() call are ignored.  If
+    optional arg 'onerror' is specified, it should be a function; it
+    will be called with one argument, an os.error instance.  It can
+    report the error to continue with the walk, or raise the exception
+    to abort the walk.  Note that the filename is available as the
+    filename attribute of the exception object.
+
+    Caution:  if you pass a relative pathname for top, don't change the
+    current working directory between resumptions of walk.  walk never
+    changes the current directory, and assumes that the client doesn't
+    either.
+
+    Example:
+
+    from os.path import join, getsize
+    for root, dirs, files in walk('python/Lib/email'):
+        print root, "consumes",
+        print sum([getsize(join(root, name)) for name in files]),
+        print "bytes in", len(files), "non-directory files"
+        if 'CVS' in dirs:
+            dirs.remove('CVS')  # don't visit CVS directories
+    """
+
+    from os.path import join, isdir, islink
+
+    # We may not have read permission for top, in which case we can't
+    # get a list of the files the directory contains.  os.path.walk
+    # always suppressed the exception then, rather than blow up for a
+    # minor reason when (say) a thousand readable directories are still
+    # left to visit.  That logic is copied here.
+    try:
+        # Note that listdir and error are globals in this module due
+        # to earlier import-*.
+        names = listdir(top)
+    except error, err:
+        if onerror is not None:
+            onerror(err)
+        return
+
+    dirs, nondirs = [], []
+    for name in names:
+        if isdir(join(top, name)):
+            dirs.append(name)
+        else:
+            nondirs.append(name)
+
+    if topdown:
+        yield top, dirs, nondirs
+    for name in dirs:
+        path = join(top, name)
+        if not islink(path):
+            for x in walk(path, topdown, onerror):
+                yield x
+    if not topdown:
+        yield top, dirs, nondirs
+
+__all__.append("walk")
+
+# Make sure os.environ exists, at least
+try:
+    environ
+except NameError:
+    environ = {}
+
+def execl(file, *args):
+    """execl(file, *args)
+
+    Execute the executable file with argument list args, replacing the
+    current process. """
+    execv(file, args)
+
+def execle(file, *args):
+    """execle(file, *args, env)
+
+    Execute the executable file with argument list args and
+    environment env, replacing the current process. """
+    env = args[-1]
+    execve(file, args[:-1], env)
+
+def execlp(file, *args):
+    """execlp(file, *args)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args, replacing the current process. """
+    execvp(file, args)
+
+def execlpe(file, *args):
+    """execlpe(file, *args, env)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args and environment env, replacing the current
+    process. """
+    env = args[-1]
+    execvpe(file, args[:-1], env)
+
+def execvp(file, args):
+    """execp(file, args)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args, replacing the current process.
+    args may be a list or tuple of strings. """
+    _execvpe(file, args)
+
+def execvpe(file, args, env):
+    """execvpe(file, args, env)
+
+    Execute the executable file (which is searched for along $PATH)
+    with argument list args and environment env , replacing the
+    current process.
+    args may be a list or tuple of strings. """
+    _execvpe(file, args, env)
+
+__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
+
+def _execvpe(file, args, env=None):
+    from errno import ENOENT, ENOTDIR
+
+    if env is not None:
+        func = execve
+        argrest = (args, env)
+    else:
+        func = execv
+        argrest = (args,)
+        env = environ
+
+    head, tail = path.split(file)
+    if head:
+        func(file, *argrest)
+        return
+    if 'PATH' in env:
+        envpath = env['PATH']
+    else:
+        envpath = defpath
+    PATH = envpath.split(pathsep)
+    saved_exc = None
+    saved_tb = None
+    for dir in PATH:
+        fullname = path.join(dir, file)
+        try:
+            func(fullname, *argrest)
+        except error, e:
+            tb = sys.exc_info()[2]
+            if (e.errno != ENOENT and e.errno != ENOTDIR
+                and saved_exc is None):
+                saved_exc = e
+                saved_tb = tb
+    if saved_exc:
+        raise error, saved_exc, saved_tb
+    raise error, e, tb
+
+# Change environ to automatically call putenv() if it exists
+try:
+    # This will fail if there's no putenv
+    putenv
+except NameError:
+    pass
+else:
+    import UserDict
+
+    # Fake unsetenv() for Windows
+    # not sure about os2 here but
+    # I'm guessing they are the same.
+
+    if name in ('os2', 'nt'):
+        def unsetenv(key):
+            putenv(key, "")
+
+    if name == "riscos":
+        # On RISC OS, all env access goes through getenv and putenv
+        from riscosenviron import _Environ
+    elif name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE
+        # But we store them as upper case
+        class _Environ(UserDict.IterableUserDict):
+            def __init__(self, environ):
+                UserDict.UserDict.__init__(self)
+                data = self.data
+                for k, v in environ.items():
+                    data[k.upper()] = v
+            def __setitem__(self, key, item):
+                putenv(key, item)
+                self.data[key.upper()] = item
+            def __getitem__(self, key):
+                return self.data[key.upper()]
+            try:
+                unsetenv
+            except NameError:
+                def __delitem__(self, key):
+                    del self.data[key.upper()]
+            else:
+                def __delitem__(self, key):
+                    unsetenv(key)
+                    del self.data[key.upper()]
+            def has_key(self, key):
+                return key.upper() in self.data
+            def __contains__(self, key):
+                return key.upper() in self.data
+            def get(self, key, failobj=None):
+                return self.data.get(key.upper(), failobj)
+            def update(self, dict):
+                for k, v in dict.items():
+                    self[k] = v
+            def copy(self):
+                return dict(self)
+
+    else:  # Where Env Var Names Can Be Mixed Case
+        class _Environ(UserDict.IterableUserDict):
+            def __init__(self, environ):
+                UserDict.UserDict.__init__(self)
+                self.data = environ
+            def __setitem__(self, key, item):
+                putenv(key, item)
+                self.data[key] = item
+            def update(self, dict):
+                for k, v in dict.items():
+                    self[k] = v
+            try:
+                unsetenv
+            except NameError:
+                pass
+            else:
+                def __delitem__(self, key):
+                    unsetenv(key)
+                    del self.data[key]
+            def copy(self):
+                return dict(self)
+
+
+    environ = _Environ(environ)
+
+def getenv(key, default=None):
+    """Get an environment variable, return None if it doesn't exist.
+    The optional second argument can specify an alternate default."""
+    return environ.get(key, default)
+__all__.append("getenv")
+
+def _exists(name):
+    try:
+        eval(name)
+        return True
+    except NameError:
+        return False
+
+# Supply spawn*() (probably only for Unix)
+if _exists("fork") and not _exists("spawnv") and _exists("execv"):
+
+    P_WAIT = 0
+    P_NOWAIT = P_NOWAITO = 1
+
+    # XXX Should we support P_DETACH?  I suppose it could fork()**2
+    # and close the std I/O streams.  Also, P_OVERLAY is the same
+    # as execv*()?
+
+    def _spawnvef(mode, file, args, env, func):
+        # Internal helper; func is the exec*() function to use
+        pid = fork()
+        if not pid:
+            # Child
+            try:
+                if env is None:
+                    func(file, args)
+                else:
+                    func(file, args, env)
+            except:
+                _exit(127)
+        else:
+            # Parent
+            if mode == P_NOWAIT:
+                return pid # Caller is responsible for waiting!
+            while 1:
+                wpid, sts = waitpid(pid, 0)
+                if WIFSTOPPED(sts):
+                    continue
+                elif WIFSIGNALED(sts):
+                    return -WTERMSIG(sts)
+                elif WIFEXITED(sts):
+                    return WEXITSTATUS(sts)
+                else:
+                    raise error, "Not stopped, signaled or exited???"
+
+    def spawnv(mode, file, args):
+        """spawnv(mode, file, args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, None, execv)
+
+    def spawnve(mode, file, args, env):
+        """spawnve(mode, file, args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+specified environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, env, execve)
+
+    # Note: spawnvp[e] is't currently supported on Windows
+
+    def spawnvp(mode, file, args):
+        """spawnvp(mode, file, args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, None, execvp)
+
+    def spawnvpe(mode, file, args, env):
+        """spawnvpe(mode, file, args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return _spawnvef(mode, file, args, env, execvpe)
+
+if _exists("spawnv"):
+    # These aren't supplied by the basic Windows code
+    # but can be easily implemented in Python
+
+    def spawnl(mode, file, *args):
+        """spawnl(mode, file, *args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return spawnv(mode, file, args)
+
+    def spawnle(mode, file, *args):
+        """spawnle(mode, file, *args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        env = args[-1]
+        return spawnve(mode, file, args[:-1], env)
+
+if _exists("spawnvp"):
+    # At the moment, Windows doesn't implement spawnvp[e],
+    # so it won't have spawnlp[e] either.
+    def spawnlp(mode, file, *args):
+        """spawnlp(mode, file, *args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        return spawnvp(mode, file, args)
+
+    def spawnlpe(mode, file, *args):
+        """spawnlpe(mode, file, *args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+        env = args[-1]
+        return spawnvpe(mode, file, args[:-1], env)
+
+
+    __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp",
+                    "spawnvpe","spawnl","spawnle",])
+
+
+# Supply popen2 etc. (for Unix)
+if _exists("fork"):
+    if not _exists("popen2"):
+        def popen2(cmd, mode="t", bufsize=-1):
+            import popen2
+            stdout, stdin = popen2.popen2(cmd, bufsize)
+            return stdin, stdout
+        __all__.append("popen2")
+
+    if not _exists("popen3"):
+        def popen3(cmd, mode="t", bufsize=-1):
+            import popen2
+            stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
+            return stdin, stdout, stderr
+        __all__.append("popen3")
+
+    if not _exists("popen4"):
+        def popen4(cmd, mode="t", bufsize=-1):
+            import popen2
+            stdout, stdin = popen2.popen4(cmd, bufsize)
+            return stdin, stdout
+        __all__.append("popen4")
+
+import copy_reg as _copy_reg
+
+def _make_stat_result(tup, dict):
+    return stat_result(tup, dict)
+
+def _pickle_stat_result(sr):
+    (type, args) = sr.__reduce__()
+    return (_make_stat_result, args)
+
+try:
+    _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
+except NameError: # stat_result may not exist
+    pass
+
+def _make_statvfs_result(tup, dict):
+    return statvfs_result(tup, dict)
+
+def _pickle_statvfs_result(sr):
+    (type, args) = sr.__reduce__()
+    return (_make_statvfs_result, args)
+
+try:
+    _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
+                     _make_statvfs_result)
+except NameError: # statvfs_result may not exist
+    pass

Modified: pypy/trunk/src/pypy/appspace/types.py
==============================================================================
--- pypy/trunk/src/pypy/appspace/types.py	(original)
+++ pypy/trunk/src/pypy/appspace/types.py	Sun Nov 30 18:53:12 2003
@@ -1,5 +1,8 @@
 """Appspace types module. 
 
+!! This file has been copied practicaly verbatim from the CPython source.
+!! See http://www.python.org/2.3.2/license.html for licensing info.
+
 Define names for all type symbols known in the standard interpreter.
 
 Types that are part of optional modules (e.g. array) are not listed.
@@ -24,6 +27,10 @@
     pass
 FloatType = float
 try:
+    BooleanType = bool
+except NameError:
+    pass
+try:
     ComplexType = complex
 except NameError:
     pass
@@ -79,6 +86,9 @@
 ModuleType = type(sys)
 try:
     FileType = file
+except NameError:
+   pass
+try:
     XRangeType = type(xrange(0))
 except NameError:
    pass
@@ -100,5 +110,9 @@
 EllipsisType = type(Ellipsis)
 
 #DictProxyType = type(TypeType.__dict__)
+try:
+    NotImplementedType = type(NotImplemented)
+except NameError:
+   pass
 
 del sys, _f, _C, _x#, generators                  # Not for export

Modified: pypy/trunk/src/pypy/module/__init__.py
==============================================================================
--- pypy/trunk/src/pypy/module/__init__.py	(original)
+++ pypy/trunk/src/pypy/module/__init__.py	Sun Nov 30 18:53:12 2003
@@ -28,4 +28,9 @@
                     ('os_modules','Mac',_std_spaces),
                     ('os_modules','Ce',_std_spaces),
                     ('os_modules','Riscos',_std_spaces),
+                    ('mathmodule','Math',_std_spaces),
+                    ('_randommodule','RandomHelper',_std_spaces),
+                    ('cStringIOmodule','CStringIO',_std_spaces),
+                    ('itertoolsmodule','Itertools',_std_spaces),
+                    ('_sremodule','SreHelper',_std_spaces),
                     ]

Added: pypy/trunk/src/pypy/module/_randommodule.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/module/_randommodule.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,20 @@
+"""Bootstrap the builtin _random module.
+
+"""
+import sys
+
+from pypy.interpreter.extmodule import ExtModule
+
+_names = sys.builtin_module_names
+
+# We use the second (metaclassish) meaning of type to construct a subclass
+#   of ExtModule - can't modify some attributes (like __doc__) after class
+#   creation, and wrapping code does not properly look at instance variables.
+
+def RandomHelper(space):
+    if '_random' in _names:
+        import _random
+        _randomhelper = type('_random', (ExtModule,), _random.__dict__)
+        return _randomhelper(space)
+    else:
+        return None

Added: pypy/trunk/src/pypy/module/_sremodule.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/module/_sremodule.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,17 @@
+"""Bootstrap the builtin _sre module.
+
+"""
+import sys
+
+from pypy.interpreter.extmodule import ExtModule
+
+_names = sys.builtin_module_names
+
+# We use the second (metaclassish) meaning of type to construct a subclass
+#   of ExtModule - can't modify some attributes (like __doc__) after class
+#   creation, and wrapping code does not properly look at instance variables.
+
+def SreHelper(space):
+    import _sre
+    _srehelper = type('_sre', (ExtModule,), _sre.__dict__)
+    return _srehelper(space)

Modified: pypy/trunk/src/pypy/module/builtin.py
==============================================================================
--- pypy/trunk/src/pypy/module/builtin.py	(original)
+++ pypy/trunk/src/pypy/module/builtin.py	Sun Nov 30 18:53:12 2003
@@ -94,9 +94,13 @@
         elif loc is None:
             loc = glob
         f = file(filename)
-        source = f.read()
-        f.close()
-        exec source in glob, loc
+        try:
+            source = f.read()
+        finally:
+            f.close()
+        #Don't exec the source directly, as this loses the filename info
+        co = compile(source, filename, 'exec')
+        exec co in glob, loc
 
     ####essentially implemented by the objectspace
     def abs(self, w_val):
@@ -383,6 +387,9 @@
         except AttributeError:
             return False
 
+    def app_callable(self, ob):
+        return hasattr(ob, '__call__')
+
     def app_dir(self, *args):
         """dir([object]) -> list of strings
         

Added: pypy/trunk/src/pypy/module/cStringIOmodule.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/module/cStringIOmodule.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,20 @@
+"""Bootstrap the builtin cStringIO module.
+
+"""
+import sys
+
+from pypy.interpreter.extmodule import ExtModule
+
+_names = sys.builtin_module_names
+
+# We use the second (metaclassish) meaning of type to construct a subclass
+#   of ExtModule - can't modify some attributes (like __doc__) after class
+#   creation, and wrapping code does not properly look at instance variables.
+
+def CStringIO(space):
+    if 'cStringIO' in _names:
+        import cStringIO
+        _cStringIO = type('cStringIO', (ExtModule,), cStringIO.__dict__)
+        return _cStringIO(space)
+    else:
+        return None

Added: pypy/trunk/src/pypy/module/itertoolsmodule.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/module/itertoolsmodule.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,20 @@
+"""Bootstrap the builtin itertools module.
+
+"""
+import sys
+
+from pypy.interpreter.extmodule import ExtModule
+
+_names = sys.builtin_module_names
+
+# We use the second (metaclassish) meaning of type to construct a subclass
+#   of ExtModule - can't modify some attributes (like __doc__) after class
+#   creation, and wrapping code does not properly look at instance variables.
+
+def Itertools(space):
+    if 'itertools' in _names:
+        import itertools
+        _itertools = type('itertools', (ExtModule,), itertools.__dict__)
+        return _itertools(space)
+    else:
+        return None

Added: pypy/trunk/src/pypy/module/mathmodule.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/module/mathmodule.py	Sun Nov 30 18:53:12 2003
@@ -0,0 +1,20 @@
+"""Bootstrap the builtin math module.
+
+"""
+import sys
+
+from pypy.interpreter.extmodule import ExtModule
+
+_names = sys.builtin_module_names
+
+# We use the second (metaclassish) meaning of type to construct a subclass
+#   of ExtModule - can't modify some attributes (like __doc__) after class
+#   creation, and wrapping code does not properly look at instance variables.
+
+def Math(space):
+    if 'math' in _names:
+        import math
+        _math = type('math', (ExtModule,), math.__dict__)
+        return _math(space)
+    else:
+        return None

Modified: pypy/trunk/src/pypy/module/sysmodule.py
==============================================================================
--- pypy/trunk/src/pypy/module/sysmodule.py	(original)
+++ pypy/trunk/src/pypy/module/sysmodule.py	Sun Nov 30 18:53:12 2003
@@ -20,6 +20,10 @@
         self.w_path = space.newlist([appdir] + [p for p in cpy_sys.path if p!= pypydir])
         self.w_modules = space.newdict([])
         self.w_builtin_module_names = space.newlist([])
+        self.w_warnoptions = space.newlist([space.wrap(i) for i in cpy_sys.warnoptions])
+        # XXX - Replace with appropriate PyPy version numbering
+        self.w_hexversion = space.wrap(cpy_sys.hexversion)
+        self.w_platform = space.wrap(cpy_sys.platform)
         ExtModule.__init__(self, space)
 
     stdout = cpy_sys.stdout

Modified: pypy/trunk/src/pypy/module/test/test_builtin.py
==============================================================================
--- pypy/trunk/src/pypy/module/test/test_builtin.py	(original)
+++ pypy/trunk/src/pypy/module/test/test_builtin.py	Sun Nov 30 18:53:12 2003
@@ -95,6 +95,19 @@
         self.assert_(hasattr(self.space.builtin, 'xrange'))
         self.assertEquals(self.space.builtin.xrange(3).stop, 3)
 
+    def test_callable(self):
+        class Call:
+            def __call__(self, a):
+                return a+2
+        self.failIf(not callable(Call()),
+                    "Builtin function 'callable' misreads callable object")
+    def test_uncallable(self):
+        class NoCall:
+            pass
+        self.failIf(callable(NoCall()),
+                    "Builtin function 'callable' misreads uncallable object")
+        
+
 
 if __name__ == '__main__':
     test.main()

Modified: pypy/trunk/src/pypy/module/test/test_sysmodule.py
==============================================================================
--- pypy/trunk/src/pypy/module/test/test_sysmodule.py	(original)
+++ pypy/trunk/src/pypy/module/test/test_sysmodule.py	Sun Nov 30 18:53:12 2003
@@ -29,6 +29,18 @@
         import sys
         self.failUnless(hasattr(sys, 'builtin_module_names'),
                         "sys.builtin_module_names gone missing")        
+    def test_warnoptions_exists(self):
+        import sys
+        self.failUnless(hasattr(sys, 'warnoptions'),
+                        "sys.warnoptions gone missing")
+    def test_hexversion_exists(self):
+        import sys
+        self.failUnless(hasattr(sys, 'hexversion'),
+                        "sys.hexversion gone missing")
+    def test_platform_exists(self):
+        import sys
+        self.failUnless(hasattr(sys, 'platform'), "sys.platform gone missing")
+
     def test_sys_in_modules(self):
         import sys
         modules = sys.modules


More information about the Pypy-commit mailing list