All tests pass now for python 2 and python 3

This commit is contained in:
Holger Rapp 2012-01-10 18:11:34 +01:00
parent cad74ab10c
commit c1b60dc367
9 changed files with 101 additions and 44 deletions

View File

@ -3,6 +3,7 @@
import vim import vim
from UltiSnips.Geometry import Position from UltiSnips.Geometry import Position
from UltiSnips.Compatibility import make_suitable_for_vim
__all__ = [ "TextBuffer", "VimBuffer" ] __all__ = [ "TextBuffer", "VimBuffer" ]
@ -59,9 +60,9 @@ class VimBuffer(Buffer):
return vim.current.buffer[a] return vim.current.buffer[a]
def __setitem__(self, a, b): def __setitem__(self, a, b):
if isinstance(a,slice): if isinstance(a,slice):
vim.current.buffer[a.start:a.stop] = b vim.current.buffer[a.start:a.stop] = make_suitable_for_vim(b)
else: else:
vim.current.buffer[a] = b vim.current.buffer[a] = make_suitable_for_vim(b)
# Open any folds this might have created # Open any folds this might have created
vim.current.window.cursor = a.start + 1, 0 vim.current.window.cursor = a.start + 1, 0

View File

@ -8,15 +8,60 @@ as many python versions as possible.
import sys import sys
__all__ = ['as_unicode'] __all__ = ['as_unicode', 'compatible_exec', 'CheapTotalOrdering']
if sys.version_info >= (3,0): if sys.version_info >= (3,0):
from UltiSnips.Compatibility_py3 import *
class CheapTotalOrdering:
"""Total ordering only appears in python 2.7. We try to stay compatible with
python 2.5 for now, so we define our own"""
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def as_unicode(s): def as_unicode(s):
if isinstance(s, bytes): if isinstance(s, bytes):
return s.decode("utf-8") return s.decode("utf-8")
return s return s
def make_suitable_for_vim(s):
return s
else: else:
from UltiSnips.Compatibility_py2 import *
class CheapTotalOrdering(object):
"""Total ordering only appears in python 2.7. We try to stay compatible with
python 2.5 for now, so we define our own"""
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def as_unicode(s): def as_unicode(s):
if not isinstance(s, unicode): if not isinstance(s, unicode):
return s.decode("uft-8") return s.decode("utf-8")
return s return s
def make_suitable_for_vim(s):
if isinstance(s, list):
return [ a.encode("utf-8") for a in s ]
return s.encode("utf-8")

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
# encoding: utf-8
"""
This file contains code that is invalid in python3 and must therefore never be
seen by the interpretor
"""
def compatible_exec(code, gglobals = None, glocals = None):
if gglobals is not None and glocals is not None:
exec code in gglobals, glocals
elif gglobals is not None:
exec code in gglobals
else:
exec code

View File

@ -0,0 +1,10 @@
#!/usr/bin/env python
# encoding: utf-8
"""
This file contains code that is invalid in python2 and must therefore never be
seen by the interpretor
"""
compatible_exec = exec

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from UltiSnips.Util import CheapTotalOrdering from UltiSnips.Compatibility import CheapTotalOrdering
__all__ = [ "Position", "Span" ] __all__ = [ "Position", "Span" ]

View File

@ -7,11 +7,13 @@ import stat
import tempfile import tempfile
import vim import vim
from UltiSnips.Util import IndentUtil, CheapTotalOrdering
from UltiSnips.Buffer import TextBuffer from UltiSnips.Buffer import TextBuffer
from UltiSnips.Compatibility import CheapTotalOrdering
from UltiSnips.Compatibility import compatible_exec
from UltiSnips.Geometry import Span, Position from UltiSnips.Geometry import Span, Position
from UltiSnips.Lexer import tokenize, EscapeCharToken, TransformationToken, \ from UltiSnips.Lexer import tokenize, EscapeCharToken, TransformationToken, \
TabStopToken, MirrorToken, PythonCodeToken, VimLCodeToken, ShellCodeToken TabStopToken, MirrorToken, PythonCodeToken, VimLCodeToken, ShellCodeToken
from UltiSnips.Util import IndentUtil
__all__ = [ "Mirror", "Transformation", "SnippetInstance", "StartMarker" ] __all__ = [ "Mirror", "Transformation", "SnippetInstance", "StartMarker" ]
@ -146,7 +148,7 @@ class _TOParser(object):
for parent, token in all_tokens: for parent, token in all_tokens:
if isinstance(token, TransformationToken): if isinstance(token, TransformationToken):
if token.no not in seen_ts: if token.no not in seen_ts:
raise RuntimeError("Tabstop %i is not known but is used by a Transformation" % t._ts) raise RuntimeError("Tabstop %i is not known but is used by a Transformation" % token.no)
Transformation(parent, seen_ts[token.no], token) Transformation(parent, seen_ts[token.no], token)
def _do_parse(self, all_tokens, seen_ts): def _do_parse(self, all_tokens, seen_ts):
@ -646,7 +648,7 @@ class PythonCode(TextObject):
self._globals = {} self._globals = {}
globals = snippet.globals.get("!p", []) globals = snippet.globals.get("!p", [])
exec("\n".join(globals).replace("\r\n", "\n"), self._globals) compatible_exec("\n".join(globals).replace("\r\n", "\n"), self._globals)
# Add Some convenience to the code # Add Some convenience to the code
self._code = "import re, os, vim, string, random\n" + code self._code = "import re, os, vim, string, random\n" + code
@ -674,7 +676,7 @@ class PythonCode(TextObject):
}) })
self._code = self._code.replace("\r\n", "\n") self._code = self._code.replace("\r\n", "\n")
exec(self._code, self._globals, local_d) compatible_exec(self._code, self._globals, local_d)
if self._snip._rv_changed: if self._snip._rv_changed:
self.current_text = self._snip.rv self.current_text = self._snip.rv

View File

@ -7,23 +7,6 @@ import vim
from UltiSnips.Compatibility import as_unicode from UltiSnips.Compatibility import as_unicode
class CheapTotalOrdering: # TODO: use functools for >= 2.7
"""Total ordering only appears in python 2.7. We try to stay compatible with
python 2.5 for now, so we define our own"""
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
def vim_string(inp): def vim_string(inp):
""" Creates a vim-friendly string from a group of """ Creates a vim-friendly string from a group of
dicts, lists and strings. dicts, lists and strings.
@ -36,7 +19,7 @@ def vim_string(inp):
"%s:%s" % (conv(key), conv(value)) "%s:%s" % (conv(key), conv(value))
for key, value in obj.iteritems()]) + '}') for key, value in obj.iteritems()]) + '}')
else: else:
rv = as_unicode('"%s"' % str(obj).replace('"', '\\"')) rv = as_unicode('"%s"') % as_unicode(obj).replace('"', '\\"')
return rv return rv
return conv(inp) return conv(inp)

View File

@ -6,12 +6,12 @@ import glob
import hashlib import hashlib
import os import os
import re import re
import string
import traceback import traceback
import vim import vim
from UltiSnips.Geometry import Position from UltiSnips.Geometry import Position
from UltiSnips.Compatibility import make_suitable_for_vim
from UltiSnips.TextObjects import * from UltiSnips.TextObjects import *
from UltiSnips.Buffer import VimBuffer from UltiSnips.Buffer import VimBuffer
from UltiSnips.Util import IndentUtil, vim_string, as_unicode from UltiSnips.Util import IndentUtil, vim_string, as_unicode
@ -22,7 +22,7 @@ from UltiSnips.Langmap import LangMapTranslator
# which is deprecated since 2.5 and will no longer work in 2.7. Let's hope # which is deprecated since 2.5 and will no longer work in 2.7. Let's hope
# vim gets this fixed before) # vim gets this fixed before)
import sys import sys
if sys.version_info[:2] >= (2,6): if (2,6) <= sys.version_info[:2] < (3,0):
import warnings import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=DeprecationWarning)
@ -322,7 +322,7 @@ class Snippet(object):
self._matched = "" self._matched = ""
# Don't expand on whitespace # Don't expand on whitespace
if trigger and trigger[-1] in string.whitespace: if trigger and trigger.rstrip() is not trigger:
return False return False
words = self._words_for_line(trigger) words = self._words_for_line(trigger)
@ -360,7 +360,7 @@ class Snippet(object):
self._matched = "" self._matched = ""
# Don't expand on whitespace # Don't expand on whitespace
if trigger and trigger[-1] in string.whitespace: if trigger and trigger.rstrip() is not trigger:
return False return False
words = self._words_for_line(trigger) words = self._words_for_line(trigger)
@ -943,7 +943,7 @@ class SnippetManager(object):
line = vim.current.line line = vim.current.line
# Get the word to the left of the current edit position # Get the word to the left of the current edit position
before, after = line[:col], line[col:] before, after = as_unicode(line[:col]), as_unicode(line[col:])
return before, after return before, after
@ -982,7 +982,7 @@ class SnippetManager(object):
try: try:
# let vim_string format it as a vim list # let vim_string format it as a vim list
rv = vim.eval("inputlist(%s)" % vim_string(display)) rv = vim.eval(make_suitable_for_vim(as_unicode("inputlist(%s)") % vim_string(display)))
if rv is None or rv == '0': if rv is None or rv == '0':
return None return None
rv = int(rv) rv = int(rv)

20
test.py
View File

@ -37,8 +37,6 @@ WIN = platform.system() == "Windows"
from textwrap import dedent from textwrap import dedent
# Some constants for better reading # Some constants for better reading
BS = '\x7f' BS = '\x7f'
ESC = '\x1b' ESC = '\x1b'
@ -131,12 +129,12 @@ def send_win(keys, session):
################ end windows ################ ################ end windows ################
def send_screen(s, session):
def send_screen(s,session):
s = s.replace("'", r"'\''") s = s.replace("'", r"'\''")
os.system(("screen -x %s -X stuff '%s'" % (session, s)).encode("utf-8")) cmd = "screen -x %s -X stuff '%s'" % (session, s)
if sys.version_info >= (3,0):
cmd = cmd.encode("utf-8")
os.system(cmd)
def send(s, session): def send(s, session):
@ -149,7 +147,7 @@ def focus(title=None):
if WIN: if WIN:
focus_win(title=title) focus_win(title=title)
def type(str, session, sleeptime): def send_keystrokes(str, session, sleeptime):
""" """
Send the keystrokes to vim via screen. Pause after each char, so Send the keystrokes to vim via screen. Pause after each char, so
vim can handle this vim can handle this
@ -182,8 +180,8 @@ class _VimTest(unittest.TestCase):
else: else:
self.send(":py3 << EOF\n%s\nEOF\n" % s) self.send(":py3 << EOF\n%s\nEOF\n" % s)
def type(self,s): def send_keystrokes(self,s):
type(s, self.session, self.sleeptime) send_keystrokes(s, self.session, self.sleeptime)
def check_output(self): def check_output(self):
wanted = self.text_before + '\n\n' + self.wanted + \ wanted = self.text_before + '\n\n' + self.wanted + \
@ -269,7 +267,7 @@ class _VimTest(unittest.TestCase):
self.send("i") self.send("i")
# Execute the command # Execute the command
self.type(self.keys) self.send_keystrokes(self.keys)
self.send(ESC) self.send(ESC)