basic python 3 compatibility

This commit is contained in:
David Halter
2012-05-19 23:49:25 +02:00
parent 7ac17aa036
commit c95510cf50
6 changed files with 48 additions and 22 deletions

View File

@@ -2,6 +2,8 @@
This is a compatibility module, to make it possible to use jedi also with older
python versions.
"""
import sys
# next was defined in python 2.6, in python 3 obj.next won't be possible
# anymore
try:
@@ -31,8 +33,6 @@ except ImportError:
try:
property.setter
except AttributeError:
import sys
class property(property):
def __init__(self, fget, *args, **kwargs):
self.__doc__ = fget.__doc__
@@ -49,3 +49,11 @@ except AttributeError:
return cls_ns[propname]
else:
property = property
# Borrowed from Ned Batchelder
if sys.hexversion > 0x03000000:
def exec_function(source, global_map):
exec(source, global_map)
else:
eval(compile("""def exec_function(source, global_map):
exec source in global_map """, 'blub', 'exec'))

View File

@@ -5,6 +5,8 @@ import os
import debug
import parsing
from _compatibility import exec_function
module_find_path = sys.path[1:]
@@ -89,7 +91,8 @@ class Parser(CachedModule):
temp, sys.path = sys.path, self.sys_path
# TODO reenable and check (stackoverflow question - pylab builtins)
#print 'sypa', sys.path
exec 'import %s as module' % self.name in self._content
exec_function('import %s as module' % self.name, self._content)
self.sys_path, sys.path = sys.path, temp
self.sys_path.pop(0)
@@ -171,7 +174,7 @@ class Parser(CachedModule):
classes, funcs, stmts, members = get_types(names)
# classes
for name, cl in classes.iteritems():
for name, cl in classes.items():
bases = (c.__name__ for c in cl.__bases__)
code += 'class %s(%s):\n' % (name, ','.join(bases))
if depth == 0:
@@ -180,7 +183,7 @@ class Parser(CachedModule):
code += '\n'
# functions
for name, func in funcs.iteritems():
for name, func in funcs.items():
params, ret = parse_function_doc(func)
doc_str = parsing.indent_block('"""\n%s\n"""\n' % func.__doc__)
try:
@@ -201,7 +204,7 @@ class Parser(CachedModule):
code += mixin[:pos] + doc_str + mixin[pos:]
# class members (functions)
for name, func in members.iteritems():
for name, func in members.items():
ret = 'pass'
code += '@property\ndef %s(self):\n' % (name)
block = '"""\n%s\n"""\n' % func.__doc__
@@ -209,8 +212,8 @@ class Parser(CachedModule):
code += parsing.indent_block(block)
# variables
for name, value in stmts.iteritems():
if type(value) == file:
for name, value in stmts.items():
if type(value).__name__ == 'file':
value = 'file'
elif type(value).__name__ in ['int', 'bool', 'float',
'dict', 'list', 'tuple']:
@@ -290,7 +293,12 @@ def parse_function_doc(func):
class _Builtin(object):
_builtins = Parser(name='__builtin__')
# Python 3 compatibility
if sys.hexversion > 0x03000000:
name = 'builtins'
else:
name='__builtin__'
_builtins = Parser(name=name)
@property
def scope(self):

View File

@@ -3,7 +3,7 @@
import functions
functions.debug.debug_function = functions.debug.print_to_stdout
functions.debug.ignored_modules = ['parsing', 'builtin']
#functions.debug.ignored_modules = ['parsing', 'builtin']
#functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
functions.modules.builtin.module_find_path.insert(0, '.')
@@ -19,7 +19,7 @@ for i in range(1):
#completions = functions.get_definitions(code, 181, 2, path)
#completions = functions.complete(code, 42, 200, path)
print '\n', ', '.join(sorted(str(c) for c in completions))
print('\n', ', '.join(sorted(str(c) for c in completions)))
#print [n.name for n in completions]
#print [n.name.get_parent_until() for n in completions]
print '#', len(completions)
print('#', len(completions))

View File

@@ -1,3 +1,4 @@
from __future__ import with_statement
import re
import tokenize
import imp
@@ -60,6 +61,9 @@ class ModuleWithCursor(Module):
self._row_temp = None
self._relevant_temp = None
# Call the parser already here, because it will be used anyways.
# Also, the position is here important (which will not be used by
# default), therefore fill the cache here.
self._parser = parsing.PyFuzzyParser(source, path, row)
def get_path_until_cursor(self, column):
@@ -192,10 +196,8 @@ def find_module(current_module, point_path):
# is a directory module
if is_package_directory:
path += '/__init__.py'
# python2.5 cannot cope with the `with` statement
#with open(path) as f:
# source = f.read()
source = open(path).read()
with open(path) as f:
source = f.read()
else:
source = current_namespace[0].read()
if path.endswith('.py'):

View File

@@ -133,7 +133,7 @@ class c1():
def c3(self, daeparam):
import os as c4 #from parsing import Scope as c4
c5 = 1
c5 = c4(
c5 = c4()
if 1:
print 1
#return c5+'asdf'
@@ -178,3 +178,4 @@ a = next(gen_exe)
def ret():
r = []
return r.

View File

@@ -34,7 +34,7 @@ TODO check meta classes
from _compatibility import next, literal_eval
import tokenize
import cStringIO
from io import BytesIO
import re
import debug
@@ -229,7 +229,7 @@ class Module(Scope):
The top scope, which is always a module.
"""
def __init__(self, path, docstr=''):
super(Module, self).__init__(path, docstr)
super(Module, self).__init__(0, 0, docstr)
self.path = path
self.global_vars = []
@@ -1245,7 +1245,13 @@ class PyFuzzyParser(object):
:raises: IndentationError
"""
buf = cStringIO.StringIO(self.code)
buf = BytesIO(self.code.encode())
#print(self.code.encode())
#print(list(tokenize.tokenize(BytesIO(self.code.encode()).readline))[:9])
import sys
if sys.hexversion > 0x03000000:
self.gen = tokenize.tokenize(buf.readline)
else:
self.gen = tokenize.generate_tokens(buf.readline)
self.currentscope = self.scope
@@ -1270,6 +1276,7 @@ class PyFuzzyParser(object):
# check again for unindented stuff. this is true for syntax
# errors. only check for names, because thats relevant here. If
# some docstrings are not indented, I don't care.
print(self.scope.indent, self.scope)
while indent <= self.scope.indent \
and (token_type == tokenize.NAME or tok in ['(', '['])\
and self.scope != self.top: