Merge pull request #187 from Astrac/python-3.3

Python 3.3
This commit is contained in:
David Halter
2013-03-27 10:21:15 -07:00
7 changed files with 83 additions and 24 deletions

View File

@@ -4,6 +4,7 @@ env:
- TOXENV=py26 - TOXENV=py26
- TOXENV=py27 - TOXENV=py27
- TOXENV=py32 - TOXENV=py32
- TOXENV=py33
install: install:
- pip install --quiet --use-mirrors tox - pip install --quiet --use-mirrors tox
script: script:

View File

@@ -7,11 +7,69 @@ Most of the code here is necessary to support Python 2.5. Once this dependency
will be dropped, we'll get rid of most code. will be dropped, we'll get rid of most code.
""" """
import sys import sys
import imp
import os
try:
import importlib
except:
pass
is_py3k = sys.hexversion >= 0x03000000 is_py3k = sys.hexversion >= 0x03000000
is_py33 = sys.hexversion >= 0x03030000
is_py25 = sys.hexversion < 0x02060000 is_py25 = sys.hexversion < 0x02060000
def find_module_py33(string, path=None):
mod_info = (None, None, None)
loader = None
if path is not None:
# Check for the module in the specidied path
loader = importlib.machinery.PathFinder.find_module(string, path)
else:
# Check for the module in sys.path
loader = importlib.machinery.PathFinder.find_module(string, sys.path)
if loader is None:
# Fallback to find builtins
loader = importlib.find_loader(string)
if loader is None:
raise ImportError
try:
if (loader.is_package(string)):
mod_info = (None, os.path.dirname(loader.path), True)
else:
filename = loader.get_filename(string)
if filename and os.path.exists(filename):
mod_info = (open(filename, 'U'), filename, False)
else:
mod_info = (None, filename, False)
except AttributeError:
mod_info = (None, loader.load_module(string).__name__, False)
return mod_info
def find_module_pre_py33(string, path=None):
mod_info = None
if path is None:
mod_info = imp.find_module(string)
else:
mod_info = imp.find_module(string, path)
return (mod_info[0], mod_info[1], mod_info[2][2] == imp.PKG_DIRECTORY)
def find_module(string, path=None):
"""Provides information about a module.
This function isolates the differences in importing libraries introduced with
python 3.3 on; it gets a module name and optionally a path. It will return a
tuple containin an open file for the module (if not builtin), the filename
or the name of the module if it is a builtin one and a boolean indicating
if the module is contained in a package."""
if is_py33:
return find_module_py33(string, path)
else:
return find_module_pre_py33(string, path)
# next was defined in python 2.6, in python 3 obj.next won't be possible # next was defined in python 2.6, in python 3 obj.next won't be possible
# anymore # anymore
try: try:

View File

@@ -21,6 +21,7 @@ from __future__ import with_statement
import time import time
import os import os
import sys import sys
import hashlib
try: try:
import cPickle as pickle import cPickle as pickle
except: except:
@@ -221,7 +222,7 @@ def save_module(path, name, parser, pickling=True):
class _ModulePickling(object): class _ModulePickling(object):
version = 1 version = 2
""" """
Version number (integer) for file system cache. Version number (integer) for file system cache.
@@ -312,7 +313,7 @@ class _ModulePickling(object):
shutil.rmtree(self._cache_directory()) shutil.rmtree(self._cache_directory())
def _get_hashed_path(self, path): def _get_hashed_path(self, path):
return self._get_path('%s.pkl' % hash(path)) return self._get_path('%s.pkl' % hashlib.md5(path.encode("utf-8")).hexdigest())
def _get_path(self, file): def _get_path(self, file):
dir = self._cache_directory() dir = self._cache_directory()

View File

@@ -5,9 +5,8 @@ any actual importing done. This module is about finding modules in the
filesystem. This can be quite tricky sometimes, because Python imports are not filesystem. This can be quite tricky sometimes, because Python imports are not
always that simple. always that simple.
Currently the import process uses ``imp`` to find modules. In the future, it's This module uses imp for python up to 3.2 and importlib for python 3.3 on; the
a goal to use ``importlib`` for this purpose. There's a `pull request correct implementation is delegated to _compatibility.
<https://github.com/davidhalter/jedi/pull/109>`_ for that.
This module also supports import autocompletion, which means to complete This module also supports import autocompletion, which means to complete
statements like ``from datetim`` (curser at the end would return ``datetime``). statements like ``from datetim`` (curser at the end would return ``datetime``).
@@ -17,10 +16,10 @@ from __future__ import with_statement
import os import os
import pkgutil import pkgutil
import imp
import sys import sys
import itertools import itertools
from jedi._compatibility import find_module
from jedi import modules from jedi import modules
from jedi import debug from jedi import debug
from jedi import parsing_representation as pr from jedi import parsing_representation as pr
@@ -238,20 +237,22 @@ class ImportPath(pr.Base):
global imports_processed global imports_processed
imports_processed += 1 imports_processed += 1
importing = None
if path is not None: if path is not None:
return imp.find_module(string, [path]) importing = find_module(string, [path])
else: else:
debug.dbg('search_module', string, self.file_path) debug.dbg('search_module', string, self.file_path)
# Override the sys.path. It works only good that way. # Override the sys.path. It works only good that way.
# Injecting the path directly into `find_module` did not work. # Injecting the path directly into `find_module` did not work.
sys.path, temp = sys_path_mod, sys.path sys.path, temp = sys_path_mod, sys.path
try: try:
i = imp.find_module(string) importing = find_module(string)
except ImportError: except ImportError:
sys.path = temp sys.path = temp
raise raise
sys.path = temp sys.path = temp
return i
return importing
if self.file_path: if self.file_path:
sys_path_mod = list(self.sys_path_with_modifications()) sys_path_mod = list(self.sys_path_with_modifications())
@@ -259,6 +260,9 @@ class ImportPath(pr.Base):
else: else:
sys_path_mod = list(modules.get_sys_path()) sys_path_mod = list(modules.get_sys_path())
def module_not_found():
raise ModuleNotFound('The module you searched has not been found')
current_namespace = (None, None, None) current_namespace = (None, None, None)
# now execute those paths # now execute those paths
rest = [] rest = []
@@ -277,12 +281,14 @@ class ImportPath(pr.Base):
if current_namespace[1]: if current_namespace[1]:
rest = self.import_path[i:] rest = self.import_path[i:]
else: else:
raise ModuleNotFound( module_not_found()
'The module you searched has not been found')
if current_namespace == (None, None, False):
module_not_found()
sys_path_mod.pop(0) # TODO why is this here? sys_path_mod.pop(0) # TODO why is this here?
path = current_namespace[1] path = current_namespace[1]
is_package_directory = current_namespace[2][2] == imp.PKG_DIRECTORY is_package_directory = current_namespace[2]
f = None f = None
if is_package_directory or current_namespace[0]: if is_package_directory or current_namespace[0]:

View File

@@ -560,8 +560,10 @@ class Flow(Scope):
@parent.setter @parent.setter
def parent(self, value): def parent(self, value):
self._parent = value self._parent = value
if self.next: try:
self.next.parent = value self.next.parent = value
except AttributeError:
return
def get_code(self, first_indent=False, indention=' '): def get_code(self, first_indent=False, indention=' '):
stmts = [] stmts = []

View File

@@ -89,12 +89,3 @@ def huhu(db):
""" """
#? sqlite3.Connection() #? sqlite3.Connection()
db db
# -----------------
# various regression tests
# -----------------
#62
import threading
#? ['_Verbose', '_VERBOSE']
threading._Verbose

View File

@@ -1,5 +1,5 @@
[tox] [tox]
envlist = py25, py26, py27, py32 envlist = py25, py26, py27, py32, py33
[testenv] [testenv]
deps = deps =
pytest pytest