diff --git a/.bzrignore b/.bzrignore index 378eac2..5d658c0 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1 +1,4 @@ build +dist +pyreadline.egg-info/ +__pycache__/ diff --git a/doc/ChangeLog b/doc/ChangeLog index 730a5fe..2854b86 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,6 @@ +2011-04-10 Takayuki SHIMIZUKAWA + * Python3 ready. + 2008-08-25 Jörgen Stenarson * Merging tab insert patch from Vivian De Smedt. Removed comments with vds initials. diff --git a/doc/source/introduction.rst b/doc/source/introduction.rst index 67fda64..028ffa1 100644 --- a/doc/source/introduction.rst +++ b/doc/source/introduction.rst @@ -11,7 +11,7 @@ like python library can also be useful when implementing commandline like interfaces in GUIs. The use of pyreadline for anything but the windows console is still under development. -The pyreadline module does not yet support Python 3.x this will be targeted for the 2.0 version. +The pyreadline module support also Python 3.x. Version 1.7 will be the last release with compatibility with 2.4 and 2.5. The next major release will target 2.6, 2.7 and 3.x. The 1.7 series will only receive bugfixes diff --git a/eggsetup.py b/eggsetup.py index b5bcf75..7661d85 100644 --- a/eggsetup.py +++ b/eggsetup.py @@ -8,7 +8,7 @@ #***************************************************************************** import glob from setuptools import setup,find_packages -execfile('pyreadline/release.py') +exec(compile(open('pyreadline/release.py').read(), 'pyreadline/release.py', 'exec')) setup(name=name, version = version, diff --git a/pyreadline/console/console.py b/pyreadline/console/console.py index 213486c..17f5b7d 100644 --- a/pyreadline/console/console.py +++ b/pyreadline/console/console.py @@ -32,6 +32,9 @@ try: except ImportError: raise ImportError(u"You need ctypes to run this code") +if sys.version_info < (2, 6): + bytes = str + def nolog(string): pass @@ -289,7 +292,7 @@ class Console(object): # This pattern should match all characters that change the cursor position differently # than a normal character. - motion_char_re = re.compile(u'([\n\r\t\010\007])') + motion_char_re = re.compile('([\n\r\t\010\007])'.encode('ascii')) def write_scrolling(self, text, attr=None): u'''write text at current cursor position while watching for scrolling. @@ -309,7 +312,7 @@ class Console(object): w, h = self.size() scroll = 0 # the result # split the string into ordinary characters and funny characters - chunks = self.motion_char_re.split(text) + chunks = self.motion_char_re.split(ensure_str(text)) for chunk in chunks: n = self.write_color(chunk, attr) if len(chunk) == 1: # the funny characters will be alone @@ -760,7 +763,7 @@ def hook_wrapper_23(stdin, stdout, prompt): # call the Python hook res = ensure_str(readline_hook(prompt)) # make sure it returned the right sort of thing - if res and not isinstance(res, str): + if res and not isinstance(res, bytes): raise TypeError, u'readline must return a string.' except KeyboardInterrupt: # GNU readline returns 0 on keyboard interrupt @@ -784,7 +787,7 @@ def hook_wrapper(prompt): # call the Python hook res = ensure_str(readline_hook(prompt)) # make sure it returned the right sort of thing - if res and not isinstance(res, str): + if res and not isinstance(res, bytes): raise TypeError, u'readline must return a string.' except KeyboardInterrupt: # GNU readline returns 0 on keyboard interrupt @@ -808,7 +811,7 @@ def install_readline(hook): readline_hook = hook # get the address of PyOS_ReadlineFunctionPointer so we can update it PyOS_RFP = c_void_p.from_address(Console.GetProcAddress(sys.dllhandle, - "PyOS_ReadlineFunctionPointer")) + "PyOS_ReadlineFunctionPointer".encode('ascii'))) # save a reference to the generated C-callable so it doesn't go away if sys.version < '2.3': readline_ref = HOOKFUNC22(hook_wrapper) diff --git a/pyreadline/lineeditor/history.py b/pyreadline/lineeditor/history.py index 8498435..f1544da 100644 --- a/pyreadline/lineeditor/history.py +++ b/pyreadline/lineeditor/history.py @@ -15,9 +15,7 @@ else: import lineobj -import exceptions - -class EscapeHistory(exceptions.Exception): +class EscapeHistory(Exception): pass from pyreadline.logger import log @@ -93,7 +91,7 @@ class LineHistory(object): fp = open(filename, u'wb') for line in self.history[-self.history_length:]: fp.write(ensure_str(line.get_line_text())) - fp.write(u'\n') + fp.write('\n'.encode('ascii')) fp.close() diff --git a/pyreadline/lineeditor/lineobj.py b/pyreadline/lineeditor/lineobj.py index 4347ffb..25ab657 100644 --- a/pyreadline/lineeditor/lineobj.py +++ b/pyreadline/lineeditor/lineobj.py @@ -10,7 +10,7 @@ import re, operator, sys import wordmatcher import pyreadline.clipboard as clipboard from pyreadline.logger import log -from pyreadline.unicode_helper import ensure_unicode +from pyreadline.unicode_helper import ensure_unicode, biter kill_ring_to_clipboard = False #set to true to copy every addition to kill ring to clipboard @@ -272,12 +272,12 @@ class TextLine(object): def _insert_text(self, text, argument=1): text = text * argument if self.overwrite: - for c in text: + for c in biter(text): #if self.point: self.line_buffer[self.point] = c self.point += 1 else: - for c in text: + for c in biter(text): self.line_buffer.insert(self.point, c) self.point += 1 diff --git a/pyreadline/modes/basemode.py b/pyreadline/modes/basemode.py index bf458d3..e6de04f 100644 --- a/pyreadline/modes/basemode.py +++ b/pyreadline/modes/basemode.py @@ -195,7 +195,7 @@ class BaseMode(object): i = 0 while 1: try: - r = ensure_unicode(self.completer(text, i)) + r = self.completer(ensure_unicode(text), i) except IndexError: break i += 1 @@ -215,7 +215,7 @@ class BaseMode(object): break text = ensure_str(u''.join(buf[self.begidx:self.endidx])) log(u'file complete text="%s"' % ensure_unicode(text)) - completions = map(ensure_unicode, glob.glob(os.path.expanduser(text) + '*')) + completions = map(ensure_unicode, glob.glob(os.path.expanduser(text) + '*'.encode('ascii'))) if self.mark_directories == u'on': mc = [] for f in completions: diff --git a/pyreadline/release.py b/pyreadline/release.py index 4998c23..7ecc2a4 100644 --- a/pyreadline/release.py +++ b/pyreadline/release.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -u"""Release data for the pyreadline project. +"""Release data for the pyreadline project. $Id$""" @@ -13,23 +13,23 @@ $Id$""" # Name of the package for release purposes. This is the name which labels # the tarballs and RPMs made by distutils, so it's best to lowercase it. -name = u'pyreadline' +name = 'pyreadline' # For versions with substrings (like 0.6.16.svn), use an extra . to separate # the new substring. We have to avoid using either dashes or underscores, # because bdist_rpm does not accept dashes (an RPM) convention, and # bdist_deb does not accept underscores (a Debian convention). -branch = u'' +branch = '' -version = u'1.7.1' +version = '2.0' -revision = u'$Revision$' +revision = '$Revision$' -description = u"A python implmementation of GNU readline." +description = "A python implmementation of GNU readline." long_description = \ -u""" +""" The pyreadline package is a python implementation of GNU readline functionality it is based on the ctypes based UNC readline package by Gary Bishop. It is not complete. It has been tested for use with windows 2000 and windows xp. @@ -58,31 +58,32 @@ Features: .. _repository: """ -license = u'BSD' +license = 'BSD' -authors = {u'Jorgen' : (u'Jorgen Stenarson',u'jorgen.stenarson@bostream.nu'), - u'Gary': (u'Gary Bishop', ''), - u'Jack': (u'Jack Trainor', ''), +authors = {'Jorgen' : ('Jorgen Stenarson','jorgen.stenarson@bostream.nu'), + 'Gary': ('Gary Bishop', ''), + 'Jack': ('Jack Trainor', ''), } -url = u'http://ipython.scipy.org/moin/PyReadline/Intro' +url = 'http://ipython.scipy.org/moin/PyReadline/Intro' -download_url = u'https://launchpad.net/pyreadline/+download' +download_url = 'https://launchpad.net/pyreadline/+download' -platforms = [u'Windows XP/2000/NT', - u'Windows 95/98/ME'] +platforms = ['Windows XP/2000/NT', + 'Windows 95/98/ME'] -keywords = [u'readline', - u'pyreadline'] +keywords = ['readline', + 'pyreadline'] -classifiers = [u'Development Status :: 5 - Production/Stable', - u'Environment :: Console', - u'Operating System :: Microsoft :: Windows', - u'License :: OSI Approved :: BSD License', - u'Programming Language :: Python :: 2.4', - u'Programming Language :: Python :: 2.5', - u'Programming Language :: Python :: 2.6', - u'Programming Language :: Python :: 2.7', +classifiers = ['Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Operating System :: Microsoft :: Windows', + 'License :: OSI Approved :: BSD License', + 'Programming Language :: Python :: 2.4', + 'Programming Language :: Python :: 2.5', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.2', ] diff --git a/pyreadline/rlmain.py b/pyreadline/rlmain.py index 66e469a..23deb9d 100644 --- a/pyreadline/rlmain.py +++ b/pyreadline/rlmain.py @@ -282,9 +282,9 @@ class BaseReadline(object): self.mode = modes[name] def bind_key(key, name): - import new + import types if callable(name): - modes[mode]._bind_key(key, new.instancemethod(name, modes[mode], modes[mode].__class__)) + modes[mode]._bind_key(key, types.MethodType(name, modes[mode])) elif hasattr(modes[mode], name): modes[mode]._bind_key(key, getattr(modes[mode], name)) else: diff --git a/pyreadline/test/test_emacs.py b/pyreadline/test/test_emacs.py index 8554f18..534dbdb 100644 --- a/pyreadline/test/test_emacs.py +++ b/pyreadline/test/test_emacs.py @@ -9,12 +9,12 @@ import sys, unittest import pdb -sys.path.append (u'../..') +sys.path.insert(0, u'../..') from pyreadline.modes.emacs import * from pyreadline import keysyms from pyreadline.lineeditor import lineobj -from common import * +from pyreadline.test.common import * from pyreadline.logger import log import pyreadline.logger as logger logger.sock_silent=True diff --git a/pyreadline/test/test_vi.py b/pyreadline/test/test_vi.py index 8b5c904..6504556 100644 --- a/pyreadline/test/test_vi.py +++ b/pyreadline/test/test_vi.py @@ -7,15 +7,15 @@ #***************************************************************************** import sys, unittest,pdb -sys.path.append (u'../..') +sys.path.insert(0, u'../..') from pyreadline.modes.vi import * from pyreadline import keysyms from pyreadline.lineeditor import lineobj from pyreadline.logger import log import pyreadline.logger as logger -from common import * +from pyreadline.test.common import * -from common import * +from pyreadline.test.common import * #---------------------------------------------------------------------- class ViModeTest (ViMode): diff --git a/pyreadline/unicode_helper.py b/pyreadline/unicode_helper.py index bf171ab..7bb8811 100644 --- a/pyreadline/unicode_helper.py +++ b/pyreadline/unicode_helper.py @@ -17,9 +17,14 @@ except AttributeError: if pyreadline_codepage is None: pyreadline_codepage = u"ascii" +if sys.version_info < (2, 6): + bytes = str + +PY3 = (sys.version_info >= (3, 0)) + def ensure_unicode(text): u"""helper to ensure that text passed to WriteConsoleW is unicode""" - if isinstance(text, str): + if isinstance(text, bytes): try: return text.decode(pyreadline_codepage, u"replace") except (LookupError, TypeError): @@ -34,3 +39,9 @@ def ensure_str(text): except (LookupError, TypeError): return text.encode(u"ascii", u"replace") return text + +def biter(text): + if PY3 and isinstance(text, bytes): + return (s.to_bytes(1, 'big') for s in text) + else: + return iter(text) diff --git a/setup.py b/setup.py index 79a698b..9501c1d 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,7 @@ #***************************************************************************** import os +import sys import glob # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly @@ -16,8 +17,25 @@ import glob if os.path.exists('MANIFEST'): os.remove('MANIFEST') # -from distutils.core import setup -execfile('pyreadline/release.py') +extra = {} +_distribute = False + +try: + import setuptools + setup = setuptools.setup + _distribute = getattr(setuptools, '_distribute', False) +except ImportError: + from distutils.core import setup + +if sys.version_info >= (3, 0): + if _distribute == False: + raise RuntimeError('You must installed `distribute` to setup pyreadline with Python3') + + extra.update( + use_2to3=True + ) + +exec(compile(open('pyreadline/release.py').read(), 'pyreadline/release.py', 'exec')) try: import sphinx @@ -50,5 +68,6 @@ setup(name=name, package_data = {'pyreadline':['configuration/*']}, data_files = [], cmdclass = cmd_class, + **extra )