[pypy-commit] pypy list-strategies: merge
cfbolz
noreply at buildbot.pypy.org
Fri Sep 23 13:13:11 CEST 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: list-strategies
Changeset: r47497:aac2064d18e3
Date: 2011-04-12 15:07 +0200
http://bitbucket.org/pypy/pypy/changeset/aac2064d18e3/
Log: merge
diff too long, truncating to 10000 out of 21908 lines
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,8 @@
pypy/doc/*.html
pypy/doc/config/*.html
pypy/doc/discussion/*.html
+pypy/module/cpyext/src/*.o
+pypy/module/cpyext/test/*.o
pypy/module/test_lib_pypy/ctypes_tests/*.o
pypy/translator/c/src/dtoa.o
pypy/translator/goal/pypy-c
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -17,7 +17,6 @@
^pypy/doc/.+\.html$
^pypy/doc/basicblock\.asc$
^pypy/doc/.+\.svninfo$
-^pypy/translator/c/src/dtoa.o$
^pypy/translator/c/src/libffi_msvc/.+\.obj$
^pypy/translator/c/src/libffi_msvc/.+\.dll$
^pypy/translator/c/src/libffi_msvc/.+\.lib$
@@ -52,6 +51,7 @@
^pypy/doc/discussion/.+\.html$
^include/.+\.h$
^include/.+\.inl$
+^pypy/doc/_build/.*$
^pypy/doc/config/.+\.html$
^pypy/doc/config/style\.css$
^pypy/doc/jit/.+\.html$
@@ -63,4 +63,4 @@
^pypy/doc/image/parsing_example.+\.png$
^compiled
^.git/
-^release/
\ No newline at end of file
+^release/
diff --git a/.hgsub b/.hgsub
deleted file mode 100644
--- a/.hgsub
+++ /dev/null
@@ -1,3 +0,0 @@
-greenlet = [svn]http://codespeak.net/svn/greenlet/trunk/c
-testrunner = [svn]http://codespeak.net/svn/pypy/build/testrunner
-lib_pypy/pyrepl = [svn]http://codespeak.net/svn/pyrepl/trunk/pyrepl/pyrepl
diff --git a/.hgsubstate b/.hgsubstate
deleted file mode 100644
--- a/.hgsubstate
+++ /dev/null
@@ -1,3 +0,0 @@
-80037 greenlet
-80348 lib_pypy/pyrepl
-80409 testrunner
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -108,6 +108,7 @@
Anders Qvist
Alan McIntyre
Bert Freudenberg
+ Tav
Heinrich-Heine University, Germany
Open End AB (formerly AB Strakt), Sweden
diff --git a/_pytest/__init__.py b/_pytest/__init__.py
--- a/_pytest/__init__.py
+++ b/_pytest/__init__.py
@@ -1,1 +1,2 @@
#
+__version__ = '2.0.3.dev3'
diff --git a/_pytest/config.py b/_pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -252,6 +252,16 @@
self.hook = self.pluginmanager.hook
self._inicache = {}
+ @classmethod
+ def fromdictargs(cls, option_dict, args):
+ """ constructor useable for subprocesses. """
+ config = cls()
+ config._preparse(args, addopts=False)
+ config.option.__dict__.update(option_dict)
+ for x in config.option.plugins:
+ config.pluginmanager.consider_pluginarg(x)
+ return config
+
def _onimportconftest(self, conftestmodule):
self.trace("loaded conftestmodule %r" %(conftestmodule,))
self.pluginmanager.consider_conftest(conftestmodule)
diff --git a/_pytest/core.py b/_pytest/core.py
--- a/_pytest/core.py
+++ b/_pytest/core.py
@@ -164,14 +164,17 @@
def consider_preparse(self, args):
for opt1,opt2 in zip(args, args[1:]):
if opt1 == "-p":
- if opt2.startswith("no:"):
- name = opt2[3:]
- if self.getplugin(name) is not None:
- self.unregister(None, name=name)
- self._name2plugin[name] = -1
- else:
- if self.getplugin(opt2) is None:
- self.import_plugin(opt2)
+ self.consider_pluginarg(opt2)
+
+ def consider_pluginarg(self, arg):
+ if arg.startswith("no:"):
+ name = arg[3:]
+ if self.getplugin(name) is not None:
+ self.unregister(None, name=name)
+ self._name2plugin[name] = -1
+ else:
+ if self.getplugin(arg) is None:
+ self.import_plugin(arg)
def consider_conftest(self, conftestmodule):
if self.register(conftestmodule, name=conftestmodule.__file__):
diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py
--- a/_pytest/junitxml.py
+++ b/_pytest/junitxml.py
@@ -106,7 +106,13 @@
'<skipped message="expected test failure">%s</skipped>',
report.keywords['xfail'])
else:
- self.appendlog("<skipped/>")
+ filename, lineno, skipreason = report.longrepr
+ if skipreason.startswith("Skipped: "):
+ skipreason = skipreason[9:]
+ self.appendlog('<skipped type="pytest.skip" '
+ 'message="%s">%s</skipped>',
+ skipreason, "%s:%s: %s" % report.longrepr,
+ )
self._closetestcase()
self.skipped += 1
diff --git a/_pytest/python.py b/_pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -70,11 +70,13 @@
res = __multicall__.execute()
if res is not None:
return res
- if collector._istestclasscandidate(name, obj):
+ if inspect.isclass(obj):
#if hasattr(collector.obj, 'unittest'):
# return # we assume it's a mixin class for a TestCase derived one
- Class = collector._getcustomclass("Class")
- return Class(name, parent=collector)
+ if collector.classnamefilter(name):
+ if not hasinit(obj):
+ Class = collector._getcustomclass("Class")
+ return Class(name, parent=collector)
elif collector.funcnamefilter(name) and hasattr(obj, '__call__'):
if is_generator(obj):
return Generator(name, parent=collector)
@@ -194,14 +196,6 @@
return self.ihook.pytest_pycollect_makeitem(
collector=self, name=name, obj=obj)
- def _istestclasscandidate(self, name, obj):
- if self.classnamefilter(name) and \
- inspect.isclass(obj):
- if hasinit(obj):
- # XXX WARN
- return False
- return True
-
def _genfunctions(self, name, funcobj):
module = self.getparent(Module).obj
clscol = self.getparent(Class)
diff --git a/_pytest/resultlog.py b/_pytest/resultlog.py
--- a/_pytest/resultlog.py
+++ b/_pytest/resultlog.py
@@ -74,7 +74,7 @@
elif report.failed:
longrepr = str(report.longrepr)
elif report.skipped:
- longrepr = str(report.longrepr[2])
+ longrepr = str(report.longrepr)
self.log_outcome(report, code, longrepr)
def pytest_collectreport(self, report):
diff --git a/dotviewer/conftest.py b/dotviewer/conftest.py
--- a/dotviewer/conftest.py
+++ b/dotviewer/conftest.py
@@ -6,4 +6,6 @@
dest="pygame", default=False,
help="allow interactive tests using Pygame")
-option = py.test.config.option
+def pytest_configure(config):
+ global option
+ option = config.option
diff --git a/lib-python/TODO b/lib-python/TODO
--- a/lib-python/TODO
+++ b/lib-python/TODO
@@ -2,7 +2,7 @@
===================
You can find the results of the most recent buildbot run at:
-http://buildbot.pypy.org/summary?branch=fast-forward
+http://buildbot.pypy.org/
Probably easy tasks
@@ -39,18 +39,8 @@
Medium tasks
------------
-- Ast objects should be picklable, see in pypy/module/_ast/test/test_ast.py:
- test_pickle()
-
- socket module has a couple of changes (including AF_TIPC packet range)
-- (test_lib2to3) When a "for" loop runs a generator function, if the loop is
- exited before the end, the "finally" clause of the generator is not called
- until the next gc collection. In our case, in lib2to3/pytree.py,
- WildcardPattern.match_seq() does not exhaust the generate_matches() generator,
- and stderr is not restored.
-
-
Longer tasks
------------
diff --git a/lib-python/modified-2.7.0/ctypes/test/test_internals.py b/lib-python/modified-2.7.0/ctypes/test/test_internals.py
--- a/lib-python/modified-2.7.0/ctypes/test/test_internals.py
+++ b/lib-python/modified-2.7.0/ctypes/test/test_internals.py
@@ -2,7 +2,6 @@
import unittest
from ctypes import *
from sys import getrefcount as grc
-from ctypes.test import xfail
# XXX This test must be reviewed for correctness!!!
@@ -29,13 +28,18 @@
self.assertEqual(refcnt, grc(i))
self.assertEqual(ci._objects, None)
- @xfail
def test_c_char_p(self):
s = "Hello, World"
refcnt = grc(s)
cs = c_char_p(s)
self.assertEqual(refcnt + 1, grc(s))
- self.assertSame(cs._objects, s)
+ try:
+ # Moving gcs need to allocate a nonmoving buffer
+ cs._objects._obj
+ except AttributeError:
+ self.assertSame(cs._objects, s)
+ else:
+ self.assertSame(cs._objects._obj, s)
def test_simple_struct(self):
class X(Structure):
diff --git a/lib-python/modified-2.7.0/ctypes/test/test_loading.py b/lib-python/modified-2.7.0/ctypes/test/test_loading.py
--- a/lib-python/modified-2.7.0/ctypes/test/test_loading.py
+++ b/lib-python/modified-2.7.0/ctypes/test/test_loading.py
@@ -2,7 +2,7 @@
import sys, unittest
import os
from ctypes.util import find_library
-from ctypes.test import is_resource_enabled
+from ctypes.test import is_resource_enabled, xfail
libc_name = None
if os.name == "nt":
@@ -75,6 +75,7 @@
self.assertRaises(AttributeError, dll.__getitem__, 1234)
if os.name == "nt":
+ @xfail
def test_1703286_A(self):
from _ctypes import LoadLibrary, FreeLibrary
# On winXP 64-bit, advapi32 loads at an address that does
@@ -85,6 +86,7 @@
handle = LoadLibrary("advapi32")
FreeLibrary(handle)
+ @xfail
def test_1703286_B(self):
# Since on winXP 64-bit advapi32 loads like described
# above, the (arbitrarily selected) CloseEventLog function
diff --git a/lib-python/modified-2.7.0/ctypes/test/test_parameters.py b/lib-python/modified-2.7.0/ctypes/test/test_parameters.py
--- a/lib-python/modified-2.7.0/ctypes/test/test_parameters.py
+++ b/lib-python/modified-2.7.0/ctypes/test/test_parameters.py
@@ -89,6 +89,8 @@
pa = c_wchar_p.from_param(c_wchar_p(u"123"))
self.assertEqual(type(pa), c_wchar_p)
+ if sys.platform == "win32":
+ test_cw_strings = xfail(test_cw_strings)
@xfail
def test_int_pointers(self):
diff --git a/lib-python/modified-2.7.0/distutils/command/build_ext.py b/lib-python/modified-2.7.0/distutils/command/build_ext.py
--- a/lib-python/modified-2.7.0/distutils/command/build_ext.py
+++ b/lib-python/modified-2.7.0/distutils/command/build_ext.py
@@ -184,7 +184,7 @@
# the 'libs' directory is for binary installs - we assume that
# must be the *native* platform. But we don't really support
# cross-compiling via a binary install anyway, so we let it go.
- self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
+ self.library_dirs.append(os.path.join(sys.exec_prefix, 'include'))
if self.debug:
self.build_temp = os.path.join(self.build_temp, "Debug")
else:
@@ -192,8 +192,13 @@
# Append the source distribution include and library directories,
# this allows distutils on windows to work in the source tree
- self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
- if MSVC_VERSION == 9:
+ if 0:
+ # pypy has no PC directory
+ self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
+ if 1:
+ # pypy has no PCBuild directory
+ pass
+ elif MSVC_VERSION == 9:
# Use the .lib files for the correct architecture
if self.plat_name == 'win32':
suffix = ''
@@ -695,24 +700,14 @@
shared extension. On most platforms, this is just 'ext.libraries';
on Windows and OS/2, we add the Python library (eg. python20.dll).
"""
- # The python library is always needed on Windows. For MSVC, this
- # is redundant, since the library is mentioned in a pragma in
- # pyconfig.h that MSVC groks. The other Windows compilers all seem
- # to need it mentioned explicitly, though, so that's what we do.
- # Append '_d' to the python import library on debug builds.
+ # The python library is always needed on Windows.
if sys.platform == "win32":
- from distutils.msvccompiler import MSVCCompiler
- if not isinstance(self.compiler, MSVCCompiler):
- template = "python%d%d"
- if self.debug:
- template = template + '_d'
- pythonlib = (template %
- (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
- # don't extend ext.libraries, it may be shared with other
- # extensions, it is a reference to the original list
- return ext.libraries + [pythonlib]
- else:
- return ext.libraries
+ template = "python%d%d"
+ pythonlib = (template %
+ (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
+ # don't extend ext.libraries, it may be shared with other
+ # extensions, it is a reference to the original list
+ return ext.libraries + [pythonlib]
elif sys.platform == "os2emx":
# EMX/GCC requires the python library explicitly, and I
# believe VACPP does as well (though not confirmed) - AIM Apr01
diff --git a/lib-python/modified-2.7.0/distutils/msvc9compiler.py b/lib-python/modified-2.7.0/distutils/msvc9compiler.py
--- a/lib-python/modified-2.7.0/distutils/msvc9compiler.py
+++ b/lib-python/modified-2.7.0/distutils/msvc9compiler.py
@@ -644,6 +644,7 @@
temp_manifest = os.path.join(
build_temp,
os.path.basename(output_filename) + ".manifest")
+ ld_args.append('/MANIFEST')
ld_args.append('/MANIFESTFILE:' + temp_manifest)
if extra_preargs:
diff --git a/lib-python/modified-2.7.0/sqlite3/test/regression.py b/lib-python/modified-2.7.0/sqlite3/test/regression.py
--- a/lib-python/modified-2.7.0/sqlite3/test/regression.py
+++ b/lib-python/modified-2.7.0/sqlite3/test/regression.py
@@ -264,6 +264,16 @@
"""
self.assertRaises(sqlite.Warning, self.con, 1)
+ def CheckUpdateDescriptionNone(self):
+ """
+ Call Cursor.update with an UPDATE query and check that it sets the
+ cursor's description to be None.
+ """
+ cur = self.con.cursor()
+ cur.execute("CREATE TABLE foo (id INTEGER)")
+ cur.execute("UPDATE foo SET id = 3 WHERE id = 1")
+ self.assertEqual(cur.description, None)
+
def suite():
regression_suite = unittest.makeSuite(RegressionTests, "Check")
return unittest.TestSuite((regression_suite,))
diff --git a/lib_pypy/_pypy_wait.py b/lib_pypy/_pypy_wait.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_pypy_wait.py
@@ -0,0 +1,51 @@
+from ctypes import CDLL, c_int, POINTER, byref
+from ctypes.util import find_library
+from resource import _struct_rusage, struct_rusage
+
+__all__ = ["wait3", "wait4"]
+
+libc = CDLL(find_library("c"))
+c_wait3 = libc.wait3
+
+c_wait3.argtypes = [POINTER(c_int), c_int, POINTER(_struct_rusage)]
+
+c_wait4 = libc.wait4
+
+c_wait4.argtypes = [c_int, POINTER(c_int), c_int, POINTER(_struct_rusage)]
+
+def create_struct_rusage(c_struct):
+ return struct_rusage((
+ float(c_struct.ru_utime),
+ float(c_struct.ru_stime),
+ c_struct.ru_maxrss,
+ c_struct.ru_ixrss,
+ c_struct.ru_idrss,
+ c_struct.ru_isrss,
+ c_struct.ru_minflt,
+ c_struct.ru_majflt,
+ c_struct.ru_nswap,
+ c_struct.ru_inblock,
+ c_struct.ru_oublock,
+ c_struct.ru_msgsnd,
+ c_struct.ru_msgrcv,
+ c_struct.ru_nsignals,
+ c_struct.ru_nvcsw,
+ c_struct.ru_nivcsw))
+
+def wait3(options):
+ status = c_int()
+ _rusage = _struct_rusage()
+ pid = c_wait3(byref(status), c_int(options), byref(_rusage))
+
+ rusage = create_struct_rusage(_rusage)
+
+ return pid, status.value, rusage
+
+def wait4(pid, options):
+ status = c_int()
+ _rusage = _struct_rusage()
+ pid = c_wait4(c_int(pid), byref(status), c_int(options), byref(_rusage))
+
+ rusage = create_struct_rusage(_rusage)
+
+ return pid, status.value, rusage
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -31,9 +31,9 @@
from threading import _get_ident as thread_get_ident
names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split()
-for name in names:
+for name in names:
try:
- sqlite = cdll.LoadLibrary(name)
+ sqlite = cdll.LoadLibrary(name)
break
except OSError:
continue
@@ -232,7 +232,7 @@
return unicode(x, 'utf-8')
class Connection(object):
- def __init__(self, database, isolation_level="", detect_types=0, timeout=None, *args, **kwargs):
+ def __init__(self, database, isolation_level="", detect_types=0, timeout=None, cached_statements=None, factory=None):
self.db = c_void_p()
if sqlite.sqlite3_open(database, byref(self.db)) != SQLITE_OK:
raise OperationalError("Could not open database")
@@ -1032,6 +1032,8 @@
self.statement = None
def _get_description(self):
+ if self.kind == "DML":
+ return None
desc = []
for i in xrange(sqlite.sqlite3_column_count(self.statement)):
name = sqlite.sqlite3_column_name(self.statement, i).split("[")[0].strip()
@@ -1140,7 +1142,7 @@
def _convert_result(con, val):
if val is None:
- sqlite.sqlite3_result_null(con)
+ sqlite.sqlite3_result_null(con)
elif isinstance(val, (bool, int, long)):
sqlite.sqlite3_result_int64(con, int(val))
elif isinstance(val, str):
diff --git a/lib_pypy/pypy_test/test_os_wait.py b/lib_pypy/pypy_test/test_os_wait.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pypy_test/test_os_wait.py
@@ -0,0 +1,44 @@
+# Generates the resource cache
+from __future__ import absolute_import
+from lib_pypy.ctypes_config_cache import rebuild
+rebuild.rebuild_one('resource.ctc.py')
+
+import os
+
+from lib_pypy._pypy_wait import wait3, wait4
+
+if hasattr(os, 'wait3'):
+ def test_os_wait3():
+ exit_status = 0x33
+
+ if not hasattr(os, "fork"):
+ skip("Need fork() to test wait3()")
+
+ child = os.fork()
+ if child == 0: # in child
+ os._exit(exit_status)
+ else:
+ pid, status, rusage = wait3(0)
+ assert child == pid
+ assert os.WIFEXITED(status)
+ assert os.WEXITSTATUS(status) == exit_status
+ assert isinstance(rusage.ru_utime, float)
+ assert isinstance(rusage.ru_maxrss, int)
+
+if hasattr(os, 'wait4'):
+ def test_os_wait4():
+ exit_status = 0x33
+
+ if not hasattr(os, "fork"):
+ skip("Need fork() to test wait4()")
+
+ child = os.fork()
+ if child == 0: # in child
+ os._exit(exit_status)
+ else:
+ pid, status, rusage = wait4(child, 0)
+ assert child == pid
+ assert os.WIFEXITED(status)
+ assert os.WEXITSTATUS(status) == exit_status
+ assert isinstance(rusage.ru_utime, float)
+ assert isinstance(rusage.ru_maxrss, int)
diff --git a/lib_pypy/pyrepl/__init__.py b/lib_pypy/pyrepl/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/__init__.py
@@ -0,0 +1,19 @@
+# Copyright 2000-2008 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/lib_pypy/pyrepl/cmdrepl.py b/lib_pypy/pyrepl/cmdrepl.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/cmdrepl.py
@@ -0,0 +1,118 @@
+# Copyright 2000-2007 Michael Hudson-Doyle <micahel at gmail.com>
+# Maciek Fijalkowski
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Wedge pyrepl behaviour into cmd.Cmd-derived classes.
+
+replize, when given a subclass of cmd.Cmd, returns a class that
+behaves almost identically to the supplied class, except that it uses
+pyrepl instead if raw_input.
+
+It was designed to let you do this:
+
+>>> import pdb
+>>> from pyrepl import replize
+>>> pdb.Pdb = replize(pdb.Pdb)
+
+which is in fact done by the `pythoni' script that comes with
+pyrepl."""
+
+from __future__ import nested_scopes
+
+from pyrepl import completing_reader as cr, reader, completer
+from pyrepl.completing_reader import CompletingReader as CR
+import cmd
+
+class CmdReader(CR):
+ def collect_keymap(self):
+ return super(CmdReader, self).collect_keymap() + (
+ ("\\M-\\n", "invalid-key"),
+ ("\\n", "accept"))
+
+ CR_init = CR.__init__
+ def __init__(self, completions):
+ self.CR_init(self)
+ self.completions = completions
+
+ def get_completions(self, stem):
+ if len(stem) != self.pos:
+ return []
+ return cr.uniqify([s for s in self.completions
+ if s.startswith(stem)])
+
+def replize(klass, history_across_invocations=1):
+
+ """Return a subclass of the cmd.Cmd-derived klass that uses
+ pyrepl instead of readline.
+
+ Raises a ValueError if klass does not derive from cmd.Cmd.
+
+ The optional history_across_invocations parameter (default 1)
+ controls whether instances of the returned class share
+ histories."""
+
+ completions = [s[3:]
+ for s in completer.get_class_members(klass)
+ if s.startswith("do_")]
+
+ if not issubclass(klass, cmd.Cmd):
+ raise Exception
+# if klass.cmdloop.im_class is not cmd.Cmd:
+# print "this may not work"
+
+ class CmdRepl(klass):
+ k_init = klass.__init__
+
+ if history_across_invocations:
+ _CmdRepl__history = []
+ def __init__(self, *args, **kw):
+ self.k_init(*args, **kw)
+ self.__reader = CmdReader(completions)
+ self.__reader.history = CmdRepl._CmdRepl__history
+ self.__reader.historyi = len(CmdRepl._CmdRepl__history)
+ else:
+ def __init__(self, *args, **kw):
+ self.k_init(*args, **kw)
+ self.__reader = CmdReader(completions)
+
+ def cmdloop(self, intro=None):
+ self.preloop()
+ if intro is not None:
+ self.intro = intro
+ if self.intro:
+ print self.intro
+ stop = None
+ while not stop:
+ if self.cmdqueue:
+ line = self.cmdqueue[0]
+ del self.cmdqueue[0]
+ else:
+ try:
+ self.__reader.ps1 = self.prompt
+ line = self.__reader.readline()
+ except EOFError:
+ line = "EOF"
+ line = self.precmd(line)
+ stop = self.onecmd(line)
+ stop = self.postcmd(stop, line)
+ self.postloop()
+
+ CmdRepl.__name__ = "replize(%s.%s)"%(klass.__module__, klass.__name__)
+ return CmdRepl
+
diff --git a/lib_pypy/pyrepl/commands.py b/lib_pypy/pyrepl/commands.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/commands.py
@@ -0,0 +1,385 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Antonio Cuni
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import sys, os
+
+# Catgories of actions:
+# killing
+# yanking
+# motion
+# editing
+# history
+# finishing
+# [completion]
+
+class Command(object):
+ finish = 0
+ kills_digit_arg = 1
+ def __init__(self, reader, (event_name, event)):
+ self.reader = reader
+ self.event = event
+ self.event_name = event_name
+ def do(self):
+ pass
+
+class KillCommand(Command):
+ def kill_range(self, start, end):
+ if start == end:
+ return
+ r = self.reader
+ b = r.buffer
+ text = b[start:end]
+ del b[start:end]
+ if is_kill(r.last_command):
+ if start < r.pos:
+ r.kill_ring[-1] = text + r.kill_ring[-1]
+ else:
+ r.kill_ring[-1] = r.kill_ring[-1] + text
+ else:
+ r.kill_ring.append(text)
+ r.pos = start
+ r.dirty = 1
+
+class YankCommand(Command):
+ pass
+
+class MotionCommand(Command):
+ pass
+
+class EditCommand(Command):
+ pass
+
+class FinishCommand(Command):
+ finish = 1
+ pass
+
+def is_kill(command):
+ return command and issubclass(command, KillCommand)
+
+def is_yank(command):
+ return command and issubclass(command, YankCommand)
+
+# etc
+
+class digit_arg(Command):
+ kills_digit_arg = 0
+ def do(self):
+ r = self.reader
+ c = self.event[-1]
+ if c == "-":
+ if r.arg is not None:
+ r.arg = -r.arg
+ else:
+ r.arg = -1
+ else:
+ d = int(c)
+ if r.arg is None:
+ r.arg = d
+ else:
+ if r.arg < 0:
+ r.arg = 10*r.arg - d
+ else:
+ r.arg = 10*r.arg + d
+ r.dirty = 1
+
+class clear_screen(Command):
+ def do(self):
+ r = self.reader
+ r.console.clear()
+ r.dirty = 1
+
+class refresh(Command):
+ def do(self):
+ self.reader.dirty = 1
+
+class repaint(Command):
+ def do(self):
+ self.reader.dirty = 1
+ self.reader.console.repaint_prep()
+
+class kill_line(KillCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ eol = r.eol()
+ for c in b[r.pos:eol]:
+ if not c.isspace():
+ self.kill_range(r.pos, eol)
+ return
+ else:
+ self.kill_range(r.pos, eol+1)
+
+class unix_line_discard(KillCommand):
+ def do(self):
+ r = self.reader
+ self.kill_range(r.bol(), r.pos)
+
+# XXX unix_word_rubout and backward_kill_word should actually
+# do different things...
+
+class unix_word_rubout(KillCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ self.kill_range(r.bow(), r.pos)
+
+class kill_word(KillCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ self.kill_range(r.pos, r.eow())
+
+class backward_kill_word(KillCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ self.kill_range(r.bow(), r.pos)
+
+class yank(YankCommand):
+ def do(self):
+ r = self.reader
+ if not r.kill_ring:
+ r.error("nothing to yank")
+ return
+ r.insert(r.kill_ring[-1])
+
+class yank_pop(YankCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ if not r.kill_ring:
+ r.error("nothing to yank")
+ return
+ if not is_yank(r.last_command):
+ r.error("previous command was not a yank")
+ return
+ repl = len(r.kill_ring[-1])
+ r.kill_ring.insert(0, r.kill_ring.pop())
+ t = r.kill_ring[-1]
+ b[r.pos - repl:r.pos] = t
+ r.pos = r.pos - repl + len(t)
+ r.dirty = 1
+
+class interrupt(FinishCommand):
+ def do(self):
+ import signal
+ self.reader.console.finish()
+ os.kill(os.getpid(), signal.SIGINT)
+
+class suspend(Command):
+ def do(self):
+ import signal
+ r = self.reader
+ p = r.pos
+ r.console.finish()
+ os.kill(os.getpid(), signal.SIGSTOP)
+ ## this should probably be done
+ ## in a handler for SIGCONT?
+ r.console.prepare()
+ r.pos = p
+ r.posxy = 0, 0
+ r.dirty = 1
+ r.console.screen = []
+
+class up(MotionCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ bol1 = r.bol()
+ if bol1 == 0:
+ if r.historyi > 0:
+ r.select_item(r.historyi - 1)
+ return
+ r.pos = 0
+ r.error("start of buffer")
+ return
+ bol2 = r.bol(bol1-1)
+ line_pos = r.pos - bol1
+ if line_pos > bol1 - bol2 - 1:
+ r.sticky_y = line_pos
+ r.pos = bol1 - 1
+ else:
+ r.pos = bol2 + line_pos
+
+class down(MotionCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ for i in range(r.get_arg()):
+ bol1 = r.bol()
+ eol1 = r.eol()
+ if eol1 == len(b):
+ if r.historyi < len(r.history):
+ r.select_item(r.historyi + 1)
+ r.pos = r.eol(0)
+ return
+ r.pos = len(b)
+ r.error("end of buffer")
+ return
+ eol2 = r.eol(eol1+1)
+ if r.pos - bol1 > eol2 - eol1 - 1:
+ r.pos = eol2
+ else:
+ r.pos = eol1 + (r.pos - bol1) + 1
+
+class left(MotionCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ p = r.pos - 1
+ if p >= 0:
+ r.pos = p
+ else:
+ self.reader.error("start of buffer")
+
+class right(MotionCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ for i in range(r.get_arg()):
+ p = r.pos + 1
+ if p <= len(b):
+ r.pos = p
+ else:
+ self.reader.error("end of buffer")
+
+class beginning_of_line(MotionCommand):
+ def do(self):
+ self.reader.pos = self.reader.bol()
+
+class end_of_line(MotionCommand):
+ def do(self):
+ r = self.reader
+ self.reader.pos = self.reader.eol()
+
+class home(MotionCommand):
+ def do(self):
+ self.reader.pos = 0
+
+class end(MotionCommand):
+ def do(self):
+ self.reader.pos = len(self.reader.buffer)
+
+class forward_word(MotionCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ r.pos = r.eow()
+
+class backward_word(MotionCommand):
+ def do(self):
+ r = self.reader
+ for i in range(r.get_arg()):
+ r.pos = r.bow()
+
+class self_insert(EditCommand):
+ def do(self):
+ r = self.reader
+ r.insert(self.event * r.get_arg())
+
+class insert_nl(EditCommand):
+ def do(self):
+ r = self.reader
+ r.insert("\n" * r.get_arg())
+
+class transpose_characters(EditCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ s = r.pos - 1
+ if s < 0:
+ r.error("cannot transpose at start of buffer")
+ else:
+ if s == len(b):
+ s -= 1
+ t = min(s + r.get_arg(), len(b) - 1)
+ c = b[s]
+ del b[s]
+ b.insert(t, c)
+ r.pos = t
+ r.dirty = 1
+
+class backspace(EditCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ for i in range(r.get_arg()):
+ if r.pos > 0:
+ r.pos -= 1
+ del b[r.pos]
+ r.dirty = 1
+ else:
+ self.reader.error("can't backspace at start")
+
+class delete(EditCommand):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ if ( r.pos == 0 and len(b) == 0 # this is something of a hack
+ and self.event[-1] == "\004"):
+ r.update_screen()
+ r.console.finish()
+ raise EOFError
+ for i in range(r.get_arg()):
+ if r.pos != len(b):
+ del b[r.pos]
+ r.dirty = 1
+ else:
+ self.reader.error("end of buffer")
+
+class accept(FinishCommand):
+ def do(self):
+ pass
+
+class help(Command):
+ def do(self):
+ self.reader.msg = self.reader.help_text
+ self.reader.dirty = 1
+
+class invalid_key(Command):
+ def do(self):
+ pending = self.reader.console.getpending()
+ s = ''.join(self.event) + pending.data
+ self.reader.error("`%r' not bound"%s)
+
+class invalid_command(Command):
+ def do(self):
+ s = self.event_name
+ self.reader.error("command `%s' not known"%s)
+
+class qIHelp(Command):
+ def do(self):
+ r = self.reader
+ r.insert((self.event + r.console.getpending().data) * r.get_arg())
+ r.pop_input_trans()
+
+from pyrepl import input
+
+class QITrans(object):
+ def push(self, evt):
+ self.evt = evt
+ def get(self):
+ return ('qIHelp', self.evt.raw)
+
+class quoted_insert(Command):
+ kills_digit_arg = 0
+ def do(self):
+ self.reader.push_input_trans(QITrans())
diff --git a/lib_pypy/pyrepl/completer.py b/lib_pypy/pyrepl/completer.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/completer.py
@@ -0,0 +1,87 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import __builtin__
+
+class Completer:
+ def __init__(self, ns):
+ self.ns = ns
+
+ def complete(self, text):
+ if "." in text:
+ return self.attr_matches(text)
+ else:
+ return self.global_matches(text)
+
+ def global_matches(self, text):
+ """Compute matches when text is a simple name.
+
+ Return a list of all keywords, built-in functions and names
+ currently defines in __main__ that match.
+
+ """
+ import keyword
+ matches = []
+ n = len(text)
+ for list in [keyword.kwlist,
+ __builtin__.__dict__.keys(),
+ self.ns.keys()]:
+ for word in list:
+ if word[:n] == text and word != "__builtins__":
+ matches.append(word)
+ return matches
+
+ def attr_matches(self, text):
+ """Compute matches when text contains a dot.
+
+ Assuming the text is of the form NAME.NAME....[NAME], and is
+ evaluatable in the globals of __main__, it will be evaluated
+ and its attributes (as revealed by dir()) are used as possible
+ completions. (For class instances, class members are are also
+ considered.)
+
+ WARNING: this can still invoke arbitrary C code, if an object
+ with a __getattr__ hook is evaluated.
+
+ """
+ import re
+ m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
+ if not m:
+ return []
+ expr, attr = m.group(1, 3)
+ object = eval(expr, self.ns)
+ words = dir(object)
+ if hasattr(object, '__class__'):
+ words.append('__class__')
+ words = words + get_class_members(object.__class__)
+ matches = []
+ n = len(attr)
+ for word in words:
+ if word[:n] == attr and word != "__builtins__":
+ matches.append("%s.%s" % (expr, word))
+ return matches
+
+def get_class_members(klass):
+ ret = dir(klass)
+ if hasattr(klass, '__bases__'):
+ for base in klass.__bases__:
+ ret = ret + get_class_members(base)
+ return ret
+
+
diff --git a/lib_pypy/pyrepl/completing_reader.py b/lib_pypy/pyrepl/completing_reader.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/completing_reader.py
@@ -0,0 +1,280 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Antonio Cuni
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl import commands, reader
+from pyrepl.reader import Reader
+
+def uniqify(l):
+ d = {}
+ for i in l:
+ d[i] = 1
+ r = d.keys()
+ r.sort()
+ return r
+
+def prefix(wordlist, j = 0):
+ d = {}
+ i = j
+ try:
+ while 1:
+ for word in wordlist:
+ d[word[i]] = 1
+ if len(d) > 1:
+ return wordlist[0][j:i]
+ i += 1
+ d = {}
+ except IndexError:
+ return wordlist[0][j:i]
+
+import re
+def stripcolor(s):
+ return stripcolor.regexp.sub('', s)
+stripcolor.regexp = re.compile(r"\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[m|K]")
+
+def real_len(s):
+ return len(stripcolor(s))
+
+def left_align(s, maxlen):
+ stripped = stripcolor(s)
+ if len(stripped) > maxlen:
+ # too bad, we remove the color
+ return stripped[:maxlen]
+ padding = maxlen - len(stripped)
+ return s + ' '*padding
+
+def build_menu(cons, wordlist, start, use_brackets, sort_in_column):
+ if use_brackets:
+ item = "[ %s ]"
+ padding = 4
+ else:
+ item = "%s "
+ padding = 2
+ maxlen = min(max(map(real_len, wordlist)), cons.width - padding)
+ cols = cons.width / (maxlen + padding)
+ rows = (len(wordlist) - 1)/cols + 1
+
+ if sort_in_column:
+ # sort_in_column=False (default) sort_in_column=True
+ # A B C A D G
+ # D E F B E
+ # G C F
+ #
+ # "fill" the table with empty words, so we always have the same amout
+ # of rows for each column
+ missing = cols*rows - len(wordlist)
+ wordlist = wordlist + ['']*missing
+ indexes = [(i%cols)*rows + i//cols for i in range(len(wordlist))]
+ wordlist = [wordlist[i] for i in indexes]
+ menu = []
+ i = start
+ for r in range(rows):
+ row = []
+ for col in range(cols):
+ row.append(item % left_align(wordlist[i], maxlen))
+ i += 1
+ if i >= len(wordlist):
+ break
+ menu.append( ''.join(row) )
+ if i >= len(wordlist):
+ i = 0
+ break
+ if r + 5 > cons.height:
+ menu.append(" %d more... "%(len(wordlist) - i))
+ break
+ return menu, i
+
+# this gets somewhat user interface-y, and as a result the logic gets
+# very convoluted.
+#
+# To summarise the summary of the summary:- people are a problem.
+# -- The Hitch-Hikers Guide to the Galaxy, Episode 12
+
+#### Desired behaviour of the completions commands.
+# the considerations are:
+# (1) how many completions are possible
+# (2) whether the last command was a completion
+# (3) if we can assume that the completer is going to return the same set of
+# completions: this is controlled by the ``assume_immutable_completions``
+# variable on the reader, which is True by default to match the historical
+# behaviour of pyrepl, but e.g. False in the ReadlineAlikeReader to match
+# more closely readline's semantics (this is needed e.g. by
+# fancycompleter)
+#
+# if there's no possible completion, beep at the user and point this out.
+# this is easy.
+#
+# if there's only one possible completion, stick it in. if the last thing
+# user did was a completion, point out that he isn't getting anywhere, but
+# only if the ``assume_immutable_completions`` is True.
+#
+# now it gets complicated.
+#
+# for the first press of a completion key:
+# if there's a common prefix, stick it in.
+
+# irrespective of whether anything got stuck in, if the word is now
+# complete, show the "complete but not unique" message
+
+# if there's no common prefix and if the word is not now complete,
+# beep.
+
+# common prefix -> yes no
+# word complete \/
+# yes "cbnu" "cbnu"
+# no - beep
+
+# for the second bang on the completion key
+# there will necessarily be no common prefix
+# show a menu of the choices.
+
+# for subsequent bangs, rotate the menu around (if there are sufficient
+# choices).
+
+class complete(commands.Command):
+ def do(self):
+ r = self.reader
+ stem = r.get_stem()
+ if r.assume_immutable_completions and \
+ r.last_command_is(self.__class__):
+ completions = r.cmpltn_menu_choices
+ else:
+ r.cmpltn_menu_choices = completions = \
+ r.get_completions(stem)
+ if len(completions) == 0:
+ r.error("no matches")
+ elif len(completions) == 1:
+ if r.assume_immutable_completions and \
+ len(completions[0]) == len(stem) and \
+ r.last_command_is(self.__class__):
+ r.msg = "[ sole completion ]"
+ r.dirty = 1
+ r.insert(completions[0][len(stem):])
+ else:
+ p = prefix(completions, len(stem))
+ if p <> '':
+ r.insert(p)
+ if r.last_command_is(self.__class__):
+ if not r.cmpltn_menu_vis:
+ r.cmpltn_menu_vis = 1
+ r.cmpltn_menu, r.cmpltn_menu_end = build_menu(
+ r.console, completions, r.cmpltn_menu_end,
+ r.use_brackets, r.sort_in_column)
+ r.dirty = 1
+ elif stem + p in completions:
+ r.msg = "[ complete but not unique ]"
+ r.dirty = 1
+ else:
+ r.msg = "[ not unique ]"
+ r.dirty = 1
+
+class self_insert(commands.self_insert):
+ def do(self):
+ commands.self_insert.do(self)
+ r = self.reader
+ if r.cmpltn_menu_vis:
+ stem = r.get_stem()
+ if len(stem) < 1:
+ r.cmpltn_reset()
+ else:
+ completions = [w for w in r.cmpltn_menu_choices
+ if w.startswith(stem)]
+ if completions:
+ r.cmpltn_menu, r.cmpltn_menu_end = build_menu(
+ r.console, completions, 0,
+ r.use_brackets, r.sort_in_column)
+ else:
+ r.cmpltn_reset()
+
+class CompletingReader(Reader):
+ """Adds completion support
+
+ Adds instance variables:
+ * cmpltn_menu, cmpltn_menu_vis, cmpltn_menu_end, cmpltn_choices:
+ *
+ """
+ # see the comment for the complete command
+ assume_immutable_completions = True
+ use_brackets = True # display completions inside []
+ sort_in_column = False
+
+ def collect_keymap(self):
+ return super(CompletingReader, self).collect_keymap() + (
+ (r'\t', 'complete'),)
+
+ def __init__(self, console):
+ super(CompletingReader, self).__init__(console)
+ self.cmpltn_menu = ["[ menu 1 ]", "[ menu 2 ]"]
+ self.cmpltn_menu_vis = 0
+ self.cmpltn_menu_end = 0
+ for c in [complete, self_insert]:
+ self.commands[c.__name__] = c
+ self.commands[c.__name__.replace('_', '-')] = c
+
+ def after_command(self, cmd):
+ super(CompletingReader, self).after_command(cmd)
+ if not isinstance(cmd, complete) and not isinstance(cmd, self_insert):
+ self.cmpltn_reset()
+
+ def calc_screen(self):
+ screen = super(CompletingReader, self).calc_screen()
+ if self.cmpltn_menu_vis:
+ ly = self.lxy[1]
+ screen[ly:ly] = self.cmpltn_menu
+ self.screeninfo[ly:ly] = [(0, [])]*len(self.cmpltn_menu)
+ self.cxy = self.cxy[0], self.cxy[1] + len(self.cmpltn_menu)
+ return screen
+
+ def finish(self):
+ super(CompletingReader, self).finish()
+ self.cmpltn_reset()
+
+ def cmpltn_reset(self):
+ self.cmpltn_menu = []
+ self.cmpltn_menu_vis = 0
+ self.cmpltn_menu_end = 0
+ self.cmpltn_menu_choices = []
+
+ def get_stem(self):
+ st = self.syntax_table
+ SW = reader.SYNTAX_WORD
+ b = self.buffer
+ p = self.pos - 1
+ while p >= 0 and st.get(b[p], SW) == SW:
+ p -= 1
+ return u''.join(b[p+1:self.pos])
+
+ def get_completions(self, stem):
+ return []
+
+def test():
+ class TestReader(CompletingReader):
+ def get_completions(self, stem):
+ return [s for l in map(lambda x:x.split(),self.history)
+ for s in l if s and s.startswith(stem)]
+ reader = TestReader()
+ reader.ps1 = "c**> "
+ reader.ps2 = "c/*> "
+ reader.ps3 = "c|*> "
+ reader.ps4 = "c\*> "
+ while reader.readline():
+ pass
+
+if __name__=='__main__':
+ test()
diff --git a/lib_pypy/pyrepl/console.py b/lib_pypy/pyrepl/console.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/console.py
@@ -0,0 +1,93 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+class Event:
+ """An Event. `evt' is 'key' or somesuch."""
+
+ def __init__(self, evt, data, raw=''):
+ self.evt = evt
+ self.data = data
+ self.raw = raw
+
+ def __repr__(self):
+ return 'Event(%r, %r)'%(self.evt, self.data)
+
+class Console:
+ """Attributes:
+
+ screen,
+ height,
+ width,
+ """
+
+ def refresh(self, screen, xy):
+ pass
+
+ def prepare(self):
+ pass
+
+ def restore(self):
+ pass
+
+ def move_cursor(self, x, y):
+ pass
+
+ def set_cursor_vis(self, vis):
+ pass
+
+ def getheightwidth(self):
+ """Return (height, width) where height and width are the height
+ and width of the terminal window in characters."""
+ pass
+
+ def get_event(self, block=1):
+ """Return an Event instance. Returns None if |block| is false
+ and there is no event pending, otherwise waits for the
+ completion of an event."""
+ pass
+
+ def beep(self):
+ pass
+
+ def clear(self):
+ """Wipe the screen"""
+ pass
+
+ def finish(self):
+ """Move the cursor to the end of the display and otherwise get
+ ready for end. XXX could be merged with restore? Hmm."""
+ pass
+
+ def flushoutput(self):
+ """Flush all output to the screen (assuming there's some
+ buffering going on somewhere)."""
+ pass
+
+ def forgetinput(self):
+ """Forget all pending, but not yet processed input."""
+ pass
+
+ def getpending(self):
+ """Return the characters that have been typed but not yet
+ processed."""
+ pass
+
+ def wait(self):
+ """Wait for an event."""
+ pass
diff --git a/lib_pypy/pyrepl/copy_code.py b/lib_pypy/pyrepl/copy_code.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/copy_code.py
@@ -0,0 +1,73 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import new
+
+def copy_code_with_changes(codeobject,
+ argcount=None,
+ nlocals=None,
+ stacksize=None,
+ flags=None,
+ code=None,
+ consts=None,
+ names=None,
+ varnames=None,
+ filename=None,
+ name=None,
+ firstlineno=None,
+ lnotab=None):
+ if argcount is None: argcount = codeobject.co_argcount
+ if nlocals is None: nlocals = codeobject.co_nlocals
+ if stacksize is None: stacksize = codeobject.co_stacksize
+ if flags is None: flags = codeobject.co_flags
+ if code is None: code = codeobject.co_code
+ if consts is None: consts = codeobject.co_consts
+ if names is None: names = codeobject.co_names
+ if varnames is None: varnames = codeobject.co_varnames
+ if filename is None: filename = codeobject.co_filename
+ if name is None: name = codeobject.co_name
+ if firstlineno is None: firstlineno = codeobject.co_firstlineno
+ if lnotab is None: lnotab = codeobject.co_lnotab
+ return new.code(argcount,
+ nlocals,
+ stacksize,
+ flags,
+ code,
+ consts,
+ names,
+ varnames,
+ filename,
+ name,
+ firstlineno,
+ lnotab)
+
+code_attrs=['argcount',
+ 'nlocals',
+ 'stacksize',
+ 'flags',
+ 'code',
+ 'consts',
+ 'names',
+ 'varnames',
+ 'filename',
+ 'name',
+ 'firstlineno',
+ 'lnotab']
+
+
diff --git a/lib_pypy/pyrepl/curses.py b/lib_pypy/pyrepl/curses.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/curses.py
@@ -0,0 +1,39 @@
+
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Some try-import logic for two purposes: avoiding to bring in the whole
+# pure Python curses package if possible; and, in _curses is not actually
+# present, falling back to _minimal_curses (which is either a ctypes-based
+# pure Python module or a PyPy built-in module).
+try:
+ import _curses
+except ImportError:
+ try:
+ import _minimal_curses as _curses
+ except ImportError:
+ # Who knows, maybe some environment has "curses" but not "_curses".
+ # If not, at least the following import gives a clean ImportError.
+ import _curses
+
+setupterm = _curses.setupterm
+tigetstr = _curses.tigetstr
+tparm = _curses.tparm
+error = _curses.error
diff --git a/lib_pypy/pyrepl/fancy_termios.py b/lib_pypy/pyrepl/fancy_termios.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/fancy_termios.py
@@ -0,0 +1,52 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import termios
+
+class TermState:
+ def __init__(self, tuples):
+ self.iflag, self.oflag, self.cflag, self.lflag, \
+ self.ispeed, self.ospeed, self.cc = tuples
+ def as_list(self):
+ return [self.iflag, self.oflag, self.cflag, self.lflag,
+ self.ispeed, self.ospeed, self.cc]
+
+ def copy(self):
+ return self.__class__(self.as_list())
+
+def tcgetattr(fd):
+ return TermState(termios.tcgetattr(fd))
+
+def tcsetattr(fd, when, attrs):
+ termios.tcsetattr(fd, when, attrs.as_list())
+
+class Term(TermState):
+ TS__init__ = TermState.__init__
+ def __init__(self, fd=0):
+ self.TS__init__(termios.tcgetattr(fd))
+ self.fd = fd
+ self.stack = []
+ def save(self):
+ self.stack.append( self.as_list() )
+ def set(self, when=termios.TCSANOW):
+ termios.tcsetattr(self.fd, when, self.as_list())
+ def restore(self):
+ self.TS__init__(self.stack.pop())
+ self.set()
+
diff --git a/lib_pypy/pyrepl/historical_reader.py b/lib_pypy/pyrepl/historical_reader.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/historical_reader.py
@@ -0,0 +1,311 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl import reader, commands
+from pyrepl.reader import Reader as R
+
+isearch_keymap = tuple(
+ [('\\%03o'%c, 'isearch-end') for c in range(256) if chr(c) != '\\'] + \
+ [(c, 'isearch-add-character')
+ for c in map(chr, range(32, 127)) if c != '\\'] + \
+ [('\\%03o'%c, 'isearch-add-character')
+ for c in range(256) if chr(c).isalpha() and chr(c) != '\\'] + \
+ [('\\\\', 'self-insert'),
+ (r'\C-r', 'isearch-backwards'),
+ (r'\C-s', 'isearch-forwards'),
+ (r'\C-c', 'isearch-cancel'),
+ (r'\C-g', 'isearch-cancel'),
+ (r'\<backspace>', 'isearch-backspace')])
+
+del c
+
+ISEARCH_DIRECTION_NONE = ''
+ISEARCH_DIRECTION_BACKWARDS = 'r'
+ISEARCH_DIRECTION_FORWARDS = 'f'
+
+class next_history(commands.Command):
+ def do(self):
+ r = self.reader
+ if r.historyi == len(r.history):
+ r.error("end of history list")
+ return
+ r.select_item(r.historyi + 1)
+
+class previous_history(commands.Command):
+ def do(self):
+ r = self.reader
+ if r.historyi == 0:
+ r.error("start of history list")
+ return
+ r.select_item(r.historyi - 1)
+
+class restore_history(commands.Command):
+ def do(self):
+ r = self.reader
+ if r.historyi != len(r.history):
+ if r.get_unicode() != r.history[r.historyi]:
+ r.buffer = list(r.history[r.historyi])
+ r.pos = len(r.buffer)
+ r.dirty = 1
+
+class first_history(commands.Command):
+ def do(self):
+ self.reader.select_item(0)
+
+class last_history(commands.Command):
+ def do(self):
+ self.reader.select_item(len(self.reader.history))
+
+class operate_and_get_next(commands.FinishCommand):
+ def do(self):
+ self.reader.next_history = self.reader.historyi + 1
+
+class yank_arg(commands.Command):
+ def do(self):
+ r = self.reader
+ if r.last_command is self.__class__:
+ r.yank_arg_i += 1
+ else:
+ r.yank_arg_i = 0
+ if r.historyi < r.yank_arg_i:
+ r.error("beginning of history list")
+ return
+ a = r.get_arg(-1)
+ # XXX how to split?
+ words = r.get_item(r.historyi - r.yank_arg_i - 1).split()
+ if a < -len(words) or a >= len(words):
+ r.error("no such arg")
+ return
+ w = words[a]
+ b = r.buffer
+ if r.yank_arg_i > 0:
+ o = len(r.yank_arg_yanked)
+ else:
+ o = 0
+ b[r.pos - o:r.pos] = list(w)
+ r.yank_arg_yanked = w
+ r.pos += len(w) - o
+ r.dirty = 1
+
+class forward_history_isearch(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_FORWARDS
+ r.isearch_start = r.historyi, r.pos
+ r.isearch_term = ''
+ r.dirty = 1
+ r.push_input_trans(r.isearch_trans)
+
+
+class reverse_history_isearch(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_BACKWARDS
+ r.dirty = 1
+ r.isearch_term = ''
+ r.push_input_trans(r.isearch_trans)
+ r.isearch_start = r.historyi, r.pos
+
+class isearch_cancel(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_NONE
+ r.pop_input_trans()
+ r.select_item(r.isearch_start[0])
+ r.pos = r.isearch_start[1]
+ r.dirty = 1
+
+class isearch_add_character(commands.Command):
+ def do(self):
+ r = self.reader
+ b = r.buffer
+ r.isearch_term += self.event[-1]
+ r.dirty = 1
+ p = r.pos + len(r.isearch_term) - 1
+ if b[p:p+1] != [r.isearch_term[-1]]:
+ r.isearch_next()
+
+class isearch_backspace(commands.Command):
+ def do(self):
+ r = self.reader
+ if len(r.isearch_term) > 0:
+ r.isearch_term = r.isearch_term[:-1]
+ r.dirty = 1
+ else:
+ r.error("nothing to rubout")
+
+class isearch_forwards(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_FORWARDS
+ r.isearch_next()
+
+class isearch_backwards(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_BACKWARDS
+ r.isearch_next()
+
+class isearch_end(commands.Command):
+ def do(self):
+ r = self.reader
+ r.isearch_direction = ISEARCH_DIRECTION_NONE
+ r.console.forgetinput()
+ r.pop_input_trans()
+ r.dirty = 1
+
+class HistoricalReader(R):
+ """Adds history support (with incremental history searching) to the
+ Reader class.
+
+ Adds the following instance variables:
+ * history:
+ a list of strings
+ * historyi:
+ * transient_history:
+ * next_history:
+ * isearch_direction, isearch_term, isearch_start:
+ * yank_arg_i, yank_arg_yanked:
+ used by the yank-arg command; not actually manipulated by any
+ HistoricalReader instance methods.
+ """
+
+ def collect_keymap(self):
+ return super(HistoricalReader, self).collect_keymap() + (
+ (r'\C-n', 'next-history'),
+ (r'\C-p', 'previous-history'),
+ (r'\C-o', 'operate-and-get-next'),
+ (r'\C-r', 'reverse-history-isearch'),
+ (r'\C-s', 'forward-history-isearch'),
+ (r'\M-r', 'restore-history'),
+ (r'\M-.', 'yank-arg'),
+ (r'\<page down>', 'last-history'),
+ (r'\<page up>', 'first-history'))
+
+
+ def __init__(self, console):
+ super(HistoricalReader, self).__init__(console)
+ self.history = []
+ self.historyi = 0
+ self.transient_history = {}
+ self.next_history = None
+ self.isearch_direction = ISEARCH_DIRECTION_NONE
+ for c in [next_history, previous_history, restore_history,
+ first_history, last_history, yank_arg,
+ forward_history_isearch, reverse_history_isearch,
+ isearch_end, isearch_add_character, isearch_cancel,
+ isearch_add_character, isearch_backspace,
+ isearch_forwards, isearch_backwards, operate_and_get_next]:
+ self.commands[c.__name__] = c
+ self.commands[c.__name__.replace('_', '-')] = c
+ from pyrepl import input
+ self.isearch_trans = input.KeymapTranslator(
+ isearch_keymap, invalid_cls=isearch_end,
+ character_cls=isearch_add_character)
+
+ def select_item(self, i):
+ self.transient_history[self.historyi] = self.get_unicode()
+ buf = self.transient_history.get(i)
+ if buf is None:
+ buf = self.history[i]
+ self.buffer = list(buf)
+ self.historyi = i
+ self.pos = len(self.buffer)
+ self.dirty = 1
+
+ def get_item(self, i):
+ if i <> len(self.history):
+ return self.transient_history.get(i, self.history[i])
+ else:
+ return self.transient_history.get(i, self.get_unicode())
+
+ def prepare(self):
+ super(HistoricalReader, self).prepare()
+ try:
+ self.transient_history = {}
+ if self.next_history is not None \
+ and self.next_history < len(self.history):
+ self.historyi = self.next_history
+ self.buffer[:] = list(self.history[self.next_history])
+ self.pos = len(self.buffer)
+ self.transient_history[len(self.history)] = ''
+ else:
+ self.historyi = len(self.history)
+ self.next_history = None
+ except:
+ self.restore()
+ raise
+
+ def get_prompt(self, lineno, cursor_on_line):
+ if cursor_on_line and self.isearch_direction <> ISEARCH_DIRECTION_NONE:
+ d = 'rf'[self.isearch_direction == ISEARCH_DIRECTION_FORWARDS]
+ return "(%s-search `%s') "%(d, self.isearch_term)
+ else:
+ return super(HistoricalReader, self).get_prompt(lineno, cursor_on_line)
+
+ def isearch_next(self):
+ st = self.isearch_term
+ p = self.pos
+ i = self.historyi
+ s = self.get_unicode()
+ forwards = self.isearch_direction == ISEARCH_DIRECTION_FORWARDS
+ while 1:
+ if forwards:
+ p = s.find(st, p + 1)
+ else:
+ p = s.rfind(st, 0, p + len(st) - 1)
+ if p != -1:
+ self.select_item(i)
+ self.pos = p
+ return
+ elif ((forwards and i == len(self.history) - 1)
+ or (not forwards and i == 0)):
+ self.error("not found")
+ return
+ else:
+ if forwards:
+ i += 1
+ s = self.get_item(i)
+ p = -1
+ else:
+ i -= 1
+ s = self.get_item(i)
+ p = len(s)
+
+ def finish(self):
+ super(HistoricalReader, self).finish()
+ ret = self.get_unicode()
+ for i, t in self.transient_history.items():
+ if i < len(self.history) and i != self.historyi:
+ self.history[i] = t
+ if ret:
+ self.history.append(ret)
+
+def test():
+ from pyrepl.unix_console import UnixConsole
+ reader = HistoricalReader(UnixConsole())
+ reader.ps1 = "h**> "
+ reader.ps2 = "h/*> "
+ reader.ps3 = "h|*> "
+ reader.ps4 = "h\*> "
+ while reader.readline():
+ pass
+
+if __name__=='__main__':
+ test()
diff --git a/lib_pypy/pyrepl/input.py b/lib_pypy/pyrepl/input.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/input.py
@@ -0,0 +1,97 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# (naming modules after builtin functions is not such a hot idea...)
+
+# an KeyTrans instance translates Event objects into Command objects
+
+# hmm, at what level do we want [C-i] and [tab] to be equivalent?
+# [meta-a] and [esc a]? obviously, these are going to be equivalent
+# for the UnixConsole, but should they be for PygameConsole?
+
+# it would in any situation seem to be a bad idea to bind, say, [tab]
+# and [C-i] to *different* things... but should binding one bind the
+# other?
+
+# executive, temporary decision: [tab] and [C-i] are distinct, but
+# [meta-key] is identified with [esc key]. We demand that any console
+# class does quite a lot towards emulating a unix terminal.
+
+from pyrepl import unicodedata_
+
+class InputTranslator(object):
+ def push(self, evt):
+ pass
+ def get(self):
+ pass
+ def empty(self):
+ pass
+
+class KeymapTranslator(InputTranslator):
+ def __init__(self, keymap, verbose=0,
+ invalid_cls=None, character_cls=None):
+ self.verbose = verbose
+ from pyrepl.keymap import compile_keymap, parse_keys
+ self.keymap = keymap
+ self.invalid_cls = invalid_cls
+ self.character_cls = character_cls
+ d = {}
+ for keyspec, command in keymap:
+ keyseq = tuple(parse_keys(keyspec))
+ d[keyseq] = command
+ if self.verbose:
+ print d
+ self.k = self.ck = compile_keymap(d, ())
+ self.results = []
+ self.stack = []
+ def push(self, evt):
+ if self.verbose:
+ print "pushed", evt.data,
+ key = evt.data
+ d = self.k.get(key)
+ if isinstance(d, dict):
+ if self.verbose:
+ print "transition"
+ self.stack.append(key)
+ self.k = d
+ else:
+ if d is None:
+ if self.verbose:
+ print "invalid"
+ if self.stack or len(key) > 1 or unicodedata_.category(key) == 'C':
+ self.results.append(
+ (self.invalid_cls, self.stack + [key]))
+ else:
+ # small optimization:
+ self.k[key] = self.character_cls
+ self.results.append(
+ (self.character_cls, [key]))
+ else:
+ if self.verbose:
+ print "matched", d
+ self.results.append((d, self.stack + [key]))
+ self.stack = []
+ self.k = self.ck
+ def get(self):
+ if self.results:
+ return self.results.pop(0)
+ else:
+ return None
+ def empty(self):
+ return not self.results
diff --git a/lib_pypy/pyrepl/keymap.py b/lib_pypy/pyrepl/keymap.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/keymap.py
@@ -0,0 +1,186 @@
+# Copyright 2000-2008 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+functions for parsing keyspecs
+
+Support for turning keyspecs into appropriate sequences.
+
+pyrepl uses it's own bastardized keyspec format, which is meant to be
+a strict superset of readline's \"KEYSEQ\" format (which is to say
+that if you can come up with a spec readline accepts that this
+doesn't, you've found a bug and should tell me about it).
+
+Note that this is the `\\C-o' style of readline keyspec, not the
+`Control-o' sort.
+
+A keyspec is a string representing a sequence of keypresses that can
+be bound to a command.
+
+All characters other than the backslash represent themselves. In the
+traditional manner, a backslash introduces a escape sequence.
+
+The extension to readline is that the sequence \\<KEY> denotes the
+sequence of charaters produced by hitting KEY.
+
+Examples:
+
+`a' - what you get when you hit the `a' key
+`\\EOA' - Escape - O - A (up, on my terminal)
+`\\<UP>' - the up arrow key
+`\\<up>' - ditto (keynames are case insensitive)
+`\\C-o', `\\c-o' - control-o
+`\\M-.' - meta-period
+`\\E.' - ditto (that's how meta works for pyrepl)
+`\\<tab>', `\\<TAB>', `\\t', `\\011', '\\x09', '\\X09', '\\C-i', '\\C-I'
+ - all of these are the tab character. Can you think of any more?
+"""
+
+_escapes = {
+ '\\':'\\',
+ "'":"'",
+ '"':'"',
+ 'a':'\a',
+ 'b':'\h',
+ 'e':'\033',
+ 'f':'\f',
+ 'n':'\n',
+ 'r':'\r',
+ 't':'\t',
+ 'v':'\v'
+ }
+
+_keynames = {
+ 'backspace': 'backspace',
+ 'delete': 'delete',
+ 'down': 'down',
+ 'end': 'end',
+ 'enter': '\r',
+ 'escape': '\033',
+ 'f1' : 'f1', 'f2' : 'f2', 'f3' : 'f3', 'f4' : 'f4',
+ 'f5' : 'f5', 'f6' : 'f6', 'f7' : 'f7', 'f8' : 'f8',
+ 'f9' : 'f9', 'f10': 'f10', 'f11': 'f11', 'f12': 'f12',
+ 'f13': 'f13', 'f14': 'f14', 'f15': 'f15', 'f16': 'f16',
+ 'f17': 'f17', 'f18': 'f18', 'f19': 'f19', 'f20': 'f20',
+ 'home': 'home',
+ 'insert': 'insert',
+ 'left': 'left',
+ 'page down': 'page down',
+ 'page up': 'page up',
+ 'return': '\r',
+ 'right': 'right',
+ 'space': ' ',
+ 'tab': '\t',
+ 'up': 'up',
+ }
+
+class KeySpecError(Exception):
+ pass
+
+def _parse_key1(key, s):
+ ctrl = 0
+ meta = 0
+ ret = ''
+ while not ret and s < len(key):
+ if key[s] == '\\':
+ c = key[s+1].lower()
+ if _escapes.has_key(c):
+ ret = _escapes[c]
+ s += 2
+ elif c == "c":
+ if key[s + 2] != '-':
+ raise KeySpecError, \
+ "\\C must be followed by `-' (char %d of %s)"%(
+ s + 2, repr(key))
+ if ctrl:
+ raise KeySpecError, "doubled \\C- (char %d of %s)"%(
+ s + 1, repr(key))
+ ctrl = 1
+ s += 3
+ elif c == "m":
+ if key[s + 2] != '-':
+ raise KeySpecError, \
+ "\\M must be followed by `-' (char %d of %s)"%(
+ s + 2, repr(key))
+ if meta:
+ raise KeySpecError, "doubled \\M- (char %d of %s)"%(
+ s + 1, repr(key))
+ meta = 1
+ s += 3
+ elif c.isdigit():
+ n = key[s+1:s+4]
+ ret = chr(int(n, 8))
+ s += 4
+ elif c == 'x':
+ n = key[s+2:s+4]
+ ret = chr(int(n, 16))
+ s += 4
+ elif c == '<':
+ t = key.find('>', s)
+ if t == -1:
+ raise KeySpecError, \
+ "unterminated \\< starting at char %d of %s"%(
+ s + 1, repr(key))
+ ret = key[s+2:t].lower()
+ if ret not in _keynames:
+ raise KeySpecError, \
+ "unrecognised keyname `%s' at char %d of %s"%(
+ ret, s + 2, repr(key))
+ ret = _keynames[ret]
+ s = t + 1
+ else:
+ raise KeySpecError, \
+ "unknown backslash escape %s at char %d of %s"%(
+ `c`, s + 2, repr(key))
+ else:
+ ret = key[s]
+ s += 1
+ if ctrl:
+ if len(ret) > 1:
+ raise KeySpecError, "\\C- must be followed by a character"
+ ret = chr(ord(ret) & 0x1f) # curses.ascii.ctrl()
+ if meta:
+ ret = ['\033', ret]
+ else:
+ ret = [ret]
+ return ret, s
+
+def parse_keys(key):
+ s = 0
+ r = []
+ while s < len(key):
+ k, s = _parse_key1(key, s)
+ r.extend(k)
+ return r
+
+def compile_keymap(keymap, empty=''):
+ r = {}
+ for key, value in keymap.items():
+ r.setdefault(key[0], {})[key[1:]] = value
+ for key, value in r.items():
+ if empty in value:
+ if len(value) <> 1:
+ raise KeySpecError, \
+ "key definitions for %s clash"%(value.values(),)
+ else:
+ r[key] = value[empty]
+ else:
+ r[key] = compile_keymap(value, empty)
+ return r
diff --git a/lib_pypy/pyrepl/keymaps.py b/lib_pypy/pyrepl/keymaps.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/keymaps.py
@@ -0,0 +1,140 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+reader_emacs_keymap = tuple(
+ [(r'\C-a', 'beginning-of-line'),
+ (r'\C-b', 'left'),
+ (r'\C-c', 'interrupt'),
+ (r'\C-d', 'delete'),
+ (r'\C-e', 'end-of-line'),
+ (r'\C-f', 'right'),
+ (r'\C-g', 'cancel'),
+ (r'\C-h', 'backspace'),
+ (r'\C-j', 'self-insert'),
+ (r'\<return>', 'accept'),
+ (r'\C-k', 'kill-line'),
+ (r'\C-l', 'clear-screen'),
+# (r'\C-m', 'accept'),
+ (r'\C-q', 'quoted-insert'),
+ (r'\C-t', 'transpose-characters'),
+ (r'\C-u', 'unix-line-discard'),
+ (r'\C-v', 'quoted-insert'),
+ (r'\C-w', 'unix-word-rubout'),
+ (r'\C-x\C-u', 'upcase-region'),
+ (r'\C-y', 'yank'),
+ (r'\C-z', 'suspend'),
+
+ (r'\M-b', 'backward-word'),
+ (r'\M-c', 'capitalize-word'),
+ (r'\M-d', 'kill-word'),
+ (r'\M-f', 'forward-word'),
+ (r'\M-l', 'downcase-word'),
+ (r'\M-t', 'transpose-words'),
+ (r'\M-u', 'upcase-word'),
+ (r'\M-y', 'yank-pop'),
+ (r'\M--', 'digit-arg'),
+ (r'\M-0', 'digit-arg'),
+ (r'\M-1', 'digit-arg'),
+ (r'\M-2', 'digit-arg'),
+ (r'\M-3', 'digit-arg'),
+ (r'\M-4', 'digit-arg'),
+ (r'\M-5', 'digit-arg'),
+ (r'\M-6', 'digit-arg'),
+ (r'\M-7', 'digit-arg'),
+ (r'\M-8', 'digit-arg'),
+ (r'\M-9', 'digit-arg'),
+ (r'\M-\n', 'self-insert'),
+ (r'\<backslash>', 'self-insert')] + \
+ [(c, 'self-insert')
+ for c in map(chr, range(32, 127)) if c <> '\\'] + \
+ [(c, 'self-insert')
+ for c in map(chr, range(128, 256)) if c.isalpha()] + \
+ [(r'\<up>', 'up'),
+ (r'\<down>', 'down'),
+ (r'\<left>', 'left'),
+ (r'\<right>', 'right'),
+ (r'\<insert>', 'quoted-insert'),
+ (r'\<delete>', 'delete'),
+ (r'\<backspace>', 'backspace'),
+ (r'\M-\<backspace>', 'backward-kill-word'),
+ (r'\<end>', 'end'),
+ (r'\<home>', 'home'),
+ (r'\<f1>', 'help'),
+ (r'\EOF', 'end'), # the entries in the terminfo database for xterms
+ (r'\EOH', 'home'), # seem to be wrong. this is a less than ideal
+ # workaround
+ ])
+
+hist_emacs_keymap = reader_emacs_keymap + (
+ (r'\C-n', 'next-history'),
+ (r'\C-p', 'previous-history'),
+ (r'\C-o', 'operate-and-get-next'),
+ (r'\C-r', 'reverse-history-isearch'),
+ (r'\C-s', 'forward-history-isearch'),
+ (r'\M-r', 'restore-history'),
+ (r'\M-.', 'yank-arg'),
+ (r'\<page down>', 'last-history'),
+ (r'\<page up>', 'first-history'))
+
+comp_emacs_keymap = hist_emacs_keymap + (
+ (r'\t', 'complete'),)
+
+python_emacs_keymap = comp_emacs_keymap + (
+ (r'\n', 'maybe-accept'),
+ (r'\M-\n', 'self-insert'))
+
+reader_vi_insert_keymap = tuple(
+ [(c, 'self-insert')
+ for c in map(chr, range(32, 127)) if c <> '\\'] + \
+ [(c, 'self-insert')
+ for c in map(chr, range(128, 256)) if c.isalpha()] + \
+ [(r'\C-d', 'delete'),
+ (r'\<backspace>', 'backspace'),
+ ('')])
+
+reader_vi_command_keymap = tuple(
+ [
+ ('E', 'enter-emacs-mode'),
+ ('R', 'enter-replace-mode'),
+ ('dw', 'delete-word'),
+ ('dd', 'delete-line'),
+
+ ('h', 'left'),
+ ('i', 'enter-insert-mode'),
+ ('j', 'down'),
+ ('k', 'up'),
+ ('l', 'right'),
+ ('r', 'replace-char'),
+ ('w', 'forward-word'),
+ ('x', 'delete'),
+ ('.', 'repeat-edit'), # argh!
+ (r'\<insert>', 'enter-insert-mode'),
+ ] +
+ [(c, 'digit-arg') for c in '01234567689'] +
+ [])
+
+
+reader_keymaps = {
+ 'emacs' : reader_emacs_keymap,
+ 'vi-insert' : reader_vi_insert_keymap,
+ 'vi-command' : reader_vi_command_keymap
+ }
+
+del c # from the listcomps
+
diff --git a/lib_pypy/pyrepl/module_lister.py b/lib_pypy/pyrepl/module_lister.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/module_lister.py
@@ -0,0 +1,70 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl.completing_reader import uniqify
+import os, sys
+
+# for the completion support.
+# this is all quite nastily written.
+_packages = {}
+
+def _make_module_list_dir(dir, suffs, prefix=''):
+ l = []
+ for fname in os.listdir(dir):
+ file = os.path.join(dir, fname)
+ if os.path.isfile(file):
+ for suff in suffs:
+ if fname.endswith(suff):
+ l.append( prefix + fname[:-len(suff)] )
+ break
+ elif os.path.isdir(file) \
+ and os.path.exists(os.path.join(file, "__init__.py")):
+ l.append( prefix + fname )
+ _packages[prefix + fname] = _make_module_list_dir(
+ file, suffs, prefix + fname + '.' )
+ l = uniqify(l)
+ l.sort()
+ return l
+
+def _make_module_list():
+ import imp
+ suffs = [x[0] for x in imp.get_suffixes() if x[0] != '.pyc']
+ def compare(x, y):
+ c = -cmp(len(x), len(y))
+ if c:
+ return c
+ else:
+ return -cmp(x, y)
+ suffs.sort(compare)
+ _packages[''] = list(sys.builtin_module_names)
+ for dir in sys.path:
+ if dir == '':
+ dir = '.'
+ if os.path.isdir(dir):
+ _packages[''] += _make_module_list_dir(dir, suffs)
+ _packages[''].sort()
+
+def find_modules(stem):
+ l = stem.split('.')
+ pack = '.'.join(l[:-1])
+ try:
+ mods = _packages[pack]
+ except KeyError:
+ raise ImportError, "can't find \"%s\" package"%pack
+ return [mod for mod in mods if mod.startswith(stem)]
diff --git a/lib_pypy/pyrepl/pygame_console.py b/lib_pypy/pyrepl/pygame_console.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/pygame_console.py
@@ -0,0 +1,353 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# the pygame console is currently thoroughly broken.
+
+# there's a fundamental difference from the UnixConsole: here we're
+# the terminal emulator too, in effect. This means, e.g., for pythoni
+# we really need a separate process (or thread) to monitor for ^C
+# during command execution and zap the executor process. Making this
+# work on non-Unix is expected to be even more entertaining.
+
+from pygame.locals import *
+from pyrepl.console import Console, Event
+from pyrepl import pygame_keymap
+import pygame
+import types
+
+lmargin = 5
+rmargin = 5
+tmargin = 5
+bmargin = 5
+
+try:
+ bool
+except NameError:
+ def bool(x):
+ return not not x
+
+modcolors = {K_LCTRL:1,
+ K_RCTRL:1,
+ K_LMETA:1,
+ K_RMETA:1,
+ K_LALT:1,
+ K_RALT:1,
+ K_LSHIFT:1,
+ K_RSHIFT:1}
+
+class colors:
+ fg = 250,240,230
+ bg = 5, 5, 5
+ cursor = 230, 0, 230
+ margin = 5, 5, 15
+
+class FakeStdout:
+ def __init__(self, con):
+ self.con = con
+ def write(self, text):
+ self.con.write(text)
+ def flush(self):
+ pass
+
+class FakeStdin:
+ def __init__(self, con):
+ self.con = con
+ def read(self, n=None):
+ # argh!
+ raise NotImplementedError
+ def readline(self, n=None):
+ from reader import Reader
+ try:
+ # this isn't quite right: it will clobber any prompt that's
+ # been printed. Not sure how to get around this...
+ return Reader(self.con).readline()
+ except EOFError:
+ return ''
+
+class PyGameConsole(Console):
+ """Attributes:
+
+ (keymap),
+ (fd),
+ screen,
+ height,
+ width,
+ """
+
+ def __init__(self):
+ self.pygame_screen = pygame.display.set_mode((800, 600))
+ pygame.font.init()
+ pygame.key.set_repeat(500, 30)
+ self.font = pygame.font.Font(
+ "/usr/X11R6/lib/X11/fonts/TTF/luximr.ttf", 15)
+ self.fw, self.fh = self.fontsize = self.font.size("X")
+ self.cursor = pygame.Surface(self.fontsize)
+ self.cursor.fill(colors.cursor)
+ self.clear()
+ self.curs_vis = 1
+ self.height, self.width = self.getheightwidth()
+ pygame.display.update()
+ pygame.event.set_allowed(None)
+ pygame.event.set_allowed(KEYDOWN)
+
+ def install_keymap(self, keymap):
+ """Install a given keymap.
+
+ keymap is a tuple of 2-element tuples; each small tuple is a
+ pair (keyspec, event-name). The format for keyspec is
+ modelled on that used by readline (so read that manual for
+ now!)."""
+ self.k = self.keymap = pygame_keymap.compile_keymap(keymap)
+
+ def char_rect(self, x, y):
+ return self.char_pos(x, y), self.fontsize
+
+ def char_pos(self, x, y):
+ return (lmargin + x*self.fw,
+ tmargin + y*self.fh + self.cur_top + self.scroll)
+
+ def paint_margin(self):
+ s = self.pygame_screen
+ c = colors.margin
+ s.fill(c, [0, 0, 800, tmargin])
+ s.fill(c, [0, 0, lmargin, 600])
+ s.fill(c, [0, 600 - bmargin, 800, bmargin])
+ s.fill(c, [800 - rmargin, 0, lmargin, 600])
+
+ def refresh(self, screen, (cx, cy)):
+ self.screen = screen
+ self.pygame_screen.fill(colors.bg,
+ [0, tmargin + self.cur_top + self.scroll,
+ 800, 600])
+ self.paint_margin()
+
+ line_top = self.cur_top
+ width, height = self.fontsize
+ self.cxy = (cx, cy)
+ cp = self.char_pos(cx, cy)
+ if cp[1] < tmargin:
+ self.scroll = - (cy*self.fh + self.cur_top)
+ self.repaint()
+ elif cp[1] + self.fh > 600 - bmargin:
+ self.scroll += (600 - bmargin) - (cp[1] + self.fh)
+ self.repaint()
+ if self.curs_vis:
+ self.pygame_screen.blit(self.cursor, self.char_pos(cx, cy))
+ for line in screen:
+ if 0 <= line_top + self.scroll <= (600 - bmargin - tmargin - self.fh):
+ if line:
+ ren = self.font.render(line, 1, colors.fg)
+ self.pygame_screen.blit(ren, (lmargin,
+ tmargin + line_top + self.scroll))
+ line_top += self.fh
+ pygame.display.update()
+
+ def prepare(self):
+ self.cmd_buf = ''
+ self.k = self.keymap
+ self.height, self.width = self.getheightwidth()
+ self.curs_vis = 1
+ self.cur_top = self.pos[0]
+ self.event_queue = []
+
+ def restore(self):
+ pass
+
+ def blit_a_char(self, linen, charn):
+ line = self.screen[linen]
+ if charn < len(line):
+ text = self.font.render(line[charn], 1, colors.fg)
+ self.pygame_screen.blit(text, self.char_pos(charn, linen))
+
+ def move_cursor(self, x, y):
+ cp = self.char_pos(x, y)
+ if cp[1] < tmargin or cp[1] + self.fh > 600 - bmargin:
+ self.event_queue.append(Event('refresh', '', ''))
+ else:
+ if self.curs_vis:
+ cx, cy = self.cxy
+ self.pygame_screen.fill(colors.bg, self.char_rect(cx, cy))
+ self.blit_a_char(cy, cx)
+ self.pygame_screen.blit(self.cursor, cp)
+ self.blit_a_char(y, x)
+ pygame.display.update()
+ self.cxy = (x, y)
+
+ def set_cursor_vis(self, vis):
+ self.curs_vis = vis
+ if vis:
+ self.move_cursor(*self.cxy)
+ else:
+ cx, cy = self.cxy
+ self.pygame_screen.fill(colors.bg, self.char_rect(cx, cy))
+ self.blit_a_char(cy, cx)
+ pygame.display.update()
+
+ def getheightwidth(self):
+ """Return (height, width) where height and width are the height
+ and width of the terminal window in characters."""
+ return ((600 - tmargin - bmargin)/self.fh,
+ (800 - lmargin - rmargin)/self.fw)
+
+ def tr_event(self, pyg_event):
+ shift = bool(pyg_event.mod & KMOD_SHIFT)
+ ctrl = bool(pyg_event.mod & KMOD_CTRL)
+ meta = bool(pyg_event.mod & (KMOD_ALT|KMOD_META))
+
+ try:
+ return self.k[(pyg_event.unicode, meta, ctrl)], pyg_event.unicode
+ except KeyError:
+ try:
+ return self.k[(pyg_event.key, meta, ctrl)], pyg_event.unicode
+ except KeyError:
+ return "invalid-key", pyg_event.unicode
+
+ def get_event(self, block=1):
+ """Return an Event instance. Returns None if |block| is false
+ and there is no event pending, otherwise waits for the
+ completion of an event."""
+ while 1:
+ if self.event_queue:
+ return self.event_queue.pop(0)
+ elif block:
+ pyg_event = pygame.event.wait()
+ else:
+ pyg_event = pygame.event.poll()
+ if pyg_event.type == NOEVENT:
+ return
+
+ if pyg_event.key in modcolors:
+ continue
+
+ k, c = self.tr_event(pyg_event)
+ self.cmd_buf += c.encode('ascii', 'replace')
+ self.k = k
+
+ if not isinstance(k, types.DictType):
+ e = Event(k, self.cmd_buf, [])
+ self.k = self.keymap
+ self.cmd_buf = ''
+ return e
+
+ def beep(self):
+ # uhh, can't be bothered now.
+ # pygame.sound.something, I guess.
+ pass
+
+ def clear(self):
+ """Wipe the screen"""
+ self.pygame_screen.fill(colors.bg)
+ #self.screen = []
+ self.pos = [0, 0]
+ self.grobs = []
+ self.cur_top = 0
+ self.scroll = 0
+
+ def finish(self):
+ """Move the cursor to the end of the display and otherwise get
+ ready for end. XXX could be merged with restore? Hmm."""
+ if self.curs_vis:
+ cx, cy = self.cxy
+ self.pygame_screen.fill(colors.bg, self.char_rect(cx, cy))
+ self.blit_a_char(cy, cx)
+ for line in self.screen:
+ self.write_line(line, 1)
+ if self.curs_vis:
+ self.pygame_screen.blit(self.cursor,
+ (lmargin + self.pos[1],
+ tmargin + self.pos[0] + self.scroll))
+ pygame.display.update()
+
+ def flushoutput(self):
+ """Flush all output to the screen (assuming there's some
+ buffering going on somewhere)"""
+ # no buffering here, ma'am (though perhaps there should be!)
+ pass
+
+ def forgetinput(self):
+ """Forget all pending, but not yet processed input."""
+ while pygame.event.poll().type <> NOEVENT:
+ pass
+
+ def getpending(self):
+ """Return the characters that have been typed but not yet
+ processed."""
+ events = []
+ while 1:
+ event = pygame.event.poll()
+ if event.type == NOEVENT:
+ break
+ events.append(event)
+
+ return events
+
+ def wait(self):
+ """Wait for an event."""
+ raise Exception, "erp!"
+
+ def repaint(self):
+ # perhaps we should consolidate grobs?
+ self.pygame_screen.fill(colors.bg)
+ self.paint_margin()
+ for (y, x), surf, text in self.grobs:
+ if surf and 0 < y + self.scroll:
+ self.pygame_screen.blit(surf, (lmargin + x,
+ tmargin + y + self.scroll))
+ pygame.display.update()
+
+ def write_line(self, line, ret):
+ charsleft = (self.width*self.fw - self.pos[1])/self.fw
+ while len(line) > charsleft:
+ self.write_line(line[:charsleft], 1)
+ line = line[charsleft:]
+ if line:
+ ren = self.font.render(line, 1, colors.fg, colors.bg)
+ self.grobs.append((self.pos[:], ren, line))
+ self.pygame_screen.blit(ren,
+ (lmargin + self.pos[1],
+ tmargin + self.pos[0] + self.scroll))
+ else:
+ self.grobs.append((self.pos[:], None, line))
+ if ret:
+ self.pos[0] += self.fh
+ if tmargin + self.pos[0] + self.scroll + self.fh > 600 - bmargin:
+ self.scroll = 600 - bmargin - self.pos[0] - self.fh - tmargin
+ self.repaint()
+ self.pos[1] = 0
+ else:
+ self.pos[1] += self.fw*len(line)
+
+ def write(self, text):
+ lines = text.split("\n")
+ if self.curs_vis:
+ self.pygame_screen.fill(colors.bg,
+ (lmargin + self.pos[1],
+ tmargin + self.pos[0] + self.scroll,
+ self.fw, self.fh))
+ for line in lines[:-1]:
+ self.write_line(line, 1)
+ self.write_line(lines[-1], 0)
+ if self.curs_vis:
+ self.pygame_screen.blit(self.cursor,
+ (lmargin + self.pos[1],
+ tmargin + self.pos[0] + self.scroll))
+ pygame.display.update()
+
+ def flush(self):
+ pass
diff --git a/lib_pypy/pyrepl/pygame_keymap.py b/lib_pypy/pyrepl/pygame_keymap.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/pygame_keymap.py
@@ -0,0 +1,250 @@
+# Copyright 2000-2008 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# keyspec parsing for a pygame console. currently this is simply copy
+# n' change from the unix (ie. trad terminal) variant; probably some
+# refactoring will happen when I work out how it will work best.
+
+# A key is represented as *either*
+
+# a) a (keycode, meta, ctrl) sequence (used for special keys such as
+# f1, the up arrow key, etc)
+# b) a (unichar, meta, ctrl) sequence (used for printable chars)
+
+# Because we allow keystokes like '\\C-xu', I'll use the same trick as
+# the unix keymap module uses.
+
+# '\\C-a' --> (K_a, 0, 1)
+
+# XXX it's actually possible to test this module, so it should have a
+# XXX test suite.
+
+from pygame.locals import *
+
+_escapes = {
+ '\\': K_BACKSLASH,
+ "'" : K_QUOTE,
+ '"' : K_QUOTEDBL,
+# 'a' : '\a',
+ 'b' : K_BACKSLASH,
+ 'e' : K_ESCAPE,
+# 'f' : '\f',
+ 'n' : K_RETURN,
+ 'r' : K_RETURN,
+ 't' : K_TAB,
+# 'v' : '\v'
+ }
+
+_keynames = {
+ 'backspace' : K_BACKSPACE,
+ 'delete' : K_DELETE,
+ 'down' : K_DOWN,
+ 'end' : K_END,
+ 'enter' : K_KP_ENTER,
+ 'escape' : K_ESCAPE,
+ 'f1' : K_F1, 'f2' : K_F2, 'f3' : K_F3, 'f4' : K_F4,
+ 'f5' : K_F5, 'f6' : K_F6, 'f7' : K_F7, 'f8' : K_F8,
+ 'f9' : K_F9, 'f10': K_F10,'f11': K_F11,'f12': K_F12,
+ 'f13': K_F13,'f14': K_F14,'f15': K_F15,
+ 'home' : K_HOME,
+ 'insert' : K_INSERT,
+ 'left' : K_LEFT,
+ 'pgdown' : K_PAGEDOWN, 'page down' : K_PAGEDOWN,
+ 'pgup' : K_PAGEUP, 'page up' : K_PAGEUP,
+ 'return' : K_RETURN,
+ 'right' : K_RIGHT,
+ 'space' : K_SPACE,
+ 'tab' : K_TAB,
+ 'up' : K_UP,
+ }
+
+class KeySpecError(Exception):
+ pass
+
+def _parse_key1(key, s):
+ ctrl = 0
+ meta = 0
+ ret = ''
+ while not ret and s < len(key):
+ if key[s] == '\\':
+ c = key[s+1].lower()
+ if _escapes.has_key(c):
+ ret = _escapes[c]
+ s += 2
+ elif c == "c":
+ if key[s + 2] != '-':
+ raise KeySpecError, \
+ "\\C must be followed by `-' (char %d of %s)"%(
+ s + 2, repr(key))
+ if ctrl:
+ raise KeySpecError, "doubled \\C- (char %d of %s)"%(
+ s + 1, repr(key))
+ ctrl = 1
+ s += 3
+ elif c == "m":
+ if key[s + 2] != '-':
+ raise KeySpecError, \
+ "\\M must be followed by `-' (char %d of %s)"%(
+ s + 2, repr(key))
+ if meta:
+ raise KeySpecError, "doubled \\M- (char %d of %s)"%(
+ s + 1, repr(key))
+ meta = 1
+ s += 3
+ elif c.isdigit():
+ n = key[s+1:s+4]
+ ret = chr(int(n, 8))
+ s += 4
+ elif c == 'x':
+ n = key[s+2:s+4]
+ ret = chr(int(n, 16))
+ s += 4
+ elif c == '<':
+ t = key.find('>', s)
+ if t == -1:
+ raise KeySpecError, \
+ "unterminated \\< starting at char %d of %s"%(
+ s + 1, repr(key))
+ try:
+ ret = _keynames[key[s+2:t].lower()]
+ s = t + 1
+ except KeyError:
+ raise KeySpecError, \
+ "unrecognised keyname `%s' at char %d of %s"%(
+ key[s+2:t], s + 2, repr(key))
+ if ret is None:
+ return None, s
+ else:
+ raise KeySpecError, \
+ "unknown backslash escape %s at char %d of %s"%(
+ `c`, s + 2, repr(key))
+ else:
+ if ctrl:
+ ret = chr(ord(key[s]) & 0x1f) # curses.ascii.ctrl()
+ ret = unicode(ret)
+ else:
+ ret = unicode(key[s])
+ s += 1
+ return (ret, meta, ctrl), s
+
+def parse_keys(key):
+ s = 0
+ r = []
+ while s < len(key):
+ k, s = _parse_key1(key, s)
+ if k is None:
+ return None
+ r.append(k)
+ return tuple(r)
+
+def _compile_keymap(keymap):
+ r = {}
+ for key, value in keymap.items():
+ r.setdefault(key[0], {})[key[1:]] = value
+ for key, value in r.items():
+ if value.has_key(()):
+ if len(value) <> 1:
+ raise KeySpecError, \
+ "key definitions for %s clash"%(value.values(),)
+ else:
+ r[key] = value[()]
+ else:
+ r[key] = _compile_keymap(value)
+ return r
+
+def compile_keymap(keymap):
+ r = {}
+ for key, value in keymap:
+ k = parse_keys(key)
+ if value is None and r.has_key(k):
+ del r[k]
+ if k is not None:
+ r[k] = value
+ return _compile_keymap(r)
+
+def keyname(key):
+ longest_match = ''
+ longest_match_name = ''
+ for name, keyseq in keyset.items():
+ if keyseq and key.startswith(keyseq) and \
+ len(keyseq) > len(longest_match):
+ longest_match = keyseq
+ longest_match_name = name
+ if len(longest_match) > 0:
+ return longest_match_name, len(longest_match)
+ else:
+ return None, 0
+
+_unescapes = {'\r':'\\r', '\n':'\\n', '\177':'^?'}
+
+#for k,v in _escapes.items():
+# _unescapes[v] = k
+
+def unparse_key(keyseq):
+ if not keyseq:
+ return ''
+ name, s = keyname(keyseq)
+ if name:
+ if name <> 'escape' or s == len(keyseq):
+ return '\\<' + name + '>' + unparse_key(keyseq[s:])
+ else:
+ return '\\M-' + unparse_key(keyseq[1:])
+ else:
+ c = keyseq[0]
+ r = keyseq[1:]
+ if c == '\\':
+ p = '\\\\'
+ elif _unescapes.has_key(c):
+ p = _unescapes[c]
+ elif ord(c) < ord(' '):
+ p = '\\C-%s'%(chr(ord(c)+96),)
+ elif ord(' ') <= ord(c) <= ord('~'):
+ p = c
+ else:
+ p = '\\%03o'%(ord(c),)
+ return p + unparse_key(r)
+
+def _unparse_keyf(keyseq):
+ if not keyseq:
+ return []
+ name, s = keyname(keyseq)
+ if name:
+ if name <> 'escape' or s == len(keyseq):
+ return [name] + _unparse_keyf(keyseq[s:])
+ else:
+ rest = _unparse_keyf(keyseq[1:])
+ return ['M-'+rest[0]] + rest[1:]
+ else:
+ c = keyseq[0]
+ r = keyseq[1:]
+ if c == '\\':
+ p = '\\'
+ elif _unescapes.has_key(c):
+ p = _unescapes[c]
+ elif ord(c) < ord(' '):
+ p = 'C-%s'%(chr(ord(c)+96),)
+ elif ord(' ') <= ord(c) <= ord('~'):
+ p = c
+ else:
+ p = '\\%03o'%(ord(c),)
+ return [p] + _unparse_keyf(r)
+
+def unparse_keyf(keyseq):
+ return " ".join(_unparse_keyf(keyseq))
diff --git a/lib_pypy/pyrepl/python_reader.py b/lib_pypy/pyrepl/python_reader.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/python_reader.py
@@ -0,0 +1,392 @@
+# Copyright 2000-2007 Michael Hudson-Doyle <micahel at gmail.com>
+# Bob Ippolito
+# Maciek Fijalkowski
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# one impressive collections of imports:
+from pyrepl.completing_reader import CompletingReader
+from pyrepl.historical_reader import HistoricalReader
+from pyrepl import completing_reader, reader
+from pyrepl import copy_code, commands, completer
+from pyrepl import module_lister
+import new, sys, os, re, code, traceback
+import atexit, warnings
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+try:
+ import imp
+ imp.find_module("twisted")
+ from twisted.internet import reactor
+ from twisted.internet.abstract import FileDescriptor
+except ImportError:
+ default_interactmethod = "interact"
+else:
+ default_interactmethod = "twistedinteract"
+
+CommandCompiler = code.CommandCompiler
+
+def eat_it(*args):
+ """this function eats warnings, if you were wondering"""
+ pass
+
+class maybe_accept(commands.Command):
+ def do(self):
+ r = self.reader
+ text = r.get_unicode()
+ try:
+ # ooh, look at the hack:
+ code = r.compiler("#coding:utf-8\n"+text.encode('utf-8'))
+ except (OverflowError, SyntaxError, ValueError):
+ self.finish = 1
+ else:
+ if code is None:
+ r.insert("\n")
+ else:
+ self.finish = 1
+
+from_line_prog = re.compile(
+ "^from\s+(?P<mod>[A-Za-z_.0-9]*)\s+import\s+(?P<name>[A-Za-z_.0-9]*)")
+import_line_prog = re.compile(
+ "^(?:import|from)\s+(?P<mod>[A-Za-z_.0-9]*)\s*$")
+
+def mk_saver(reader):
+ def saver(reader=reader):
+ try:
+ file = open(os.path.expanduser("~/.pythoni.hist"), "w")
+ except IOError:
+ pass
+ else:
+ pickle.dump(reader.history, file)
+ file.close()
+ return saver
+
+class PythonicReader(CompletingReader, HistoricalReader):
+ def collect_keymap(self):
+ return super(PythonicReader, self).collect_keymap() + (
+ (r'\n', 'maybe-accept'),
+ (r'\M-\n', 'insert-nl'))
+
+ def __init__(self, console, locals,
+ compiler=None):
+ super(PythonicReader, self).__init__(console)
+ self.completer = completer.Completer(locals)
+ st = self.syntax_table
+ for c in "._0123456789":
+ st[c] = reader.SYNTAX_WORD
+ self.locals = locals
+ if compiler is None:
+ self.compiler = CommandCompiler()
+ else:
+ self.compiler = compiler
+ try:
+ file = open(os.path.expanduser("~/.pythoni.hist"))
+ except IOError:
+ pass
+ else:
+ try:
+ self.history = pickle.load(file)
+ except:
+ self.history = []
+ self.historyi = len(self.history)
+ file.close()
+ atexit.register(mk_saver(self))
+ for c in [maybe_accept]:
+ self.commands[c.__name__] = c
+ self.commands[c.__name__.replace('_', '-')] = c
+
+ def get_completions(self, stem):
+ b = self.get_unicode()
+ m = import_line_prog.match(b)
+ if m:
+ if not self._module_list_ready:
+ module_lister._make_module_list()
+ self._module_list_ready = True
+
+ mod = m.group("mod")
+ try:
+ return module_lister.find_modules(mod)
+ except ImportError:
+ pass
+ m = from_line_prog.match(b)
+ if m:
+ mod, name = m.group("mod", "name")
+ try:
+ l = module_lister._packages[mod]
+ except KeyError:
+ try:
+ mod = __import__(mod, self.locals, self.locals, [''])
+ return [x for x in dir(mod) if x.startswith(name)]
+ except ImportError:
+ pass
+ else:
+ return [x[len(mod) + 1:]
+ for x in l if x.startswith(mod + '.' + name)]
+ try:
+ l = completing_reader.uniqify(self.completer.complete(stem))
+ return l
+ except (NameError, AttributeError):
+ return []
+
+class ReaderConsole(code.InteractiveInterpreter):
+ II_init = code.InteractiveInterpreter.__init__
+ def __init__(self, console, locals=None):
+ if locals is None:
+ locals = {}
+ self.II_init(locals)
+ self.compiler = CommandCompiler()
+ self.compile = self.compiler.compiler
+ self.reader = PythonicReader(console, locals, self.compiler)
+ locals['Reader'] = self.reader
+
+ def run_user_init_file(self):
+ for key in "PYREPLSTARTUP", "PYTHONSTARTUP":
+ initfile = os.environ.get(key)
+ if initfile is not None and os.path.exists(initfile):
+ break
+ else:
+ return
+ try:
+ execfile(initfile, self.locals, self.locals)
+ except:
+ etype, value, tb = sys.exc_info()
+ traceback.print_exception(etype, value, tb.tb_next)
+
+ def execute(self, text):
+ try:
+ # ooh, look at the hack:
+ code = self.compile("# coding:utf8\n"+text.encode('utf-8'),
+ '<input>', 'single')
+ except (OverflowError, SyntaxError, ValueError):
+ self.showsyntaxerror("<input>")
+ else:
+ self.runcode(code)
+ sys.stdout.flush()
+
+ def interact(self):
+ while 1:
+ try: # catches EOFError's and KeyboardInterrupts during execution
+ try: # catches KeyboardInterrupts during editing
+ try: # warning saver
+ # can't have warnings spewed onto terminal
+ sv = warnings.showwarning
+ warnings.showwarning = eat_it
+ l = unicode(self.reader.readline(), 'utf-8')
+ finally:
+ warnings.showwarning = sv
+ except KeyboardInterrupt:
+ print "KeyboardInterrupt"
+ else:
+ if l:
+ self.execute(l)
+ except EOFError:
+ break
+ except KeyboardInterrupt:
+ continue
+
+ def prepare(self):
+ self.sv_sw = warnings.showwarning
+ warnings.showwarning = eat_it
+ self.reader.prepare()
+ self.reader.refresh() # we want :after methods...
+
+ def restore(self):
+ self.reader.restore()
+ warnings.showwarning = self.sv_sw
+
+ def handle1(self, block=1):
+ try:
+ r = 1
+ r = self.reader.handle1(block)
+ except KeyboardInterrupt:
+ self.restore()
+ print "KeyboardInterrupt"
+ self.prepare()
+ else:
+ if self.reader.finished:
+ text = self.reader.get_unicode()
+ self.restore()
+ if text:
+ self.execute(text)
+ self.prepare()
+ return r
+
+ def tkfilehandler(self, file, mask):
+ try:
+ self.handle1(block=0)
+ except:
+ self.exc_info = sys.exc_info()
+
+ # how the <expletive> do you get this to work on Windows (without
+ # createfilehandler)? threads, I guess
+ def really_tkinteract(self):
+ import _tkinter
+ _tkinter.createfilehandler(
+ self.reader.console.input_fd, _tkinter.READABLE,
+ self.tkfilehandler)
+
+ self.exc_info = None
+ while 1:
+ # dooneevent will return 0 without blocking if there are
+ # no Tk windows, 1 after blocking until an event otherwise
+ # so the following does what we want (this wasn't expected
+ # to be obvious).
+ if not _tkinter.dooneevent(_tkinter.ALL_EVENTS):
+ self.handle1(block=1)
+ if self.exc_info:
+ type, value, tb = self.exc_info
+ self.exc_info = None
+ raise type, value, tb
+
+ def tkinteract(self):
+ """Run a Tk-aware Python interactive session.
+
+ This function simulates the Python top-level in a way that
+ allows Tk's mainloop to run."""
+
+ # attempting to understand the control flow of this function
+ # without help may cause internal injuries. so, some
+ # explanation.
+
+ # The outer while loop is there to restart the interaction if
+ # the user types control-c when execution is deep in our
+ # innards. I'm not sure this can't leave internals in an
+ # inconsistent state, but it's a good start.
+
+ # then the inside loop keeps calling self.handle1 until
+ # _tkinter gets imported; then control shifts to
+ # self.really_tkinteract, above.
+
+ # this function can only return via an exception; we mask
+ # EOFErrors (but they end the interaction) and
+ # KeyboardInterrupts cause a restart. All other exceptions
+ # are likely bugs in pyrepl (well, 'cept for SystemExit, of
+ # course).
+
+ while 1:
+ try:
+ try:
+ self.prepare()
+ try:
+ while 1:
+ if sys.modules.has_key("_tkinter"):
+ self.really_tkinteract()
+ # really_tkinteract is not expected to
+ # return except via an exception, but:
+ break
+ self.handle1()
+ except EOFError:
+ pass
+ finally:
+ self.restore()
+ except KeyboardInterrupt:
+ continue
+ else:
+ break
+
+ def twistedinteract(self):
+ from twisted.internet import reactor
+ from twisted.internet.abstract import FileDescriptor
+ import signal
+ outerself = self
+ class Me(FileDescriptor):
+ def fileno(self):
+ """ We want to select on FD 0 """
+ return 0
+
+ def doRead(self):
+ """called when input is ready"""
+ try:
+ outerself.handle1()
+ except EOFError:
+ reactor.stop()
+
+ reactor.addReader(Me())
+ reactor.callWhenRunning(signal.signal,
+ signal.SIGINT,
+ signal.default_int_handler)
+ self.prepare()
+ try:
+ reactor.run()
+ finally:
+ self.restore()
+
+
+ def cocoainteract(self, inputfilehandle=None, outputfilehandle=None):
+ # only call this when there's a run loop already going!
+ # note that unlike the other *interact methods, this returns immediately
+ from cocoasupport import CocoaInteracter
+ self.cocoainteracter = CocoaInteracter.alloc().init(self, inputfilehandle, outputfilehandle)
+
+
+def main(use_pygame_console=0, interactmethod=default_interactmethod, print_banner=True, clear_main=True):
+ si, se, so = sys.stdin, sys.stderr, sys.stdout
+ try:
+ if 0 and use_pygame_console: # pygame currently borked
+ from pyrepl.pygame_console import PyGameConsole, FakeStdin, FakeStdout
+ con = PyGameConsole()
+ sys.stderr = sys.stdout = FakeStdout(con)
+ sys.stdin = FakeStdin(con)
+ else:
+ from pyrepl.unix_console import UnixConsole
+ try:
+ import locale
+ except ImportError:
+ encoding = None
+ else:
+ if hasattr(locale, 'nl_langinfo') \
+ and hasattr(locale, 'CODESET'):
+ encoding = locale.nl_langinfo(locale.CODESET)
+ elif os.environ.get('TERM_PROGRAM') == 'Apple_Terminal':
+ # /me whistles innocently...
+ code = int(os.popen(
+ "defaults read com.apple.Terminal StringEncoding"
+ ).read())
+ if code == 4:
+ encoding = 'utf-8'
+ # More could go here -- and what's here isn't
+ # bulletproof. What would be? AppleScript?
+ # Doesn't seem to be possible.
+ else:
+ encoding = None
+ else:
+ encoding = None # so you get ASCII...
+ con = UnixConsole(0, 1, None, encoding)
+ if print_banner:
+ print "Python", sys.version, "on", sys.platform
+ print 'Type "help", "copyright", "credits" or "license" '\
+ 'for more information.'
+ sys.path.insert(0, os.getcwd())
+
+ if clear_main and __name__ != '__main__':
+ mainmod = new.module('__main__')
+ sys.modules['__main__'] = mainmod
+ else:
+ mainmod = sys.modules['__main__']
+
+ rc = ReaderConsole(con, mainmod.__dict__)
+ rc.reader._module_list_ready = False
+ rc.run_user_init_file()
+ getattr(rc, interactmethod)()
+ finally:
+ sys.stdin, sys.stderr, sys.stdout = si, se, so
+
+if __name__ == '__main__':
+ main()
diff --git a/lib_pypy/pyrepl/reader.py b/lib_pypy/pyrepl/reader.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/reader.py
@@ -0,0 +1,614 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Antonio Cuni
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import types
+from pyrepl import unicodedata_
+from pyrepl import commands
+from pyrepl import input
+
+def _make_unctrl_map():
+ uc_map = {}
+ for c in map(unichr, range(256)):
+ if unicodedata_.category(c)[0] <> 'C':
+ uc_map[c] = c
+ for i in range(32):
+ c = unichr(i)
+ uc_map[c] = u'^' + unichr(ord('A') + i - 1)
+ uc_map['\t'] = ' ' # display TABs as 4 characters
+ uc_map['\177'] = u'^?'
+ for i in range(256):
+ c = unichr(i)
+ if not uc_map.has_key(c):
+ uc_map[c] = u'\\%03o'%i
+ return uc_map
+
+# disp_str proved to be a bottleneck for large inputs, so it's been
+# rewritten in C; it's not required though.
+try:
+ raise ImportError # currently it's borked by the unicode support
+
+ from _pyrepl_utils import disp_str, init_unctrl_map
+
+ init_unctrl_map(_make_unctrl_map())
+
+ del init_unctrl_map
+except ImportError:
+ def _my_unctrl(c, u=_make_unctrl_map()):
+ if c in u:
+ return u[c]
+ else:
+ if unicodedata_.category(c).startswith('C'):
+ return '\u%04x'%(ord(c),)
+ else:
+ return c
+
+ def disp_str(buffer, join=''.join, uc=_my_unctrl):
+ """ disp_str(buffer:string) -> (string, [int])
+
+ Return the string that should be the printed represenation of
+ |buffer| and a list detailing where the characters of |buffer|
+ get used up. E.g.:
+
+ >>> disp_str(chr(3))
+ ('^C', [1, 0])
+
+ the list always contains 0s or 1s at present; it could conceivably
+ go higher as and when unicode support happens."""
+ s = map(uc, buffer)
+ return (join(s),
+ map(ord, join(map(lambda x:'\001'+(len(x)-1)*'\000', s))))
+
+ del _my_unctrl
+
+del _make_unctrl_map
+
+# syntax classes:
+
+[SYNTAX_WHITESPACE,
+ SYNTAX_WORD,
+ SYNTAX_SYMBOL] = range(3)
+
+def make_default_syntax_table():
+ # XXX perhaps should use some unicodedata here?
+ st = {}
+ for c in map(unichr, range(256)):
+ st[c] = SYNTAX_SYMBOL
+ for c in [a for a in map(unichr, range(256)) if a.isalpha()]:
+ st[c] = SYNTAX_WORD
+ st[u'\n'] = st[u' '] = SYNTAX_WHITESPACE
+ return st
+
+default_keymap = tuple(
+ [(r'\C-a', 'beginning-of-line'),
+ (r'\C-b', 'left'),
+ (r'\C-c', 'interrupt'),
+ (r'\C-d', 'delete'),
+ (r'\C-e', 'end-of-line'),
+ (r'\C-f', 'right'),
+ (r'\C-g', 'cancel'),
+ (r'\C-h', 'backspace'),
+ (r'\C-j', 'accept'),
+ (r'\<return>', 'accept'),
+ (r'\C-k', 'kill-line'),
+ (r'\C-l', 'clear-screen'),
+ (r'\C-m', 'accept'),
+ (r'\C-q', 'quoted-insert'),
+ (r'\C-t', 'transpose-characters'),
+ (r'\C-u', 'unix-line-discard'),
+ (r'\C-v', 'quoted-insert'),
+ (r'\C-w', 'unix-word-rubout'),
+ (r'\C-x\C-u', 'upcase-region'),
+ (r'\C-y', 'yank'),
+ (r'\C-z', 'suspend'),
+
+ (r'\M-b', 'backward-word'),
+ (r'\M-c', 'capitalize-word'),
+ (r'\M-d', 'kill-word'),
+ (r'\M-f', 'forward-word'),
+ (r'\M-l', 'downcase-word'),
+ (r'\M-t', 'transpose-words'),
+ (r'\M-u', 'upcase-word'),
+ (r'\M-y', 'yank-pop'),
+ (r'\M--', 'digit-arg'),
+ (r'\M-0', 'digit-arg'),
+ (r'\M-1', 'digit-arg'),
+ (r'\M-2', 'digit-arg'),
+ (r'\M-3', 'digit-arg'),
+ (r'\M-4', 'digit-arg'),
+ (r'\M-5', 'digit-arg'),
+ (r'\M-6', 'digit-arg'),
+ (r'\M-7', 'digit-arg'),
+ (r'\M-8', 'digit-arg'),
+ (r'\M-9', 'digit-arg'),
+ #(r'\M-\n', 'insert-nl'),
+ ('\\\\', 'self-insert')] + \
+ [(c, 'self-insert')
+ for c in map(chr, range(32, 127)) if c <> '\\'] + \
+ [(c, 'self-insert')
+ for c in map(chr, range(128, 256)) if c.isalpha()] + \
+ [(r'\<up>', 'up'),
+ (r'\<down>', 'down'),
+ (r'\<left>', 'left'),
+ (r'\<right>', 'right'),
+ (r'\<insert>', 'quoted-insert'),
+ (r'\<delete>', 'delete'),
+ (r'\<backspace>', 'backspace'),
+ (r'\M-\<backspace>', 'backward-kill-word'),
+ (r'\<end>', 'end'),
+ (r'\<home>', 'home'),
+ (r'\<f1>', 'help'),
+ (r'\EOF', 'end'), # the entries in the terminfo database for xterms
+ (r'\EOH', 'home'), # seem to be wrong. this is a less than ideal
+ # workaround
+ ])
+
+del c # from the listcomps
+
+class Reader(object):
+ """The Reader class implements the bare bones of a command reader,
+ handling such details as editing and cursor motion. What it does
+ not support are such things as completion or history support -
+ these are implemented elsewhere.
+
+ Instance variables of note include:
+
+ * buffer:
+ A *list* (*not* a string at the moment :-) containing all the
+ characters that have been entered.
+ * console:
+ Hopefully encapsulates the OS dependent stuff.
+ * pos:
+ A 0-based index into `buffer' for where the insertion point
+ is.
+ * screeninfo:
+ Ahem. This list contains some info needed to move the
+ insertion point around reasonably efficiently. I'd like to
+ get rid of it, because its contents are obtuse (to put it
+ mildly) but I haven't worked out if that is possible yet.
+ * cxy, lxy:
+ the position of the insertion point in screen ... XXX
+ * syntax_table:
+ Dictionary mapping characters to `syntax class'; read the
+ emacs docs to see what this means :-)
+ * commands:
+ Dictionary mapping command names to command classes.
+ * arg:
+ The emacs-style prefix argument. It will be None if no such
+ argument has been provided.
+ * dirty:
+ True if we need to refresh the display.
+ * kill_ring:
+ The emacs-style kill-ring; manipulated with yank & yank-pop
+ * ps1, ps2, ps3, ps4:
+ prompts. ps1 is the prompt for a one-line input; for a
+ multiline input it looks like:
+ ps2> first line of input goes here
+ ps3> second and further
+ ps3> lines get ps3
+ ...
+ ps4> and the last one gets ps4
+ As with the usual top-level, you can set these to instances if
+ you like; str() will be called on them (once) at the beginning
+ of each command. Don't put really long or newline containing
+ strings here, please!
+ This is just the default policy; you can change it freely by
+ overriding get_prompt() (and indeed some standard subclasses
+ do).
+ * finished:
+ handle1 will set this to a true value if a command signals
+ that we're done.
+ """
+
+ help_text = """\
+This is pyrepl. Hear my roar.
+
+Helpful text may appear here at some point in the future when I'm
+feeling more loquacious than I am now."""
+
+ msg_at_bottom = True
+
+ def __init__(self, console):
+ self.buffer = []
+ self.ps1 = "->> "
+ self.ps2 = "/>> "
+ self.ps3 = "|.. "
+ self.ps4 = "\__ "
+ self.kill_ring = []
+ self.arg = None
+ self.finished = 0
+ self.console = console
+ self.commands = {}
+ self.msg = ''
+ for v in vars(commands).values():
+ if ( isinstance(v, type)
+ and issubclass(v, commands.Command)
+ and v.__name__[0].islower() ):
+ self.commands[v.__name__] = v
+ self.commands[v.__name__.replace('_', '-')] = v
+ self.syntax_table = make_default_syntax_table()
+ self.input_trans_stack = []
+ self.keymap = self.collect_keymap()
+ self.input_trans = input.KeymapTranslator(
+ self.keymap,
+ invalid_cls='invalid-key',
+ character_cls='self-insert')
+
+ def collect_keymap(self):
+ return default_keymap
+
+ def calc_screen(self):
+ """The purpose of this method is to translate changes in
+ self.buffer into changes in self.screen. Currently it rips
+ everything down and starts from scratch, which whilst not
+ especially efficient is certainly simple(r).
+ """
+ lines = self.get_unicode().split("\n")
+ screen = []
+ screeninfo = []
+ w = self.console.width - 1
+ p = self.pos
+ for ln, line in zip(range(len(lines)), lines):
+ ll = len(line)
+ if 0 <= p <= ll:
+ if self.msg and not self.msg_at_bottom:
+ for mline in self.msg.split("\n"):
+ screen.append(mline)
+ screeninfo.append((0, []))
+ self.lxy = p, ln
+ prompt = self.get_prompt(ln, ll >= p >= 0)
+ while '\n' in prompt:
+ pre_prompt, _, prompt = prompt.partition('\n')
+ screen.append(pre_prompt)
+ screeninfo.append((0, []))
+ p -= ll + 1
+ prompt, lp = self.process_prompt(prompt)
+ l, l2 = disp_str(line)
+ wrapcount = (len(l) + lp) / w
+ if wrapcount == 0:
+ screen.append(prompt + l)
+ screeninfo.append((lp, l2+[1]))
+ else:
+ screen.append(prompt + l[:w-lp] + "\\")
+ screeninfo.append((lp, l2[:w-lp]))
+ for i in range(-lp + w, -lp + wrapcount*w, w):
+ screen.append(l[i:i+w] + "\\")
+ screeninfo.append((0, l2[i:i + w]))
+ screen.append(l[wrapcount*w - lp:])
+ screeninfo.append((0, l2[wrapcount*w - lp:]+[1]))
+ self.screeninfo = screeninfo
+ self.cxy = self.pos2xy(self.pos)
+ if self.msg and self.msg_at_bottom:
+ for mline in self.msg.split("\n"):
+ screen.append(mline)
+ screeninfo.append((0, []))
+ return screen
+
+ def process_prompt(self, prompt):
+ """ Process the prompt.
+
+ This means calculate the length of the prompt. The character \x01
+ and \x02 are used to bracket ANSI control sequences and need to be
+ excluded from the length calculation. So also a copy of the prompt
+ is returned with these control characters removed. """
+
+ out_prompt = ''
+ l = len(prompt)
+ pos = 0
+ while True:
+ s = prompt.find('\x01', pos)
+ if s == -1:
+ break
+ e = prompt.find('\x02', s)
+ if e == -1:
+ break
+ # Found start and end brackets, subtract from string length
+ l = l - (e-s+1)
+ out_prompt += prompt[pos:s] + prompt[s+1:e]
+ pos = e+1
+ out_prompt += prompt[pos:]
+ return out_prompt, l
+
+ def bow(self, p=None):
+ """Return the 0-based index of the word break preceding p most
+ immediately.
+
+ p defaults to self.pos; word boundaries are determined using
+ self.syntax_table."""
+ if p is None:
+ p = self.pos
+ st = self.syntax_table
+ b = self.buffer
+ p -= 1
+ while p >= 0 and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
+ p -= 1
+ while p >= 0 and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
+ p -= 1
+ return p + 1
+
+ def eow(self, p=None):
+ """Return the 0-based index of the word break following p most
+ immediately.
+
+ p defaults to self.pos; word boundaries are determined using
+ self.syntax_table."""
+ if p is None:
+ p = self.pos
+ st = self.syntax_table
+ b = self.buffer
+ while p < len(b) and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
+ p += 1
+ while p < len(b) and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
+ p += 1
+ return p
+
+ def bol(self, p=None):
+ """Return the 0-based index of the line break preceding p most
+ immediately.
+
+ p defaults to self.pos."""
+ # XXX there are problems here.
+ if p is None:
+ p = self.pos
+ b = self.buffer
+ p -= 1
+ while p >= 0 and b[p] <> '\n':
+ p -= 1
+ return p + 1
+
+ def eol(self, p=None):
+ """Return the 0-based index of the line break following p most
+ immediately.
+
+ p defaults to self.pos."""
+ if p is None:
+ p = self.pos
+ b = self.buffer
+ while p < len(b) and b[p] <> '\n':
+ p += 1
+ return p
+
+ def get_arg(self, default=1):
+ """Return any prefix argument that the user has supplied,
+ returning `default' if there is None. `default' defaults
+ (groan) to 1."""
+ if self.arg is None:
+ return default
+ else:
+ return self.arg
+
+ def get_prompt(self, lineno, cursor_on_line):
+ """Return what should be in the left-hand margin for line
+ `lineno'."""
+ if self.arg is not None and cursor_on_line:
+ return "(arg: %s) "%self.arg
+ if "\n" in self.buffer:
+ if lineno == 0:
+ return self._ps2
+ elif lineno == self.buffer.count("\n"):
+ return self._ps4
+ else:
+ return self._ps3
+ else:
+ return self._ps1
+
+ def push_input_trans(self, itrans):
+ self.input_trans_stack.append(self.input_trans)
+ self.input_trans = itrans
+
+ def pop_input_trans(self):
+ self.input_trans = self.input_trans_stack.pop()
+
+ def pos2xy(self, pos):
+ """Return the x, y coordinates of position 'pos'."""
+ # this *is* incomprehensible, yes.
+ y = 0
+ assert 0 <= pos <= len(self.buffer)
+ if pos == len(self.buffer):
+ y = len(self.screeninfo) - 1
+ p, l2 = self.screeninfo[y]
+ return p + len(l2) - 1, y
+ else:
+ for p, l2 in self.screeninfo:
+ l = l2.count(1)
+ if l > pos:
+ break
+ else:
+ pos -= l
+ y += 1
+ c = 0
+ i = 0
+ while c < pos:
+ c += l2[i]
+ i += 1
+ while l2[i] == 0:
+ i += 1
+ return p + i, y
+
+ def insert(self, text):
+ """Insert 'text' at the insertion point."""
+ self.buffer[self.pos:self.pos] = list(text)
+ self.pos += len(text)
+ self.dirty = 1
+
+ def update_cursor(self):
+ """Move the cursor to reflect changes in self.pos"""
+ self.cxy = self.pos2xy(self.pos)
+ self.console.move_cursor(*self.cxy)
+
+ def after_command(self, cmd):
+ """This function is called to allow post command cleanup."""
+ if getattr(cmd, "kills_digit_arg", 1):
+ if self.arg is not None:
+ self.dirty = 1
+ self.arg = None
+
+ def prepare(self):
+ """Get ready to run. Call restore when finished. You must not
+ write to the console in between the calls to prepare and
+ restore."""
+ try:
+ self.console.prepare()
+ self.arg = None
+ self.screeninfo = []
+ self.finished = 0
+ del self.buffer[:]
+ self.pos = 0
+ self.dirty = 1
+ self.last_command = None
+ self._ps1, self._ps2, self._ps3, self._ps4 = \
+ map(str, [self.ps1, self.ps2, self.ps3, self.ps4])
+ except:
+ self.restore()
+ raise
+
+ def last_command_is(self, klass):
+ if not self.last_command:
+ return 0
+ return issubclass(klass, self.last_command)
+
+ def restore(self):
+ """Clean up after a run."""
+ self.console.restore()
+
+ def finish(self):
+ """Called when a command signals that we're finished."""
+ pass
+
+ def error(self, msg="none"):
+ self.msg = "! " + msg + " "
+ self.dirty = 1
+ self.console.beep()
+
+ def update_screen(self):
+ if self.dirty:
+ self.refresh()
+
+ def refresh(self):
+ """Recalculate and refresh the screen."""
+ # this call sets up self.cxy, so call it first.
+ screen = self.calc_screen()
+ self.console.refresh(screen, self.cxy)
+ self.dirty = 0 # forgot this for a while (blush)
+
+ def do_cmd(self, cmd):
+ #print cmd
+ if isinstance(cmd[0], str):
+ cmd = self.commands.get(cmd[0],
+ commands.invalid_command)(self, cmd)
+ elif isinstance(cmd[0], type):
+ cmd = cmd[0](self, cmd)
+
+ cmd.do()
+
+ self.after_command(cmd)
+
+ if self.dirty:
+ self.refresh()
+ else:
+ self.update_cursor()
+
+ if not isinstance(cmd, commands.digit_arg):
+ self.last_command = cmd.__class__
+
+ self.finished = cmd.finish
+ if self.finished:
+ self.console.finish()
+ self.finish()
+
+ def handle1(self, block=1):
+ """Handle a single event. Wait as long as it takes if block
+ is true (the default), otherwise return None if no event is
+ pending."""
+
+ if self.msg:
+ self.msg = ''
+ self.dirty = 1
+
+ while 1:
+ event = self.console.get_event(block)
+ if not event: # can only happen if we're not blocking
+ return None
+
+ if event.evt == 'key':
+ self.input_trans.push(event)
+ elif event.evt == 'scroll':
+ self.refresh()
+ elif event.evt == 'resize':
+ self.refresh()
+ else:
+ pass
+
+ cmd = self.input_trans.get()
+
+ if cmd is None:
+ if block:
+ continue
+ else:
+ return None
+
+ self.do_cmd(cmd)
+ return 1
+
+ def push_char(self, char):
+ self.console.push_char(char)
+ self.handle1(0)
+
+ def readline(self):
+ """Read a line. The implementation of this method also shows
+ how to drive Reader if you want more control over the event
+ loop."""
+ self.prepare()
+ try:
+ self.refresh()
+ while not self.finished:
+ self.handle1()
+ return self.get_buffer()
+ finally:
+ self.restore()
+
+ def bind(self, spec, command):
+ self.keymap = self.keymap + ((spec, command),)
+ self.input_trans = input.KeymapTranslator(
+ self.keymap,
+ invalid_cls='invalid-key',
+ character_cls='self-insert')
+
+ def get_buffer(self, encoding=None):
+ if encoding is None:
+ encoding = self.console.encoding
+ return u''.join(self.buffer).encode(self.console.encoding)
+
+ def get_unicode(self):
+ """Return the current buffer as a unicode string."""
+ return u''.join(self.buffer)
+
+def test():
+ from pyrepl.unix_console import UnixConsole
+ reader = Reader(UnixConsole())
+ reader.ps1 = "**> "
+ reader.ps2 = "/*> "
+ reader.ps3 = "|*> "
+ reader.ps4 = "\*> "
+ while reader.readline():
+ pass
+
+if __name__=='__main__':
+ test()
diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/readline.py
@@ -0,0 +1,408 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Alex Gaynor
+# Antonio Cuni
+# Armin Rigo
+# Holger Krekel
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""A compatibility wrapper reimplementing the 'readline' standard module
+on top of pyrepl. Not all functionalities are supported. Contains
+extensions for multiline input.
+"""
+
+import sys, os
+from pyrepl import commands
+from pyrepl.historical_reader import HistoricalReader
+from pyrepl.completing_reader import CompletingReader
+from pyrepl.unix_console import UnixConsole, _error
+
+
+ENCODING = 'latin1' # XXX hard-coded
+
+__all__ = ['add_history',
+ 'clear_history',
+ 'get_begidx',
+ 'get_completer',
+ 'get_completer_delims',
+ 'get_current_history_length',
+ 'get_endidx',
+ 'get_history_item',
+ 'get_history_length',
+ 'get_line_buffer',
+ 'insert_text',
+ 'parse_and_bind',
+ 'read_history_file',
+ 'read_init_file',
+ 'redisplay',
+ 'remove_history_item',
+ 'replace_history_item',
+ 'set_completer',
+ 'set_completer_delims',
+ 'set_history_length',
+ 'set_pre_input_hook',
+ 'set_startup_hook',
+ 'write_history_file',
+ # ---- multiline extensions ----
+ 'multiline_input',
+ ]
+
+# ____________________________________________________________
+
+class ReadlineConfig(object):
+ readline_completer = None
+ completer_delims = dict.fromkeys(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?')
+
+class ReadlineAlikeReader(HistoricalReader, CompletingReader):
+
+ assume_immutable_completions = False
+ use_brackets = False
+ sort_in_column = True
+
+ def error(self, msg="none"):
+ pass # don't show error messages by default
+
+ def get_stem(self):
+ b = self.buffer
+ p = self.pos - 1
+ completer_delims = self.config.completer_delims
+ while p >= 0 and b[p] not in completer_delims:
+ p -= 1
+ return ''.join(b[p+1:self.pos])
+
+ def get_completions(self, stem):
+ result = []
+ function = self.config.readline_completer
+ if function is not None:
+ try:
+ stem = str(stem) # rlcompleter.py seems to not like unicode
+ except UnicodeEncodeError:
+ pass # but feed unicode anyway if we have no choice
+ state = 0
+ while True:
+ try:
+ next = function(stem, state)
+ except:
+ break
+ if not isinstance(next, str):
+ break
+ result.append(next)
+ state += 1
+ # emulate the behavior of the standard readline that sorts
+ # the completions before displaying them.
+ result.sort()
+ return result
+
+ def get_trimmed_history(self, maxlength):
+ if maxlength >= 0:
+ cut = len(self.history) - maxlength
+ if cut < 0:
+ cut = 0
+ else:
+ cut = 0
+ return self.history[cut:]
+
+ # --- simplified support for reading multiline Python statements ---
+
+ # This duplicates small parts of pyrepl.python_reader. I'm not
+ # reusing the PythonicReader class directly for two reasons. One is
+ # to try to keep as close as possible to CPython's prompt. The
+ # other is that it is the readline module that we are ultimately
+ # implementing here, and I don't want the built-in raw_input() to
+ # start trying to read multiline inputs just because what the user
+ # typed look like valid but incomplete Python code. So we get the
+ # multiline feature only when using the multiline_input() function
+ # directly (see _pypy_interact.py).
+
+ more_lines = None
+
+ def collect_keymap(self):
+ return super(ReadlineAlikeReader, self).collect_keymap() + (
+ (r'\n', 'maybe-accept'),)
+
+ def __init__(self, console):
+ super(ReadlineAlikeReader, self).__init__(console)
+ self.commands['maybe_accept'] = maybe_accept
+ self.commands['maybe-accept'] = maybe_accept
+
+ def after_command(self, cmd):
+ super(ReadlineAlikeReader, self).after_command(cmd)
+ if self.more_lines is None:
+ # Force single-line input if we are in raw_input() mode.
+ # Although there is no direct way to add a \n in this mode,
+ # multiline buffers can still show up using various
+ # commands, e.g. navigating the history.
+ try:
+ index = self.buffer.index("\n")
+ except ValueError:
+ pass
+ else:
+ self.buffer = self.buffer[:index]
+ if self.pos > len(self.buffer):
+ self.pos = len(self.buffer)
+
+class maybe_accept(commands.Command):
+ def do(self):
+ r = self.reader
+ r.dirty = 1 # this is needed to hide the completion menu, if visible
+ #
+ # if there are already several lines and the cursor
+ # is not on the last one, always insert a new \n.
+ text = r.get_unicode()
+ if "\n" in r.buffer[r.pos:]:
+ r.insert("\n")
+ elif r.more_lines is not None and r.more_lines(text):
+ r.insert("\n")
+ else:
+ self.finish = 1
+
+# ____________________________________________________________
+
+class _ReadlineWrapper(object):
+ f_in = 0
+ f_out = 1
+ reader = None
+ saved_history_length = -1
+ startup_hook = None
+ config = ReadlineConfig()
+
+ def get_reader(self):
+ if self.reader is None:
+ console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING)
+ self.reader = ReadlineAlikeReader(console)
+ self.reader.config = self.config
+ return self.reader
+
+ def raw_input(self, prompt=''):
+ try:
+ reader = self.get_reader()
+ except _error:
+ return _old_raw_input(prompt)
+ if self.startup_hook is not None:
+ self.startup_hook()
+ reader.ps1 = prompt
+ return reader.readline()
+
+ def multiline_input(self, more_lines, ps1, ps2):
+ """Read an input on possibly multiple lines, asking for more
+ lines as long as 'more_lines(unicodetext)' returns an object whose
+ boolean value is true.
+ """
+ reader = self.get_reader()
+ saved = reader.more_lines
+ try:
+ reader.more_lines = more_lines
+ reader.ps1 = reader.ps2 = ps1
+ reader.ps3 = reader.ps4 = ps2
+ return reader.readline()
+ finally:
+ reader.more_lines = saved
+
+ def parse_and_bind(self, string):
+ pass # XXX we don't support parsing GNU-readline-style init files
+
+ def set_completer(self, function=None):
+ self.config.readline_completer = function
+
+ def get_completer(self):
+ return self.config.readline_completer
+
+ def set_completer_delims(self, string):
+ self.config.completer_delims = dict.fromkeys(string)
+
+ def get_completer_delims(self):
+ chars = self.config.completer_delims.keys()
+ chars.sort()
+ return ''.join(chars)
+
+ def _histline(self, line):
+ return unicode(line.rstrip('\n'), ENCODING)
+
+ def get_history_length(self):
+ return self.saved_history_length
+
+ def set_history_length(self, length):
+ self.saved_history_length = length
+
+ def get_current_history_length(self):
+ return len(self.get_reader().history)
+
+ def read_history_file(self, filename='~/.history'):
+ # multiline extension (really a hack) for the end of lines that
+ # are actually continuations inside a single multiline_input()
+ # history item: we use \r\n instead of just \n. If the history
+ # file is passed to GNU readline, the extra \r are just ignored.
+ history = self.get_reader().history
+ f = open(os.path.expanduser(filename), 'r')
+ buffer = []
+ for line in f:
+ if line.endswith('\r\n'):
+ buffer.append(line)
+ else:
+ line = self._histline(line)
+ if buffer:
+ line = ''.join(buffer).replace('\r', '') + line
+ del buffer[:]
+ if line:
+ history.append(line)
+ f.close()
+
+ def write_history_file(self, filename='~/.history'):
+ maxlength = self.saved_history_length
+ history = self.get_reader().get_trimmed_history(maxlength)
+ f = open(os.path.expanduser(filename), 'w')
+ for entry in history:
+ if isinstance(entry, unicode):
+ entry = entry.encode(ENCODING)
+ entry = entry.replace('\n', '\r\n') # multiline history support
+ f.write(entry + '\n')
+ f.close()
+
+ def clear_history(self):
+ del self.get_reader().history[:]
+
+ def get_history_item(self, index):
+ history = self.get_reader().history
+ if 1 <= index <= len(history):
+ return history[index-1]
+ else:
+ return None # blame readline.c for not raising
+
+ def remove_history_item(self, index):
+ history = self.get_reader().history
+ if 0 <= index < len(history):
+ del history[index]
+ else:
+ raise ValueError("No history item at position %d" % index)
+ # blame readline.c for raising ValueError
+
+ def replace_history_item(self, index, line):
+ history = self.get_reader().history
+ if 0 <= index < len(history):
+ history[index] = self._histline(line)
+ else:
+ raise ValueError("No history item at position %d" % index)
+ # blame readline.c for raising ValueError
+
+ def add_history(self, line):
+ self.get_reader().history.append(self._histline(line))
+
+ def set_startup_hook(self, function=None):
+ self.startup_hook = function
+
+ def get_line_buffer(self):
+ return self.get_reader().get_buffer()
+
+ def _get_idxs(self):
+ start = cursor = self.get_reader().pos
+ buf = self.get_line_buffer()
+ for i in xrange(cursor - 1, -1, -1):
+ if buf[i] in self.get_completer_delims():
+ break
+ start = i
+ return start, cursor
+
+ def get_begidx(self):
+ return self._get_idxs()[0]
+
+ def get_endidx(self):
+ return self._get_idxs()[1]
+
+ def insert_text(self, text):
+ return self.get_reader().insert(text)
+
+
+_wrapper = _ReadlineWrapper()
+
+# ____________________________________________________________
+# Public API
+
+parse_and_bind = _wrapper.parse_and_bind
+set_completer = _wrapper.set_completer
+get_completer = _wrapper.get_completer
+set_completer_delims = _wrapper.set_completer_delims
+get_completer_delims = _wrapper.get_completer_delims
+get_history_length = _wrapper.get_history_length
+set_history_length = _wrapper.set_history_length
+get_current_history_length = _wrapper.get_current_history_length
+read_history_file = _wrapper.read_history_file
+write_history_file = _wrapper.write_history_file
+clear_history = _wrapper.clear_history
+get_history_item = _wrapper.get_history_item
+remove_history_item = _wrapper.remove_history_item
+replace_history_item = _wrapper.replace_history_item
+add_history = _wrapper.add_history
+set_startup_hook = _wrapper.set_startup_hook
+get_line_buffer = _wrapper.get_line_buffer
+get_begidx = _wrapper.get_begidx
+get_endidx = _wrapper.get_endidx
+insert_text = _wrapper.insert_text
+
+# Extension
+multiline_input = _wrapper.multiline_input
+
+# Internal hook
+_get_reader = _wrapper.get_reader
+
+# ____________________________________________________________
+# Stubs
+
+def _make_stub(_name, _ret):
+ def stub(*args, **kwds):
+ import warnings
+ warnings.warn("readline.%s() not implemented" % _name, stacklevel=2)
+ stub.func_name = _name
+ globals()[_name] = stub
+
+for _name, _ret in [
+ ('read_init_file', None),
+ ('redisplay', None),
+ ('set_pre_input_hook', None),
+ ]:
+ assert _name not in globals(), _name
+ _make_stub(_name, _ret)
+
+# ____________________________________________________________
+
+def _setup():
+ global _old_raw_input
+ if _old_raw_input is not None:
+ return # don't run _setup twice
+
+ try:
+ f_in = sys.stdin.fileno()
+ f_out = sys.stdout.fileno()
+ except (AttributeError, ValueError):
+ return
+ if not os.isatty(f_in) or not os.isatty(f_out):
+ return
+
+ _wrapper.f_in = f_in
+ _wrapper.f_out = f_out
+
+ if hasattr(sys, '__raw_input__'): # PyPy
+ _old_raw_input = sys.__raw_input__
+ sys.__raw_input__ = _wrapper.raw_input
+ else:
+ # this is not really what readline.c does. Better than nothing I guess
+ import __builtin__
+ _old_raw_input = __builtin__.raw_input
+ __builtin__.raw_input = _wrapper.raw_input
+
+_old_raw_input = None
+_setup()
diff --git a/lib_pypy/pyrepl/simple_interact.py b/lib_pypy/pyrepl/simple_interact.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/simple_interact.py
@@ -0,0 +1,64 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""This is an alternative to python_reader which tries to emulate
+the CPython prompt as closely as possible, with the exception of
+allowing multiline input and multiline history entries.
+"""
+
+import sys
+from pyrepl.readline import multiline_input, _error, _get_reader
+
+def check(): # returns False if there is a problem initializing the state
+ try:
+ _get_reader()
+ except _error:
+ return False
+ return True
+
+def run_multiline_interactive_console(mainmodule=None):
+ import code
+ if mainmodule is None:
+ import __main__ as mainmodule
+ console = code.InteractiveConsole(mainmodule.__dict__)
+
+ def more_lines(unicodetext):
+ # ooh, look at the hack:
+ src = "#coding:utf-8\n"+unicodetext.encode('utf-8')
+ try:
+ code = console.compile(src, '<input>', 'single')
+ except (OverflowError, SyntaxError, ValueError):
+ return False
+ else:
+ return code is None
+
+ while 1:
+ try:
+ ps1 = getattr(sys, 'ps1', '>>> ')
+ ps2 = getattr(sys, 'ps2', '... ')
+ try:
+ statement = multiline_input(more_lines, ps1, ps2)
+ except EOFError:
+ break
+ more = console.push(statement)
+ assert not more
+ except KeyboardInterrupt:
+ console.write("\nKeyboardInterrupt\n")
+ console.resetbuffer()
diff --git a/lib_pypy/pyrepl/test/test_functional.py b/lib_pypy/pyrepl/test/test_functional.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/test/test_functional.py
@@ -0,0 +1,50 @@
+# Copyright 2000-2007 Michael Hudson-Doyle <micahel at gmail.com>
+# Maciek Fijalkowski
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# some functional tests, to see if this is really working
+
+import py
+import sys
+
+class TestTerminal(object):
+ def _spawn(self, *args, **kwds):
+ try:
+ import pexpect
+ except ImportError, e:
+ py.test.skip(str(e))
+ kwds.setdefault('timeout', 10)
+ child = pexpect.spawn(*args, **kwds)
+ child.logfile = sys.stdout
+ return child
+
+ def spawn(self, argv=[]):
+ # avoid running start.py, cause it might contain
+ # things like readline or rlcompleter(2) included
+ child = self._spawn(sys.executable, ['-S'] + argv)
+ child.sendline('from pyrepl.python_reader import main')
+ child.sendline('main()')
+ return child
+
+ def test_basic(self):
+ child = self.spawn()
+ child.sendline('a = 3')
+ child.sendline('a')
+ child.expect('3')
+
diff --git a/lib_pypy/pyrepl/tests/__init__.py b/lib_pypy/pyrepl/tests/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/tests/__init__.py
@@ -0,0 +1,20 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# moo
diff --git a/lib_pypy/pyrepl/tests/basic.py b/lib_pypy/pyrepl/tests/basic.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/tests/basic.py
@@ -0,0 +1,115 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl.console import Event
+from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase
+
+class SimpleTestCase(ReaderTestCase):
+
+ def test_basic(self):
+ self.run_test([(('self-insert', 'a'), ['a']),
+ ( 'accept', ['a'])])
+
+ def test_repeat(self):
+ self.run_test([(('digit-arg', '3'), ['']),
+ (('self-insert', 'a'), ['aaa']),
+ ( 'accept', ['aaa'])])
+
+ def test_kill_line(self):
+ self.run_test([(('self-insert', 'abc'), ['abc']),
+ ( 'left', None),
+ ( 'kill-line', ['ab']),
+ ( 'accept', ['ab'])])
+
+ def test_unix_line_discard(self):
+ self.run_test([(('self-insert', 'abc'), ['abc']),
+ ( 'left', None),
+ ( 'unix-word-rubout', ['c']),
+ ( 'accept', ['c'])])
+
+ def test_kill_word(self):
+ self.run_test([(('self-insert', 'ab cd'), ['ab cd']),
+ ( 'beginning-of-line', ['ab cd']),
+ ( 'kill-word', [' cd']),
+ ( 'accept', [' cd'])])
+
+ def test_backward_kill_word(self):
+ self.run_test([(('self-insert', 'ab cd'), ['ab cd']),
+ ( 'backward-kill-word', ['ab ']),
+ ( 'accept', ['ab '])])
+
+ def test_yank(self):
+ self.run_test([(('self-insert', 'ab cd'), ['ab cd']),
+ ( 'backward-kill-word', ['ab ']),
+ ( 'beginning-of-line', ['ab ']),
+ ( 'yank', ['cdab ']),
+ ( 'accept', ['cdab '])])
+
+ def test_yank_pop(self):
+ self.run_test([(('self-insert', 'ab cd'), ['ab cd']),
+ ( 'backward-kill-word', ['ab ']),
+ ( 'left', ['ab ']),
+ ( 'backward-kill-word', [' ']),
+ ( 'yank', ['ab ']),
+ ( 'yank-pop', ['cd ']),
+ ( 'accept', ['cd '])])
+
+ def test_interrupt(self):
+ try:
+ self.run_test([( 'interrupt', [''])])
+ except KeyboardInterrupt:
+ pass
+ else:
+ self.fail('KeyboardInterrupt got lost')
+
+ # test_suspend -- hah
+
+ def test_up(self):
+ self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']),
+ ( 'up', ['ab', 'cd']),
+ (('self-insert', 'e'), ['abe', 'cd']),
+ ( 'accept', ['abe', 'cd'])])
+
+ def test_down(self):
+ self.run_test([(('self-insert', 'ab\ncd'), ['ab', 'cd']),
+ ( 'up', ['ab', 'cd']),
+ (('self-insert', 'e'), ['abe', 'cd']),
+ ( 'down', ['abe', 'cd']),
+ (('self-insert', 'f'), ['abe', 'cdf']),
+ ( 'accept', ['abe', 'cdf'])])
+
+ def test_left(self):
+ self.run_test([(('self-insert', 'ab'), ['ab']),
+ ( 'left', ['ab']),
+ (('self-insert', 'c'), ['acb']),
+ ( 'accept', ['acb'])])
+
+ def test_right(self):
+ self.run_test([(('self-insert', 'ab'), ['ab']),
+ ( 'left', ['ab']),
+ (('self-insert', 'c'), ['acb']),
+ ( 'right', ['acb']),
+ (('self-insert', 'd'), ['acbd']),
+ ( 'accept', ['acbd'])])
+
+def test():
+ run_testcase(SimpleTestCase)
+
+if __name__ == '__main__':
+ test()
diff --git a/lib_pypy/pyrepl/tests/bugs.py b/lib_pypy/pyrepl/tests/bugs.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/tests/bugs.py
@@ -0,0 +1,36 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl.console import Event
+from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase
+
+# this test case should contain as-verbatim-as-possible versions of
+# (applicable) bug reports
+
+class BugsTestCase(ReaderTestCase):
+
+ def test_transpose_at_start(self):
+ self.run_test([( 'transpose', [EA, '']),
+ ( 'accept', [''])])
+
+def test():
+ run_testcase(BugsTestCase)
+
+if __name__ == '__main__':
+ test()
diff --git a/lib_pypy/pyrepl/tests/infrastructure.py b/lib_pypy/pyrepl/tests/infrastructure.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/tests/infrastructure.py
@@ -0,0 +1,82 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl.reader import Reader
+from pyrepl.console import Console, Event
+import unittest
+import sys
+
+class EqualsAnything(object):
+ def __eq__(self, other):
+ return True
+EA = EqualsAnything()
+
+class TestConsole(Console):
+ height = 24
+ width = 80
+ encoding = 'utf-8'
+
+ def __init__(self, events, testcase, verbose=False):
+ self.events = events
+ self.next_screen = None
+ self.verbose = verbose
+ self.testcase = testcase
+
+ def refresh(self, screen, xy):
+ if self.next_screen is not None:
+ self.testcase.assertEqual(
+ screen, self.next_screen,
+ "[ %s != %s after %r ]"%(screen, self.next_screen,
+ self.last_event_name))
+
+ def get_event(self, block=1):
+ ev, sc = self.events.pop(0)
+ self.next_screen = sc
+ if not isinstance(ev, tuple):
+ ev = (ev,)
+ self.last_event_name = ev[0]
+ if self.verbose:
+ print "event", ev
+ return Event(*ev)
+
+class TestReader(Reader):
+ def get_prompt(self, lineno, cursor_on_line):
+ return ''
+ def refresh(self):
+ Reader.refresh(self)
+ self.dirty = True
+
+class ReaderTestCase(unittest.TestCase):
+ def run_test(self, test_spec, reader_class=TestReader):
+ # remember to finish your test_spec with 'accept' or similar!
+ con = TestConsole(test_spec, self)
+ reader = reader_class(con)
+ reader.readline()
+
+class BasicTestRunner:
+ def run(self, test):
+ result = unittest.TestResult()
+ test(result)
+ return result
+
+def run_testcase(testclass):
+ suite = unittest.makeSuite(testclass)
+ runner = unittest.TextTestRunner(sys.stdout, verbosity=1)
+ result = runner.run(suite)
+
diff --git a/lib_pypy/pyrepl/tests/wishes.py b/lib_pypy/pyrepl/tests/wishes.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/tests/wishes.py
@@ -0,0 +1,38 @@
+# Copyright 2000-2004 Michael Hudson-Doyle <micahel at gmail.com>
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from pyrepl.console import Event
+from pyrepl.tests.infrastructure import ReaderTestCase, EA, run_testcase
+
+# this test case should contain as-verbatim-as-possible versions of
+# (applicable) feature requests
+
+class WishesTestCase(ReaderTestCase):
+
+ def test_quoted_insert_repeat(self):
+ self.run_test([(('digit-arg', '3'), ['']),
+ ( 'quoted-insert', ['']),
+ (('self-insert', '\033'), ['^[^[^[']),
+ ( 'accept', None)])
+
+def test():
+ run_testcase(WishesTestCase)
+
+if __name__ == '__main__':
+ test()
diff --git a/lib_pypy/pyrepl/unicodedata_.py b/lib_pypy/pyrepl/unicodedata_.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/unicodedata_.py
@@ -0,0 +1,59 @@
+try:
+ from unicodedata import *
+except ImportError:
+
+ def category(ch):
+ """
+ ASCII only implementation
+ """
+ if type(ch) is not unicode:
+ raise TypeError
+ if len(ch) != 1:
+ raise TypeError
+ return _categories.get(ord(ch), 'Co') # "Other, private use"
+
+ _categories = {
+ 0: 'Cc', 1: 'Cc', 2: 'Cc', 3: 'Cc', 4: 'Cc', 5: 'Cc',
+ 6: 'Cc', 7: 'Cc', 8: 'Cc', 9: 'Cc', 10: 'Cc', 11: 'Cc',
+ 12: 'Cc', 13: 'Cc', 14: 'Cc', 15: 'Cc', 16: 'Cc', 17: 'Cc',
+ 18: 'Cc', 19: 'Cc', 20: 'Cc', 21: 'Cc', 22: 'Cc', 23: 'Cc',
+ 24: 'Cc', 25: 'Cc', 26: 'Cc', 27: 'Cc', 28: 'Cc', 29: 'Cc',
+ 30: 'Cc', 31: 'Cc', 32: 'Zs', 33: 'Po', 34: 'Po', 35: 'Po',
+ 36: 'Sc', 37: 'Po', 38: 'Po', 39: 'Po', 40: 'Ps', 41: 'Pe',
+ 42: 'Po', 43: 'Sm', 44: 'Po', 45: 'Pd', 46: 'Po', 47: 'Po',
+ 48: 'Nd', 49: 'Nd', 50: 'Nd', 51: 'Nd', 52: 'Nd', 53: 'Nd',
+ 54: 'Nd', 55: 'Nd', 56: 'Nd', 57: 'Nd', 58: 'Po', 59: 'Po',
+ 60: 'Sm', 61: 'Sm', 62: 'Sm', 63: 'Po', 64: 'Po', 65: 'Lu',
+ 66: 'Lu', 67: 'Lu', 68: 'Lu', 69: 'Lu', 70: 'Lu', 71: 'Lu',
+ 72: 'Lu', 73: 'Lu', 74: 'Lu', 75: 'Lu', 76: 'Lu', 77: 'Lu',
+ 78: 'Lu', 79: 'Lu', 80: 'Lu', 81: 'Lu', 82: 'Lu', 83: 'Lu',
+ 84: 'Lu', 85: 'Lu', 86: 'Lu', 87: 'Lu', 88: 'Lu', 89: 'Lu',
+ 90: 'Lu', 91: 'Ps', 92: 'Po', 93: 'Pe', 94: 'Sk', 95: 'Pc',
+ 96: 'Sk', 97: 'Ll', 98: 'Ll', 99: 'Ll', 100: 'Ll', 101: 'Ll',
+ 102: 'Ll', 103: 'Ll', 104: 'Ll', 105: 'Ll', 106: 'Ll', 107: 'Ll',
+ 108: 'Ll', 109: 'Ll', 110: 'Ll', 111: 'Ll', 112: 'Ll', 113: 'Ll',
+ 114: 'Ll', 115: 'Ll', 116: 'Ll', 117: 'Ll', 118: 'Ll', 119: 'Ll',
+ 120: 'Ll', 121: 'Ll', 122: 'Ll', 123: 'Ps', 124: 'Sm', 125: 'Pe',
+ 126: 'Sm', 127: 'Cc', 128: 'Cc', 129: 'Cc', 130: 'Cc', 131: 'Cc',
+ 132: 'Cc', 133: 'Cc', 134: 'Cc', 135: 'Cc', 136: 'Cc', 137: 'Cc',
+ 138: 'Cc', 139: 'Cc', 140: 'Cc', 141: 'Cc', 142: 'Cc', 143: 'Cc',
+ 144: 'Cc', 145: 'Cc', 146: 'Cc', 147: 'Cc', 148: 'Cc', 149: 'Cc',
+ 150: 'Cc', 151: 'Cc', 152: 'Cc', 153: 'Cc', 154: 'Cc', 155: 'Cc',
+ 156: 'Cc', 157: 'Cc', 158: 'Cc', 159: 'Cc', 160: 'Zs', 161: 'Po',
+ 162: 'Sc', 163: 'Sc', 164: 'Sc', 165: 'Sc', 166: 'So', 167: 'So',
+ 168: 'Sk', 169: 'So', 170: 'Ll', 171: 'Pi', 172: 'Sm', 173: 'Cf',
+ 174: 'So', 175: 'Sk', 176: 'So', 177: 'Sm', 178: 'No', 179: 'No',
+ 180: 'Sk', 181: 'Ll', 182: 'So', 183: 'Po', 184: 'Sk', 185: 'No',
+ 186: 'Ll', 187: 'Pf', 188: 'No', 189: 'No', 190: 'No', 191: 'Po',
+ 192: 'Lu', 193: 'Lu', 194: 'Lu', 195: 'Lu', 196: 'Lu', 197: 'Lu',
+ 198: 'Lu', 199: 'Lu', 200: 'Lu', 201: 'Lu', 202: 'Lu', 203: 'Lu',
+ 204: 'Lu', 205: 'Lu', 206: 'Lu', 207: 'Lu', 208: 'Lu', 209: 'Lu',
+ 210: 'Lu', 211: 'Lu', 212: 'Lu', 213: 'Lu', 214: 'Lu', 215: 'Sm',
+ 216: 'Lu', 217: 'Lu', 218: 'Lu', 219: 'Lu', 220: 'Lu', 221: 'Lu',
+ 222: 'Lu', 223: 'Ll', 224: 'Ll', 225: 'Ll', 226: 'Ll', 227: 'Ll',
+ 228: 'Ll', 229: 'Ll', 230: 'Ll', 231: 'Ll', 232: 'Ll', 233: 'Ll',
+ 234: 'Ll', 235: 'Ll', 236: 'Ll', 237: 'Ll', 238: 'Ll', 239: 'Ll',
+ 240: 'Ll', 241: 'Ll', 242: 'Ll', 243: 'Ll', 244: 'Ll', 245: 'Ll',
+ 246: 'Ll', 247: 'Sm', 248: 'Ll', 249: 'Ll', 250: 'Ll', 251: 'Ll',
+ 252: 'Ll', 253: 'Ll', 254: 'Ll'
+ }
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -0,0 +1,567 @@
+# Copyright 2000-2010 Michael Hudson-Doyle <micahel at gmail.com>
+# Antonio Cuni
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import termios, select, os, struct, errno
+import signal, re, time, sys
+from fcntl import ioctl
+from pyrepl import curses
+from pyrepl.fancy_termios import tcgetattr, tcsetattr
+from pyrepl.console import Console, Event
+from pyrepl import unix_eventqueue
+
+class InvalidTerminal(RuntimeError):
+ pass
+
+_error = (termios.error, curses.error, InvalidTerminal)
+
+# there are arguments for changing this to "refresh"
+SIGWINCH_EVENT = 'repaint'
+
+FIONREAD = getattr(termios, "FIONREAD", None)
+TIOCGWINSZ = getattr(termios, "TIOCGWINSZ", None)
+
+def _my_getstr(cap, optional=0):
+ r = curses.tigetstr(cap)
+ if not optional and r is None:
+ raise InvalidTerminal, \
+ "terminal doesn't have the required '%s' capability"%cap
+ return r
+
+# at this point, can we say: AAAAAAAAAAAAAAAAAAAAAARGH!
+def maybe_add_baudrate(dict, rate):
+ name = 'B%d'%rate
+ if hasattr(termios, name):
+ dict[getattr(termios, name)] = rate
+
+ratedict = {}
+for r in [0, 110, 115200, 1200, 134, 150, 1800, 19200, 200, 230400,
+ 2400, 300, 38400, 460800, 4800, 50, 57600, 600, 75, 9600]:
+ maybe_add_baudrate(ratedict, r)
+
+del r, maybe_add_baudrate
+
+delayprog = re.compile("\\$<([0-9]+)((?:/|\\*){0,2})>")
+
+try:
+ poll = select.poll
+except AttributeError:
+ # this is exactly the minumum necessary to support what we
+ # do with poll objects
+ class poll:
+ def __init__(self):
+ pass
+ def register(self, fd, flag):
+ self.fd = fd
+ def poll(self, timeout=None):
+ r,w,e = select.select([self.fd],[],[],timeout)
+ return r
+
+POLLIN = getattr(select, "POLLIN", None)
+
+class UnixConsole(Console):
+ def __init__(self, f_in=0, f_out=1, term=None, encoding=None):
+ if encoding is None:
+ encoding = sys.getdefaultencoding()
+
+ self.encoding = encoding
+
+ if isinstance(f_in, int):
+ self.input_fd = f_in
+ else:
+ self.input_fd = f_in.fileno()
+
+ if isinstance(f_out, int):
+ self.output_fd = f_out
+ else:
+ self.output_fd = f_out.fileno()
+
+ self.pollob = poll()
+ self.pollob.register(self.input_fd, POLLIN)
+ curses.setupterm(term, self.output_fd)
+ self.term = term
+
+ self._bel = _my_getstr("bel")
+ self._civis = _my_getstr("civis", optional=1)
+ self._clear = _my_getstr("clear")
+ self._cnorm = _my_getstr("cnorm", optional=1)
+ self._cub = _my_getstr("cub", optional=1)
+ self._cub1 = _my_getstr("cub1", 1)
+ self._cud = _my_getstr("cud", 1)
+ self._cud1 = _my_getstr("cud1", 1)
+ self._cuf = _my_getstr("cuf", 1)
+ self._cuf1 = _my_getstr("cuf1", 1)
+ self._cup = _my_getstr("cup")
+ self._cuu = _my_getstr("cuu", 1)
+ self._cuu1 = _my_getstr("cuu1", 1)
+ self._dch1 = _my_getstr("dch1", 1)
+ self._dch = _my_getstr("dch", 1)
+ self._el = _my_getstr("el")
+ self._hpa = _my_getstr("hpa", 1)
+ self._ich = _my_getstr("ich", 1)
+ self._ich1 = _my_getstr("ich1", 1)
+ self._ind = _my_getstr("ind", 1)
+ self._pad = _my_getstr("pad", 1)
+ self._ri = _my_getstr("ri", 1)
+ self._rmkx = _my_getstr("rmkx", 1)
+ self._smkx = _my_getstr("smkx", 1)
+
+ ## work out how we're going to sling the cursor around
+ if 0 and self._hpa: # hpa don't work in windows telnet :-(
+ self.__move_x = self.__move_x_hpa
+ elif self._cub and self._cuf:
+ self.__move_x = self.__move_x_cub_cuf
+ elif self._cub1 and self._cuf1:
+ self.__move_x = self.__move_x_cub1_cuf1
+ else:
+ raise RuntimeError, "insufficient terminal (horizontal)"
+
+ if self._cuu and self._cud:
+ self.__move_y = self.__move_y_cuu_cud
+ elif self._cuu1 and self._cud1:
+ self.__move_y = self.__move_y_cuu1_cud1
+ else:
+ raise RuntimeError, "insufficient terminal (vertical)"
+
+ if self._dch1:
+ self.dch1 = self._dch1
+ elif self._dch:
+ self.dch1 = curses.tparm(self._dch, 1)
+ else:
+ self.dch1 = None
+
+ if self._ich1:
+ self.ich1 = self._ich1
+ elif self._ich:
+ self.ich1 = curses.tparm(self._ich, 1)
+ else:
+ self.ich1 = None
+
+ self.__move = self.__move_short
+
+ self.event_queue = unix_eventqueue.EventQueue(self.input_fd)
+ self.partial_char = ''
+ self.cursor_visible = 1
+
+ def change_encoding(self, encoding):
+ self.encoding = encoding
+
+ def refresh(self, screen, (cx, cy)):
+ # this function is still too long (over 90 lines)
+
+ if not self.__gone_tall:
+ while len(self.screen) < min(len(screen), self.height):
+ self.__hide_cursor()
+ self.__move(0, len(self.screen) - 1)
+ self.__write("\n")
+ self.__posxy = 0, len(self.screen)
+ self.screen.append("")
+ else:
+ while len(self.screen) < len(screen):
+ self.screen.append("")
+
+ if len(screen) > self.height:
+ self.__gone_tall = 1
+ self.__move = self.__move_tall
+
+ px, py = self.__posxy
+ old_offset = offset = self.__offset
+ height = self.height
+
+ if 0:
+ global counter
+ try:
+ counter
+ except NameError:
+ counter = 0
+ self.__write_code(curses.tigetstr("setaf"), counter)
+ counter += 1
+ if counter > 8:
+ counter = 0
+
+ # we make sure the cursor is on the screen, and that we're
+ # using all of the screen if we can
+ if cy < offset:
+ offset = cy
+ elif cy >= offset + height:
+ offset = cy - height + 1
+ elif offset > 0 and len(screen) < offset + height:
+ offset = max(len(screen) - height, 0)
+ screen.append("")
+
+ oldscr = self.screen[old_offset:old_offset + height]
+ newscr = screen[offset:offset + height]
+
+ # use hardware scrolling if we have it.
+ if old_offset > offset and self._ri:
+ self.__hide_cursor()
+ self.__write_code(self._cup, 0, 0)
+ self.__posxy = 0, old_offset
+ for i in range(old_offset - offset):
+ self.__write_code(self._ri)
+ oldscr.pop(-1)
+ oldscr.insert(0, "")
+ elif old_offset < offset and self._ind:
+ self.__hide_cursor()
+ self.__write_code(self._cup, self.height - 1, 0)
+ self.__posxy = 0, old_offset + self.height - 1
+ for i in range(offset - old_offset):
+ self.__write_code(self._ind)
+ oldscr.pop(0)
+ oldscr.append("")
+
+ self.__offset = offset
+
+ for y, oldline, newline, in zip(range(offset, offset + height),
+ oldscr,
+ newscr):
+ if oldline != newline:
+ self.__write_changed_line(y, oldline, newline, px)
+
+ y = len(newscr)
+ while y < len(oldscr):
+ self.__hide_cursor()
+ self.__move(0, y)
+ self.__posxy = 0, y
+ self.__write_code(self._el)
+ y += 1
+
+ self.__show_cursor()
+
+ self.screen = screen
+ self.move_cursor(cx, cy)
+ self.flushoutput()
+
+ def __write_changed_line(self, y, oldline, newline, px):
+ # this is frustrating; there's no reason to test (say)
+ # self.dch1 inside the loop -- but alternative ways of
+ # structuring this function are equally painful (I'm trying to
+ # avoid writing code generators these days...)
+ x = 0
+ minlen = min(len(oldline), len(newline))
+ #
+ # reuse the oldline as much as possible, but stop as soon as we
+ # encounter an ESCAPE, because it might be the start of an escape
+ # sequene
+ while x < minlen and oldline[x] == newline[x] and newline[x] != '\x1b':
+ x += 1
+ if oldline[x:] == newline[x+1:] and self.ich1:
+ if ( y == self.__posxy[1] and x > self.__posxy[0]
+ and oldline[px:x] == newline[px+1:x+1] ):
+ x = px
+ self.__move(x, y)
+ self.__write_code(self.ich1)
+ self.__write(newline[x])
+ self.__posxy = x + 1, y
+ elif x < minlen and oldline[x + 1:] == newline[x + 1:]:
+ self.__move(x, y)
+ self.__write(newline[x])
+ self.__posxy = x + 1, y
+ elif (self.dch1 and self.ich1 and len(newline) == self.width
+ and x < len(newline) - 2
+ and newline[x+1:-1] == oldline[x:-2]):
+ self.__hide_cursor()
+ self.__move(self.width - 2, y)
+ self.__posxy = self.width - 2, y
+ self.__write_code(self.dch1)
+ self.__move(x, y)
+ self.__write_code(self.ich1)
+ self.__write(newline[x])
+ self.__posxy = x + 1, y
+ else:
+ self.__hide_cursor()
+ self.__move(x, y)
+ if len(oldline) > len(newline):
+ self.__write_code(self._el)
+ self.__write(newline[x:])
+ self.__posxy = len(newline), y
+
+ if '\x1b' in newline:
+ # ANSI escape characters are present, so we can't assume
+ # anything about the position of the cursor. Moving the cursor
+ # to the left margin should work to get to a known position.
+ self.move_cursor(0, y)
+
+ def __write(self, text):
+ self.__buffer.append((text, 0))
+
+ def __write_code(self, fmt, *args):
+ self.__buffer.append((curses.tparm(fmt, *args), 1))
+
+ def __maybe_write_code(self, fmt, *args):
+ if fmt:
+ self.__write_code(fmt, *args)
+
+ def __move_y_cuu1_cud1(self, y):
+ dy = y - self.__posxy[1]
+ if dy > 0:
+ self.__write_code(dy*self._cud1)
+ elif dy < 0:
+ self.__write_code((-dy)*self._cuu1)
+
+ def __move_y_cuu_cud(self, y):
+ dy = y - self.__posxy[1]
+ if dy > 0:
+ self.__write_code(self._cud, dy)
+ elif dy < 0:
+ self.__write_code(self._cuu, -dy)
+
+ def __move_x_hpa(self, x):
+ if x != self.__posxy[0]:
+ self.__write_code(self._hpa, x)
+
+ def __move_x_cub1_cuf1(self, x):
+ dx = x - self.__posxy[0]
+ if dx > 0:
+ self.__write_code(self._cuf1*dx)
+ elif dx < 0:
+ self.__write_code(self._cub1*(-dx))
+
+ def __move_x_cub_cuf(self, x):
+ dx = x - self.__posxy[0]
+ if dx > 0:
+ self.__write_code(self._cuf, dx)
+ elif dx < 0:
+ self.__write_code(self._cub, -dx)
+
+ def __move_short(self, x, y):
+ self.__move_x(x)
+ self.__move_y(y)
+
+ def __move_tall(self, x, y):
+ assert 0 <= y - self.__offset < self.height, y - self.__offset
+ self.__write_code(self._cup, y - self.__offset, x)
+
+ def move_cursor(self, x, y):
+ if y < self.__offset or y >= self.__offset + self.height:
+ self.event_queue.insert(Event('scroll', None))
+ else:
+ self.__move(x, y)
+ self.__posxy = x, y
+ self.flushoutput()
+
+ def prepare(self):
+ # per-readline preparations:
+ self.__svtermstate = tcgetattr(self.input_fd)
+ raw = self.__svtermstate.copy()
+ raw.iflag &=~ (termios.BRKINT | termios.INPCK |
+ termios.ISTRIP | termios.IXON)
+ raw.oflag &=~ (termios.OPOST)
+ raw.cflag &=~ (termios.CSIZE|termios.PARENB)
+ raw.cflag |= (termios.CS8)
+ raw.lflag &=~ (termios.ICANON|termios.ECHO|
+ termios.IEXTEN|(termios.ISIG*1))
+ raw.cc[termios.VMIN] = 1
+ raw.cc[termios.VTIME] = 0
+ tcsetattr(self.input_fd, termios.TCSADRAIN, raw)
+
+ self.screen = []
+ self.height, self.width = self.getheightwidth()
+
+ self.__buffer = []
+
+ self.__posxy = 0, 0
+ self.__gone_tall = 0
+ self.__move = self.__move_short
+ self.__offset = 0
+
+ self.__maybe_write_code(self._smkx)
+
+ self.old_sigwinch = signal.signal(
+ signal.SIGWINCH, self.__sigwinch)
+
+ def restore(self):
+ self.__maybe_write_code(self._rmkx)
+ self.flushoutput()
+ tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
+
+ signal.signal(signal.SIGWINCH, self.old_sigwinch)
+
+ def __sigwinch(self, signum, frame):
+ self.height, self.width = self.getheightwidth()
+ self.event_queue.insert(Event('resize', None))
+
+ def push_char(self, char):
+ self.partial_char += char
+ try:
+ c = unicode(self.partial_char, self.encoding)
+ except UnicodeError, e:
+ if len(e.args) > 4 and \
+ e.args[4] == 'unexpected end of data':
+ pass
+ else:
+ raise
+ else:
+ self.partial_char = ''
+ self.event_queue.push(c)
+
+ def get_event(self, block=1):
+ while self.event_queue.empty():
+ while 1: # All hail Unix!
+ try:
+ self.push_char(os.read(self.input_fd, 1))
+ except (IOError, OSError), err:
+ if err.errno == errno.EINTR:
+ if not self.event_queue.empty():
+ return self.event_queue.get()
+ else:
+ continue
+ else:
+ raise
+ else:
+ break
+ if not block:
+ break
+ return self.event_queue.get()
+
+ def wait(self):
+ self.pollob.poll()
+
+ def set_cursor_vis(self, vis):
+ if vis:
+ self.__show_cursor()
+ else:
+ self.__hide_cursor()
+
+ def __hide_cursor(self):
+ if self.cursor_visible:
+ self.__maybe_write_code(self._civis)
+ self.cursor_visible = 0
+
+ def __show_cursor(self):
+ if not self.cursor_visible:
+ self.__maybe_write_code(self._cnorm)
+ self.cursor_visible = 1
+
+ def repaint_prep(self):
+ if not self.__gone_tall:
+ self.__posxy = 0, self.__posxy[1]
+ self.__write("\r")
+ ns = len(self.screen)*['\000'*self.width]
+ self.screen = ns
+ else:
+ self.__posxy = 0, self.__offset
+ self.__move(0, self.__offset)
+ ns = self.height*['\000'*self.width]
+ self.screen = ns
+
+ if TIOCGWINSZ:
+ def getheightwidth(self):
+ try:
+ return int(os.environ["LINES"]), int(os.environ["COLUMNS"])
+ except KeyError:
+ height, width = struct.unpack(
+ "hhhh", ioctl(self.input_fd, TIOCGWINSZ, "\000"*8))[0:2]
+ if not height: return 25, 80
+ return height, width
+ else:
+ def getheightwidth(self):
+ try:
+ return int(os.environ["LINES"]), int(os.environ["COLUMNS"])
+ except KeyError:
+ return 25, 80
+
+ def forgetinput(self):
+ termios.tcflush(self.input_fd, termios.TCIFLUSH)
+
+ def flushoutput(self):
+ for text, iscode in self.__buffer:
+ if iscode:
+ self.__tputs(text)
+ else:
+ os.write(self.output_fd, text.encode(self.encoding))
+ del self.__buffer[:]
+
+ def __tputs(self, fmt, prog=delayprog):
+ """A Python implementation of the curses tputs function; the
+ curses one can't really be wrapped in a sane manner.
+
+ I have the strong suspicion that this is complexity that
+ will never do anyone any good."""
+ # using .get() means that things will blow up
+ # only if the bps is actually needed (which I'm
+ # betting is pretty unlkely)
+ bps = ratedict.get(self.__svtermstate.ospeed)
+ while 1:
+ m = prog.search(fmt)
+ if not m:
+ os.write(self.output_fd, fmt)
+ break
+ x, y = m.span()
+ os.write(self.output_fd, fmt[:x])
+ fmt = fmt[y:]
+ delay = int(m.group(1))
+ if '*' in m.group(2):
+ delay *= self.height
+ if self._pad:
+ nchars = (bps*delay)/1000
+ os.write(self.output_fd, self._pad*nchars)
+ else:
+ time.sleep(float(delay)/1000.0)
+
+ def finish(self):
+ y = len(self.screen) - 1
+ while y >= 0 and not self.screen[y]:
+ y -= 1
+ self.__move(0, min(y, self.height + self.__offset - 1))
+ self.__write("\n\r")
+ self.flushoutput()
+
+ def beep(self):
+ self.__maybe_write_code(self._bel)
+ self.flushoutput()
+
+ if FIONREAD:
+ def getpending(self):
+ e = Event('key', '', '')
+
+ while not self.event_queue.empty():
+ e2 = self.event_queue.get()
+ e.data += e2.data
+ e.raw += e.raw
+
+ amount = struct.unpack(
+ "i", ioctl(self.input_fd, FIONREAD, "\0\0\0\0"))[0]
+ raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace')
+ e.data += raw
+ e.raw += raw
+ return e
+ else:
+ def getpending(self):
+ e = Event('key', '', '')
+
+ while not self.event_queue.empty():
+ e2 = self.event_queue.get()
+ e.data += e2.data
+ e.raw += e.raw
+
+ amount = 10000
+ raw = unicode(os.read(self.input_fd, amount), self.encoding, 'replace')
+ e.data += raw
+ e.raw += raw
+ return e
+
+ def clear(self):
+ self.__write_code(self._clear)
+ self.__gone_tall = 1
+ self.__move = self.__move_tall
+ self.__posxy = 0, 0
+ self.screen = []
+
diff --git a/lib_pypy/pyrepl/unix_eventqueue.py b/lib_pypy/pyrepl/unix_eventqueue.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pyrepl/unix_eventqueue.py
@@ -0,0 +1,86 @@
+# Copyright 2000-2008 Michael Hudson-Doyle <micahel at gmail.com>
+# Armin Rigo
+#
+# All Rights Reserved
+#
+#
+# Permission to use, copy, modify, and distribute this software and
+# its documentation for any purpose is hereby granted without fee,
+# provided that the above copyright notice appear in all copies and
+# that both that copyright notice and this permission notice appear in
+# supporting documentation.
+#
+# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Bah, this would be easier to test if curses/terminfo didn't have so
+# much non-introspectable global state.
+
+from pyrepl import keymap
+from pyrepl.console import Event
+from pyrepl import curses
+from termios import tcgetattr, VERASE
+import os
+
+_keynames = {
+ "delete" : "kdch1",
+ "down" : "kcud1",
+ "end" : "kend",
+ "enter" : "kent",
+ "f1" : "kf1", "f2" : "kf2", "f3" : "kf3", "f4" : "kf4",
+ "f5" : "kf5", "f6" : "kf6", "f7" : "kf7", "f8" : "kf8",
+ "f9" : "kf9", "f10" : "kf10", "f11" : "kf11", "f12" : "kf12",
+ "f13" : "kf13", "f14" : "kf14", "f15" : "kf15", "f16" : "kf16",
+ "f17" : "kf17", "f18" : "kf18", "f19" : "kf19", "f20" : "kf20",
+ "home" : "khome",
+ "insert" : "kich1",
+ "left" : "kcub1",
+ "page down" : "knp",
+ "page up" : "kpp",
+ "right" : "kcuf1",
+ "up" : "kcuu1",
+ }
+
+class EventQueue(object):
+ def __init__(self, fd):
+ our_keycodes = {}
+ for key, tiname in _keynames.items():
+ keycode = curses.tigetstr(tiname)
+ if keycode:
+ our_keycodes[keycode] = unicode(key)
+ if os.isatty(fd):
+ our_keycodes[tcgetattr(fd)[6][VERASE]] = u'backspace'
+ self.k = self.ck = keymap.compile_keymap(our_keycodes)
+ self.events = []
+ self.buf = []
+ def get(self):
+ if self.events:
+ return self.events.pop(0)
+ else:
+ return None
+ def empty(self):
+ return not self.events
+ def insert(self, event):
+ self.events.append(event)
+ def push(self, char):
+ if char in self.k:
+ k = self.k[char]
+ if isinstance(k, dict):
+ self.buf.append(char)
+ self.k = k
+ else:
+ self.events.append(Event('key', k, ''.join(self.buf) + char))
+ self.buf = []
+ self.k = self.ck
+ elif self.buf:
+ self.events.extend([Event('key', c, c) for c in self.buf])
+ self.buf = []
+ self.k = self.ck
+ self.push(char)
+ else:
+ self.events.append(Event('key', char, char))
diff --git a/py/_io/terminalwriter.py b/py/_io/terminalwriter.py
--- a/py/_io/terminalwriter.py
+++ b/py/_io/terminalwriter.py
@@ -81,6 +81,9 @@
oldcolors = GetConsoleInfo(handle).wAttributes
attr |= (oldcolors & 0x0f0)
SetConsoleTextAttribute(handle, attr)
+ while len(text) > 32768:
+ file.write(text[:32768])
+ text = text[32768:]
file.write(text)
SetConsoleTextAttribute(handle, oldcolors)
else:
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -3,6 +3,7 @@
from pypy.interpreter.pycode import cpython_code_signature
from pypy.interpreter.argument import rawshape
from pypy.interpreter.argument import ArgErr
+from pypy.interpreter.function import Defaults
from pypy.tool.sourcetools import valid_identifier
from pypy.tool.pairtype import extendabletype
@@ -15,7 +16,7 @@
overridden = False
normalized = False
modified = True
-
+
def __init__(self, desc):
self.descs = { desc: True }
self.calltables = {} # see calltable_lookup_row()
@@ -172,7 +173,7 @@
class FunctionDesc(Desc):
knowntype = types.FunctionType
overridden = False
-
+
def __init__(self, bookkeeper, pyobj=None,
name=None, signature=None, defaults=None,
specializer=None):
@@ -230,7 +231,7 @@
return '_'.join(map(nameof, thing))
else:
return str(thing)[:30]
-
+
if key is not None and alt_name is None:
postfix = valid_identifier(nameof(key))
alt_name = "%s__%s"%(self.name, postfix)
@@ -250,7 +251,7 @@
for x in defaults:
defs_s.append(self.bookkeeper.immutablevalue(x))
try:
- inputcells = args.match_signature(signature, defs_s)
+ inputcells = args.match_signature(signature, Defaults(defs_s))
except ArgErr, e:
raise TypeError, "signature mismatch: %s" % e.getmsg(self.name)
return inputcells
@@ -291,7 +292,7 @@
def bind_under(self, classdef, name):
# XXX static methods
- return self.bookkeeper.getmethoddesc(self,
+ return self.bookkeeper.getmethoddesc(self,
classdef, # originclassdef,
None, # selfclassdef
name)
@@ -574,7 +575,7 @@
while name not in cdesc.classdict:
cdesc = cdesc.basedesc
if cdesc is None:
- return None
+ return None
else:
return cdesc
@@ -750,7 +751,7 @@
class MethodDesc(Desc):
knowntype = types.MethodType
- def __init__(self, bookkeeper, funcdesc, originclassdef,
+ def __init__(self, bookkeeper, funcdesc, originclassdef,
selfclassdef, name, flags={}):
super(MethodDesc, self).__init__(bookkeeper)
self.funcdesc = funcdesc
@@ -803,7 +804,7 @@
# FunctionDescs, not MethodDescs. The present method returns the
# FunctionDesc to use as a key in that family.
return self.funcdesc
-
+
def simplify_desc_set(descs):
# Some hacking needed to make contains() happy on SomePBC: if the
# set of MethodDescs contains some "redundant" ones, i.e. ones that
@@ -894,7 +895,7 @@
return s_ImpossibleValue
else:
return self.bookkeeper.immutablevalue(value)
-
+
def create_new_attribute(self, name, value):
try:
self.read_attribute(name)
@@ -946,7 +947,7 @@
s_self = SomePBC([self.frozendesc])
args = args.prepend(s_self)
return self.funcdesc.pycall(schedule, args, s_previous_result)
-
+
def consider_call_site(bookkeeper, family, descs, args, s_result):
shape = rawshape(args, nextra=1) # account for the extra 'self'
funcdescs = [mofdesc.funcdesc for mofdesc in descs]
diff --git a/pypy/annotation/unaryop.py b/pypy/annotation/unaryop.py
--- a/pypy/annotation/unaryop.py
+++ b/pypy/annotation/unaryop.py
@@ -499,10 +499,14 @@
def getanyitem(str):
return str.basecharclass()
- def method_split(str, patt): # XXX
+ def method_split(str, patt, max=-1):
getbookkeeper().count("str_split", str, patt)
return getbookkeeper().newlist(str.basestringclass())
+ def method_rsplit(str, patt, max=-1):
+ getbookkeeper().count("str_rsplit", str, patt)
+ return getbookkeeper().newlist(str.basestringclass())
+
def method_replace(str, s1, s2):
return str.basestringclass()
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -159,6 +159,11 @@
cmdline="--allworkingmodules",
negation=True),
+ StrOption("extmodules",
+ "Comma-separated list of third-party builtin modules",
+ cmdline="--ext",
+ default=None),
+
BoolOption("translationmodules",
"use only those modules that are needed to run translate.py on pypy",
default=False,
@@ -356,8 +361,8 @@
config.objspace.std.suggest(optimized_list_getitem=True)
config.objspace.std.suggest(getattributeshortcut=True)
config.objspace.std.suggest(newshortcut=True)
- if not IS_64_BITS:
- config.objspace.std.suggest(withsmalllong=True)
+ #if not IS_64_BITS:
+ # config.objspace.std.suggest(withsmalllong=True)
# extra costly optimizations only go in level 3
if level == '3':
diff --git a/pypy/config/test/test_pypyoption.py b/pypy/config/test/test_pypyoption.py
--- a/pypy/config/test/test_pypyoption.py
+++ b/pypy/config/test/test_pypyoption.py
@@ -70,6 +70,6 @@
prefix = descr._name
c = Config(descr)
for path in c.getpaths(include_groups=True):
- fn = prefix + "." + path + ".txt"
+ fn = prefix + "." + path + ".rst"
yield check_file_exists, fn
diff --git a/pypy/doc/Makefile b/pypy/doc/Makefile
new file mode 100644
--- /dev/null
+++ b/pypy/doc/Makefile
@@ -0,0 +1,89 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PyPy.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyPy.qhc"
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/pypy/doc/__pypy__-module.txt b/pypy/doc/__pypy__-module.rst
rename from pypy/doc/__pypy__-module.txt
rename to pypy/doc/__pypy__-module.rst
diff --git a/pypy/doc/_ref.txt b/pypy/doc/_ref.rst
rename from pypy/doc/_ref.txt
rename to pypy/doc/_ref.rst
--- a/pypy/doc/_ref.txt
+++ b/pypy/doc/_ref.rst
@@ -3,48 +3,48 @@
.. _`lib-python/`: ../../lib-python
.. _`lib-python/2.5.2/dis.py`: ../../lib-python/2.5.2/dis.py
.. _`annotation/`:
-.. _`pypy/annotation`: ../../pypy/annotation
-.. _`pypy/annotation/annrpython.py`: ../../pypy/annotation/annrpython.py
-.. _`annotation/binaryop.py`: ../../pypy/annotation/binaryop.py
-.. _`pypy/annotation/builtin.py`: ../../pypy/annotation/builtin.py
-.. _`pypy/annotation/model.py`: ../../pypy/annotation/model.py
-.. _`bin/`: ../../pypy/bin
-.. _`config/`: ../../pypy/config
-.. _`pypy/config/pypyoption.py`: ../../pypy/config/pypyoption.py
-.. _`doc/`: ../../pypy/doc
-.. _`doc/config/`: ../../pypy/doc/config
-.. _`doc/discussion/`: ../../pypy/doc/discussion
+.. _`pypy/annotation`: ../../../../pypy/annotation
+.. _`pypy/annotation/annrpython.py`: ../../../../pypy/annotation/annrpython.py
+.. _`annotation/binaryop.py`: ../../../../pypy/annotation/binaryop.py
+.. _`pypy/annotation/builtin.py`: ../../../../pypy/annotation/builtin.py
+.. _`pypy/annotation/model.py`: ../../../../pypy/annotation/model.py
+.. _`bin/`: ../../../../pypy/bin
+.. _`config/`: ../../../../pypy/config
+.. _`pypy/config/pypyoption.py`: ../../../../pypy/config/pypyoption.py
+.. _`doc/`: ../../../../pypy/doc
+.. _`doc/config/`: ../../../../pypy/doc/config
+.. _`doc/discussion/`: ../../../../pypy/doc/discussion
.. _`interpreter/`:
-.. _`pypy/interpreter`: ../../pypy/interpreter
-.. _`pypy/interpreter/argument.py`: ../../pypy/interpreter/argument.py
+.. _`pypy/interpreter`: ../../../../pypy/interpreter
+.. _`pypy/interpreter/argument.py`: ../../../../pypy/interpreter/argument.py
.. _`interpreter/astcompiler/`:
-.. _`pypy/interpreter/astcompiler`: ../../pypy/interpreter/astcompiler
-.. _`pypy/interpreter/executioncontext.py`: ../../pypy/interpreter/executioncontext.py
-.. _`pypy/interpreter/function.py`: ../../pypy/interpreter/function.py
+.. _`pypy/interpreter/astcompiler`: ../../../../pypy/interpreter/astcompiler
+.. _`pypy/interpreter/executioncontext.py`: ../../../../pypy/interpreter/executioncontext.py
+.. _`pypy/interpreter/function.py`: ../../../../pypy/interpreter/function.py
.. _`interpreter/gateway.py`:
-.. _`pypy/interpreter/gateway.py`: ../../pypy/interpreter/gateway.py
-.. _`pypy/interpreter/generator.py`: ../../pypy/interpreter/generator.py
-.. _`pypy/interpreter/mixedmodule.py`: ../../pypy/interpreter/mixedmodule.py
-.. _`pypy/interpreter/module.py`: ../../pypy/interpreter/module.py
-.. _`pypy/interpreter/nestedscope.py`: ../../pypy/interpreter/nestedscope.py
-.. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py
+.. _`pypy/interpreter/gateway.py`: ../../../../pypy/interpreter/gateway.py
+.. _`pypy/interpreter/generator.py`: ../../../../pypy/interpreter/generator.py
+.. _`pypy/interpreter/mixedmodule.py`: ../../../../pypy/interpreter/mixedmodule.py
+.. _`pypy/interpreter/module.py`: ../../../../pypy/interpreter/module.py
+.. _`pypy/interpreter/nestedscope.py`: ../../../../pypy/interpreter/nestedscope.py
+.. _`pypy/interpreter/pyopcode.py`: ../../../../pypy/interpreter/pyopcode.py
.. _`interpreter/pyparser/`:
-.. _`pypy/interpreter/pyparser`: ../../pypy/interpreter/pyparser
-.. _`pypy/interpreter/pyparser/pytokenizer.py`: ../../pypy/interpreter/pyparser/pytokenizer.py
-.. _`pypy/interpreter/pyparser/parser.py`: ../../pypy/interpreter/pyparser/parser.py
-.. _`pypy/interpreter/pyparser/pyparse.py`: ../../pypy/interpreter/pyparser/pyparse.py
-.. _`pypy/interpreter/pyparser/future.py`: ../../pypy/interpreter/pyparser/future.py
-.. _`pypy/interpreter/pyparser/metaparser.py`: ../../pypy/interpreter/pyparser/metaparser.py
-.. _`pypy/interpreter/astcompiler/astbuilder.py`: ../../pypy/interpreter/astcompiler/astbuilder.py
-.. _`pypy/interpreter/astcompiler/optimize.py`: ../../pypy/interpreter/astcompiler/optimize.py
-.. _`pypy/interpreter/astcompiler/codegen.py`: ../../pypy/interpreter/astcompiler/codegen.py
-.. _`pypy/interpreter/astcompiler/tools/asdl_py.py`: ../../pypy/interpreter/astcompiler/tools/asdl_py.py
-.. _`pypy/interpreter/astcompiler/tools/Python.asdl`: ../../pypy/interpreter/astcompiler/tools/Python.asdl
-.. _`pypy/interpreter/astcompiler/assemble.py`: ../../pypy/interpreter/astcompiler/assemble.py
-.. _`pypy/interpreter/astcompiler/symtable.py`: ../../pypy/interpreter/astcompiler/symtable.py
-.. _`pypy/interpreter/astcompiler/asthelpers.py`: ../../pypy/interpreter/astcompiler/asthelpers.py
-.. _`pypy/interpreter/astcompiler/ast.py`: ../../pypy/interpreter/astcompiler/ast.py
-.. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py
+.. _`pypy/interpreter/pyparser`: ../../../../pypy/interpreter/pyparser
+.. _`pypy/interpreter/pyparser/pytokenizer.py`: ../../../../pypy/interpreter/pyparser/pytokenizer.py
+.. _`pypy/interpreter/pyparser/parser.py`: ../../../../pypy/interpreter/pyparser/parser.py
+.. _`pypy/interpreter/pyparser/pyparse.py`: ../../../../pypy/interpreter/pyparser/pyparse.py
+.. _`pypy/interpreter/pyparser/future.py`: ../../../../pypy/interpreter/pyparser/future.py
+.. _`pypy/interpreter/pyparser/metaparser.py`: ../../../../pypy/interpreter/pyparser/metaparser.py
+.. _`pypy/interpreter/astcompiler/astbuilder.py`: ../../../../pypy/interpreter/astcompiler/astbuilder.py
+.. _`pypy/interpreter/astcompiler/optimize.py`: ../../../../pypy/interpreter/astcompiler/optimize.py
+.. _`pypy/interpreter/astcompiler/codegen.py`: ../../../../pypy/interpreter/astcompiler/codegen.py
+.. _`pypy/interpreter/astcompiler/tools/asdl_py.py`: ../../../../pypy/interpreter/astcompiler/tools/asdl_py.py
+.. _`pypy/interpreter/astcompiler/tools/Python.asdl`: ../../../../pypy/interpreter/astcompiler/tools/Python.asdl
+.. _`pypy/interpreter/astcompiler/assemble.py`: ../../../../pypy/interpreter/astcompiler/assemble.py
+.. _`pypy/interpreter/astcompiler/symtable.py`: ../../../../pypy/interpreter/astcompiler/symtable.py
+.. _`pypy/interpreter/astcompiler/asthelpers.py`: ../../../../pypy/interpreter/astcompiler/asthelpers.py
+.. _`pypy/interpreter/astcompiler/ast.py`: ../../../../pypy/interpreter/astcompiler/ast.py
+.. _`pypy/interpreter/typedef.py`: ../../../../pypy/interpreter/typedef.py
.. _`lib/`:
.. _`lib_pypy/`: ../../lib_pypy
.. _`lib/distributed/`: ../../lib_pypy/distributed
@@ -52,56 +52,56 @@
.. _`lib_pypy/pypy_test/`: ../../lib_pypy/pypy_test
.. _`module/`:
.. _`pypy/module`:
-.. _`pypy/module/`: ../../pypy/module
-.. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py
-.. _`pypy/module/_stackless/test/test_clonable.py`: ../../pypy/module/_stackless/test/test_clonable.py
-.. _`pypy/module/_stackless/test/test_composable_coroutine.py`: ../../pypy/module/_stackless/test/test_composable_coroutine.py
+.. _`pypy/module/`: ../../../../pypy/module
+.. _`pypy/module/__builtin__/__init__.py`: ../../../../pypy/module/__builtin__/__init__.py
+.. _`pypy/module/_stackless/test/test_clonable.py`: ../../../../pypy/module/_stackless/test/test_clonable.py
+.. _`pypy/module/_stackless/test/test_composable_coroutine.py`: ../../../../pypy/module/_stackless/test/test_composable_coroutine.py
.. _`objspace/`:
-.. _`pypy/objspace`: ../../pypy/objspace
-.. _`objspace/dump.py`: ../../pypy/objspace/dump.py
-.. _`objspace/flow/`: ../../pypy/objspace/flow
+.. _`pypy/objspace`: ../../../../pypy/objspace
+.. _`objspace/dump.py`: ../../../../pypy/objspace/dump.py
+.. _`objspace/flow/`: ../../../../pypy/objspace/flow
.. _`objspace/std/`:
-.. _`pypy/objspace/std`: ../../pypy/objspace/std
-.. _`objspace/taint.py`: ../../pypy/objspace/taint.py
+.. _`pypy/objspace/std`: ../../../../pypy/objspace/std
+.. _`objspace/taint.py`: ../../../../pypy/objspace/taint.py
.. _`objspace/thunk.py`:
-.. _`pypy/objspace/thunk.py`: ../../pypy/objspace/thunk.py
+.. _`pypy/objspace/thunk.py`: ../../../../pypy/objspace/thunk.py
.. _`objspace/trace.py`:
-.. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py
+.. _`pypy/objspace/trace.py`: ../../../../pypy/objspace/trace.py
.. _`pypy/rlib`:
-.. _`rlib/`: ../../pypy/rlib
-.. _`pypy/rlib/rarithmetic.py`: ../../pypy/rlib/rarithmetic.py
-.. _`pypy/rlib/test`: ../../pypy/rlib/test
+.. _`rlib/`: ../../../../pypy/rlib
+.. _`pypy/rlib/rarithmetic.py`: ../../../../pypy/rlib/rarithmetic.py
+.. _`pypy/rlib/test`: ../../../../pypy/rlib/test
.. _`pypy/rpython`:
.. _`pypy/rpython/`:
-.. _`rpython/`: ../../pypy/rpython
-.. _`rpython/lltypesystem/`: ../../pypy/rpython/lltypesystem
+.. _`rpython/`: ../../../../pypy/rpython
+.. _`rpython/lltypesystem/`: ../../../../pypy/rpython/lltypesystem
.. _`pypy/rpython/lltypesystem/lltype.py`:
-.. _`rpython/lltypesystem/lltype.py`: ../../pypy/rpython/lltypesystem/lltype.py
-.. _`rpython/memory/`: ../../pypy/rpython/memory
-.. _`rpython/memory/gc/generation.py`: ../../pypy/rpython/memory/gc/generation.py
-.. _`rpython/memory/gc/hybrid.py`: ../../pypy/rpython/memory/gc/hybrid.py
-.. _`rpython/memory/gc/markcompact.py`: ../../pypy/rpython/memory/gc/markcompact.py
-.. _`rpython/memory/gc/marksweep.py`: ../../pypy/rpython/memory/gc/marksweep.py
-.. _`rpython/memory/gc/semispace.py`: ../../pypy/rpython/memory/gc/semispace.py
-.. _`rpython/ootypesystem/`: ../../pypy/rpython/ootypesystem
-.. _`rpython/ootypesystem/ootype.py`: ../../pypy/rpython/ootypesystem/ootype.py
-.. _`rpython/rint.py`: ../../pypy/rpython/rint.py
-.. _`rpython/rlist.py`: ../../pypy/rpython/rlist.py
-.. _`rpython/rmodel.py`: ../../pypy/rpython/rmodel.py
-.. _`pypy/rpython/rtyper.py`: ../../pypy/rpython/rtyper.py
-.. _`pypy/rpython/test/test_llinterp.py`: ../../pypy/rpython/test/test_llinterp.py
-.. _`pypy/test_all.py`: ../../pypy/test_all.py
-.. _`tool/`: ../../pypy/tool
-.. _`tool/algo/`: ../../pypy/tool/algo
-.. _`tool/pytest/`: ../../pypy/tool/pytest
+.. _`rpython/lltypesystem/lltype.py`: ../../../../pypy/rpython/lltypesystem/lltype.py
+.. _`rpython/memory/`: ../../../../pypy/rpython/memory
+.. _`rpython/memory/gc/generation.py`: ../../../../pypy/rpython/memory/gc/generation.py
+.. _`rpython/memory/gc/hybrid.py`: ../../../../pypy/rpython/memory/gc/hybrid.py
+.. _`rpython/memory/gc/markcompact.py`: ../../../../pypy/rpython/memory/gc/markcompact.py
+.. _`rpython/memory/gc/marksweep.py`: ../../../../pypy/rpython/memory/gc/marksweep.py
+.. _`rpython/memory/gc/semispace.py`: ../../../../pypy/rpython/memory/gc/semispace.py
+.. _`rpython/ootypesystem/`: ../../../../pypy/rpython/ootypesystem
+.. _`rpython/ootypesystem/ootype.py`: ../../../../pypy/rpython/ootypesystem/ootype.py
+.. _`rpython/rint.py`: ../../../../pypy/rpython/rint.py
+.. _`rpython/rlist.py`: ../../../../pypy/rpython/rlist.py
+.. _`rpython/rmodel.py`: ../../../../pypy/rpython/rmodel.py
+.. _`pypy/rpython/rtyper.py`: ../../../../pypy/rpython/rtyper.py
+.. _`pypy/rpython/test/test_llinterp.py`: ../../../../pypy/rpython/test/test_llinterp.py
+.. _`pypy/test_all.py`: ../../../../pypy/test_all.py
+.. _`tool/`: ../../../../pypy/tool
+.. _`tool/algo/`: ../../../../pypy/tool/algo
+.. _`tool/pytest/`: ../../../../pypy/tool/pytest
.. _`pypy/translator`:
-.. _`translator/`: ../../pypy/translator
-.. _`translator/backendopt/`: ../../pypy/translator/backendopt
-.. _`translator/c/`: ../../pypy/translator/c
-.. _`translator/cli/`: ../../pypy/translator/cli
-.. _`translator/goal/`: ../../pypy/translator/goal
-.. _`pypy/translator/goal/targetnopstandalone.py`: ../../pypy/translator/goal/targetnopstandalone.py
-.. _`translator/jvm/`: ../../pypy/translator/jvm
-.. _`translator/stackless/`: ../../pypy/translator/stackless
-.. _`translator/tool/`: ../../pypy/translator/tool
+.. _`translator/`: ../../../../pypy/translator
+.. _`translator/backendopt/`: ../../../../pypy/translator/backendopt
+.. _`translator/c/`: ../../../../pypy/translator/c
+.. _`translator/cli/`: ../../../../pypy/translator/cli
+.. _`translator/goal/`: ../../../../pypy/translator/goal
+.. _`pypy/translator/goal/targetnopstandalone.py`: ../../../../pypy/translator/goal/targetnopstandalone.py
+.. _`translator/jvm/`: ../../../../pypy/translator/jvm
+.. _`translator/stackless/`: ../../../../pypy/translator/stackless
+.. _`translator/tool/`: ../../../../pypy/translator/tool
.. _`translator/js/`: http://codespeak.net/svn/pypy/branch/oo-jit/pypy/translator/js/
diff --git a/pypy/doc/architecture.txt b/pypy/doc/architecture.rst
rename from pypy/doc/architecture.txt
rename to pypy/doc/architecture.rst
--- a/pypy/doc/architecture.txt
+++ b/pypy/doc/architecture.rst
@@ -1,9 +1,9 @@
==================================================
-PyPy - Goals and Architecture Overview
+Goals and Architecture Overview
==================================================
.. contents::
-.. sectnum::
+
This document gives an overview of the goals and architecture of PyPy.
See `getting started`_ for a practical introduction and starting points.
@@ -260,5 +260,5 @@
.. _`generate Just-In-Time Compilers`: jit/index.html
.. _`JIT Generation in PyPy`: jit/index.html
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/buildtool.txt b/pypy/doc/buildtool.rst
rename from pypy/doc/buildtool.txt
rename to pypy/doc/buildtool.rst
--- a/pypy/doc/buildtool.txt
+++ b/pypy/doc/buildtool.rst
@@ -2,6 +2,8 @@
PyPyBuilder
============
+.. include:: crufty.rst
+
What is this?
=============
diff --git a/pypy/doc/carbonpython.txt b/pypy/doc/carbonpython.rst
rename from pypy/doc/carbonpython.txt
rename to pypy/doc/carbonpython.rst
diff --git a/pypy/doc/cleanup-todo.txt b/pypy/doc/cleanup-todo.rst
rename from pypy/doc/cleanup-todo.txt
rename to pypy/doc/cleanup-todo.rst
diff --git a/pypy/doc/cleanup.rst b/pypy/doc/cleanup.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/cleanup.rst
@@ -0,0 +1,46 @@
+Old documentation that needs review
+-----------------------------------
+
+.. The following stuff is old (and crufty?), and needs further investigation:
+
+.. doc-index: This needs merging somehow
+
+.. svn-help.rst: Needs merging/replacing with hg stuff:
+
+
+.. toctree::
+
+ buildtool.rst
+ distribution.rst
+
+ externaltools.rst
+
+ geninterp.rst
+
+ objspace-proxies.rst
+
+ old_news.rst
+
+ project-ideas.rst
+
+ rffi.rst
+
+ sandbox.rst
+
+ statistic/index.rst
+
+ theory.rst
+
+ translation-aspects.rst
+
+ docindex.rst
+
+ svn-help.rst
+
+ dot-net.rst
+
+ maemo.rst
+
+
+
+
diff --git a/pypy/doc/cli-backend.txt b/pypy/doc/cli-backend.rst
rename from pypy/doc/cli-backend.txt
rename to pypy/doc/cli-backend.rst
diff --git a/pypy/doc/clr-module.txt b/pypy/doc/clr-module.rst
rename from pypy/doc/clr-module.txt
rename to pypy/doc/clr-module.rst
diff --git a/pypy/doc/coding-guide.txt b/pypy/doc/coding-guide.rst
rename from pypy/doc/coding-guide.txt
rename to pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.txt
+++ b/pypy/doc/coding-guide.rst
@@ -1,9 +1,9 @@
=====================================
-PyPy - Coding Guide
+Coding Guide
=====================================
.. contents::
-.. sectnum::
+
This document describes coding requirements and conventions for
@@ -354,7 +354,7 @@
silent wrap-around. Whenever we need more control, we use the following
helpers (which live the `pypy/rlib/rarithmetic.py`_):
-.. _`pypy/rlib/rarithmetic.py`: ../../pypy/rlib/rarithmetic.py
+.. _`pypy/rlib/rarithmetic.py`: ../../../../pypy/rlib/rarithmetic.py
**ovfcheck()**
@@ -1085,4 +1085,4 @@
which will check that remote URLs are reachable.
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
new file mode 100644
--- /dev/null
+++ b/pypy/doc/conf.py
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+#
+# PyPy documentation build configuration file, created by
+# sphinx-quickstart on Mon Mar 14 10:44:41 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'PyPy'
+copyright = u'2011, The PyPy Project'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.5'
+# The full version, including alpha/beta/rc tags.
+release = '1.5-alpha'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'PyPydoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('temp_index', 'PyPy.tex', u'PyPy Documentation',
+ u'The PyPy Project', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}
diff --git a/pypy/doc/config/commandline.txt b/pypy/doc/config/commandline.rst
rename from pypy/doc/config/commandline.txt
rename to pypy/doc/config/commandline.rst
diff --git a/pypy/doc/config/confrest.py b/pypy/doc/config/confrest.py
--- a/pypy/doc/config/confrest.py
+++ b/pypy/doc/config/confrest.py
@@ -7,7 +7,6 @@
all_optiondescrs = [pypyoption.pypy_optiondescription,
translationoption.translation_optiondescription,
]
-
start_to_descr = dict([(descr._name, descr) for descr in all_optiondescrs])
class PyPyPage(PyPyPage):
@@ -29,7 +28,7 @@
Page = PyPyPage
def get_content(self, txtpath, encoding):
- if txtpath.basename == "commandline.txt":
+ if txtpath.basename == "commandline.rst":
result = []
for line in txtpath.read().splitlines():
if line.startswith('.. GENERATE:'):
diff --git a/pypy/doc/config/generate.py b/pypy/doc/config/generate.py
--- a/pypy/doc/config/generate.py
+++ b/pypy/doc/config/generate.py
@@ -8,8 +8,8 @@
for descr in all_optiondescrs:
prefix = descr._name
c = config.Config(descr)
- thisdir.join(prefix + ".txt").ensure()
+ thisdir.join(prefix + ".rst").ensure()
for p in c.getpaths(include_groups=True):
- basename = prefix + "." + p + ".txt"
+ basename = prefix + "." + p + ".rst"
f = thisdir.join(basename)
f.ensure()
diff --git a/pypy/doc/config/index.txt b/pypy/doc/config/index.rst
rename from pypy/doc/config/index.txt
rename to pypy/doc/config/index.rst
diff --git a/pypy/doc/config/objspace.allworkingmodules.txt b/pypy/doc/config/objspace.allworkingmodules.rst
rename from pypy/doc/config/objspace.allworkingmodules.txt
rename to pypy/doc/config/objspace.allworkingmodules.rst
diff --git a/pypy/doc/config/objspace.disable_call_speedhacks.txt b/pypy/doc/config/objspace.disable_call_speedhacks.rst
rename from pypy/doc/config/objspace.disable_call_speedhacks.txt
rename to pypy/doc/config/objspace.disable_call_speedhacks.rst
diff --git a/pypy/doc/config/objspace.extmodules.rst b/pypy/doc/config/objspace.extmodules.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.extmodules.rst
@@ -0,0 +1,12 @@
+You can pass a comma-separated list of third-party builtin modules
+which should be translated along with the standard modules within
+``pypy.module``.
+
+The module names need to be fully qualified (i.e. have a ``.`` in them),
+be on the ``$PYTHONPATH`` and not conflict with any existing ones, e.g.
+``mypkg.somemod``.
+
+Once translated, the module will be accessible with a simple::
+
+ import somemod
+
diff --git a/pypy/doc/config/objspace.geninterp.txt b/pypy/doc/config/objspace.geninterp.rst
rename from pypy/doc/config/objspace.geninterp.txt
rename to pypy/doc/config/objspace.geninterp.rst
diff --git a/pypy/doc/config/objspace.honor__builtins__.txt b/pypy/doc/config/objspace.honor__builtins__.rst
rename from pypy/doc/config/objspace.honor__builtins__.txt
rename to pypy/doc/config/objspace.honor__builtins__.rst
diff --git a/pypy/doc/config/objspace.logbytecodes.txt b/pypy/doc/config/objspace.logbytecodes.rst
rename from pypy/doc/config/objspace.logbytecodes.txt
rename to pypy/doc/config/objspace.logbytecodes.rst
diff --git a/pypy/doc/config/objspace.lonepycfiles.txt b/pypy/doc/config/objspace.lonepycfiles.rst
rename from pypy/doc/config/objspace.lonepycfiles.txt
rename to pypy/doc/config/objspace.lonepycfiles.rst
diff --git a/pypy/doc/config/objspace.name.txt b/pypy/doc/config/objspace.name.rst
rename from pypy/doc/config/objspace.name.txt
rename to pypy/doc/config/objspace.name.rst
diff --git a/pypy/doc/config/objspace.nofaking.txt b/pypy/doc/config/objspace.nofaking.rst
rename from pypy/doc/config/objspace.nofaking.txt
rename to pypy/doc/config/objspace.nofaking.rst
diff --git a/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt b/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.rst
rename from pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt
rename to pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.rst
diff --git a/pypy/doc/config/objspace.opcodes.CALL_METHOD.txt b/pypy/doc/config/objspace.opcodes.CALL_METHOD.rst
rename from pypy/doc/config/objspace.opcodes.CALL_METHOD.txt
rename to pypy/doc/config/objspace.opcodes.CALL_METHOD.rst
diff --git a/pypy/doc/config/objspace.opcodes.txt b/pypy/doc/config/objspace.opcodes.rst
rename from pypy/doc/config/objspace.opcodes.txt
rename to pypy/doc/config/objspace.opcodes.rst
diff --git a/pypy/doc/config/objspace.txt b/pypy/doc/config/objspace.rst
rename from pypy/doc/config/objspace.txt
rename to pypy/doc/config/objspace.rst
diff --git a/pypy/doc/config/objspace.soabi.txt b/pypy/doc/config/objspace.soabi.rst
rename from pypy/doc/config/objspace.soabi.txt
rename to pypy/doc/config/objspace.soabi.rst
diff --git a/pypy/doc/config/objspace.std.builtinshortcut.txt b/pypy/doc/config/objspace.std.builtinshortcut.rst
rename from pypy/doc/config/objspace.std.builtinshortcut.txt
rename to pypy/doc/config/objspace.std.builtinshortcut.rst
diff --git a/pypy/doc/config/objspace.std.getattributeshortcut.txt b/pypy/doc/config/objspace.std.getattributeshortcut.rst
rename from pypy/doc/config/objspace.std.getattributeshortcut.txt
rename to pypy/doc/config/objspace.std.getattributeshortcut.rst
diff --git a/pypy/doc/config/objspace.std.logspaceoptypes.txt b/pypy/doc/config/objspace.std.logspaceoptypes.rst
rename from pypy/doc/config/objspace.std.logspaceoptypes.txt
rename to pypy/doc/config/objspace.std.logspaceoptypes.rst
diff --git a/pypy/doc/config/objspace.std.methodcachesizeexp.txt b/pypy/doc/config/objspace.std.methodcachesizeexp.rst
rename from pypy/doc/config/objspace.std.methodcachesizeexp.txt
rename to pypy/doc/config/objspace.std.methodcachesizeexp.rst
diff --git a/pypy/doc/config/objspace.std.multimethods.txt b/pypy/doc/config/objspace.std.multimethods.rst
rename from pypy/doc/config/objspace.std.multimethods.txt
rename to pypy/doc/config/objspace.std.multimethods.rst
diff --git a/pypy/doc/config/objspace.std.mutable_builtintypes.txt b/pypy/doc/config/objspace.std.mutable_builtintypes.rst
rename from pypy/doc/config/objspace.std.mutable_builtintypes.txt
rename to pypy/doc/config/objspace.std.mutable_builtintypes.rst
diff --git a/pypy/doc/config/objspace.std.newshortcut.txt b/pypy/doc/config/objspace.std.newshortcut.rst
rename from pypy/doc/config/objspace.std.newshortcut.txt
rename to pypy/doc/config/objspace.std.newshortcut.rst
diff --git a/pypy/doc/config/objspace.std.optimized_comparison_op.txt b/pypy/doc/config/objspace.std.optimized_comparison_op.rst
rename from pypy/doc/config/objspace.std.optimized_comparison_op.txt
rename to pypy/doc/config/objspace.std.optimized_comparison_op.rst
diff --git a/pypy/doc/config/objspace.std.optimized_int_add.txt b/pypy/doc/config/objspace.std.optimized_int_add.rst
rename from pypy/doc/config/objspace.std.optimized_int_add.txt
rename to pypy/doc/config/objspace.std.optimized_int_add.rst
diff --git a/pypy/doc/config/objspace.std.optimized_list_getitem.txt b/pypy/doc/config/objspace.std.optimized_list_getitem.rst
rename from pypy/doc/config/objspace.std.optimized_list_getitem.txt
rename to pypy/doc/config/objspace.std.optimized_list_getitem.rst
diff --git a/pypy/doc/config/objspace.std.prebuiltintfrom.txt b/pypy/doc/config/objspace.std.prebuiltintfrom.rst
rename from pypy/doc/config/objspace.std.prebuiltintfrom.txt
rename to pypy/doc/config/objspace.std.prebuiltintfrom.rst
diff --git a/pypy/doc/config/objspace.std.prebuiltintto.txt b/pypy/doc/config/objspace.std.prebuiltintto.rst
rename from pypy/doc/config/objspace.std.prebuiltintto.txt
rename to pypy/doc/config/objspace.std.prebuiltintto.rst
diff --git a/pypy/doc/config/objspace.std.txt b/pypy/doc/config/objspace.std.rst
rename from pypy/doc/config/objspace.std.txt
rename to pypy/doc/config/objspace.std.rst
diff --git a/pypy/doc/config/objspace.std.sharesmallstr.txt b/pypy/doc/config/objspace.std.sharesmallstr.rst
rename from pypy/doc/config/objspace.std.sharesmallstr.txt
rename to pypy/doc/config/objspace.std.sharesmallstr.rst
diff --git a/pypy/doc/config/objspace.std.withcelldict.txt b/pypy/doc/config/objspace.std.withcelldict.rst
rename from pypy/doc/config/objspace.std.withcelldict.txt
rename to pypy/doc/config/objspace.std.withcelldict.rst
diff --git a/pypy/doc/config/objspace.std.withdictmeasurement.txt b/pypy/doc/config/objspace.std.withdictmeasurement.rst
rename from pypy/doc/config/objspace.std.withdictmeasurement.txt
rename to pypy/doc/config/objspace.std.withdictmeasurement.rst
diff --git a/pypy/doc/config/objspace.std.withmapdict.txt b/pypy/doc/config/objspace.std.withmapdict.rst
rename from pypy/doc/config/objspace.std.withmapdict.txt
rename to pypy/doc/config/objspace.std.withmapdict.rst
diff --git a/pypy/doc/config/objspace.std.withmethodcache.txt b/pypy/doc/config/objspace.std.withmethodcache.rst
rename from pypy/doc/config/objspace.std.withmethodcache.txt
rename to pypy/doc/config/objspace.std.withmethodcache.rst
diff --git a/pypy/doc/config/objspace.std.withmethodcachecounter.txt b/pypy/doc/config/objspace.std.withmethodcachecounter.rst
rename from pypy/doc/config/objspace.std.withmethodcachecounter.txt
rename to pypy/doc/config/objspace.std.withmethodcachecounter.rst
diff --git a/pypy/doc/config/objspace.std.withprebuiltchar.txt b/pypy/doc/config/objspace.std.withprebuiltchar.rst
rename from pypy/doc/config/objspace.std.withprebuiltchar.txt
rename to pypy/doc/config/objspace.std.withprebuiltchar.rst
diff --git a/pypy/doc/config/objspace.std.withprebuiltint.txt b/pypy/doc/config/objspace.std.withprebuiltint.rst
rename from pypy/doc/config/objspace.std.withprebuiltint.txt
rename to pypy/doc/config/objspace.std.withprebuiltint.rst
diff --git a/pypy/doc/config/objspace.std.withrangelist.txt b/pypy/doc/config/objspace.std.withrangelist.rst
rename from pypy/doc/config/objspace.std.withrangelist.txt
rename to pypy/doc/config/objspace.std.withrangelist.rst
diff --git a/pypy/doc/config/objspace.std.withrope.txt b/pypy/doc/config/objspace.std.withrope.rst
rename from pypy/doc/config/objspace.std.withrope.txt
rename to pypy/doc/config/objspace.std.withrope.rst
diff --git a/pypy/doc/config/objspace.std.withropeunicode.txt b/pypy/doc/config/objspace.std.withropeunicode.rst
rename from pypy/doc/config/objspace.std.withropeunicode.txt
rename to pypy/doc/config/objspace.std.withropeunicode.rst
diff --git a/pypy/doc/config/objspace.std.withsmallint.txt b/pypy/doc/config/objspace.std.withsmallint.rst
rename from pypy/doc/config/objspace.std.withsmallint.txt
rename to pypy/doc/config/objspace.std.withsmallint.rst
diff --git a/pypy/doc/config/objspace.std.withsmalllong.txt b/pypy/doc/config/objspace.std.withsmalllong.rst
rename from pypy/doc/config/objspace.std.withsmalllong.txt
rename to pypy/doc/config/objspace.std.withsmalllong.rst
diff --git a/pypy/doc/config/objspace.std.withstrbuf.txt b/pypy/doc/config/objspace.std.withstrbuf.rst
rename from pypy/doc/config/objspace.std.withstrbuf.txt
rename to pypy/doc/config/objspace.std.withstrbuf.rst
diff --git a/pypy/doc/config/objspace.std.withstrjoin.txt b/pypy/doc/config/objspace.std.withstrjoin.rst
rename from pypy/doc/config/objspace.std.withstrjoin.txt
rename to pypy/doc/config/objspace.std.withstrjoin.rst
diff --git a/pypy/doc/config/objspace.std.withstrslice.txt b/pypy/doc/config/objspace.std.withstrslice.rst
rename from pypy/doc/config/objspace.std.withstrslice.txt
rename to pypy/doc/config/objspace.std.withstrslice.rst
diff --git a/pypy/doc/config/objspace.std.withtproxy.txt b/pypy/doc/config/objspace.std.withtproxy.rst
rename from pypy/doc/config/objspace.std.withtproxy.txt
rename to pypy/doc/config/objspace.std.withtproxy.rst
diff --git a/pypy/doc/config/objspace.std.withtypeversion.txt b/pypy/doc/config/objspace.std.withtypeversion.rst
rename from pypy/doc/config/objspace.std.withtypeversion.txt
rename to pypy/doc/config/objspace.std.withtypeversion.rst
diff --git a/pypy/doc/config/objspace.timing.txt b/pypy/doc/config/objspace.timing.rst
rename from pypy/doc/config/objspace.timing.txt
rename to pypy/doc/config/objspace.timing.rst
diff --git a/pypy/doc/config/objspace.translationmodules.txt b/pypy/doc/config/objspace.translationmodules.rst
rename from pypy/doc/config/objspace.translationmodules.txt
rename to pypy/doc/config/objspace.translationmodules.rst
diff --git a/pypy/doc/config/objspace.usemodules.__builtin__.txt b/pypy/doc/config/objspace.usemodules.__builtin__.rst
rename from pypy/doc/config/objspace.usemodules.__builtin__.txt
rename to pypy/doc/config/objspace.usemodules.__builtin__.rst
diff --git a/pypy/doc/config/objspace.usemodules.__pypy__.txt b/pypy/doc/config/objspace.usemodules.__pypy__.rst
rename from pypy/doc/config/objspace.usemodules.__pypy__.txt
rename to pypy/doc/config/objspace.usemodules.__pypy__.rst
diff --git a/pypy/doc/config/objspace.usemodules._ast.txt b/pypy/doc/config/objspace.usemodules._ast.rst
rename from pypy/doc/config/objspace.usemodules._ast.txt
rename to pypy/doc/config/objspace.usemodules._ast.rst
diff --git a/pypy/doc/config/objspace.usemodules._bisect.txt b/pypy/doc/config/objspace.usemodules._bisect.rst
rename from pypy/doc/config/objspace.usemodules._bisect.txt
rename to pypy/doc/config/objspace.usemodules._bisect.rst
diff --git a/pypy/doc/config/objspace.usemodules._codecs.txt b/pypy/doc/config/objspace.usemodules._codecs.rst
rename from pypy/doc/config/objspace.usemodules._codecs.txt
rename to pypy/doc/config/objspace.usemodules._codecs.rst
diff --git a/pypy/doc/config/objspace.usemodules._collections.txt b/pypy/doc/config/objspace.usemodules._collections.rst
rename from pypy/doc/config/objspace.usemodules._collections.txt
rename to pypy/doc/config/objspace.usemodules._collections.rst
diff --git a/pypy/doc/config/objspace.usemodules._demo.txt b/pypy/doc/config/objspace.usemodules._demo.rst
rename from pypy/doc/config/objspace.usemodules._demo.txt
rename to pypy/doc/config/objspace.usemodules._demo.rst
diff --git a/pypy/doc/config/objspace.usemodules._ffi.txt b/pypy/doc/config/objspace.usemodules._ffi.rst
rename from pypy/doc/config/objspace.usemodules._ffi.txt
rename to pypy/doc/config/objspace.usemodules._ffi.rst
diff --git a/pypy/doc/config/objspace.usemodules._file.txt b/pypy/doc/config/objspace.usemodules._file.rst
rename from pypy/doc/config/objspace.usemodules._file.txt
rename to pypy/doc/config/objspace.usemodules._file.rst
diff --git a/pypy/doc/config/objspace.usemodules._hashlib.txt b/pypy/doc/config/objspace.usemodules._hashlib.rst
rename from pypy/doc/config/objspace.usemodules._hashlib.txt
rename to pypy/doc/config/objspace.usemodules._hashlib.rst
diff --git a/pypy/doc/config/objspace.usemodules._io.txt b/pypy/doc/config/objspace.usemodules._io.rst
rename from pypy/doc/config/objspace.usemodules._io.txt
rename to pypy/doc/config/objspace.usemodules._io.rst
diff --git a/pypy/doc/config/objspace.usemodules._locale.txt b/pypy/doc/config/objspace.usemodules._locale.rst
rename from pypy/doc/config/objspace.usemodules._locale.txt
rename to pypy/doc/config/objspace.usemodules._locale.rst
diff --git a/pypy/doc/config/objspace.usemodules._lsprof.txt b/pypy/doc/config/objspace.usemodules._lsprof.rst
rename from pypy/doc/config/objspace.usemodules._lsprof.txt
rename to pypy/doc/config/objspace.usemodules._lsprof.rst
diff --git a/pypy/doc/config/objspace.usemodules._md5.txt b/pypy/doc/config/objspace.usemodules._md5.rst
rename from pypy/doc/config/objspace.usemodules._md5.txt
rename to pypy/doc/config/objspace.usemodules._md5.rst
diff --git a/pypy/doc/config/objspace.usemodules._minimal_curses.txt b/pypy/doc/config/objspace.usemodules._minimal_curses.rst
rename from pypy/doc/config/objspace.usemodules._minimal_curses.txt
rename to pypy/doc/config/objspace.usemodules._minimal_curses.rst
diff --git a/pypy/doc/config/objspace.usemodules._multiprocessing.txt b/pypy/doc/config/objspace.usemodules._multiprocessing.rst
rename from pypy/doc/config/objspace.usemodules._multiprocessing.txt
rename to pypy/doc/config/objspace.usemodules._multiprocessing.rst
diff --git a/pypy/doc/config/objspace.usemodules._pickle_support.txt b/pypy/doc/config/objspace.usemodules._pickle_support.rst
rename from pypy/doc/config/objspace.usemodules._pickle_support.txt
rename to pypy/doc/config/objspace.usemodules._pickle_support.rst
diff --git a/pypy/doc/config/objspace.usemodules._random.txt b/pypy/doc/config/objspace.usemodules._random.rst
rename from pypy/doc/config/objspace.usemodules._random.txt
rename to pypy/doc/config/objspace.usemodules._random.rst
diff --git a/pypy/doc/config/objspace.usemodules._rawffi.txt b/pypy/doc/config/objspace.usemodules._rawffi.rst
rename from pypy/doc/config/objspace.usemodules._rawffi.txt
rename to pypy/doc/config/objspace.usemodules._rawffi.rst
diff --git a/pypy/doc/config/objspace.usemodules._sha.txt b/pypy/doc/config/objspace.usemodules._sha.rst
rename from pypy/doc/config/objspace.usemodules._sha.txt
rename to pypy/doc/config/objspace.usemodules._sha.rst
diff --git a/pypy/doc/config/objspace.usemodules._socket.txt b/pypy/doc/config/objspace.usemodules._socket.rst
rename from pypy/doc/config/objspace.usemodules._socket.txt
rename to pypy/doc/config/objspace.usemodules._socket.rst
diff --git a/pypy/doc/config/objspace.usemodules._sre.txt b/pypy/doc/config/objspace.usemodules._sre.rst
rename from pypy/doc/config/objspace.usemodules._sre.txt
rename to pypy/doc/config/objspace.usemodules._sre.rst
diff --git a/pypy/doc/config/objspace.usemodules._ssl.txt b/pypy/doc/config/objspace.usemodules._ssl.rst
rename from pypy/doc/config/objspace.usemodules._ssl.txt
rename to pypy/doc/config/objspace.usemodules._ssl.rst
diff --git a/pypy/doc/config/objspace.usemodules._stackless.txt b/pypy/doc/config/objspace.usemodules._stackless.rst
rename from pypy/doc/config/objspace.usemodules._stackless.txt
rename to pypy/doc/config/objspace.usemodules._stackless.rst
diff --git a/pypy/doc/config/objspace.usemodules._testing.txt b/pypy/doc/config/objspace.usemodules._testing.rst
rename from pypy/doc/config/objspace.usemodules._testing.txt
rename to pypy/doc/config/objspace.usemodules._testing.rst
diff --git a/pypy/doc/config/objspace.usemodules._warnings.txt b/pypy/doc/config/objspace.usemodules._warnings.rst
rename from pypy/doc/config/objspace.usemodules._warnings.txt
rename to pypy/doc/config/objspace.usemodules._warnings.rst
diff --git a/pypy/doc/config/objspace.usemodules._weakref.txt b/pypy/doc/config/objspace.usemodules._weakref.rst
rename from pypy/doc/config/objspace.usemodules._weakref.txt
rename to pypy/doc/config/objspace.usemodules._weakref.rst
diff --git a/pypy/doc/config/objspace.usemodules._winreg.txt b/pypy/doc/config/objspace.usemodules._winreg.rst
rename from pypy/doc/config/objspace.usemodules._winreg.txt
rename to pypy/doc/config/objspace.usemodules._winreg.rst
diff --git a/pypy/doc/config/objspace.usemodules.array.txt b/pypy/doc/config/objspace.usemodules.array.rst
rename from pypy/doc/config/objspace.usemodules.array.txt
rename to pypy/doc/config/objspace.usemodules.array.rst
diff --git a/pypy/doc/config/objspace.usemodules.binascii.txt b/pypy/doc/config/objspace.usemodules.binascii.rst
rename from pypy/doc/config/objspace.usemodules.binascii.txt
rename to pypy/doc/config/objspace.usemodules.binascii.rst
diff --git a/pypy/doc/config/objspace.usemodules.bz2.txt b/pypy/doc/config/objspace.usemodules.bz2.rst
rename from pypy/doc/config/objspace.usemodules.bz2.txt
rename to pypy/doc/config/objspace.usemodules.bz2.rst
diff --git a/pypy/doc/config/objspace.usemodules.cStringIO.txt b/pypy/doc/config/objspace.usemodules.cStringIO.rst
rename from pypy/doc/config/objspace.usemodules.cStringIO.txt
rename to pypy/doc/config/objspace.usemodules.cStringIO.rst
diff --git a/pypy/doc/config/objspace.usemodules.clr.txt b/pypy/doc/config/objspace.usemodules.clr.rst
rename from pypy/doc/config/objspace.usemodules.clr.txt
rename to pypy/doc/config/objspace.usemodules.clr.rst
diff --git a/pypy/doc/config/objspace.usemodules.cmath.txt b/pypy/doc/config/objspace.usemodules.cmath.rst
rename from pypy/doc/config/objspace.usemodules.cmath.txt
rename to pypy/doc/config/objspace.usemodules.cmath.rst
diff --git a/pypy/doc/config/objspace.usemodules.cpyext.txt b/pypy/doc/config/objspace.usemodules.cpyext.rst
rename from pypy/doc/config/objspace.usemodules.cpyext.txt
rename to pypy/doc/config/objspace.usemodules.cpyext.rst
diff --git a/pypy/doc/config/objspace.usemodules.crypt.txt b/pypy/doc/config/objspace.usemodules.crypt.rst
rename from pypy/doc/config/objspace.usemodules.crypt.txt
rename to pypy/doc/config/objspace.usemodules.crypt.rst
diff --git a/pypy/doc/config/objspace.usemodules.errno.txt b/pypy/doc/config/objspace.usemodules.errno.rst
rename from pypy/doc/config/objspace.usemodules.errno.txt
rename to pypy/doc/config/objspace.usemodules.errno.rst
diff --git a/pypy/doc/config/objspace.usemodules.exceptions.txt b/pypy/doc/config/objspace.usemodules.exceptions.rst
rename from pypy/doc/config/objspace.usemodules.exceptions.txt
rename to pypy/doc/config/objspace.usemodules.exceptions.rst
diff --git a/pypy/doc/config/objspace.usemodules.fcntl.txt b/pypy/doc/config/objspace.usemodules.fcntl.rst
rename from pypy/doc/config/objspace.usemodules.fcntl.txt
rename to pypy/doc/config/objspace.usemodules.fcntl.rst
diff --git a/pypy/doc/config/objspace.usemodules.gc.txt b/pypy/doc/config/objspace.usemodules.gc.rst
rename from pypy/doc/config/objspace.usemodules.gc.txt
rename to pypy/doc/config/objspace.usemodules.gc.rst
diff --git a/pypy/doc/config/objspace.usemodules.imp.txt b/pypy/doc/config/objspace.usemodules.imp.rst
rename from pypy/doc/config/objspace.usemodules.imp.txt
rename to pypy/doc/config/objspace.usemodules.imp.rst
diff --git a/pypy/doc/config/objspace.usemodules.itertools.txt b/pypy/doc/config/objspace.usemodules.itertools.rst
rename from pypy/doc/config/objspace.usemodules.itertools.txt
rename to pypy/doc/config/objspace.usemodules.itertools.rst
diff --git a/pypy/doc/config/objspace.usemodules.marshal.txt b/pypy/doc/config/objspace.usemodules.marshal.rst
rename from pypy/doc/config/objspace.usemodules.marshal.txt
rename to pypy/doc/config/objspace.usemodules.marshal.rst
diff --git a/pypy/doc/config/objspace.usemodules.math.txt b/pypy/doc/config/objspace.usemodules.math.rst
rename from pypy/doc/config/objspace.usemodules.math.txt
rename to pypy/doc/config/objspace.usemodules.math.rst
diff --git a/pypy/doc/config/objspace.usemodules.micronumpy.txt b/pypy/doc/config/objspace.usemodules.micronumpy.rst
rename from pypy/doc/config/objspace.usemodules.micronumpy.txt
rename to pypy/doc/config/objspace.usemodules.micronumpy.rst
diff --git a/pypy/doc/config/objspace.usemodules.mmap.txt b/pypy/doc/config/objspace.usemodules.mmap.rst
rename from pypy/doc/config/objspace.usemodules.mmap.txt
rename to pypy/doc/config/objspace.usemodules.mmap.rst
diff --git a/pypy/doc/config/objspace.usemodules.operator.txt b/pypy/doc/config/objspace.usemodules.operator.rst
rename from pypy/doc/config/objspace.usemodules.operator.txt
rename to pypy/doc/config/objspace.usemodules.operator.rst
diff --git a/pypy/doc/config/objspace.usemodules.oracle.txt b/pypy/doc/config/objspace.usemodules.oracle.rst
rename from pypy/doc/config/objspace.usemodules.oracle.txt
rename to pypy/doc/config/objspace.usemodules.oracle.rst
diff --git a/pypy/doc/config/objspace.usemodules.parser.txt b/pypy/doc/config/objspace.usemodules.parser.rst
rename from pypy/doc/config/objspace.usemodules.parser.txt
rename to pypy/doc/config/objspace.usemodules.parser.rst
diff --git a/pypy/doc/config/objspace.usemodules.posix.txt b/pypy/doc/config/objspace.usemodules.posix.rst
rename from pypy/doc/config/objspace.usemodules.posix.txt
rename to pypy/doc/config/objspace.usemodules.posix.rst
diff --git a/pypy/doc/config/objspace.usemodules.pyexpat.txt b/pypy/doc/config/objspace.usemodules.pyexpat.rst
rename from pypy/doc/config/objspace.usemodules.pyexpat.txt
rename to pypy/doc/config/objspace.usemodules.pyexpat.rst
diff --git a/pypy/doc/config/objspace.usemodules.pypyjit.txt b/pypy/doc/config/objspace.usemodules.pypyjit.rst
rename from pypy/doc/config/objspace.usemodules.pypyjit.txt
rename to pypy/doc/config/objspace.usemodules.pypyjit.rst
diff --git a/pypy/doc/config/objspace.usemodules.rbench.txt b/pypy/doc/config/objspace.usemodules.rbench.rst
rename from pypy/doc/config/objspace.usemodules.rbench.txt
rename to pypy/doc/config/objspace.usemodules.rbench.rst
diff --git a/pypy/doc/config/objspace.usemodules.rctime.txt b/pypy/doc/config/objspace.usemodules.rctime.rst
rename from pypy/doc/config/objspace.usemodules.rctime.txt
rename to pypy/doc/config/objspace.usemodules.rctime.rst
diff --git a/pypy/doc/config/objspace.usemodules.txt b/pypy/doc/config/objspace.usemodules.rst
rename from pypy/doc/config/objspace.usemodules.txt
rename to pypy/doc/config/objspace.usemodules.rst
diff --git a/pypy/doc/config/objspace.usemodules.select.txt b/pypy/doc/config/objspace.usemodules.select.rst
rename from pypy/doc/config/objspace.usemodules.select.txt
rename to pypy/doc/config/objspace.usemodules.select.rst
diff --git a/pypy/doc/config/objspace.usemodules.signal.txt b/pypy/doc/config/objspace.usemodules.signal.rst
rename from pypy/doc/config/objspace.usemodules.signal.txt
rename to pypy/doc/config/objspace.usemodules.signal.rst
diff --git a/pypy/doc/config/objspace.usemodules.struct.txt b/pypy/doc/config/objspace.usemodules.struct.rst
rename from pypy/doc/config/objspace.usemodules.struct.txt
rename to pypy/doc/config/objspace.usemodules.struct.rst
diff --git a/pypy/doc/config/objspace.usemodules.symbol.txt b/pypy/doc/config/objspace.usemodules.symbol.rst
rename from pypy/doc/config/objspace.usemodules.symbol.txt
rename to pypy/doc/config/objspace.usemodules.symbol.rst
diff --git a/pypy/doc/config/objspace.usemodules.sys.txt b/pypy/doc/config/objspace.usemodules.sys.rst
rename from pypy/doc/config/objspace.usemodules.sys.txt
rename to pypy/doc/config/objspace.usemodules.sys.rst
diff --git a/pypy/doc/config/objspace.usemodules.termios.txt b/pypy/doc/config/objspace.usemodules.termios.rst
rename from pypy/doc/config/objspace.usemodules.termios.txt
rename to pypy/doc/config/objspace.usemodules.termios.rst
diff --git a/pypy/doc/config/objspace.usemodules.thread.txt b/pypy/doc/config/objspace.usemodules.thread.rst
rename from pypy/doc/config/objspace.usemodules.thread.txt
rename to pypy/doc/config/objspace.usemodules.thread.rst
diff --git a/pypy/doc/config/objspace.usemodules.time.txt b/pypy/doc/config/objspace.usemodules.time.rst
rename from pypy/doc/config/objspace.usemodules.time.txt
rename to pypy/doc/config/objspace.usemodules.time.rst
diff --git a/pypy/doc/config/objspace.usemodules.token.txt b/pypy/doc/config/objspace.usemodules.token.rst
rename from pypy/doc/config/objspace.usemodules.token.txt
rename to pypy/doc/config/objspace.usemodules.token.rst
diff --git a/pypy/doc/config/objspace.usemodules.unicodedata.txt b/pypy/doc/config/objspace.usemodules.unicodedata.rst
rename from pypy/doc/config/objspace.usemodules.unicodedata.txt
rename to pypy/doc/config/objspace.usemodules.unicodedata.rst
diff --git a/pypy/doc/config/objspace.usemodules.zipimport.txt b/pypy/doc/config/objspace.usemodules.zipimport.rst
rename from pypy/doc/config/objspace.usemodules.zipimport.txt
rename to pypy/doc/config/objspace.usemodules.zipimport.rst
diff --git a/pypy/doc/config/objspace.usemodules.zlib.txt b/pypy/doc/config/objspace.usemodules.zlib.rst
rename from pypy/doc/config/objspace.usemodules.zlib.txt
rename to pypy/doc/config/objspace.usemodules.zlib.rst
diff --git a/pypy/doc/config/objspace.usepycfiles.txt b/pypy/doc/config/objspace.usepycfiles.rst
rename from pypy/doc/config/objspace.usepycfiles.txt
rename to pypy/doc/config/objspace.usepycfiles.rst
diff --git a/pypy/doc/config/opt.txt b/pypy/doc/config/opt.rst
rename from pypy/doc/config/opt.txt
rename to pypy/doc/config/opt.rst
diff --git a/pypy/doc/config/translation.backend.txt b/pypy/doc/config/translation.backend.rst
rename from pypy/doc/config/translation.backend.txt
rename to pypy/doc/config/translation.backend.rst
diff --git a/pypy/doc/config/translation.backendopt.clever_malloc_removal.txt b/pypy/doc/config/translation.backendopt.clever_malloc_removal.rst
rename from pypy/doc/config/translation.backendopt.clever_malloc_removal.txt
rename to pypy/doc/config/translation.backendopt.clever_malloc_removal.rst
diff --git a/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt b/pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.rst
rename from pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.txt
rename to pypy/doc/config/translation.backendopt.clever_malloc_removal_heuristic.rst
diff --git a/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt b/pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.rst
rename from pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.txt
rename to pypy/doc/config/translation.backendopt.clever_malloc_removal_threshold.rst
diff --git a/pypy/doc/config/translation.backendopt.constfold.txt b/pypy/doc/config/translation.backendopt.constfold.rst
rename from pypy/doc/config/translation.backendopt.constfold.txt
rename to pypy/doc/config/translation.backendopt.constfold.rst
diff --git a/pypy/doc/config/translation.backendopt.inline.txt b/pypy/doc/config/translation.backendopt.inline.rst
rename from pypy/doc/config/translation.backendopt.inline.txt
rename to pypy/doc/config/translation.backendopt.inline.rst
diff --git a/pypy/doc/config/translation.backendopt.inline_heuristic.txt b/pypy/doc/config/translation.backendopt.inline_heuristic.rst
rename from pypy/doc/config/translation.backendopt.inline_heuristic.txt
rename to pypy/doc/config/translation.backendopt.inline_heuristic.rst
diff --git a/pypy/doc/config/translation.backendopt.inline_threshold.txt b/pypy/doc/config/translation.backendopt.inline_threshold.rst
rename from pypy/doc/config/translation.backendopt.inline_threshold.txt
rename to pypy/doc/config/translation.backendopt.inline_threshold.rst
diff --git a/pypy/doc/config/translation.backendopt.mallocs.txt b/pypy/doc/config/translation.backendopt.mallocs.rst
rename from pypy/doc/config/translation.backendopt.mallocs.txt
rename to pypy/doc/config/translation.backendopt.mallocs.rst
diff --git a/pypy/doc/config/translation.backendopt.merge_if_blocks.txt b/pypy/doc/config/translation.backendopt.merge_if_blocks.rst
rename from pypy/doc/config/translation.backendopt.merge_if_blocks.txt
rename to pypy/doc/config/translation.backendopt.merge_if_blocks.rst
diff --git a/pypy/doc/config/translation.backendopt.none.txt b/pypy/doc/config/translation.backendopt.none.rst
rename from pypy/doc/config/translation.backendopt.none.txt
rename to pypy/doc/config/translation.backendopt.none.rst
diff --git a/pypy/doc/config/translation.backendopt.print_statistics.txt b/pypy/doc/config/translation.backendopt.print_statistics.rst
rename from pypy/doc/config/translation.backendopt.print_statistics.txt
rename to pypy/doc/config/translation.backendopt.print_statistics.rst
diff --git a/pypy/doc/config/translation.backendopt.profile_based_inline.txt b/pypy/doc/config/translation.backendopt.profile_based_inline.rst
rename from pypy/doc/config/translation.backendopt.profile_based_inline.txt
rename to pypy/doc/config/translation.backendopt.profile_based_inline.rst
diff --git a/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt b/pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.rst
rename from pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.txt
rename to pypy/doc/config/translation.backendopt.profile_based_inline_heuristic.rst
diff --git a/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt b/pypy/doc/config/translation.backendopt.profile_based_inline_threshold.rst
rename from pypy/doc/config/translation.backendopt.profile_based_inline_threshold.txt
rename to pypy/doc/config/translation.backendopt.profile_based_inline_threshold.rst
diff --git a/pypy/doc/config/translation.backendopt.raisingop2direct_call.txt b/pypy/doc/config/translation.backendopt.raisingop2direct_call.rst
rename from pypy/doc/config/translation.backendopt.raisingop2direct_call.txt
rename to pypy/doc/config/translation.backendopt.raisingop2direct_call.rst
diff --git a/pypy/doc/config/translation.backendopt.really_remove_asserts.txt b/pypy/doc/config/translation.backendopt.really_remove_asserts.rst
rename from pypy/doc/config/translation.backendopt.really_remove_asserts.txt
rename to pypy/doc/config/translation.backendopt.really_remove_asserts.rst
diff --git a/pypy/doc/config/translation.backendopt.remove_asserts.txt b/pypy/doc/config/translation.backendopt.remove_asserts.rst
rename from pypy/doc/config/translation.backendopt.remove_asserts.txt
rename to pypy/doc/config/translation.backendopt.remove_asserts.rst
diff --git a/pypy/doc/config/translation.backendopt.txt b/pypy/doc/config/translation.backendopt.rst
rename from pypy/doc/config/translation.backendopt.txt
rename to pypy/doc/config/translation.backendopt.rst
diff --git a/pypy/doc/config/translation.backendopt.stack_optimization.txt b/pypy/doc/config/translation.backendopt.stack_optimization.rst
rename from pypy/doc/config/translation.backendopt.stack_optimization.txt
rename to pypy/doc/config/translation.backendopt.stack_optimization.rst
diff --git a/pypy/doc/config/translation.backendopt.storesink.txt b/pypy/doc/config/translation.backendopt.storesink.rst
rename from pypy/doc/config/translation.backendopt.storesink.txt
rename to pypy/doc/config/translation.backendopt.storesink.rst
diff --git a/pypy/doc/config/translation.builtins_can_raise_exceptions.txt b/pypy/doc/config/translation.builtins_can_raise_exceptions.rst
rename from pypy/doc/config/translation.builtins_can_raise_exceptions.txt
rename to pypy/doc/config/translation.builtins_can_raise_exceptions.rst
diff --git a/pypy/doc/config/translation.cc.txt b/pypy/doc/config/translation.cc.rst
rename from pypy/doc/config/translation.cc.txt
rename to pypy/doc/config/translation.cc.rst
diff --git a/pypy/doc/config/translation.cli.exception_transformer.txt b/pypy/doc/config/translation.cli.exception_transformer.rst
rename from pypy/doc/config/translation.cli.exception_transformer.txt
rename to pypy/doc/config/translation.cli.exception_transformer.rst
diff --git a/pypy/doc/config/translation.cli.txt b/pypy/doc/config/translation.cli.rst
rename from pypy/doc/config/translation.cli.txt
rename to pypy/doc/config/translation.cli.rst
diff --git a/pypy/doc/config/translation.cli.trace_calls.txt b/pypy/doc/config/translation.cli.trace_calls.rst
rename from pypy/doc/config/translation.cli.trace_calls.txt
rename to pypy/doc/config/translation.cli.trace_calls.rst
diff --git a/pypy/doc/config/translation.compilerflags.txt b/pypy/doc/config/translation.compilerflags.rst
rename from pypy/doc/config/translation.compilerflags.txt
rename to pypy/doc/config/translation.compilerflags.rst
diff --git a/pypy/doc/config/translation.countmallocs.txt b/pypy/doc/config/translation.countmallocs.rst
rename from pypy/doc/config/translation.countmallocs.txt
rename to pypy/doc/config/translation.countmallocs.rst
diff --git a/pypy/doc/config/translation.debug.txt b/pypy/doc/config/translation.debug.rst
rename from pypy/doc/config/translation.debug.txt
rename to pypy/doc/config/translation.debug.rst
diff --git a/pypy/doc/config/translation.dump_static_data_info.txt b/pypy/doc/config/translation.dump_static_data_info.rst
rename from pypy/doc/config/translation.dump_static_data_info.txt
rename to pypy/doc/config/translation.dump_static_data_info.rst
diff --git a/pypy/doc/config/translation.force_make.txt b/pypy/doc/config/translation.force_make.rst
rename from pypy/doc/config/translation.force_make.txt
rename to pypy/doc/config/translation.force_make.rst
diff --git a/pypy/doc/config/translation.fork_before.txt b/pypy/doc/config/translation.fork_before.rst
rename from pypy/doc/config/translation.fork_before.txt
rename to pypy/doc/config/translation.fork_before.rst
diff --git a/pypy/doc/config/translation.gc.txt b/pypy/doc/config/translation.gc.rst
rename from pypy/doc/config/translation.gc.txt
rename to pypy/doc/config/translation.gc.rst
diff --git a/pypy/doc/config/translation.gcremovetypeptr.txt b/pypy/doc/config/translation.gcremovetypeptr.rst
rename from pypy/doc/config/translation.gcremovetypeptr.txt
rename to pypy/doc/config/translation.gcremovetypeptr.rst
diff --git a/pypy/doc/config/translation.gcrootfinder.txt b/pypy/doc/config/translation.gcrootfinder.rst
rename from pypy/doc/config/translation.gcrootfinder.txt
rename to pypy/doc/config/translation.gcrootfinder.rst
diff --git a/pypy/doc/config/translation.gctransformer.txt b/pypy/doc/config/translation.gctransformer.rst
rename from pypy/doc/config/translation.gctransformer.txt
rename to pypy/doc/config/translation.gctransformer.rst
diff --git a/pypy/doc/config/translation.insist.txt b/pypy/doc/config/translation.insist.rst
rename from pypy/doc/config/translation.insist.txt
rename to pypy/doc/config/translation.insist.rst
diff --git a/pypy/doc/config/translation.instrument.txt b/pypy/doc/config/translation.instrument.rst
rename from pypy/doc/config/translation.instrument.txt
rename to pypy/doc/config/translation.instrument.rst
diff --git a/pypy/doc/config/translation.instrumentctl.txt b/pypy/doc/config/translation.instrumentctl.rst
rename from pypy/doc/config/translation.instrumentctl.txt
rename to pypy/doc/config/translation.instrumentctl.rst
diff --git a/pypy/doc/config/translation.jit.txt b/pypy/doc/config/translation.jit.rst
rename from pypy/doc/config/translation.jit.txt
rename to pypy/doc/config/translation.jit.rst
diff --git a/pypy/doc/config/translation.jit_backend.txt b/pypy/doc/config/translation.jit_backend.rst
rename from pypy/doc/config/translation.jit_backend.txt
rename to pypy/doc/config/translation.jit_backend.rst
diff --git a/pypy/doc/config/translation.jit_ffi.txt b/pypy/doc/config/translation.jit_ffi.rst
rename from pypy/doc/config/translation.jit_ffi.txt
rename to pypy/doc/config/translation.jit_ffi.rst
diff --git a/pypy/doc/config/translation.jit_profiler.txt b/pypy/doc/config/translation.jit_profiler.rst
rename from pypy/doc/config/translation.jit_profiler.txt
rename to pypy/doc/config/translation.jit_profiler.rst
diff --git a/pypy/doc/config/translation.linkerflags.txt b/pypy/doc/config/translation.linkerflags.rst
rename from pypy/doc/config/translation.linkerflags.txt
rename to pypy/doc/config/translation.linkerflags.rst
diff --git a/pypy/doc/config/translation.list_comprehension_operations.txt b/pypy/doc/config/translation.list_comprehension_operations.rst
rename from pypy/doc/config/translation.list_comprehension_operations.txt
rename to pypy/doc/config/translation.list_comprehension_operations.rst
diff --git a/pypy/doc/config/translation.log.txt b/pypy/doc/config/translation.log.rst
rename from pypy/doc/config/translation.log.txt
rename to pypy/doc/config/translation.log.rst
diff --git a/pypy/doc/config/translation.make_jobs.txt b/pypy/doc/config/translation.make_jobs.rst
rename from pypy/doc/config/translation.make_jobs.txt
rename to pypy/doc/config/translation.make_jobs.rst
diff --git a/pypy/doc/config/translation.no__thread.txt b/pypy/doc/config/translation.no__thread.rst
rename from pypy/doc/config/translation.no__thread.txt
rename to pypy/doc/config/translation.no__thread.rst
diff --git a/pypy/doc/config/translation.noprofopt.txt b/pypy/doc/config/translation.noprofopt.rst
rename from pypy/doc/config/translation.noprofopt.txt
rename to pypy/doc/config/translation.noprofopt.rst
diff --git a/pypy/doc/config/translation.ootype.mangle.txt b/pypy/doc/config/translation.ootype.mangle.rst
rename from pypy/doc/config/translation.ootype.mangle.txt
rename to pypy/doc/config/translation.ootype.mangle.rst
diff --git a/pypy/doc/config/translation.ootype.txt b/pypy/doc/config/translation.ootype.rst
rename from pypy/doc/config/translation.ootype.txt
rename to pypy/doc/config/translation.ootype.rst
diff --git a/pypy/doc/config/translation.output.txt b/pypy/doc/config/translation.output.rst
rename from pypy/doc/config/translation.output.txt
rename to pypy/doc/config/translation.output.rst
diff --git a/pypy/doc/config/translation.platform.txt b/pypy/doc/config/translation.platform.rst
rename from pypy/doc/config/translation.platform.txt
rename to pypy/doc/config/translation.platform.rst
diff --git a/pypy/doc/config/translation.profopt.txt b/pypy/doc/config/translation.profopt.rst
rename from pypy/doc/config/translation.profopt.txt
rename to pypy/doc/config/translation.profopt.rst
diff --git a/pypy/doc/config/translation.txt b/pypy/doc/config/translation.rst
rename from pypy/doc/config/translation.txt
rename to pypy/doc/config/translation.rst
diff --git a/pypy/doc/config/translation.rweakref.txt b/pypy/doc/config/translation.rweakref.rst
rename from pypy/doc/config/translation.rweakref.txt
rename to pypy/doc/config/translation.rweakref.rst
diff --git a/pypy/doc/config/translation.sandbox.txt b/pypy/doc/config/translation.sandbox.rst
rename from pypy/doc/config/translation.sandbox.txt
rename to pypy/doc/config/translation.sandbox.rst
diff --git a/pypy/doc/config/translation.secondaryentrypoints.txt b/pypy/doc/config/translation.secondaryentrypoints.rst
rename from pypy/doc/config/translation.secondaryentrypoints.txt
rename to pypy/doc/config/translation.secondaryentrypoints.rst
diff --git a/pypy/doc/config/translation.shared.txt b/pypy/doc/config/translation.shared.rst
rename from pypy/doc/config/translation.shared.txt
rename to pypy/doc/config/translation.shared.rst
diff --git a/pypy/doc/config/translation.simplifying.txt b/pypy/doc/config/translation.simplifying.rst
rename from pypy/doc/config/translation.simplifying.txt
rename to pypy/doc/config/translation.simplifying.rst
diff --git a/pypy/doc/config/translation.stackless.txt b/pypy/doc/config/translation.stackless.rst
rename from pypy/doc/config/translation.stackless.txt
rename to pypy/doc/config/translation.stackless.rst
diff --git a/pypy/doc/config/translation.taggedpointers.txt b/pypy/doc/config/translation.taggedpointers.rst
rename from pypy/doc/config/translation.taggedpointers.txt
rename to pypy/doc/config/translation.taggedpointers.rst
diff --git a/pypy/doc/config/translation.thread.txt b/pypy/doc/config/translation.thread.rst
rename from pypy/doc/config/translation.thread.txt
rename to pypy/doc/config/translation.thread.rst
diff --git a/pypy/doc/config/translation.type_system.txt b/pypy/doc/config/translation.type_system.rst
rename from pypy/doc/config/translation.type_system.txt
rename to pypy/doc/config/translation.type_system.rst
diff --git a/pypy/doc/config/translation.vanilla.txt b/pypy/doc/config/translation.vanilla.rst
rename from pypy/doc/config/translation.vanilla.txt
rename to pypy/doc/config/translation.vanilla.rst
diff --git a/pypy/doc/config/translation.verbose.txt b/pypy/doc/config/translation.verbose.rst
rename from pypy/doc/config/translation.verbose.txt
rename to pypy/doc/config/translation.verbose.rst
diff --git a/pypy/doc/config/translation.withsmallfuncsets.txt b/pypy/doc/config/translation.withsmallfuncsets.rst
rename from pypy/doc/config/translation.withsmallfuncsets.txt
rename to pypy/doc/config/translation.withsmallfuncsets.rst
diff --git a/pypy/doc/configuration.txt b/pypy/doc/configuration.rst
rename from pypy/doc/configuration.txt
rename to pypy/doc/configuration.rst
diff --git a/pypy/doc/conftest.py b/pypy/doc/conftest.py
deleted file mode 100644
--- a/pypy/doc/conftest.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import py
-
-from pypy.config.makerestdoc import register_config_role
-docdir = py.path.local(__file__).dirpath()
-
-pytest_plugins = "pypy.doc.pytest_restdoc"
-
-def pytest_addoption(parser):
- group = parser.getgroup("pypy-doc options")
- group.addoption('--pypy-doctests', action="store_true",
- dest="pypy_doctests", default=False,
- help="enable doctests in .txt files")
- group.addoption('--generate-redirections',
- action="store_true", dest="generateredirections",
- default=True, help="Generate redirecting HTML files")
-
-def pytest_configure(config):
- register_config_role(docdir)
-
-def pytest_doctest_prepare_content(content):
- if not py.test.config.getvalue("pypy_doctests"):
- py.test.skip("specify --pypy-doctests to run doctests")
- l = []
- for line in content.split("\n"):
- if line.find('>>>>') != -1:
- line = ""
- l.append(line)
- return "\n".join(l)
-
diff --git a/pypy/doc/contributor.txt b/pypy/doc/contributor.rst
rename from pypy/doc/contributor.txt
rename to pypy/doc/contributor.rst
diff --git a/pypy/doc/cpython_differences.txt b/pypy/doc/cpython_differences.rst
rename from pypy/doc/cpython_differences.txt
rename to pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.txt
+++ b/pypy/doc/cpython_differences.rst
@@ -222,4 +222,4 @@
*more* case on PyPy than on CPython 2.6/2.7.)
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/crufty.rst b/pypy/doc/crufty.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/crufty.rst
@@ -0,0 +1,3 @@
+.. warning::
+
+ This documentation may be out-of-date or obsolete (identified on 2011-03-14 at the PyCon US sprint)
diff --git a/pypy/doc/ctypes-implementation.txt b/pypy/doc/ctypes-implementation.rst
rename from pypy/doc/ctypes-implementation.txt
rename to pypy/doc/ctypes-implementation.rst
--- a/pypy/doc/ctypes-implementation.txt
+++ b/pypy/doc/ctypes-implementation.rst
@@ -1,3 +1,4 @@
+.. include:: crufty.rst
=============================
PyPy's ctypes implementation
diff --git a/pypy/doc/dev_method.txt b/pypy/doc/dev_method.rst
rename from pypy/doc/dev_method.txt
rename to pypy/doc/dev_method.rst
diff --git a/pypy/doc/discussion/GC-performance.txt b/pypy/doc/discussion/GC-performance.rst
rename from pypy/doc/discussion/GC-performance.txt
rename to pypy/doc/discussion/GC-performance.rst
diff --git a/pypy/doc/discussion/VM-integration.txt b/pypy/doc/discussion/VM-integration.rst
rename from pypy/doc/discussion/VM-integration.txt
rename to pypy/doc/discussion/VM-integration.rst
diff --git a/pypy/doc/discussion/chained_getattr.txt b/pypy/doc/discussion/chained_getattr.rst
rename from pypy/doc/discussion/chained_getattr.txt
rename to pypy/doc/discussion/chained_getattr.rst
diff --git a/pypy/doc/discussion/cli-optimizations.txt b/pypy/doc/discussion/cli-optimizations.rst
rename from pypy/doc/discussion/cli-optimizations.txt
rename to pypy/doc/discussion/cli-optimizations.rst
diff --git a/pypy/doc/discussion/cmd-prompt-translation.txt b/pypy/doc/discussion/cmd-prompt-translation.rst
rename from pypy/doc/discussion/cmd-prompt-translation.txt
rename to pypy/doc/discussion/cmd-prompt-translation.rst
diff --git a/pypy/doc/discussion/compiled-swamp.txt b/pypy/doc/discussion/compiled-swamp.rst
rename from pypy/doc/discussion/compiled-swamp.txt
rename to pypy/doc/discussion/compiled-swamp.rst
diff --git a/pypy/doc/discussion/ctypes_modules.txt b/pypy/doc/discussion/ctypes_modules.rst
rename from pypy/doc/discussion/ctypes_modules.txt
rename to pypy/doc/discussion/ctypes_modules.rst
diff --git a/pypy/doc/discussion/ctypes_todo.txt b/pypy/doc/discussion/ctypes_todo.rst
rename from pypy/doc/discussion/ctypes_todo.txt
rename to pypy/doc/discussion/ctypes_todo.rst
diff --git a/pypy/doc/discussion/distribution-implementation.txt b/pypy/doc/discussion/distribution-implementation.rst
rename from pypy/doc/discussion/distribution-implementation.txt
rename to pypy/doc/discussion/distribution-implementation.rst
diff --git a/pypy/doc/discussion/distribution-newattempt.txt b/pypy/doc/discussion/distribution-newattempt.rst
rename from pypy/doc/discussion/distribution-newattempt.txt
rename to pypy/doc/discussion/distribution-newattempt.rst
diff --git a/pypy/doc/discussion/distribution-roadmap.txt b/pypy/doc/discussion/distribution-roadmap.rst
rename from pypy/doc/discussion/distribution-roadmap.txt
rename to pypy/doc/discussion/distribution-roadmap.rst
diff --git a/pypy/doc/discussion/distribution.txt b/pypy/doc/discussion/distribution.rst
rename from pypy/doc/discussion/distribution.txt
rename to pypy/doc/discussion/distribution.rst
diff --git a/pypy/doc/discussion/emptying-the-malloc-zoo.txt b/pypy/doc/discussion/emptying-the-malloc-zoo.rst
rename from pypy/doc/discussion/emptying-the-malloc-zoo.txt
rename to pypy/doc/discussion/emptying-the-malloc-zoo.rst
diff --git a/pypy/doc/discussion/finalizer-order.txt b/pypy/doc/discussion/finalizer-order.rst
rename from pypy/doc/discussion/finalizer-order.txt
rename to pypy/doc/discussion/finalizer-order.rst
diff --git a/pypy/doc/discussion/gc.txt b/pypy/doc/discussion/gc.rst
rename from pypy/doc/discussion/gc.txt
rename to pypy/doc/discussion/gc.rst
diff --git a/pypy/doc/discussion/howtoimplementpickling.txt b/pypy/doc/discussion/howtoimplementpickling.rst
rename from pypy/doc/discussion/howtoimplementpickling.txt
rename to pypy/doc/discussion/howtoimplementpickling.rst
diff --git a/pypy/doc/discussion/improve-rpython.txt b/pypy/doc/discussion/improve-rpython.rst
rename from pypy/doc/discussion/improve-rpython.txt
rename to pypy/doc/discussion/improve-rpython.rst
diff --git a/pypy/doc/discussion/outline-external-ootype.txt b/pypy/doc/discussion/outline-external-ootype.rst
rename from pypy/doc/discussion/outline-external-ootype.txt
rename to pypy/doc/discussion/outline-external-ootype.rst
diff --git a/pypy/doc/discussion/oz-thread-api.txt b/pypy/doc/discussion/oz-thread-api.rst
rename from pypy/doc/discussion/oz-thread-api.txt
rename to pypy/doc/discussion/oz-thread-api.rst
diff --git a/pypy/doc/discussion/paper-wishlist.txt b/pypy/doc/discussion/paper-wishlist.rst
rename from pypy/doc/discussion/paper-wishlist.txt
rename to pypy/doc/discussion/paper-wishlist.rst
diff --git a/pypy/doc/discussion/parsing-ideas.txt b/pypy/doc/discussion/parsing-ideas.rst
rename from pypy/doc/discussion/parsing-ideas.txt
rename to pypy/doc/discussion/parsing-ideas.rst
diff --git a/pypy/doc/discussion/pypy_metaclasses_in_cl.txt b/pypy/doc/discussion/pypy_metaclasses_in_cl.rst
rename from pypy/doc/discussion/pypy_metaclasses_in_cl.txt
rename to pypy/doc/discussion/pypy_metaclasses_in_cl.rst
diff --git a/pypy/doc/discussion/removing-stable-compiler.txt b/pypy/doc/discussion/removing-stable-compiler.rst
rename from pypy/doc/discussion/removing-stable-compiler.txt
rename to pypy/doc/discussion/removing-stable-compiler.rst
diff --git a/pypy/doc/discussion/security-ideas.txt b/pypy/doc/discussion/security-ideas.rst
rename from pypy/doc/discussion/security-ideas.txt
rename to pypy/doc/discussion/security-ideas.rst
diff --git a/pypy/doc/discussion/somepbc-refactoring-plan.txt b/pypy/doc/discussion/somepbc-refactoring-plan.rst
rename from pypy/doc/discussion/somepbc-refactoring-plan.txt
rename to pypy/doc/discussion/somepbc-refactoring-plan.rst
diff --git a/pypy/doc/discussion/summer-of-pypy-pytest.txt b/pypy/doc/discussion/summer-of-pypy-pytest.rst
rename from pypy/doc/discussion/summer-of-pypy-pytest.txt
rename to pypy/doc/discussion/summer-of-pypy-pytest.rst
diff --git a/pypy/doc/discussion/testing-zope.txt b/pypy/doc/discussion/testing-zope.rst
rename from pypy/doc/discussion/testing-zope.txt
rename to pypy/doc/discussion/testing-zope.rst
diff --git a/pypy/doc/discussion/thoughts_string_interning.txt b/pypy/doc/discussion/thoughts_string_interning.rst
rename from pypy/doc/discussion/thoughts_string_interning.txt
rename to pypy/doc/discussion/thoughts_string_interning.rst
diff --git a/pypy/doc/discussion/translation-swamp.txt b/pypy/doc/discussion/translation-swamp.rst
rename from pypy/doc/discussion/translation-swamp.txt
rename to pypy/doc/discussion/translation-swamp.rst
diff --git a/pypy/doc/discussion/use_case_of_logic.txt b/pypy/doc/discussion/use_case_of_logic.rst
rename from pypy/doc/discussion/use_case_of_logic.txt
rename to pypy/doc/discussion/use_case_of_logic.rst
diff --git a/pypy/doc/discussions.rst b/pypy/doc/discussions.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussions.rst
@@ -0,0 +1,41 @@
+Old discussion notes needing categorization
+-------------------------------------------
+
+The following are old discussion notes which may or may not reflect the current reality.
+
+Help from domain experts would be welcome, since some of these documents probably ought to be moved to a more prominent location, some should be deleted, and some left here.
+
+
+.. toctree::
+
+ discussion/GC-performance.rst
+ discussion/VM-integration.rst
+ discussion/chained_getattr.rst
+ discussion/cli-optimizations.rst
+ discussion/cmd-prompt-translation.rst
+ discussion/compiled-swamp.rst
+ discussion/ctypes_modules.rst
+ discussion/ctypes_todo.rst
+ discussion/distribution.rst
+ discussion/distribution-implementation.rst
+ discussion/distribution-newattempt.rst
+ discussion/distribution-roadmap.rst
+ discussion/emptying-the-malloc-zoo.rst
+ discussion/finalizer-order.rst
+ discussion/gc.rst
+ discussion/howtoimplementpickling.rst
+ discussion/improve-rpython.rst
+ discussion/outline-external-ootype.rst
+ discussion/oz-thread-api.rst
+ discussion/paper-wishlist.rst
+ discussion/parsing-ideas.rst
+ discussion/pypy_metaclasses_in_cl.rst
+ discussion/removing-stable-compiler.rst
+ discussion/security-ideas.rst
+ discussion/somepbc-refactoring-plan.rst
+ discussion/summer-of-pypy-pytest.rst
+ discussion/testing-zope.rst
+ discussion/thoughts_string_interning.rst
+ discussion/translation-swamp.rst
+ discussion/use_case_of_logic.rst
+
diff --git a/pypy/doc/distribution.txt b/pypy/doc/distribution.rst
rename from pypy/doc/distribution.txt
rename to pypy/doc/distribution.rst
--- a/pypy/doc/distribution.txt
+++ b/pypy/doc/distribution.rst
@@ -1,3 +1,6 @@
+.. include:: crufty.rst
+
+ .. ^^ Incomplete, superceded elsewhere
========================
lib/distributed features
diff --git a/pypy/doc/docindex.txt b/pypy/doc/docindex.rst
rename from pypy/doc/docindex.txt
rename to pypy/doc/docindex.rst
--- a/pypy/doc/docindex.txt
+++ b/pypy/doc/docindex.rst
@@ -4,7 +4,7 @@
.. _Python: http://www.python.org/doc/2.5.2/
-.. sectnum::
+
.. contents:: :depth: 1
@@ -310,5 +310,5 @@
.. _`graph viewer`: getting-started-dev.html#try-out-the-translator
.. _`compatibility matrix`: image/compat-matrix.png
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/dot-net.rst b/pypy/doc/dot-net.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/dot-net.rst
@@ -0,0 +1,12 @@
+.NET support
+============
+
+ .. warning::
+
+ The .NET backend within PyPy is unmaintained. This documentation may be out-of-date. We welcome contributors who are interested in doing the work to get this into shape.
+
+.. toctree::
+
+ cli-backend.rst
+ clr-module.rst
+ carbonpython.rst
diff --git a/pypy/doc/download.txt b/pypy/doc/download.txt
deleted file mode 100644
--- a/pypy/doc/download.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-Download one of the following release files:
-=============================================
-
-Download page has moved to `pypy.org`_.
-
-.. _`pypy.org`: http://pypy.org/download.html
diff --git a/pypy/doc/eventhistory.txt b/pypy/doc/eventhistory.rst
rename from pypy/doc/eventhistory.txt
rename to pypy/doc/eventhistory.rst
--- a/pypy/doc/eventhistory.txt
+++ b/pypy/doc/eventhistory.rst
@@ -1,4 +1,6 @@
-
+------------
+More sprints
+------------
The PyPy project is a worldwide collaborative effort and its
members are organizing sprints and presenting results at conferences
diff --git a/pypy/doc/extending.txt b/pypy/doc/extending.rst
rename from pypy/doc/extending.txt
rename to pypy/doc/extending.rst
diff --git a/pypy/doc/externaltools.txt b/pypy/doc/externaltools.rst
rename from pypy/doc/externaltools.txt
rename to pypy/doc/externaltools.rst
--- a/pypy/doc/externaltools.txt
+++ b/pypy/doc/externaltools.rst
@@ -1,3 +1,7 @@
+.. include:: crufty.rst
+
+ .. ^^ Incomplete and wrong, superceded elsewhere
+
External tools&programs needed by PyPy
======================================
@@ -16,6 +20,8 @@
- gcc
+ - make
+
- Some libraries (these are Debian package names, adapt as needed):
* ``python-dev``
diff --git a/pypy/doc/extradoc.txt b/pypy/doc/extradoc.rst
rename from pypy/doc/extradoc.txt
rename to pypy/doc/extradoc.rst
--- a/pypy/doc/extradoc.txt
+++ b/pypy/doc/extradoc.rst
@@ -1,5 +1,5 @@
=================================================
-PyPy - papers, talks and related projects
+Papers, talks and related projects
=================================================
Papers
diff --git a/pypy/doc/faq.txt b/pypy/doc/faq.rst
rename from pypy/doc/faq.txt
rename to pypy/doc/faq.rst
--- a/pypy/doc/faq.txt
+++ b/pypy/doc/faq.rst
@@ -416,7 +416,7 @@
.. _`RPython`: coding-guide.html#rpython
.. _`getting-started`: getting-started.html
-.. include:: _ref.txt
+.. include:: _ref.rst
----------------------------------------------------------
Why does PyPy draw a Mandelbrot fractal while translating?
diff --git a/pypy/doc/garbage_collection.txt b/pypy/doc/garbage_collection.rst
rename from pypy/doc/garbage_collection.txt
rename to pypy/doc/garbage_collection.rst
--- a/pypy/doc/garbage_collection.txt
+++ b/pypy/doc/garbage_collection.rst
@@ -3,7 +3,7 @@
==========================
.. contents::
-.. sectnum::
+
Introduction
============
@@ -124,4 +124,4 @@
More details are available as comments at the start of the source
in `rpython/memory/gc/markcompact.py`_.
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/geninterp.txt b/pypy/doc/geninterp.rst
rename from pypy/doc/geninterp.txt
rename to pypy/doc/geninterp.rst
--- a/pypy/doc/geninterp.txt
+++ b/pypy/doc/geninterp.rst
@@ -1,3 +1,7 @@
+.. include:: crufty.rst
+
+ .. ^^ apparently dead
+
The Interpreter-Level backend
-----------------------------
@@ -42,7 +46,7 @@
Example
+++++++
-.. _implementation: ../../pypy/translator/geninterplevel.py
+.. _implementation: ../../../../pypy/translator/geninterplevel.py
Let's try a little example. You might want to look at the flowgraph that it
produces. Here, we directly run the Python translation and look at the
diff --git a/pypy/doc/getting-started-dev.txt b/pypy/doc/getting-started-dev.rst
rename from pypy/doc/getting-started-dev.txt
rename to pypy/doc/getting-started-dev.rst
--- a/pypy/doc/getting-started-dev.txt
+++ b/pypy/doc/getting-started-dev.rst
@@ -1,9 +1,8 @@
===============================================================================
-PyPy - Getting Started with the Translation Toolchain and Development Process
+Getting Started with the Translation Toolchain and Development Process
===============================================================================
.. contents::
-.. sectnum::
.. _`try out the translator`:
@@ -18,9 +17,7 @@
* Download and install Pygame_.
- * Download and install `Dot Graphviz`_ (optional if you have an internet
- connection: the flowgraph viewer then connects to
- codespeak.net and lets it convert the flowgraph by a graphviz server).
+ * Download and install `Dot Graphviz`_
To start the interactive translator shell do::
@@ -410,16 +407,16 @@
.. _mixedmodule.py: http://codespeak.net/svn/pypy/trunk/pypy/interpreter/mixedmodule.py
.. _typedef.py: http://codespeak.net/svn/pypy/trunk/pypy/interpreter/typedef.py
.. _Standard object space: objspace.html#the-standard-object-space
-.. _objspace.py: ../../pypy/objspace/std/objspace.py
-.. _thunk: ../../pypy/objspace/thunk.py
-.. _trace: ../../pypy/objspace/trace.py
-.. _flow: ../../pypy/objspace/flow/
-.. _translator.py: ../../pypy/translator/translator.py
+.. _objspace.py: ../../../../pypy/objspace/std/objspace.py
+.. _thunk: ../../../../pypy/objspace/thunk.py
+.. _trace: ../../../../pypy/objspace/trace.py
+.. _flow: ../../../../pypy/objspace/flow/
+.. _translator.py: ../../../../pypy/translator/translator.py
.. _mailing lists: index.html
.. _documentation: docindex.html
.. _unit tests: coding-guide.html#test-design
.. _`directory reference`: docindex.html#directory-reference
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/getting-started-python.txt b/pypy/doc/getting-started-python.rst
rename from pypy/doc/getting-started-python.txt
rename to pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.txt
+++ b/pypy/doc/getting-started-python.rst
@@ -3,7 +3,7 @@
==============================================
.. contents::
-.. sectnum::
+
PyPy's Python interpreter is a very compliant Python
interpreter implemented in Python. When translated to C, it passes most of
@@ -35,20 +35,31 @@
You can translate the whole of PyPy's Python interpreter to low level C code,
`CLI code`_, or `JVM code`_.
-1. Install dependencies. You need (these are Debian package names,
- adapt as needed):
+1. Install build-time dependencies. On a Debian box these are::
- * ``gcc``
- * ``python-dev``
- * ``python-ctypes`` if you are still using Python2.4
- * ``libffi-dev``
+ [user at debian-box ~]$ sudo apt-get install \
+ gcc make python-dev libffi-dev pkg-config \
+ libz-dev libbz2-dev libncurses-dev libexpat1-dev \
+ libssl-dev libgc-dev python-sphinx python-greenlet
+
+ On a Fedora box these are::
+
+ [user at fedora-or-rh-box ~]$ sudo yum install \
+ gcc make python-devel libffi-devel pkg-config \
+ zlib-devel bzip2-devel ncurses-devel expat-devel \
+ openssl-devel gc-devel python-sphinx python-greenlet
+
+ The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones.
+
* ``pkg-config`` (to help us locate libffi files)
* ``libz-dev`` (for the optional ``zlib`` module)
* ``libbz2-dev`` (for the optional ``bz2`` module)
* ``libncurses-dev`` (for the optional ``_minimal_curses`` module)
* ``libexpat1-dev`` (for the optional ``pyexpat`` module)
* ``libssl-dev`` (for the optional ``_ssl`` module)
- * ``libgc-dev`` (Boehm: only when translating with `--opt=0, 1` or `size`)
+ * ``libgc-dev`` (for the Boehm garbage collector: only needed when translating with `--opt=0, 1` or `size`)
+ * ``python-sphinx`` (for the optional documentation build)
+ * ``python-greenlet`` (for the optional stackless support in interpreted mode/testing)
2. Translation is somewhat time-consuming (30 min to
over one hour) and RAM-hungry. If you have less than 1.5 GB of
@@ -68,8 +79,8 @@
possibly replacing ``--opt=jit`` with another `optimization level`_
of your choice like ``--opt=2`` if you do not want the included JIT
- compiler. (As of March 2010, the default level is ``--opt=2``, and
- ``--opt=jit`` requires an Intel **32-bit** environment.)
+ compiler. As of March 2011, Intel 32-bit environment needs **at
+ least** 2GB, and 64-bit needs 4GB.
.. _`optimization level`: config/opt.html
@@ -222,6 +233,12 @@
../../..
etc.
+If the executable fails to find suitable libraries, it will report
+``debug: WARNING: library path not found, using compiled-in sys.path``
+and then attempt to continue normally. If the default path is usable,
+most code will be fine. However, the ``sys.prefix`` will be unset
+and some existing libraries assume that this is never the case.
+
In order to use ``distutils`` or ``setuptools`` a directory ``PREFIX/site-packages`` needs to be created. Here's an example session setting up and using ``easy_install``::
$ cd PREFIX
@@ -299,4 +316,4 @@
.. _clr: clr-module.html
.. _`CPythons core language regression tests`: http://codespeak.net:8099/summary?category=applevel&branch=%3Ctrunk%3E
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/getting-started.txt b/pypy/doc/getting-started.rst
rename from pypy/doc/getting-started.txt
rename to pypy/doc/getting-started.rst
--- a/pypy/doc/getting-started.txt
+++ b/pypy/doc/getting-started.rst
@@ -1,9 +1,8 @@
==================================
-PyPy - Getting Started
+Getting Started
==================================
.. contents::
-.. sectnum::
.. _howtopypy:
@@ -34,9 +33,11 @@
repository using mercurial. We suggest using mercurial if one
wants to access the current development.
-.. _`downloading them from the download page`: download.html
+.. _`downloading them from the download page`: http://pypy.org/download.html
-If you choose to use mercurial, you must issue the following command on your
+If you choose to use mercurial,
+first make sure you have ``subversion`` installed.
+You must issue the following command on your
command line, DOS box, or terminal::
hg clone http://bitbucket.org/pypy/pypy pypy
@@ -120,4 +121,4 @@
.. _bug reports: https://codespeak.net/issue/pypy-dev/
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/glossary.txt b/pypy/doc/glossary.rst
rename from pypy/doc/glossary.txt
rename to pypy/doc/glossary.rst
--- a/pypy/doc/glossary.txt
+++ b/pypy/doc/glossary.rst
@@ -1,7 +1,17 @@
+.. _glossary:
+
+********
+Glossary
+********
+
PyPy, like any large project, has developed a jargon of its own. This
document gives brief definition of some of these terms and provides
links to more information.
+.. if you add new entries, keep the alphabetical sorting!
+
+.. glossary::
+
**abstract interpretation**
The technique of interpreting the bytecode of a user program with
an interpreter that handles abstract objects instead of concrete ones.
@@ -234,4 +244,4 @@
.. _`subsystem implementing the Python language`: architecture.html#standard-interpreter
.. _Theory: theory.html
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/how-to-release.txt b/pypy/doc/how-to-release.rst
rename from pypy/doc/how-to-release.txt
rename to pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.txt
+++ b/pypy/doc/how-to-release.rst
@@ -1,3 +1,5 @@
+.. include:: crufty.rst
+
Making a PyPy Release
=======================
diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/index-of-release-notes.rst
@@ -0,0 +1,17 @@
+Historical release notes
+------------------------
+
+.. toctree::
+
+ release-0.6
+ release-0.7.0.rst
+ release-0.8.0.rst
+ release-0.9.0.rst
+ release-0.99.0.rst
+ release-1.0.0.rst
+ release-1.1.0.rst
+ release-1.2.0.rst
+ release-1.3.0.rst
+ release-1.4.0.rst
+ release-1.4.0beta.rst
+ release-1.4.1.rst
diff --git a/pypy/doc/index-report.txt b/pypy/doc/index-report.rst
rename from pypy/doc/index-report.txt
rename to pypy/doc/index-report.rst
--- a/pypy/doc/index-report.txt
+++ b/pypy/doc/index-report.rst
@@ -1,3 +1,5 @@
+.. include:: crufty.rst
+
============================================
PyPy - Overview over the EU-reports
============================================
diff --git a/pypy/doc/index.txt b/pypy/doc/index.rst
rename from pypy/doc/index.txt
rename to pypy/doc/index.rst
--- a/pypy/doc/index.txt
+++ b/pypy/doc/index.rst
@@ -1,3 +1,6 @@
+
+Welcome to PyPy Development
+=============================================
The PyPy project aims at producing a flexible and fast Python_
implementation. The guiding idea is to translate a Python-level
@@ -12,10 +15,17 @@
* `PyPy Blog`_: news and status info about PyPy
-* `Documentation`_: extensive documentation and papers_ about PyPy.
+* `Documentation`_: extensive documentation about PyPy.
* `Getting Started`_: Getting started and playing with PyPy.
+* `Papers`_: Academic papers, talks, and related projects
+
+* `Videos`_: Videos of PyPy talks and presentations
+
+* `speed.pypy.org`_: Daily benchmarks of how fast PyPy is
+
+
Mailing lists, bug tracker, IRC channel
=============================================
@@ -55,5 +65,79 @@
.. _`FAQ`: faq.html
.. _`Documentation`: docindex.html
.. _`Getting Started`: getting-started.html
-.. _papers: extradoc.html
+.. _`Papers`: extradoc.html
+.. _`Videos`: video-index.html
.. _`Release 1.4`: http://pypy.org/download.html
+.. _`speed.pypy.org`: http://speed.pypy.org
+
+Detailed Documentation
+======================
+
+.. The following documentation is important and reasonably up-to-date:
+
+.. extradoc: should this be integrated one level up: dcolish?
+
+
+.. toctree::
+ :maxdepth: 1
+
+ getting-started.rst
+ getting-started-python.rst
+ getting-started-dev.rst
+ windows.rst
+ faq.rst
+ architecture.rst
+ coding-guide.rst
+ cpython_differences.rst
+ cleanup-todo.rst
+ garbage_collection.rst
+ interpreter.rst
+ objspace.rst
+
+ dev_method.rst
+ extending.rst
+
+ extradoc.rst
+
+ glossary.rst
+
+ contributor.rst
+
+ interpreter-optimizations.rst
+ configuration.rst
+ low-level-encapsulation.rst
+ parser.rst
+ rlib.rst
+ rtyper.rst
+ translation.rst
+ jit/_ref.rst
+ jit/index.rst
+ jit/overview.rst
+ jit/pyjitpl5.rst
+
+ index-of-release-notes.rst
+
+ ctypes-implementation.rst
+
+ how-to-release.rst
+
+ index-report.rst
+
+ stackless.rst
+
+ discussions.rst
+
+ cleanup.rst
+
+ sprint-reports.rst
+
+ eventhistory.rst
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+* :ref:`glossary`
+
diff --git a/pypy/doc/interpreter-optimizations.txt b/pypy/doc/interpreter-optimizations.rst
rename from pypy/doc/interpreter-optimizations.txt
rename to pypy/doc/interpreter-optimizations.rst
diff --git a/pypy/doc/interpreter.txt b/pypy/doc/interpreter.rst
rename from pypy/doc/interpreter.txt
rename to pypy/doc/interpreter.rst
--- a/pypy/doc/interpreter.txt
+++ b/pypy/doc/interpreter.rst
@@ -1,9 +1,9 @@
===================================
-PyPy - Bytecode Interpreter
+Bytecode Interpreter
===================================
.. contents::
-.. sectnum::
+
Introduction and Overview
@@ -407,4 +407,4 @@
as a reference for the exact attributes of interpreter classes visible
at application level.
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/jit/_ref.txt b/pypy/doc/jit/_ref.rst
rename from pypy/doc/jit/_ref.txt
rename to pypy/doc/jit/_ref.rst
diff --git a/pypy/doc/jit/index.txt b/pypy/doc/jit/index.rst
rename from pypy/doc/jit/index.txt
rename to pypy/doc/jit/index.rst
diff --git a/pypy/doc/jit/overview.txt b/pypy/doc/jit/overview.rst
rename from pypy/doc/jit/overview.txt
rename to pypy/doc/jit/overview.rst
--- a/pypy/doc/jit/overview.txt
+++ b/pypy/doc/jit/overview.rst
@@ -3,7 +3,6 @@
------------------------------------------------------------------------
.. contents::
-.. sectnum::
This is a non-technical introduction and motivation for PyPy's approach
to Just-In-Time compiler generation.
diff --git a/pypy/doc/jit/pyjitpl5.txt b/pypy/doc/jit/pyjitpl5.rst
rename from pypy/doc/jit/pyjitpl5.txt
rename to pypy/doc/jit/pyjitpl5.rst
diff --git a/pypy/doc/low-level-encapsulation.txt b/pypy/doc/low-level-encapsulation.rst
rename from pypy/doc/low-level-encapsulation.txt
rename to pypy/doc/low-level-encapsulation.rst
--- a/pypy/doc/low-level-encapsulation.txt
+++ b/pypy/doc/low-level-encapsulation.rst
@@ -3,7 +3,7 @@
============================================================
.. contents::
-.. sectnum::
+
Abstract
diff --git a/pypy/doc/maemo.txt b/pypy/doc/maemo.rst
rename from pypy/doc/maemo.txt
rename to pypy/doc/maemo.rst
diff --git a/pypy/doc/make.bat b/pypy/doc/make.bat
new file mode 100644
--- /dev/null
+++ b/pypy/doc/make.bat
@@ -0,0 +1,113 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+set SPHINXBUILD=sphinx-build
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PyPy.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PyPy.ghc
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+:end
diff --git a/pypy/doc/objspace-proxies.txt b/pypy/doc/objspace-proxies.rst
rename from pypy/doc/objspace-proxies.txt
rename to pypy/doc/objspace-proxies.rst
--- a/pypy/doc/objspace-proxies.txt
+++ b/pypy/doc/objspace-proxies.rst
@@ -3,7 +3,7 @@
=================================
.. contents::
-.. sectnum::
+
Thanks to the `Object Space`_ architecture, any feature that is
@@ -607,12 +607,12 @@
lists, dicts, exceptions, tracebacks and frames.
.. _`standard object space`: objspace.html#the-standard-object-space
-.. _`proxy_helpers.py`: ../../pypy/objspace/std/proxy_helpers.py
-.. _`proxyobject.py`: ../../pypy/objspace/std/proxyobject.py
-.. _`transparent.py`: ../../pypy/objspace/std/transparent.py
+.. _`proxy_helpers.py`: ../../../../pypy/objspace/std/proxy_helpers.py
+.. _`proxyobject.py`: ../../../../pypy/objspace/std/proxyobject.py
+.. _`transparent.py`: ../../../../pypy/objspace/std/transparent.py
.. _`tputil.py`: ../../lib_pypy/tputil.py
.. [D12.1] `High-Level Backends and Interpreter Feature Prototypes`, PyPy
EU-Report, 2007, http://codespeak.net/pypy/extradoc/eu-report/D12.1_H-L-Backends_and_Feature_Prototypes-2007-03-22.pdf
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/objspace.txt b/pypy/doc/objspace.rst
rename from pypy/doc/objspace.txt
rename to pypy/doc/objspace.rst
--- a/pypy/doc/objspace.txt
+++ b/pypy/doc/objspace.rst
@@ -1,9 +1,9 @@
======================
-PyPy - Object Spaces
+Object Spaces
======================
.. contents::
-.. sectnum::
+
.. _`objectspace`:
.. _`Object Space`:
@@ -341,7 +341,7 @@
using plain integers instead is the complex path, not the other way
around.
-.. _StdObjSpace: ../objspace/std/
+.. _StdObjSpace: ../../../../pypy/objspace/std/
Object types
@@ -394,10 +394,10 @@
For other examples of multiple implementations of the same Python type,
see `Standard Interpreter Optimizations`_.
-.. _`listtype.py`: ../objspace/std/listtype.py
-.. _`stringtype.py`: ../objspace/std/stringtype.py
-.. _`tupletype.py`: ../objspace/std/tupletype.py
-.. _`tupleobject.py`: ../objspace/std/tupleobject.py
+.. _`listtype.py`: ../../../../pypy/objspace/std/listtype.py
+.. _`stringtype.py`: ../../../../pypy/objspace/std/stringtype.py
+.. _`tupletype.py`: ../../../../pypy/objspace/std/tupletype.py
+.. _`tupleobject.py`: ../../../../pypy/objspace/std/tupleobject.py
.. _`Standard Interpreter Optimizations`: interpreter-optimizations.html
@@ -412,7 +412,7 @@
alone are not enough for the Standard Object Space: the complete picture
spans several levels in order to emulate the exact Python semantics.
-.. __: ../objspace/std/multimethod.py
+.. __: ../../../../pypy/objspace/std/multimethod.py
Consider the example of the ``space.getitem(w_a, w_b)`` operation,
corresponding to the application-level syntax ``a[b]``. The Standard
@@ -600,7 +600,7 @@
v3 = add(v2, Constant(2))
-.. _FlowObjSpace: ../objspace/flow/
+.. _FlowObjSpace: ../../../../pypy/objspace/flow/
The Flow model
@@ -650,4 +650,4 @@
.. _`What PyPy can do for your objects`: objspace-proxies.html
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/old_news.txt b/pypy/doc/old_news.rst
rename from pypy/doc/old_news.txt
rename to pypy/doc/old_news.rst
diff --git a/pypy/doc/parser.txt b/pypy/doc/parser.rst
rename from pypy/doc/parser.txt
rename to pypy/doc/parser.rst
--- a/pypy/doc/parser.txt
+++ b/pypy/doc/parser.rst
@@ -100,4 +100,4 @@
information like the line number table and stack depth are computed. Finally,
everything is passed to a brand new ``PyCode`` object.
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/project-ideas.txt b/pypy/doc/project-ideas.rst
rename from pypy/doc/project-ideas.txt
rename to pypy/doc/project-ideas.rst
diff --git a/pypy/doc/pytest_restdoc.py b/pypy/doc/pytest_restdoc.py
deleted file mode 100644
--- a/pypy/doc/pytest_restdoc.py
+++ /dev/null
@@ -1,434 +0,0 @@
-"""
-perform ReST syntax, local and remote reference tests on .rst/.txt files.
-"""
-import py
-import sys, os, re
-
-def pytest_addoption(parser):
- group = parser.getgroup("ReST", "ReST documentation check options")
- group.addoption('-R', '--urlcheck',
- action="store_true", dest="urlcheck", default=False,
- help="urlopen() remote links found in ReST text files.")
- group.addoption('--urltimeout', action="store", metavar="secs",
- type="int", dest="urlcheck_timeout", default=5,
- help="timeout in seconds for remote urlchecks")
- group.addoption('--forcegen',
- action="store_true", dest="forcegen", default=False,
- help="force generation of html files.")
-
-def pytest_collect_file(path, parent):
- if path.ext in (".txt", ".rst"):
- project = getproject(path)
- if project is not None:
- return ReSTFile(path, parent=parent, project=project)
-
-def getproject(path):
- for parent in path.parts(reverse=True):
- confrest = parent.join("confrest.py")
- if confrest.check():
- Project = confrest.pyimport().Project
- return Project(parent)
-
-class ReSTFile(py.test.collect.File):
- def __init__(self, fspath, parent, project):
- super(ReSTFile, self).__init__(fspath=fspath, parent=parent)
- self.project = project
-
- def collect(self):
- return [
- ReSTSyntaxTest("ReSTSyntax", parent=self, project=self.project),
- LinkCheckerMaker("checklinks", parent=self),
- DoctestText("doctest", parent=self),
- ]
-
-def deindent(s, sep='\n'):
- leastspaces = -1
- lines = s.split(sep)
- for line in lines:
- if not line.strip():
- continue
- spaces = len(line) - len(line.lstrip())
- if leastspaces == -1 or spaces < leastspaces:
- leastspaces = spaces
- if leastspaces == -1:
- return s
- for i, line in enumerate(lines):
- if not line.strip():
- lines[i] = ''
- else:
- lines[i] = line[leastspaces:]
- return sep.join(lines)
-
-class ReSTSyntaxTest(py.test.collect.Item):
- def __init__(self, name, parent, project):
- super(ReSTSyntaxTest, self).__init__(name=name, parent=parent)
- self.project = project
-
- def reportinfo(self):
- return self.fspath, None, "syntax check"
-
- def runtest(self):
- self.restcheck(py.path.svnwc(self.fspath))
-
- def restcheck(self, path):
- py.test.importorskip("docutils")
- self.register_linkrole()
- from docutils.utils import SystemMessage
- try:
- self._checkskip(path, self.project.get_htmloutputpath(path))
- self.project.process(path)
- except KeyboardInterrupt:
- raise
- except SystemExit, error:
- if error.message == "ERROR: dot not found":
- py.test.skip("system doesn't have graphviz installed")
- return
- raise
- except SystemMessage:
- # we assume docutils printed info on stdout
- py.test.fail("docutils processing failed, see captured stderr")
-
- def register_linkrole(self):
- #directive.register_linkrole('api', self.resolve_linkrole)
- #directive.register_linkrole('source', self.resolve_linkrole)
-#
-# # XXX fake sphinx' "toctree" and refs
-# directive.register_linkrole('ref', self.resolve_linkrole)
-
- from docutils.parsers.rst import directives
- def toctree_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- return []
- toctree_directive.content = 1
- toctree_directive.options = {'maxdepth': int, 'glob': directives.flag,
- 'hidden': directives.flag}
- directives.register_directive('toctree', toctree_directive)
- self.register_pygments()
-
- def register_pygments(self):
- # taken from pygments-main/external/rst-directive.py
- from docutils.parsers.rst import directives
- try:
- from pygments.formatters import HtmlFormatter
- except ImportError:
- def pygments_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- return []
- pygments_directive.options = {}
- else:
- # The default formatter
- DEFAULT = HtmlFormatter(noclasses=True)
- # Add name -> formatter pairs for every variant you want to use
- VARIANTS = {
- # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
- }
-
- from docutils import nodes
-
- from pygments import highlight
- from pygments.lexers import get_lexer_by_name, TextLexer
-
- def pygments_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- try:
- lexer = get_lexer_by_name(arguments[0])
- except ValueError:
- # no lexer found - use the text one instead of an exception
- lexer = TextLexer()
- # take an arbitrary option if more than one is given
- formatter = options and VARIANTS[options.keys()[0]] or DEFAULT
- parsed = highlight('\n'.join(content), lexer, formatter)
- return [nodes.raw('', parsed, format='html')]
-
- pygments_directive.options = dict([(key, directives.flag) for key in VARIANTS])
-
- pygments_directive.arguments = (1, 0, 1)
- pygments_directive.content = 1
- directives.register_directive('sourcecode', pygments_directive)
-
- def resolve_linkrole(self, name, text, check=True):
- apigen_relpath = self.project.apigen_relpath
-
- if name == 'api':
- if text == 'py':
- return ('py', apigen_relpath + 'api/index.html')
- else:
- assert text.startswith('py.'), (
- 'api link "%s" does not point to the py package') % (text,)
- dotted_name = text
- if dotted_name.find('(') > -1:
- dotted_name = dotted_name[:text.find('(')]
- # remove pkg root
- path = dotted_name.split('.')[1:]
- dotted_name = '.'.join(path)
- obj = py
- if check:
- for chunk in path:
- try:
- obj = getattr(obj, chunk)
- except AttributeError:
- raise AssertionError(
- 'problem with linkrole :api:`%s`: can not resolve '
- 'dotted name %s' % (text, dotted_name,))
- return (text, apigen_relpath + 'api/%s.html' % (dotted_name,))
- elif name == 'source':
- assert text.startswith('py/'), ('source link "%s" does not point '
- 'to the py package') % (text,)
- relpath = '/'.join(text.split('/')[1:])
- if check:
- pkgroot = py._pydir
- abspath = pkgroot.join(relpath)
- assert pkgroot.join(relpath).check(), (
- 'problem with linkrole :source:`%s`: '
- 'path %s does not exist' % (text, relpath))
- if relpath.endswith('/') or not relpath:
- relpath += 'index.html'
- else:
- relpath += '.html'
- return (text, apigen_relpath + 'source/%s' % (relpath,))
- elif name == 'ref':
- return ("", "")
-
- def _checkskip(self, lpath, htmlpath=None):
- if not self.config.getvalue("forcegen"):
- lpath = py.path.local(lpath)
- if htmlpath is not None:
- htmlpath = py.path.local(htmlpath)
- if lpath.ext == '.txt':
- htmlpath = htmlpath or lpath.new(ext='.html')
- if htmlpath.check(file=1) and htmlpath.mtime() >= lpath.mtime():
- py.test.skip("html file is up to date, use --forcegen to regenerate")
- #return [] # no need to rebuild
-
-class DoctestText(py.test.collect.Item):
- def reportinfo(self):
- return self.fspath, None, "doctest"
-
- def runtest(self):
- content = self._normalize_linesep()
- newcontent = self.config.hook.pytest_doctest_prepare_content(content=content)
- if newcontent is not None:
- content = newcontent
- s = content
- l = []
- prefix = '.. >>> '
- mod = py.std.types.ModuleType(self.fspath.purebasename)
- skipchunk = False
- for line in deindent(s).split('\n'):
- stripped = line.strip()
- if skipchunk and line.startswith(skipchunk):
- py.builtin.print_("skipping", line)
- continue
- skipchunk = False
- if stripped.startswith(prefix):
- try:
- py.builtin.exec_(py.code.Source(
- stripped[len(prefix):]).compile(), mod.__dict__)
- except ValueError:
- e = sys.exc_info()[1]
- if e.args and e.args[0] == "skipchunk":
- skipchunk = " " * (len(line) - len(line.lstrip()))
- else:
- raise
- else:
- l.append(line)
- docstring = "\n".join(l)
- mod.__doc__ = docstring
- failed, tot = py.std.doctest.testmod(mod, verbose=1)
- if failed:
- py.test.fail("doctest %s: %s failed out of %s" %(
- self.fspath, failed, tot))
-
- def _normalize_linesep(self):
- # XXX quite nasty... but it works (fixes win32 issues)
- s = self.fspath.read()
- linesep = '\n'
- if '\r' in s:
- if '\n' not in s:
- linesep = '\r'
- else:
- linesep = '\r\n'
- s = s.replace(linesep, '\n')
- return s
-
-class LinkCheckerMaker(py.test.collect.Collector):
- def collect(self):
- return list(self.genlinkchecks())
-
- def genlinkchecks(self):
- path = self.fspath
- # generating functions + args as single tests
- timeout = self.config.getvalue("urlcheck_timeout")
- for lineno, line in enumerate(path.readlines()):
- line = line.strip()
- if line.startswith('.. _'):
- if line.startswith('.. _`'):
- delim = '`:'
- else:
- delim = ':'
- l = line.split(delim, 1)
- if len(l) != 2:
- continue
- tryfn = l[1].strip()
- name = "%s:%d" %(tryfn, lineno)
- if tryfn.startswith('http:') or tryfn.startswith('https'):
- if self.config.getvalue("urlcheck"):
- yield CheckLink(name, parent=self,
- args=(tryfn, path, lineno, timeout), checkfunc=urlcheck)
- elif tryfn.startswith('webcal:'):
- continue
- else:
- i = tryfn.find('#')
- if i != -1:
- checkfn = tryfn[:i]
- else:
- checkfn = tryfn
- if checkfn.strip() and (1 or checkfn.endswith('.html')):
- yield CheckLink(name, parent=self,
- args=(tryfn, path, lineno), checkfunc=localrefcheck)
-
-class CheckLink(py.test.collect.Item):
- def __init__(self, name, parent, args, checkfunc):
- super(CheckLink, self).__init__(name, parent)
- self.args = args
- self.checkfunc = checkfunc
-
- def runtest(self):
- return self.checkfunc(*self.args)
-
- def reportinfo(self, basedir=None):
- return (self.fspath, self.args[2], "checklink: %s" % self.args[0])
-
-def urlcheck(tryfn, path, lineno, TIMEOUT_URLOPEN):
- old = py.std.socket.getdefaulttimeout()
- py.std.socket.setdefaulttimeout(TIMEOUT_URLOPEN)
- try:
- try:
- py.builtin.print_("trying remote", tryfn)
- py.std.urllib2.urlopen(tryfn)
- finally:
- py.std.socket.setdefaulttimeout(old)
- except (py.std.urllib2.URLError, py.std.urllib2.HTTPError):
- e = sys.exc_info()[1]
- if getattr(e, 'code', None) in (401, 403): # authorization required, forbidden
- py.test.skip("%s: %s" %(tryfn, str(e)))
- else:
- py.test.fail("remote reference error %r in %s:%d\n%s" %(
- tryfn, path.basename, lineno+1, e))
-
-def localrefcheck(tryfn, path, lineno):
- # assume it should be a file
- i = tryfn.find('#')
- if tryfn.startswith('javascript:'):
- return # don't check JS refs
- if i != -1:
- anchor = tryfn[i+1:]
- tryfn = tryfn[:i]
- else:
- anchor = ''
- fn = path.dirpath(tryfn)
- ishtml = fn.ext == '.html'
- fn = ishtml and fn.new(ext='.txt') or fn
- py.builtin.print_("filename is", fn)
- if not fn.check(): # not ishtml or not fn.check():
- if not py.path.local(tryfn).check(): # the html could be there
- py.test.fail("reference error %r in %s:%d" %(
- tryfn, path.basename, lineno+1))
- if anchor:
- source = unicode(fn.read(), 'latin1')
- source = source.lower().replace('-', ' ') # aehem
-
- anchor = anchor.replace('-', ' ')
- match2 = ".. _`%s`:" % anchor
- match3 = ".. _%s:" % anchor
- candidates = (anchor, match2, match3)
- py.builtin.print_("candidates", repr(candidates))
- for line in source.split('\n'):
- line = line.strip()
- if line in candidates:
- break
- else:
- py.test.fail("anchor reference error %s#%s in %s:%d" %(
- tryfn, anchor, path.basename, lineno+1))
-
-if hasattr(sys.stdout, 'fileno') and os.isatty(sys.stdout.fileno()):
- def log(msg):
- print(msg)
-else:
- def log(msg):
- pass
-
-def convert_rest_html(source, source_path, stylesheet=None, encoding='latin1'):
- """ return html latin1-encoded document for the given input.
- source a ReST-string
- sourcepath where to look for includes (basically)
- stylesheet path (to be used if any)
- """
- from docutils.core import publish_string
- kwargs = {
- 'stylesheet' : stylesheet,
- 'stylesheet_path': None,
- 'traceback' : 1,
- 'embed_stylesheet': 0,
- 'output_encoding' : encoding,
- #'halt' : 0, # 'info',
- 'halt_level' : 2,
- }
- # docutils uses os.getcwd() :-(
- source_path = os.path.abspath(str(source_path))
- prevdir = os.getcwd()
- try:
- #os.chdir(os.path.dirname(source_path))
- return publish_string(source, source_path, writer_name='html',
- settings_overrides=kwargs)
- finally:
- os.chdir(prevdir)
-
-def process(txtpath, encoding='latin1'):
- """ process a textfile """
- log("processing %s" % txtpath)
- assert txtpath.check(ext='.txt')
- if isinstance(txtpath, py.path.svnwc):
- txtpath = txtpath.localpath
- htmlpath = txtpath.new(ext='.html')
- #svninfopath = txtpath.localpath.new(ext='.svninfo')
-
- style = txtpath.dirpath('style.css')
- if style.check():
- stylesheet = style.basename
- else:
- stylesheet = None
- content = unicode(txtpath.read(), encoding)
- doc = convert_rest_html(content, txtpath, stylesheet=stylesheet, encoding=encoding)
- htmlpath.open('wb').write(doc)
- #log("wrote %r" % htmlpath)
- #if txtpath.check(svnwc=1, versioned=1):
- # info = txtpath.info()
- # svninfopath.dump(info)
-
-if sys.version_info > (3, 0):
- def _uni(s): return s
-else:
- def _uni(s):
- return unicode(s)
-
-rex1 = re.compile(r'.*<body>(.*)</body>.*', re.MULTILINE | re.DOTALL)
-rex2 = re.compile(r'.*<div class="document">(.*)</div>.*', re.MULTILINE | re.DOTALL)
-
-def strip_html_header(string, encoding='utf8'):
- """ return the content of the body-tag """
- uni = unicode(string, encoding)
- for rex in rex1,rex2:
- match = rex.search(uni)
- if not match:
- break
- uni = match.group(1)
- return uni
-
-class Project: # used for confrest.py files
- def __init__(self, sourcepath):
- self.sourcepath = sourcepath
- def process(self, path):
- return process(path)
- def get_htmloutputpath(self, path):
- return path.new(ext='html')
diff --git a/pypy/doc/redirections b/pypy/doc/redirections
deleted file mode 100644
--- a/pypy/doc/redirections
+++ /dev/null
@@ -1,10 +0,0 @@
-# please make sure this is evaluable
-{
- 'proxy.html': 'objspace-proxies.html#tproxy',
- 'news.html': 'index.html',
- 'contact.html': 'index.html',
- 'home.html': 'index.html',
- 'jit.html': 'jit/index.html',
- 'standalone-howto.html': 'faq.html#pypy-translation-tool-chain',
- 'dynamic-language-translation.html': 'http://codespeak.net/svn/pypy/extradoc/eu-report/D05.1_Publish_on_translating_a_very-high-level_description.pdf',
-}
diff --git a/pypy/doc/release-0.6.txt b/pypy/doc/release-0.6.rst
rename from pypy/doc/release-0.6.txt
rename to pypy/doc/release-0.6.rst
diff --git a/pypy/doc/release-0.7.0.txt b/pypy/doc/release-0.7.0.rst
rename from pypy/doc/release-0.7.0.txt
rename to pypy/doc/release-0.7.0.rst
diff --git a/pypy/doc/release-0.8.0.txt b/pypy/doc/release-0.8.0.rst
rename from pypy/doc/release-0.8.0.txt
rename to pypy/doc/release-0.8.0.rst
diff --git a/pypy/doc/release-0.9.0.txt b/pypy/doc/release-0.9.0.rst
rename from pypy/doc/release-0.9.0.txt
rename to pypy/doc/release-0.9.0.rst
diff --git a/pypy/doc/release-0.99.0.txt b/pypy/doc/release-0.99.0.rst
rename from pypy/doc/release-0.99.0.txt
rename to pypy/doc/release-0.99.0.rst
diff --git a/pypy/doc/release-1.0.0.txt b/pypy/doc/release-1.0.0.rst
rename from pypy/doc/release-1.0.0.txt
rename to pypy/doc/release-1.0.0.rst
diff --git a/pypy/doc/release-1.1.0.txt b/pypy/doc/release-1.1.0.rst
rename from pypy/doc/release-1.1.0.txt
rename to pypy/doc/release-1.1.0.rst
diff --git a/pypy/doc/release-1.2.0.txt b/pypy/doc/release-1.2.0.rst
rename from pypy/doc/release-1.2.0.txt
rename to pypy/doc/release-1.2.0.rst
diff --git a/pypy/doc/release-1.3.0.txt b/pypy/doc/release-1.3.0.rst
rename from pypy/doc/release-1.3.0.txt
rename to pypy/doc/release-1.3.0.rst
diff --git a/pypy/doc/release-1.4.0.txt b/pypy/doc/release-1.4.0.rst
rename from pypy/doc/release-1.4.0.txt
rename to pypy/doc/release-1.4.0.rst
diff --git a/pypy/doc/release-1.4.0beta.txt b/pypy/doc/release-1.4.0beta.rst
rename from pypy/doc/release-1.4.0beta.txt
rename to pypy/doc/release-1.4.0beta.rst
diff --git a/pypy/doc/release-1.4.1.txt b/pypy/doc/release-1.4.1.rst
rename from pypy/doc/release-1.4.1.txt
rename to pypy/doc/release-1.4.1.rst
diff --git a/pypy/doc/rffi.txt b/pypy/doc/rffi.rst
rename from pypy/doc/rffi.txt
rename to pypy/doc/rffi.rst
diff --git a/pypy/doc/rlib.txt b/pypy/doc/rlib.rst
rename from pypy/doc/rlib.txt
rename to pypy/doc/rlib.rst
--- a/pypy/doc/rlib.txt
+++ b/pypy/doc/rlib.rst
@@ -14,8 +14,8 @@
to change at some point. Usually it is useful to look at the tests in
`pypy/rlib/test`_ to get an impression of how to use a module.
-.. _`pypy/rlib`: ../../pypy/rlib
-.. _`pypy/rlib/test`: ../../pypy/rlib/test
+.. _`pypy/rlib`: ../../../../pypy/rlib
+.. _`pypy/rlib/test`: ../../../../pypy/rlib/test
``listsort``
============
@@ -29,7 +29,7 @@
be sorted using the ``listsort`` module in one program, otherwise the annotator
will be confused.
-.. _listsort: ../../pypy/rlib/listsort.py
+.. _listsort: ../../../../pypy/rlib/listsort.py
``nonconst``
============
@@ -41,7 +41,7 @@
``NonConst`` will behave during annotation like that value, but no constant
folding will happen.
-.. _nonconst: ../../pypy/rlib/nonconst.py
+.. _nonconst: ../../../../pypy/rlib/nonconst.py
.. _`flow object space`: objspace.html#the-flow-object-space
.. _`annotator`: translation.html#the-annotation-pass
@@ -95,7 +95,7 @@
won't be allocated but represented by *tagged pointers**, that is pointers
that have the lowest bit set.
-.. _objectmodel: ../../pypy/rlib/objectmodel.py
+.. _objectmodel: ../../../../pypy/rlib/objectmodel.py
``rarithmetic``
@@ -105,7 +105,7 @@
in the behaviour of arithmetic code in regular Python and RPython code. Most of
them are already described in the `coding guide`_
-.. _rarithmetic: ../../pypy/rlib/rarithmetic.py
+.. _rarithmetic: ../../../../pypy/rlib/rarithmetic.py
.. _`coding guide`: coding-guide.html
@@ -122,7 +122,7 @@
these underscores left out for better readability (so ``a.add(b)`` can be used
to add two rbigint instances).
-.. _rbigint: ../../pypy/rlib/rbigint.py
+.. _rbigint: ../../../../pypy/rlib/rbigint.py
``rrandom``
@@ -133,7 +133,7 @@
``random`` method which returns a pseudo-random floating point number between
0.0 and 1.0.
-.. _rrandom: ../../pypy/rlib/rrandom.py
+.. _rrandom: ../../../../pypy/rlib/rrandom.py
``rsocket``
===========
@@ -145,7 +145,7 @@
so on, which is not suitable for RPython. Instead, ``rsocket`` contains
a hierarchy of Address classes, in a typical static-OO-programming style.
-.. _rsocket: ../../pypy/rlib/rsocket.py
+.. _rsocket: ../../../../pypy/rlib/rsocket.py
``rstack``
@@ -210,7 +210,7 @@
f()
-.. _rstack: ../../pypy/rlib/rstack.py
+.. _rstack: ../../../../pypy/rlib/rstack.py
``streamio``
@@ -220,7 +220,7 @@
by Guido van Rossum as `sio.py`_ in the CPython sandbox as a prototype for the
upcoming new file implementation in Python 3000).
-.. _streamio: ../../pypy/rlib/streamio.py
+.. _streamio: ../../../../pypy/rlib/streamio.py
.. _`sio.py`: http://svn.python.org/view/sandbox/trunk/sio/sio.py
``unroll``
@@ -230,7 +230,7 @@
which wraps an iterator. Looping over the iterator in RPython code will not
produce a loop in the resulting flow graph but will unroll the loop instead.
-.. _unroll: ../../pypy/rlib/unroll.py
+.. _unroll: ../../../../pypy/rlib/unroll.py
``parsing``
===========
@@ -359,7 +359,7 @@
of the nonterminal and ``children`` which is a list of the children attributes.
-.. _`pypy.rlib.parsing.tree`: ../../pypy/rlib/parsing/tree.py
+.. _`pypy.rlib.parsing.tree`: ../../../../pypy/rlib/parsing/tree.py
Visitors
++++++++
@@ -531,5 +531,5 @@
.. _`Prolog interpreter`: http://codespeak.net/svn/pypy/lang/prolog/
-.. _parsing: ../../pypy/rlib/parsing/
+.. _parsing: ../../../../pypy/rlib/parsing/
.. _`json format`: http://www.json.org
diff --git a/pypy/doc/rtyper.txt b/pypy/doc/rtyper.rst
rename from pypy/doc/rtyper.txt
rename to pypy/doc/rtyper.rst
--- a/pypy/doc/rtyper.txt
+++ b/pypy/doc/rtyper.rst
@@ -2,7 +2,7 @@
=================
.. contents::
-.. sectnum::
+
The RPython Typer lives in the directory `pypy/rpython/`_.
@@ -791,4 +791,4 @@
assert res == ~3
.. _annotator: translation.html#the-annotation-pass
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/sandbox.txt b/pypy/doc/sandbox.rst
rename from pypy/doc/sandbox.txt
rename to pypy/doc/sandbox.rst
--- a/pypy/doc/sandbox.txt
+++ b/pypy/doc/sandbox.rst
@@ -1,3 +1,7 @@
+.. include:: crufty.rst
+
+ .. ^^ it continues to work, but is unmaintained
+
PyPy's sandboxing features
==========================
diff --git a/pypy/doc/sprint-reports.txt b/pypy/doc/sprint-reports.rst
rename from pypy/doc/sprint-reports.txt
rename to pypy/doc/sprint-reports.rst
--- a/pypy/doc/sprint-reports.txt
+++ b/pypy/doc/sprint-reports.rst
@@ -78,3 +78,6 @@
.. _`CERN (July 2010)`: http://morepypy.blogspot.com/2010/07/cern-sprint-report-wrapping-c-libraries.html
.. _`Düsseldorf (October 2010)`: http://morepypy.blogspot.com/2010/10/dusseldorf-sprint-report-2010.html
+Further event notes:
+
+* :ref:`eventhistory.rst`
diff --git a/pypy/doc/stackless.txt b/pypy/doc/stackless.rst
rename from pypy/doc/stackless.txt
rename to pypy/doc/stackless.rst
--- a/pypy/doc/stackless.txt
+++ b/pypy/doc/stackless.rst
@@ -2,9 +2,15 @@
Application-level Stackless features
==========================================================
+
+
Introduction
================
+.. include:: crufty.rst
+
+ .. apparently this still works; needs JIT integration; hasn't been maintained for years
+
PyPy can expose to its user language features similar to the ones
present in `Stackless Python`_: **no recursion depth limit**, and the
ability to write code in a **massively concurrent style**. It actually
@@ -619,4 +625,4 @@
.. _`documentation of the greenlets`: http://codespeak.net/svn/greenlet/trunk/doc/greenlet.txt
.. _`Stackless Transform`: translation.html#the-stackless-transform
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/statistic/index.txt b/pypy/doc/statistic/index.rst
rename from pypy/doc/statistic/index.txt
rename to pypy/doc/statistic/index.rst
diff --git a/pypy/doc/svn-help.txt b/pypy/doc/svn-help.rst
rename from pypy/doc/svn-help.txt
rename to pypy/doc/svn-help.rst
diff --git a/pypy/doc/test_redirections.py b/pypy/doc/test_redirections.py
deleted file mode 100644
--- a/pypy/doc/test_redirections.py
+++ /dev/null
@@ -1,54 +0,0 @@
-
-import py
-redir = py.path.local(__file__).dirpath('redirections')
-
-def checkexist(path):
- print "checking", path
- assert path.ext == '.html'
- assert path.new(ext='.txt').check(file=1)
-
-def checkredirection(oldname, newname):
- print "checking", newname
- if not newname.startswith('http://'):
- newpath = redir.dirpath(newname.split('#')[0])
- checkexist(newpath)
- # HACK: create the redirecting HTML file here...
- # XXX obscure fishing
- if py.test.config.option.generateredirections and '#' not in oldname:
- generate_redirection(oldname, newname)
-
-def test_eval():
- d = eval(redir.read(mode='r'))
- return d
-
-def test_redirections():
- d = test_eval()
- for oldname, newname in d.items():
- yield checkredirection, oldname, newname
-
-def test_navlist():
- navlist = eval(redir.dirpath('navlist').read())
- for entry in navlist:
- yield checkexist, redir.dirpath(entry)
-
-# ____________________________________________________________
-
-def generate_redirection(oldname, newname):
- print "redirecting from", oldname
- oldpath = redir.dirpath(oldname)
- url = newname # relative URL
- oldpath.write("""<html>
- <head>
- <meta http-equiv="refresh"
- content="0 ; URL=%s" />
- <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
- <META HTTP-EQUIV="expires" CONTENT="0">
- </head>
- <body>
- <p>
- you should be automatically redirected to
- <a href="%s">%s</a>
- </p>
- </body>
-</html>
-""" % (url, url, url))
diff --git a/pypy/doc/theory.txt b/pypy/doc/theory.rst
rename from pypy/doc/theory.txt
rename to pypy/doc/theory.rst
--- a/pypy/doc/theory.txt
+++ b/pypy/doc/theory.rst
@@ -1,9 +1,13 @@
+.. include:: crufty.rst
+
+ .. ^^ old ideas; we're not doing it this way any more
+
===================================
Techniques used in PyPy
===================================
.. contents::
-.. sectnum::
+
.. _`abstract interpretation`:
diff --git a/pypy/doc/translation-aspects.txt b/pypy/doc/translation-aspects.rst
rename from pypy/doc/translation-aspects.txt
rename to pypy/doc/translation-aspects.rst
--- a/pypy/doc/translation-aspects.txt
+++ b/pypy/doc/translation-aspects.rst
@@ -1,9 +1,12 @@
+.. include:: crufty.rst
+.. ^^ old and needs updating
+
==========================================================================================
Memory management and threading models as translation aspects -- solutions and challenges
==========================================================================================
.. contents::
-.. sectnum::
+
Introduction
=============
diff --git a/pypy/doc/translation.txt b/pypy/doc/translation.rst
rename from pypy/doc/translation.txt
rename to pypy/doc/translation.rst
--- a/pypy/doc/translation.txt
+++ b/pypy/doc/translation.rst
@@ -3,7 +3,7 @@
=====================
.. contents::
-.. sectnum::
+
This document describes the tool chain that we have developed to analyze
and "compile" RPython_ programs (like PyPy itself) to various target
@@ -107,7 +107,7 @@
.. _`abstract interpretation`: theory.html#abstract-interpretation
.. _`Flow Object Space`: objspace.html#the-flow-object-space
.. _`interactive interface`: getting-started-dev.html#try-out-the-translator
-.. _`translatorshell.py`: ../../pypy/bin/translatorshell.py
+.. _`translatorshell.py`: ../../../../pypy/bin/translatorshell.py
.. _`flow model`:
.. _`control flow graphs`:
@@ -274,7 +274,7 @@
should not attempt to actually mutate such Constants.
.. _`document describing object spaces`: objspace.html
-.. _`pypy.objspace.flow.model`: ../objspace/flow/model.py
+.. _`pypy.objspace.flow.model`: ../../../../pypy/objspace/flow/model.py
.. _Annotator:
@@ -768,4 +768,4 @@
collection of functions (which may refer to each other in a mutually
recursive fashion) and annotate and rtype them all at once.
-.. include:: _ref.txt
+.. include:: _ref.rst
diff --git a/pypy/doc/video-index.txt b/pypy/doc/video-index.rst
rename from pypy/doc/video-index.txt
rename to pypy/doc/video-index.rst
diff --git a/pypy/doc/windows.txt b/pypy/doc/windows.rst
rename from pypy/doc/windows.txt
rename to pypy/doc/windows.rst
--- a/pypy/doc/windows.txt
+++ b/pypy/doc/windows.rst
@@ -1,6 +1,6 @@
-=============
-Windows Hints
-=============
+===============
+PyPy on Windows
+===============
Pypy is supported on Windows platforms, starting with Windows 2000.
The following text gives some hints about how to translate the PyPy
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -77,13 +77,13 @@
if i == 2:
return self.kwargname
raise IndexError
-
+
class Arguments(object):
"""
Collects the arguments of a function call.
-
+
Instances should be considered immutable.
"""
@@ -146,7 +146,7 @@
self._combine_starstarargs_wrapped(w_starstararg)
def _combine_starargs_wrapped(self, w_stararg):
- # unpack the * arguments
+ # unpack the * arguments
space = self.space
try:
args_w = space.fixedview(w_stararg)
@@ -236,10 +236,10 @@
if self.arguments_w:
return self.arguments_w[0]
return None
-
+
### Parsing for function calls ###
- def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=[],
+ def _match_signature(self, w_firstarg, scope_w, signature, defaults=None,
blindargs=0):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
@@ -247,19 +247,19 @@
"""
if jit.we_are_jitted() and self._dont_jit:
return self._match_signature_jit_opaque(w_firstarg, scope_w,
- signature, defaults_w,
+ signature, defaults,
blindargs)
return self._really_match_signature(w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults, blindargs)
@jit.dont_look_inside
def _match_signature_jit_opaque(self, w_firstarg, scope_w, signature,
- defaults_w, blindargs):
+ defaults, blindargs):
return self._really_match_signature(w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults, blindargs)
@jit.unroll_safe
- def _really_match_signature(self, w_firstarg, scope_w, signature, defaults_w=[],
+ def _really_match_signature(self, w_firstarg, scope_w, signature, defaults=None,
blindargs=0):
#
# args_w = list of the normal actual parameters, wrapped
@@ -283,10 +283,10 @@
scope_w[0] = w_firstarg
input_argcount = 1
else:
- extravarargs = [ w_firstarg ]
+ extravarargs = [w_firstarg]
else:
upfront = 0
-
+
args_w = self.arguments_w
num_args = len(args_w)
@@ -327,7 +327,7 @@
elif avail > co_argcount:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, 0)
+ defaults, 0)
# the code assumes that keywords can potentially be large, but that
# argnames is typically not too large
@@ -357,12 +357,12 @@
num_remainingkwds -= 1
missing = 0
if input_argcount < co_argcount:
- def_first = co_argcount - len(defaults_w)
+ def_first = co_argcount - (0 if defaults is None else defaults.getlen())
for i in range(input_argcount, co_argcount):
if scope_w[i] is not None:
pass
elif i >= def_first:
- scope_w[i] = defaults_w[i-def_first]
+ scope_w[i] = defaults.getitem(i - def_first)
else:
# error: not enough arguments. Don't signal it immediately
# because it might be related to a problem with */** or
@@ -382,20 +382,20 @@
if co_argcount == 0:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, missing)
+ defaults, missing)
raise ArgErrUnknownKwds(num_remainingkwds, keywords, used_keywords)
if missing:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, missing)
+ defaults, missing)
return co_argcount + has_vararg + has_kwarg
-
+
def parse_into_scope(self, w_firstarg,
- scope_w, fnname, signature, defaults_w=[]):
+ scope_w, fnname, signature, defaults=None):
"""Parse args and kwargs to initialize a frame
according to the signature of code object.
Store the argumentvalues into scope_w.
@@ -403,32 +403,32 @@
"""
try:
return self._match_signature(w_firstarg,
- scope_w, signature, defaults_w, 0)
+ scope_w, signature, defaults, 0)
except ArgErr, e:
raise OperationError(self.space.w_TypeError,
self.space.wrap(e.getmsg(fnname)))
- def _parse(self, w_firstarg, signature, defaults_w, blindargs=0):
+ def _parse(self, w_firstarg, signature, defaults, blindargs=0):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
"""
scopelen = signature.scope_length()
scope_w = [None] * scopelen
- self._match_signature(w_firstarg, scope_w, signature, defaults_w,
+ self._match_signature(w_firstarg, scope_w, signature, defaults,
blindargs)
- return scope_w
+ return scope_w
def parse_obj(self, w_firstarg,
- fnname, signature, defaults_w=[], blindargs=0):
+ fnname, signature, defaults=None, blindargs=0):
"""Parse args and kwargs to initialize a frame
according to the signature of code object.
"""
try:
- return self._parse(w_firstarg, signature, defaults_w, blindargs)
+ return self._parse(w_firstarg, signature, defaults, blindargs)
except ArgErr, e:
raise OperationError(self.space.w_TypeError,
- self.space.wrap(e.getmsg(fnname)))
+ self.space.wrap(e.getmsg(fnname)))
@staticmethod
def frompacked(space, w_args=None, w_kwds=None):
@@ -473,24 +473,24 @@
self.w_starstararg)
-
- def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=[],
+
+ def _match_signature(self, w_firstarg, scope_w, signature, defaults=None,
blindargs=0):
self.combine_if_necessary()
# _match_signature is destructive
return Arguments._match_signature(
self, w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults, blindargs)
def unpack(self):
self.combine_if_necessary()
return Arguments.unpack(self)
- def match_signature(self, signature, defaults_w):
+ def match_signature(self, signature, defaults):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
"""
- return self._parse(None, signature, defaults_w)
+ return self._parse(None, signature, defaults)
def unmatch_signature(self, signature, data_w):
"""kind of inverse of match_signature"""
@@ -513,10 +513,10 @@
for w_key in space.unpackiterable(data_w_starargarg):
key = space.str_w(w_key)
w_value = space.getitem(data_w_starargarg, w_key)
- unfiltered_kwds_w[key] = w_value
+ unfiltered_kwds_w[key] = w_value
cnt += 1
assert len(data_w) == cnt
-
+
ndata_args_w = len(data_args_w)
if ndata_args_w >= need_cnt:
args_w = data_args_w[:need_cnt]
@@ -532,19 +532,19 @@
for i in range(0, len(stararg_w)):
args_w[i + datalen] = stararg_w[i]
assert len(args_w) == need_cnt
-
+
keywords = []
keywords_w = []
for key in need_kwds:
keywords.append(key)
keywords_w.append(unfiltered_kwds_w[key])
-
+
return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w)
@staticmethod
def frompacked(space, w_args=None, w_kwds=None):
raise NotImplementedError("go away")
-
+
@staticmethod
def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w):
args_w = data_w[:shape_cnt]
@@ -596,23 +596,23 @@
#
class ArgErr(Exception):
-
+
def getmsg(self, fnname):
raise NotImplementedError
class ArgErrCount(ArgErr):
def __init__(self, got_nargs, nkwds, expected_nargs, has_vararg, has_kwarg,
- defaults_w, missing_args):
+ defaults, missing_args):
self.expected_nargs = expected_nargs
self.has_vararg = has_vararg
self.has_kwarg = has_kwarg
-
- self.num_defaults = len(defaults_w)
+
+ self.num_defaults = 0 if defaults is None else defaults.getlen()
self.missing_args = missing_args
self.num_args = got_nargs
self.num_kwds = nkwds
-
+
def getmsg(self, fnname):
args = None
#args_w, kwds_w = args.unpack()
@@ -620,7 +620,7 @@
n = self.expected_nargs
if n == 0:
msg = "%s() takes no argument (%d given)" % (
- fnname,
+ fnname,
nargs)
else:
defcount = self.num_defaults
diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -3590,6 +3590,8 @@
try:
obj = space.interp_w(operator, w_new_value)
w_self.op = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'op', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -4824,6 +4826,8 @@
try:
obj = space.interp_w(boolop, w_new_value)
w_self.op = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'op', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -4911,6 +4915,8 @@
try:
obj = space.interp_w(operator, w_new_value)
w_self.op = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'op', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -4980,6 +4986,8 @@
try:
obj = space.interp_w(unaryop, w_new_value)
w_self.op = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'op', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6028,6 +6036,8 @@
try:
obj = space.interp_w(expr_context, w_new_value)
w_self.ctx = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'ctx', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6118,6 +6128,8 @@
try:
obj = space.interp_w(expr_context, w_new_value)
w_self.ctx = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'ctx', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6187,6 +6199,8 @@
try:
obj = space.interp_w(expr_context, w_new_value)
w_self.ctx = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'ctx', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6252,6 +6266,8 @@
try:
obj = space.interp_w(expr_context, w_new_value)
w_self.ctx = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'ctx', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
@@ -6318,6 +6334,8 @@
try:
obj = space.interp_w(expr_context, w_new_value)
w_self.ctx = obj.to_simple_int(space)
+ # need to save the original object too
+ w_self.setdictvalue(space, 'ctx', w_new_value)
except OperationError, e:
if not e.match(space, space.w_TypeError):
raise
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -454,6 +454,9 @@
(field.type,), 2)
self.emit("w_self.%s = obj.to_simple_int(space)" %
(field.name,), 2)
+ self.emit("# need to save the original object too", 2)
+ self.emit("w_self.setdictvalue(space, '%s', w_new_value)"
+ % (field.name,), 2)
else:
config = (field.name, field.type, repr(field.opt))
self.emit("w_self.%s = space.interp_w(%s, w_new_value, %s)" %
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -365,7 +365,11 @@
def setbuiltinmodule(self, importname):
"""NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules"""
- fullname = "pypy.module.%s" % importname
+ if '.' in importname:
+ fullname = importname
+ importname = fullname.rsplit('.', 1)[1]
+ else:
+ fullname = "pypy.module.%s" % importname
Module = __import__(fullname,
None, None, ["Module"]).Module
@@ -428,6 +432,11 @@
if value and name not in modules:
modules.append(name)
+ if self.config.objspace.extmodules:
+ for name in self.config.objspace.extmodules.split(','):
+ if name not in modules:
+ modules.append(name)
+
# a bit of custom logic: time2 or rctime take precedence over time
# XXX this could probably be done as a "requires" in the config
if ('time2' in modules or 'rctime' in modules) and 'time' in modules:
@@ -745,7 +754,12 @@
"""Unpack an iterable object into a real (interpreter-level) list.
Raise an OperationError(w_ValueError) if the length is wrong."""
w_iterator = self.iter(w_iterable)
- items = []
+ # If we know the expected length we can preallocate.
+ if expected_length == -1:
+ items = []
+ else:
+ items = [None] * expected_length
+ idx = 0
while True:
try:
w_item = self.next(w_iterator)
@@ -753,19 +767,22 @@
if not e.match(self, self.w_StopIteration):
raise
break # done
- if expected_length != -1 and len(items) == expected_length:
+ if expected_length != -1 and idx == expected_length:
raise OperationError(self.w_ValueError,
self.wrap("too many values to unpack"))
- items.append(w_item)
- if expected_length != -1 and len(items) < expected_length:
- i = len(items)
- if i == 1:
+ if expected_length == -1:
+ items.append(w_item)
+ else:
+ items[idx] = w_item
+ idx += 1
+ if expected_length != -1 and idx < expected_length:
+ if idx == 1:
plural = ""
else:
plural = "s"
raise OperationError(self.w_ValueError,
self.wrap("need more than %d value%s to unpack" %
- (i, plural)))
+ (idx, plural)))
return items
unpackiterable_unroll = jit.unroll_safe(func_with_new_name(unpackiterable,
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -21,6 +21,21 @@
assert not func.can_change_code
return func.code
+class Defaults(object):
+ _immutable_fields_ = ["items[*]"]
+
+ def __init__(self, items):
+ self.items = items
+
+ def getitems(self):
+ return jit.hint(self, promote=True).items
+
+ def getitem(self, idx):
+ return self.getitems()[idx]
+
+ def getlen(self):
+ return len(self.getitems())
+
class Function(Wrappable):
"""A function is a code object captured with some environment:
an object space, a dictionary of globals, default arguments,
@@ -36,8 +51,7 @@
self.code = code # Code instance
self.w_func_globals = w_globals # the globals dictionary
self.closure = closure # normally, list of Cell instances or None
- self.defs_w = defs_w # list of w_default's
- make_sure_not_resized(self.defs_w)
+ self.defs = Defaults(defs_w) # wrapper around list of w_default's
self.w_func_dict = None # filled out below if needed
self.w_module = None
@@ -87,7 +101,7 @@
assert isinstance(code, gateway.BuiltinCode4)
return code.fastcall_4(self.space, self, args_w[0],
args_w[1], args_w[2], args_w[3])
- elif (nargs|PyCode.FLATPYCALL) == fast_natural_arity:
+ elif (nargs | PyCode.FLATPYCALL) == fast_natural_arity:
assert isinstance(code, PyCode)
if nargs < 5:
new_frame = self.space.createframe(code, self.w_func_globals,
@@ -129,15 +143,15 @@
return code.fastcall_4(self.space, self, frame.peekvalue(3),
frame.peekvalue(2), frame.peekvalue(1),
frame.peekvalue(0))
- elif (nargs|Code.FLATPYCALL) == fast_natural_arity:
+ elif (nargs | Code.FLATPYCALL) == fast_natural_arity:
assert isinstance(code, PyCode)
return self._flat_pycall(code, nargs, frame)
- elif fast_natural_arity&Code.FLATPYCALL:
- natural_arity = fast_natural_arity&0xff
- if natural_arity > nargs >= natural_arity-len(self.defs_w):
+ elif fast_natural_arity & Code.FLATPYCALL:
+ natural_arity = fast_natural_arity & 0xff
+ if natural_arity > nargs >= natural_arity - self.defs.getlen():
assert isinstance(code, PyCode)
return self._flat_pycall_defaults(code, nargs, frame,
- natural_arity-nargs)
+ natural_arity - nargs)
elif fast_natural_arity == Code.PASSTHROUGHARGS1 and nargs >= 1:
assert isinstance(code, gateway.BuiltinCodePassThroughArguments1)
w_obj = frame.peekvalue(nargs-1)
@@ -167,12 +181,12 @@
w_arg = frame.peekvalue(nargs-1-i)
new_frame.fastlocals_w[i] = w_arg
- defs_w = self.defs_w
- ndefs = len(defs_w)
- start = ndefs-defs_to_load
+ defs = self.defs
+ ndefs = defs.getlen()
+ start = ndefs - defs_to_load
i = nargs
for j in xrange(start, ndefs):
- new_frame.fastlocals_w[i] = defs_w[j]
+ new_frame.fastlocals_w[i] = defs.getitem(j)
i += 1
return new_frame.run()
@@ -182,8 +196,10 @@
return self.w_func_dict
def setdict(self, space, w_dict):
- if not space.is_true(space.isinstance( w_dict, space.w_dict )):
- raise OperationError( space.w_TypeError, space.wrap("setting function's dictionary to a non-dict") )
+ if not space.isinstance_w(w_dict, space.w_dict):
+ raise OperationError(space.w_TypeError,
+ space.wrap("setting function's dictionary to a non-dict")
+ )
self.w_func_dict = w_dict
def descr_function__new__(space, w_subtype, w_code, w_globals,
@@ -286,7 +302,7 @@
w(self.code),
w_func_globals,
w_closure,
- nt(self.defs_w),
+ nt(self.defs.getitems()),
w_func_dict,
self.w_module,
]
@@ -296,7 +312,7 @@
from pypy.interpreter.pycode import PyCode
args_w = space.unpackiterable(w_args)
try:
- (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs_w,
+ (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs,
w_func_dict, w_module) = args_w
except ValueError:
# wrong args
@@ -321,25 +337,28 @@
if space.is_w(w_func_dict, space.w_None):
w_func_dict = None
self.w_func_dict = w_func_dict
- self.defs_w = space.fixedview(w_defs_w)
+ self.defs = Defaults(space.fixedview(w_defs))
self.w_module = w_module
def fget_func_defaults(self, space):
- values_w = self.defs_w
+ values_w = self.defs.getitems()
+ # the `None in values_w` check here is to ensure that interp-level
+ # functions with a default of NoneNotWrapped do not get their defaults
+ # exposed at applevel
if not values_w or None in values_w:
return space.w_None
return space.newtuple(values_w)
def fset_func_defaults(self, space, w_defaults):
if space.is_w(w_defaults, space.w_None):
- self.defs_w = []
+ self.defs = Defaults([])
return
if not space.is_true(space.isinstance(w_defaults, space.w_tuple)):
raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") )
- self.defs_w = space.fixedview(w_defaults)
+ self.defs = Defaults(space.fixedview(w_defaults))
def fdel_func_defaults(self, space):
- self.defs_w = []
+ self.defs = Defaults([])
def fget_func_doc(self, space):
if self.w_doc is None:
@@ -369,7 +388,7 @@
def fget___module__(self, space):
if self.w_module is None:
if self.w_func_globals is not None and not space.is_w(self.w_func_globals, space.w_None):
- self.w_module = space.call_method( self.w_func_globals, "get", space.wrap("__name__") )
+ self.w_module = space.call_method(self.w_func_globals, "get", space.wrap("__name__"))
else:
self.w_module = space.w_None
return self.w_module
@@ -601,7 +620,7 @@
def __init__(self, func):
assert isinstance(func, Function)
Function.__init__(self, func.space, func.code, func.w_func_globals,
- func.defs_w, func.closure, func.name)
+ func.defs.getitems(), func.closure, func.name)
self.w_doc = func.w_doc
self.w_func_dict = func.w_func_dict
self.w_module = func.w_module
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -13,7 +13,7 @@
NoneNotWrapped = object()
from pypy.tool.sourcetools import func_with_new_name
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.error import OperationError
from pypy.interpreter import eval
from pypy.interpreter.function import Function, Method, ClassMethod
from pypy.interpreter.function import FunctionWithFixedCode
@@ -25,7 +25,7 @@
from pypy.rlib import rstackovf
from pypy.rlib.objectmodel import we_are_translated
-# internal non-translatable parts:
+# internal non-translatable parts:
import py
class SignatureBuilder(object):
@@ -78,13 +78,13 @@
dispatch = self.dispatch
for el in unwrap_spec:
dispatch(el, *extra)
-
+
class UnwrapSpecEmit(UnwrapSpecRecipe):
def __init__(self):
self.n = 0
self.miniglobals = {}
-
+
def succ(self):
n = self.n
self.n += 1
@@ -94,7 +94,7 @@
name = obj.__name__
self.miniglobals[name] = obj
return name
-
+
#________________________________________________________________
class UnwrapSpec_Check(UnwrapSpecRecipe):
@@ -147,7 +147,7 @@
"unwrapped %s argument %s of built-in function %r should "
"not start with 'w_'" % (name, argname, self.func))
app_sig.append(argname)
-
+
def visit__ObjSpace(self, el, app_sig):
self.orig_arg()
@@ -173,7 +173,7 @@
(argname, self.func))
assert app_sig.varargname is None,(
"built-in function %r has conflicting rest args specs" % self.func)
- app_sig.varargname = argname[:-2]
+ app_sig.varargname = argname[:-2]
def visit_w_args(self, el, app_sig):
argname = self.orig_arg()
@@ -199,7 +199,7 @@
def scopenext(self):
return "scope_w[%d]" % self.succ()
-
+
def visit_function(self, (func, cls)):
self.run_args.append("%s(%s)" % (self.use(func),
self.scopenext()))
@@ -207,7 +207,7 @@
def visit_self(self, typ):
self.run_args.append("space.descr_self_interp_w(%s, %s)" %
(self.use(typ), self.scopenext()))
-
+
def visit__Wrappable(self, typ):
self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ),
self.scopenext()))
@@ -265,7 +265,7 @@
"unexpected: same spec, different run_args")
return activation_factory_cls
except KeyError:
- parts = []
+ parts = []
for el in unwrap_spec:
if isinstance(el, tuple):
parts.append(''.join([getattr(subel, '__name__', subel)
@@ -276,7 +276,7 @@
#print label
d = {}
- source = """if 1:
+ source = """if 1:
def _run(self, space, scope_w):
return self.behavior(%s)
\n""" % (', '.join(self.run_args),)
@@ -326,7 +326,7 @@
self.finger += 1
if self.n > 4:
raise FastFuncNotSupported
-
+
def nextarg(self):
arg = "w%d" % self.succ()
self.args.append(arg)
@@ -405,7 +405,7 @@
raise FastFuncNotSupported
d = {}
unwrap_info.miniglobals['func'] = func
- source = """if 1:
+ source = """if 1:
def fastfunc_%s_%d(%s):
return func(%s)
\n""" % (func.__name__, narg,
@@ -511,7 +511,7 @@
# 'w_args' for rest arguments passed as wrapped tuple
# str,int,float: unwrap argument as such type
# (function, cls) use function to check/unwrap argument of type cls
-
+
# First extract the signature from the (CPython-level) code object
from pypy.interpreter import pycode
argnames, varargname, kwargname = pycode.cpython_code_signature(func.func_code)
@@ -532,7 +532,7 @@
else:
assert descrmismatch is None, (
"descrmismatch without a self-type specified")
-
+
orig_sig = SignatureBuilder(func, argnames, varargname, kwargname)
app_sig = SignatureBuilder(func)
@@ -594,7 +594,7 @@
space = func.space
activation = self.activation
scope_w = args.parse_obj(w_obj, func.name, self.sig,
- func.defs_w, self.minargs)
+ func.defs, self.minargs)
try:
w_result = activation._run(space, scope_w)
except DescrMismatch:
@@ -615,10 +615,10 @@
if not we_are_translated():
raise
raise e
- except KeyboardInterrupt:
+ except KeyboardInterrupt:
raise OperationError(space.w_KeyboardInterrupt,
- space.w_None)
- except MemoryError:
+ space.w_None)
+ except MemoryError:
raise OperationError(space.w_MemoryError, space.w_None)
except rstackovf.StackOverflow, e:
rstackovf.check_stack_overflow()
@@ -668,7 +668,7 @@
class BuiltinCode0(BuiltinCode):
_immutable_ = True
fast_natural_arity = 0
-
+
def fastcall_0(self, space, w_func):
try:
w_result = self.fastfunc_0(space)
@@ -684,7 +684,7 @@
class BuiltinCode1(BuiltinCode):
_immutable_ = True
fast_natural_arity = 1
-
+
def fastcall_1(self, space, w_func, w1):
try:
w_result = self.fastfunc_1(space, w1)
@@ -702,7 +702,7 @@
class BuiltinCode2(BuiltinCode):
_immutable_ = True
fast_natural_arity = 2
-
+
def fastcall_2(self, space, w_func, w1, w2):
try:
w_result = self.fastfunc_2(space, w1, w2)
@@ -720,7 +720,7 @@
class BuiltinCode3(BuiltinCode):
_immutable_ = True
fast_natural_arity = 3
-
+
def fastcall_3(self, space, func, w1, w2, w3):
try:
w_result = self.fastfunc_3(space, w1, w2, w3)
@@ -738,7 +738,7 @@
class BuiltinCode4(BuiltinCode):
_immutable_ = True
fast_natural_arity = 4
-
+
def fastcall_4(self, space, func, w1, w2, w3, w4):
try:
w_result = self.fastfunc_4(space, w1, w2, w3, w4)
@@ -770,7 +770,7 @@
NOT_RPYTHON_ATTRIBUTES = ['_staticdefs']
instancecache = {}
-
+
def __new__(cls, f, app_name=None, unwrap_spec = None,
descrmismatch=None, as_classmethod=False):
@@ -846,17 +846,17 @@
return fn
-#
-# the next gateways are to be used only for
-# temporary/initialization purposes
-
-class interp2app_temp(interp2app):
+#
+# the next gateways are to be used only for
+# temporary/initialization purposes
+
+class interp2app_temp(interp2app):
"NOT_RPYTHON"
- def getcache(self, space):
+ def getcache(self, space):
return self.__dict__.setdefault(space, GatewayCache(space))
-# and now for something completely different ...
+# and now for something completely different ...
#
class ApplevelClass:
@@ -896,14 +896,14 @@
from pypy.interpreter.module import Module
return Module(space, space.wrap(name), self.getwdict(space))
- def wget(self, space, name):
- w_globals = self.getwdict(space)
+ def wget(self, space, name):
+ w_globals = self.getwdict(space)
return space.getitem(w_globals, space.wrap(name))
def interphook(self, name):
"NOT_RPYTHON"
def appcaller(space, *args_w):
- if not isinstance(space, ObjSpace):
+ if not isinstance(space, ObjSpace):
raise TypeError("first argument must be a space instance.")
# redirect if the space handles this specially
# XXX can this be factored a bit less flow space dependently?
@@ -932,7 +932,7 @@
args.arguments_w)
return space.call_args(w_func, args)
def get_function(space):
- w_func = self.wget(space, name)
+ w_func = self.wget(space, name)
return space.unwrap(w_func)
appcaller = func_with_new_name(appcaller, name)
appcaller.get_function = get_function
@@ -1123,15 +1123,15 @@
myfunc = appdef('''myfunc(x, y):
return x+y
''')
- """
- if not isinstance(source, str):
+ """
+ if not isinstance(source, str):
source = py.std.inspect.getsource(source).lstrip()
- while source.startswith('@py.test.mark.'):
+ while source.startswith(('@py.test.mark.', '@pytest.mark.')):
# these decorators are known to return the same function
# object, we may ignore them
assert '\n' in source
source = source[source.find('\n') + 1:].lstrip()
- assert source.startswith("def "), "can only transform functions"
+ assert source.startswith("def "), "can only transform functions"
source = source[4:]
p = source.find('(')
assert p >= 0
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -86,7 +86,7 @@
self._init_flags()
# Precompute what arguments need to be copied into cellvars
self._args_as_cellvars = []
-
+
if self.co_cellvars:
argcount = self.co_argcount
assert argcount >= 0 # annotator hint
@@ -146,7 +146,7 @@
def signature(self):
return self._signature
-
+
@classmethod
def _from_code(cls, space, code, hidden_applevel=False, code_hook=None):
""" Initialize the code object from a real (CPython) one.
@@ -182,7 +182,7 @@
list(code.co_cellvars),
hidden_applevel, cpython_magic)
-
+
def _compute_flatcall(self):
# Speed hack!
self.fast_natural_arity = eval.Code.HOPELESS
@@ -192,7 +192,7 @@
return
if self.co_argcount > 0xff:
return
-
+
self.fast_natural_arity = eval.Code.FLATPYCALL | self.co_argcount
def funcrun(self, func, args):
@@ -204,7 +204,7 @@
fresh_virtualizable=True)
args_matched = args.parse_into_scope(None, fresh_frame.fastlocals_w,
func.name,
- sig, func.defs_w)
+ sig, func.defs)
fresh_frame.init_cells()
return frame.run()
@@ -214,10 +214,10 @@
sig = self._signature
# speed hack
fresh_frame = jit.hint(frame, access_directly=True,
- fresh_virtualizable=True)
+ fresh_virtualizable=True)
args_matched = args.parse_into_scope(w_obj, fresh_frame.fastlocals_w,
func.name,
- sig, func.defs_w)
+ sig, func.defs)
fresh_frame.init_cells()
return frame.run()
@@ -269,7 +269,7 @@
def fget_co_consts(self, space):
return space.newtuple(self.co_consts_w)
-
+
def fget_co_names(self, space):
return space.newtuple(self.co_names_w)
@@ -280,7 +280,7 @@
return space.newtuple([space.wrap(name) for name in self.co_cellvars])
More information about the pypy-commit
mailing list