Commit 451939d5 authored by vapier@chromium.org's avatar vapier@chromium.org

pylint: upgrade to 1.3.1

The current pylint is very old at this point.  Pull in the latest version
as it supports a lot more features.  Also need to fix the pylint wrapper
to actually update sys.path to use the local modules.

This will trigger new warnings in files, but they look like legitimate
issues that should be fixed at some point.

BUG=chromium:431514
TEST=ran on some code bases and checked output

Review URL: https://codereview.chromium.org/707353002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@292954 0039d316-1c4b-4281-b951-d872f2087c98
parent c60ecf9e
...@@ -61,7 +61,10 @@ load-plugins= ...@@ -61,7 +61,10 @@ load-plugins=
# W0603: Using the global statement # W0603: Using the global statement
# W0703: Catch "Exception" # W0703: Catch "Exception"
# W1201: Specify string format arguments as logging function parameters # W1201: Specify string format arguments as logging function parameters
disable=C0103,C0111,C0302,I0010,I0011,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,W0122,W0141,W0142,W0402,W0404,W0511,W0603,W0703,W1201 #
# These should get enabled, but the codebase has too many violations currently.
# bad-continuation
disable=C0103,C0111,C0302,I0010,I0011,R0801,R0901,R0902,R0903,R0904,R0911,R0912,R0913,R0914,R0915,R0921,R0922,W0122,W0141,W0142,W0402,W0404,W0511,W0603,W0703,W1201,bad-continuation
[REPORTS] [REPORTS]
...@@ -70,9 +73,6 @@ disable=C0103,C0111,C0302,I0010,I0011,R0801,R0901,R0902,R0903,R0904,R0911,R0912, ...@@ -70,9 +73,6 @@ disable=C0103,C0111,C0302,I0010,I0011,R0801,R0901,R0902,R0903,R0904,R0911,R0912,
# (visual studio) and html # (visual studio) and html
output-format=text output-format=text
# Include message's id in output
include-ids=yes
# Put messages in a separate file for each module / package specified on the # Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be # command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". # written in a file name "pylint_global.[txt|html]".
......
URL: http://www.logilab.org/project/logilab-astng URL: http://www.logilab.org/project/logilab-astng
Version: 0.23.1 Version: 1.2.1
License: GPL License: GPL
License File: LICENSE.txt License File: LICENSE.txt
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""Python Abstract Syntax Tree New Generation """Python Abstract Syntax Tree New Generation
The aim of this module is to provide a common base representation of The aim of this module is to provide a common base representation of
...@@ -27,7 +25,7 @@ governed by pylint's needs. ...@@ -27,7 +25,7 @@ governed by pylint's needs.
It extends class defined in the python's _ast module with some It extends class defined in the python's _ast module with some
additional methods and attributes. Instance attributes are added by a additional methods and attributes. Instance attributes are added by a
builder object, which can either generate extended ast (let's call builder object, which can either generate extended ast (let's call
them astng ;) by visiting an existent ast tree or by inspecting living them astroid ;) by visiting an existent ast tree or by inspecting living
object. Methods are added by monkey patching ast classes. object. Methods are added by monkey patching ast classes.
Main modules are: Main modules are:
...@@ -35,39 +33,86 @@ Main modules are: ...@@ -35,39 +33,86 @@ Main modules are:
* nodes and scoped_nodes for more information about methods and * nodes and scoped_nodes for more information about methods and
attributes added to different node classes attributes added to different node classes
* the manager contains a high level object to get astng trees from * the manager contains a high level object to get astroid trees from
source files and living objects. It maintains a cache of previously source files and living objects. It maintains a cache of previously
constructed tree for quick access constructed tree for quick access
* builder contains the class responsible to build astng trees * builder contains the class responsible to build astroid trees
""" """
__doctype__ = "restructuredtext en" __doctype__ = "restructuredtext en"
import sys import sys
if sys.version_info >= (3, 0): import re
BUILTINS_MODULE = 'builtins' from operator import attrgetter
else:
BUILTINS_MODULE = '__builtin__'
# WARNING: internal imports order matters ! # WARNING: internal imports order matters !
# make all exception classes accessible from astng package # make all exception classes accessible from astroid package
from logilab.astng.exceptions import * from astroid.exceptions import *
# make all node classes accessible from astng package # make all node classes accessible from astroid package
from logilab.astng.nodes import * from astroid.nodes import *
# trigger extra monkey-patching # trigger extra monkey-patching
from logilab.astng import inference from astroid import inference
# more stuff available # more stuff available
from logilab.astng import raw_building from astroid import raw_building
from logilab.astng.bases import YES, Instance, BoundMethod, UnboundMethod from astroid.bases import YES, Instance, BoundMethod, UnboundMethod
from logilab.astng.node_classes import are_exclusive, unpack_infer from astroid.node_classes import are_exclusive, unpack_infer
from logilab.astng.scoped_nodes import builtin_lookup from astroid.scoped_nodes import builtin_lookup
# make a manager instance (borg) as well as Project and Package classes # make a manager instance (borg) as well as Project and Package classes
# accessible from astng package # accessible from astroid package
from logilab.astng.manager import ASTNGManager, Project from astroid.manager import AstroidManager, Project
MANAGER = ASTNGManager() MANAGER = AstroidManager()
del ASTNGManager del AstroidManager
# transform utilities (filters and decorator)
class AsStringRegexpPredicate(object):
"""Class to be used as predicate that may be given to `register_transform`
First argument is a regular expression that will be searched against the `as_string`
representation of the node onto which it's applied.
If specified, the second argument is an `attrgetter` expression that will be
applied on the node first to get the actual node on which `as_string` should
be called.
"""
def __init__(self, regexp, expression=None):
self.regexp = re.compile(regexp)
self.expression = expression
def __call__(self, node):
if self.expression is not None:
node = attrgetter(self.expression)(node)
return self.regexp.search(node.as_string())
def inference_tip(infer_function):
"""Given an instance specific inference function, return a function to be
given to MANAGER.register_transform to set this inference function.
Typical usage
.. sourcecode:: python
MANAGER.register_transform(CallFunc, inference_tip(infer_named_tuple),
AsStringRegexpPredicate('namedtuple', 'func'))
"""
def transform(node, infer_function=infer_function):
node._explicit_inference = infer_function
return node
return transform
# load brain plugins
from os import listdir
from os.path import join, dirname
BRAIN_MODULES_DIR = join(dirname(__file__), 'brain')
if BRAIN_MODULES_DIR not in sys.path:
# add it to the end of the list so user path take precedence
sys.path.append(BRAIN_MODULES_DIR)
# load modules in this directory
for module in listdir(BRAIN_MODULES_DIR):
if module.endswith('.py'):
__import__(module[:-3])
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""logilab.astng packaging information""" """astroid packaging information"""
distname = 'logilab-astng' distname = 'astroid'
modname = 'astng' modname = 'astroid'
subpackage_of = 'logilab'
numversion = (0, 23, 1) numversion = (1, 2, 1)
version = '.'.join([str(num) for num in numversion]) version = '.'.join([str(num) for num in numversion])
install_requires = ['logilab-common >= 0.53.0'] install_requires = ['logilab-common >= 0.60.0']
license = 'LGPL' license = 'LGPL'
author = 'Logilab' author = 'Logilab'
author_email = 'python-projects@lists.logilab.org' author_email = 'python-projects@lists.logilab.org'
mailinglist = "mailto://%s" % author_email mailinglist = "mailto://%s" % author_email
web = "http://www.logilab.org/project/%s" % distname web = 'http://bitbucket.org/logilab/astroid'
ftp = "ftp://ftp.logilab.org/pub/%s" % modname
description = "rebuild a new abstract syntax tree from Python's ast" description = "rebuild a new abstract syntax tree from Python's ast"
from os.path import join from os.path import join
include_dirs = [join('test', 'regrtest_data'), include_dirs = ['brain',
join('test', 'data'), join('test', 'data2')] join('test', 'regrtest_data'),
join('test', 'data'), join('test', 'data2')
]
classifiers = ["Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Quality Assurance",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
]
"""Astroid hooks for the Python 2 GObject introspection bindings.
Helps with understanding everything imported from 'gi.repository'
"""
import inspect
import sys
import re
from astroid import MANAGER, AstroidBuildingException
from astroid.builder import AstroidBuilder
_inspected_modules = {}
_identifier_re = r'^[A-Za-z_]\w*$'
def _gi_build_stub(parent):
"""
Inspect the passed module recursively and build stubs for functions,
classes, etc.
"""
classes = {}
functions = {}
constants = {}
methods = {}
for name in dir(parent):
if name.startswith("__"):
continue
# Check if this is a valid name in python
if not re.match(_identifier_re, name):
continue
try:
obj = getattr(parent, name)
except:
continue
if inspect.isclass(obj):
classes[name] = obj
elif (inspect.isfunction(obj) or
inspect.isbuiltin(obj)):
functions[name] = obj
elif (inspect.ismethod(obj) or
inspect.ismethoddescriptor(obj)):
methods[name] = obj
elif type(obj) in [int, str]:
constants[name] = obj
elif (str(obj).startswith("<flags") or
str(obj).startswith("<enum ") or
str(obj).startswith("<GType ") or
inspect.isdatadescriptor(obj)):
constants[name] = 0
elif callable(obj):
# Fall back to a function for anything callable
functions[name] = obj
else:
# Assume everything else is some manner of constant
constants[name] = 0
ret = ""
if constants:
ret += "# %s contants\n\n" % parent.__name__
for name in sorted(constants):
if name[0].isdigit():
# GDK has some busted constant names like
# Gdk.EventType.2BUTTON_PRESS
continue
val = constants[name]
strval = str(val)
if type(val) is str:
strval = '"%s"' % str(val).replace("\\", "\\\\")
ret += "%s = %s\n" % (name, strval)
if ret:
ret += "\n\n"
if functions:
ret += "# %s functions\n\n" % parent.__name__
for name in sorted(functions):
func = functions[name]
ret += "def %s(*args, **kwargs):\n" % name
ret += " pass\n"
if ret:
ret += "\n\n"
if methods:
ret += "# %s methods\n\n" % parent.__name__
for name in sorted(methods):
func = methods[name]
ret += "def %s(self, *args, **kwargs):\n" % name
ret += " pass\n"
if ret:
ret += "\n\n"
if classes:
ret += "# %s classes\n\n" % parent.__name__
for name in sorted(classes):
ret += "class %s(object):\n" % name
classret = _gi_build_stub(classes[name])
if not classret:
classret = "pass\n"
for line in classret.splitlines():
ret += " " + line + "\n"
ret += "\n"
return ret
# Overwrite Module.module_import to _actually_ import the introspected module if
# it's a gi module, then build stub code by examining its info and get an astng
# from that
from astroid.scoped_nodes import Module
_orig_import_module = Module.import_module
def _new_import_module(self, modname, relative_only=False, level=None):
# Could be a static piece of gi.repository or whatever unrelated module,
# let that fall through
try:
return _orig_import_module(self, modname, relative_only, level)
except AstroidBuildingException:
# we only consider gi.repository submodules
if not modname.startswith('gi.repository.'):
if relative_only and level is None:
level = 0
modname = self.relative_to_absolute_name(modname, level)
if not modname.startswith('gi.repository.'):
raise
# build astroid representation unless we already tried so
if modname not in _inspected_modules:
modnames = [modname]
# GLib and GObject have some special case handling
# in pygobject that we need to cope with
if modname == 'gi.repository.GLib':
modnames.append('gi._glib')
elif modname == 'gi.repository.GObject':
modnames.append('gi._gobject')
try:
modcode = ''
for m in modnames:
__import__(m)
modcode += _gi_build_stub(sys.modules[m])
except ImportError:
astng = _inspected_modules[modname] = None
else:
astng = AstroidBuilder(MANAGER).string_build(modcode, modname)
_inspected_modules[modname] = astng
else:
astng = _inspected_modules[modname]
if astng is None:
raise AstroidBuildingException('Failed to import module %r' % modname)
return astng
Module.import_module = _new_import_module
from astroid import MANAGER
from astroid.builder import AstroidBuilder
def mechanize_transform(module):
fake = AstroidBuilder(MANAGER).string_build('''
class Browser(object):
def open(self, url, data=None, timeout=None):
return None
def open_novisit(self, url, data=None, timeout=None):
return None
def open_local_file(self, filename):
return None
''')
module.locals['Browser'] = fake.locals['Browser']
import py2stdlib
py2stdlib.MODULE_TRANSFORMS['mechanize'] = mechanize_transform
"""Astroid hooks for the Python 2 qt4 module.
Currently help understanding of :
* PyQT4.QtCore
"""
from astroid import MANAGER
from astroid.builder import AstroidBuilder
def pyqt4_qtcore_transform(module):
fake = AstroidBuilder(MANAGER).string_build('''
def SIGNAL(signal_name): pass
class QObject(object):
def emit(self, signal): pass
''')
for klass in ('QObject',):
module.locals[klass] = fake.locals[klass]
import py2stdlib
py2stdlib.MODULE_TRANSFORMS['PyQt4.QtCore'] = pyqt4_qtcore_transform
This diff is collapsed.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""The ASTNGBuilder makes astng from living object and / or from _ast """The AstroidBuilder makes astroid from living object and / or from _ast
The builder is not thread safe and can't be used to parse different sources The builder is not thread safe and can't be used to parse different sources
at the same time. at the same time.
""" """
from __future__ import with_statement
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import sys, re import sys
from os.path import splitext, basename, dirname, exists, abspath from os.path import splitext, basename, exists, abspath
from logilab.common.modutils import modpath_from_file from astroid.exceptions import AstroidBuildingException, InferenceError
from astroid.raw_building import InspectBuilder
from logilab.astng.exceptions import ASTNGBuildingException, InferenceError from astroid.rebuilder import TreeRebuilder
from logilab.astng.raw_building import InspectBuilder from astroid.manager import AstroidManager
from logilab.astng.rebuilder import TreeRebuilder from astroid.bases import YES, Instance
from logilab.astng.manager import ASTNGManager from astroid.modutils import modpath_from_file
from logilab.astng.bases import YES, Instance
from _ast import PyCF_ONLY_AST from _ast import PyCF_ONLY_AST
def parse(string): def parse(string):
...@@ -44,21 +42,21 @@ if sys.version_info >= (3, 0): ...@@ -44,21 +42,21 @@ if sys.version_info >= (3, 0):
from tokenize import detect_encoding from tokenize import detect_encoding
def open_source_file(filename): def open_source_file(filename):
byte_stream = open(filename, 'bU') with open(filename, 'rb') as byte_stream:
encoding = detect_encoding(byte_stream.readline)[0] encoding = detect_encoding(byte_stream.readline)[0]
stream = open(filename, 'U', encoding=encoding) stream = open(filename, 'rU', encoding=encoding)
try: try:
data = stream.read() data = stream.read()
except UnicodeError, uex: # wrong encodingg except UnicodeError: # wrong encodingg
# detect_encoding returns utf-8 if no encoding specified # detect_encoding returns utf-8 if no encoding specified
msg = 'Wrong (%s) or no encoding specified' % encoding msg = 'Wrong (%s) or no encoding specified' % encoding
raise ASTNGBuildingException(msg) raise AstroidBuildingException(msg)
return stream, encoding, data return stream, encoding, data
else: else:
import re import re
_ENCODING_RGX = re.compile("\s*#+.*coding[:=]\s*([-\w.]+)") _ENCODING_RGX = re.compile(r"\s*#+.*coding[:=]\s*([-\w.]+)")
def _guess_encoding(string): def _guess_encoding(string):
"""get encoding from a python file as string or return None if not found """get encoding from a python file as string or return None if not found
...@@ -81,17 +79,17 @@ else: ...@@ -81,17 +79,17 @@ else:
# ast NG builder ############################################################## # ast NG builder ##############################################################
MANAGER = ASTNGManager() MANAGER = AstroidManager()
class ASTNGBuilder(InspectBuilder): class AstroidBuilder(InspectBuilder):
"""provide astng building methods""" """provide astroid building methods"""
rebuilder = TreeRebuilder()
def __init__(self, manager=None): def __init__(self, manager=None):
InspectBuilder.__init__(self)
self._manager = manager or MANAGER self._manager = manager or MANAGER
def module_build(self, module, modname=None): def module_build(self, module, modname=None):
"""build an astng from a living module instance """build an astroid from a living module instance
""" """
node = None node = None
path = getattr(module, '__file__', None) path = getattr(module, '__file__', None)
...@@ -103,46 +101,59 @@ class ASTNGBuilder(InspectBuilder): ...@@ -103,46 +101,59 @@ class ASTNGBuilder(InspectBuilder):
# this is a built-in module # this is a built-in module
# get a partial representation by introspection # get a partial representation by introspection
node = self.inspect_build(module, modname=modname, path=path) node = self.inspect_build(module, modname=modname, path=path)
# we have to handle transformation by ourselves since the rebuilder
# isn't called for builtin nodes
#
# XXX it's then only called for Module nodes, not for underlying
# nodes
node = self._manager.transform(node)
return node return node
def file_build(self, path, modname=None): def file_build(self, path, modname=None):
"""build astng from a source code file (i.e. from an ast) """build astroid from a source code file (i.e. from an ast)
path is expected to be a python source file path is expected to be a python source file
""" """
try: try:
stream, encoding, data = open_source_file(path) _, encoding, data = open_source_file(path)
except IOError, exc: except IOError, exc:
msg = 'Unable to load file %r (%s)' % (path, exc) msg = 'Unable to load file %r (%s)' % (path, exc)
raise ASTNGBuildingException(msg) raise AstroidBuildingException(msg)
except SyntaxError, exc: # py3k encoding specification error except SyntaxError, exc: # py3k encoding specification error
raise ASTNGBuildingException(exc) raise AstroidBuildingException(exc)
except LookupError, exc: # unknown encoding except LookupError, exc: # unknown encoding
raise ASTNGBuildingException(exc) raise AstroidBuildingException(exc)
# get module name if necessary # get module name if necessary
if modname is None: if modname is None:
try: try:
modname = '.'.join(modpath_from_file(path)) modname = '.'.join(modpath_from_file(path))
except ImportError: except ImportError:
modname = splitext(basename(path))[0] modname = splitext(basename(path))[0]
# build astng representation # build astroid representation
node = self.string_build(data, modname, path) module = self._data_build(data, modname, path)
node.file_encoding = encoding return self._post_build(module, encoding)
return node
def string_build(self, data, modname='', path=None): def string_build(self, data, modname='', path=None):
"""build astng from source code string and return rebuilded astng""" """build astroid from source code string and return rebuilded astroid"""
module = self._data_build(data, modname, path) module = self._data_build(data, modname, path)
self._manager.astng_cache[module.name] = module module.file_bytes = data.encode('utf-8')
return self._post_build(module, 'utf-8')
def _post_build(self, module, encoding):
"""handles encoding and delayed nodes
after a module has been built
"""
module.file_encoding = encoding
self._manager.cache_module(module)
# post tree building steps after we stored the module in the cache: # post tree building steps after we stored the module in the cache:
for from_node in module._from_nodes: for from_node in module._from_nodes:
if from_node.modname == '__future__':
for symbol, _ in from_node.names:
module.future_imports.add(symbol)
self.add_from_names_to_locals(from_node) self.add_from_names_to_locals(from_node)
# handle delayed assattr nodes # handle delayed assattr nodes
for delayed in module._delayed_assattr: for delayed in module._delayed_assattr:
self.delayed_assattr(delayed) self.delayed_assattr(delayed)
if modname:
for transformer in self._manager.transformers:
transformer(module)
return module return module
def _data_build(self, data, modname, path): def _data_build(self, data, modname, path):
...@@ -158,11 +169,11 @@ class ASTNGBuilder(InspectBuilder): ...@@ -158,11 +169,11 @@ class ASTNGBuilder(InspectBuilder):
package = True package = True
else: else:
package = path and path.find('__init__.py') > -1 or False package = path and path.find('__init__.py') > -1 or False
self.rebuilder.init() rebuilder = TreeRebuilder(self._manager)
module = self.rebuilder.visit_module(node, modname, package) module = rebuilder.visit_module(node, modname, package)
module.file = module.path = node_file module.file = module.path = node_file
module._from_nodes = self.rebuilder._from_nodes module._from_nodes = rebuilder._from_nodes
module._delayed_assattr = self.rebuilder._delayed_assattr module._delayed_assattr = rebuilder._delayed_assattr
return module return module
def add_from_names_to_locals(self, node): def add_from_names_to_locals(self, node):
...@@ -176,8 +187,8 @@ class ASTNGBuilder(InspectBuilder): ...@@ -176,8 +187,8 @@ class ASTNGBuilder(InspectBuilder):
for (name, asname) in node.names: for (name, asname) in node.names:
if name == '*': if name == '*':
try: try:
imported = node.root().import_module(node.modname) imported = node.do_import_module()
except ASTNGBuildingException: except InferenceError:
continue continue
for name in imported.wildcard_import_names(): for name in imported.wildcard_import_names():
node.parent.set_local(name, node) node.parent.set_local(name, node)
......
# This program is free software; you can redistribute it and/or modify it under # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# the terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""this module contains exceptions used in the astng library """this module contains exceptions used in the astroid library
""" """
__doctype__ = "restructuredtext en" __doctype__ = "restructuredtext en"
class ASTNGError(Exception): class AstroidError(Exception):
"""base exception class for all astng related exceptions""" """base exception class for all astroid related exceptions"""
class ASTNGBuildingException(ASTNGError): class AstroidBuildingException(AstroidError):
"""exception class when we are unable to build an astng representation""" """exception class when we are unable to build an astroid representation"""
class ResolveError(ASTNGError): class ResolveError(AstroidError):
"""base class of astng resolution/inference error""" """base class of astroid resolution/inference error"""
class NotFoundError(ResolveError): class NotFoundError(ResolveError):
"""raised when we are unable to resolve a name""" """raised when we are unable to resolve a name"""
...@@ -50,10 +36,15 @@ class NotFoundError(ResolveError): ...@@ -50,10 +36,15 @@ class NotFoundError(ResolveError):
class InferenceError(ResolveError): class InferenceError(ResolveError):
"""raised when we are unable to infer a node""" """raised when we are unable to infer a node"""
class UseInferenceDefault(Exception):
"""exception to be raised in custom inference function to indicate that it
should go back to the default behaviour
"""
class UnresolvableName(InferenceError): class UnresolvableName(InferenceError):
"""raised when we are unable to resolve a name""" """raised when we are unable to resolve a name"""
class NoDefault(ASTNGError): class NoDefault(AstroidError):
"""raised by function's `default_value` method when an argument has """raised by function's `default_value` method when an argument has
no default value no default value
""" """
......
# This program is free software; you can redistribute it and/or modify it under # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# the terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""visitor doing some postprocessing on the astng tree. """visitor doing some postprocessing on the astroid tree.
Try to resolve definitions (namespace) dictionary, relationship... Try to resolve definitions (namespace) dictionary, relationship...
This module has been imported from pyreverse This module has been imported from pyreverse
...@@ -39,25 +25,23 @@ __docformat__ = "restructuredtext en" ...@@ -39,25 +25,23 @@ __docformat__ = "restructuredtext en"
from os.path import dirname from os.path import dirname
from logilab.common.modutils import get_module_part, is_relative, \ import astroid
is_standard_module from astroid.exceptions import InferenceError
from astroid.utils import LocalsVisitor
from astroid.modutils import get_module_part, is_relative, is_standard_module
from logilab import astng class IdGeneratorMixIn(object):
from logilab.astng.exceptions import InferenceError
from logilab.astng.utils import LocalsVisitor
class IdGeneratorMixIn:
""" """
Mixin adding the ability to generate integer uid Mixin adding the ability to generate integer uid
""" """
def __init__(self, start_value=0): def __init__(self, start_value=0):
self.id_count = start_value self.id_count = start_value
def init_counter(self, start_value=0): def init_counter(self, start_value=0):
"""init the id counter """init the id counter
""" """
self.id_count = start_value self.id_count = start_value
def generate_id(self): def generate_id(self):
"""generate a new identifier """generate a new identifier
""" """
...@@ -68,26 +52,26 @@ class IdGeneratorMixIn: ...@@ -68,26 +52,26 @@ class IdGeneratorMixIn:
class Linker(IdGeneratorMixIn, LocalsVisitor): class Linker(IdGeneratorMixIn, LocalsVisitor):
""" """
walk on the project tree and resolve relationships. walk on the project tree and resolve relationships.
According to options the following attributes may be added to visited nodes: According to options the following attributes may be added to visited nodes:
* uid, * uid,
a unique identifier for the node (on astng.Project, astng.Module, a unique identifier for the node (on astroid.Project, astroid.Module,
astng.Class and astng.locals_type). Only if the linker has been instantiated astroid.Class and astroid.locals_type). Only if the linker has been instantiated
with tag=True parameter (False by default). with tag=True parameter (False by default).
* Function * Function
a mapping from locals names to their bounded value, which may be a a mapping from locals names to their bounded value, which may be a
constant like a string or an integer, or an astng node (on astng.Module, constant like a string or an integer, or an astroid node (on astroid.Module,
astng.Class and astng.Function). astroid.Class and astroid.Function).
* instance_attrs_type * instance_attrs_type
as locals_type but for klass member attributes (only on astng.Class) as locals_type but for klass member attributes (only on astroid.Class)
* implements, * implements,
list of implemented interface _objects_ (only on astng.Class nodes) list of implemented interface _objects_ (only on astroid.Class nodes)
""" """
def __init__(self, project, inherited_interfaces=0, tag=False): def __init__(self, project, inherited_interfaces=0, tag=False):
IdGeneratorMixIn.__init__(self) IdGeneratorMixIn.__init__(self)
LocalsVisitor.__init__(self) LocalsVisitor.__init__(self)
...@@ -98,30 +82,30 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -98,30 +82,30 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
# visited project # visited project
self.project = project self.project = project
def visit_project(self, node): def visit_project(self, node):
"""visit an astng.Project node """visit an astroid.Project node
* optionally tag the node with a unique id * optionally tag the node with a unique id
""" """
if self.tag: if self.tag:
node.uid = self.generate_id() node.uid = self.generate_id()
for module in node.modules: for module in node.modules:
self.visit(module) self.visit(module)
def visit_package(self, node): def visit_package(self, node):
"""visit an astng.Package node """visit an astroid.Package node
* optionally tag the node with a unique id * optionally tag the node with a unique id
""" """
if self.tag: if self.tag:
node.uid = self.generate_id() node.uid = self.generate_id()
for subelmt in node.values(): for subelmt in node.values():
self.visit(subelmt) self.visit(subelmt)
def visit_module(self, node): def visit_module(self, node):
"""visit an astng.Module node """visit an astroid.Module node
* set the locals_type mapping * set the locals_type mapping
* set the depends mapping * set the depends mapping
* optionally tag the node with a unique id * optionally tag the node with a unique id
...@@ -132,10 +116,10 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -132,10 +116,10 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.depends = [] node.depends = []
if self.tag: if self.tag:
node.uid = self.generate_id() node.uid = self.generate_id()
def visit_class(self, node): def visit_class(self, node):
"""visit an astng.Class node """visit an astroid.Class node
* set the locals_type and instance_attrs_type mappings * set the locals_type and instance_attrs_type mappings
* set the implements list and build it * set the implements list and build it
* optionally tag the node with a unique id * optionally tag the node with a unique id
...@@ -162,8 +146,8 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -162,8 +146,8 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.implements = () node.implements = ()
def visit_function(self, node): def visit_function(self, node):
"""visit an astng.Function node """visit an astroid.Function node
* set the locals_type mapping * set the locals_type mapping
* optionally tag the node with a unique id * optionally tag the node with a unique id
""" """
...@@ -172,14 +156,14 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -172,14 +156,14 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.locals_type = {} node.locals_type = {}
if self.tag: if self.tag:
node.uid = self.generate_id() node.uid = self.generate_id()
link_project = visit_project link_project = visit_project
link_module = visit_module link_module = visit_module
link_class = visit_class link_class = visit_class
link_function = visit_function link_function = visit_function
def visit_assname(self, node): def visit_assname(self, node):
"""visit an astng.AssName node """visit an astroid.AssName node
handle locals_type handle locals_type
""" """
...@@ -192,7 +176,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -192,7 +176,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
frame = node.frame() frame = node.frame()
else: else:
# the name has been defined as 'global' in the frame and belongs # the name has been defined as 'global' in the frame and belongs
# there. Btw the frame is not yet visited as the name is in the # there. Btw the frame is not yet visited as the name is in the
# root locals; the frame hence has no locals_type attribute # root locals; the frame hence has no locals_type attribute
frame = node.root() frame = node.root()
try: try:
...@@ -204,11 +188,11 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -204,11 +188,11 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
already_infered.append(valnode) already_infered.append(valnode)
except KeyError: except KeyError:
frame.locals_type[node.name] = values frame.locals_type[node.name] = values
except astng.InferenceError: except astroid.InferenceError:
pass pass
def handle_assattr_type(self, node, parent): def handle_assattr_type(self, node, parent):
"""handle an astng.AssAttr node """handle an astroid.AssAttr node
handle instance_attrs_type handle instance_attrs_type
""" """
...@@ -221,23 +205,23 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -221,23 +205,23 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
already_infered.append(valnode) already_infered.append(valnode)
except KeyError: except KeyError:
parent.instance_attrs_type[node.attrname] = values parent.instance_attrs_type[node.attrname] = values
except astng.InferenceError: except astroid.InferenceError:
pass pass
def visit_import(self, node): def visit_import(self, node):
"""visit an astng.Import node """visit an astroid.Import node
resolve module dependencies resolve module dependencies
""" """
context_file = node.root().file context_file = node.root().file
for name in node.names: for name in node.names:
relative = is_relative(name[0], context_file) relative = is_relative(name[0], context_file)
self._imported_module(node, name[0], relative) self._imported_module(node, name[0], relative)
def visit_from(self, node): def visit_from(self, node):
"""visit an astng.From node """visit an astroid.From node
resolve module dependencies resolve module dependencies
""" """
basename = node.modname basename = node.modname
...@@ -254,13 +238,13 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -254,13 +238,13 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
if fullname.find('.') > -1: if fullname.find('.') > -1:
try: try:
# XXX: don't use get_module_part, missing package precedence # XXX: don't use get_module_part, missing package precedence
fullname = get_module_part(fullname) fullname = get_module_part(fullname, context_file)
except ImportError: except ImportError:
continue continue
if fullname != basename: if fullname != basename:
self._imported_module(node, fullname, relative) self._imported_module(node, fullname, relative)
def compute_module(self, context_name, mod_path): def compute_module(self, context_name, mod_path):
"""return true if the module should be added to dependencies""" """return true if the module should be added to dependencies"""
package_dir = dirname(self.project.path) package_dir = dirname(self.project.path)
...@@ -269,7 +253,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor): ...@@ -269,7 +253,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
elif is_standard_module(mod_path, (package_dir,)): elif is_standard_module(mod_path, (package_dir,)):
return 1 return 1
return 0 return 0
# protected methods ######################################################## # protected methods ########################################################
def _imported_module(self, node, mod_path, relative): def _imported_module(self, node, mod_path, relative):
......
# This program is free software; you can redistribute it and/or modify it under # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# the terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""This module contains some mixins for the different nodes. """This module contains some mixins for the different nodes.
""" """
from logilab.astng.exceptions import (ASTNGBuildingException, InferenceError, from astroid.exceptions import (AstroidBuildingException, InferenceError,
NotFoundError) NotFoundError)
class BlockRangeMixIn(object): class BlockRangeMixIn(object):
...@@ -55,6 +41,7 @@ class BlockRangeMixIn(object): ...@@ -55,6 +41,7 @@ class BlockRangeMixIn(object):
return lineno, orelse[0].fromlineno - 1 return lineno, orelse[0].fromlineno - 1
return lineno, last or self.tolineno return lineno, last or self.tolineno
class FilterStmtsMixin(object): class FilterStmtsMixin(object):
"""Mixin for statement filtering and assignment type""" """Mixin for statement filtering and assignment type"""
...@@ -92,14 +79,13 @@ class ParentAssignTypeMixin(AssignTypeMixin): ...@@ -92,14 +79,13 @@ class ParentAssignTypeMixin(AssignTypeMixin):
return self.parent.ass_type() return self.parent.ass_type()
class FromImportMixIn(FilterStmtsMixin): class FromImportMixIn(FilterStmtsMixin):
"""MixIn for From and Import Nodes""" """MixIn for From and Import Nodes"""
def _infer_name(self, frame, name): def _infer_name(self, frame, name):
return name return name
def do_import_module(self, modname): def do_import_module(self, modname=None):
"""return the ast for a module whose name is <modname> imported by <self> """return the ast for a module whose name is <modname> imported by <self>
""" """
# handle special case where we are on a package node importing a module # handle special case where we are on a package node importing a module
...@@ -108,6 +94,8 @@ class FromImportMixIn(FilterStmtsMixin): ...@@ -108,6 +94,8 @@ class FromImportMixIn(FilterStmtsMixin):
# XXX: no more needed ? # XXX: no more needed ?
mymodule = self.root() mymodule = self.root()
level = getattr(self, 'level', None) # Import as no level level = getattr(self, 'level', None) # Import as no level
if modname is None:
modname = self.modname
# XXX we should investigate deeper if we really want to check # XXX we should investigate deeper if we really want to check
# importing itself: modname and mymodule.name be relative or absolute # importing itself: modname and mymodule.name be relative or absolute
if mymodule.relative_to_absolute_name(modname, level) == mymodule.name: if mymodule.relative_to_absolute_name(modname, level) == mymodule.name:
...@@ -115,7 +103,7 @@ class FromImportMixIn(FilterStmtsMixin): ...@@ -115,7 +103,7 @@ class FromImportMixIn(FilterStmtsMixin):
return mymodule return mymodule
try: try:
return mymodule.import_module(modname, level=level) return mymodule.import_module(modname, level=level)
except ASTNGBuildingException: except AstroidBuildingException:
raise InferenceError(modname) raise InferenceError(modname)
except SyntaxError, ex: except SyntaxError, ex:
raise InferenceError(str(ex)) raise InferenceError(str(ex))
...@@ -132,5 +120,3 @@ class FromImportMixIn(FilterStmtsMixin): ...@@ -132,5 +120,3 @@ class FromImportMixIn(FilterStmtsMixin):
return name return name
raise NotFoundError(asname) raise NotFoundError(asname)
This diff is collapsed.
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
""" """
on all nodes : on all nodes :
.is_statement, returning true if the node should be considered as a .is_statement, returning true if the node should be considered as a
...@@ -28,7 +26,7 @@ on all nodes : ...@@ -28,7 +26,7 @@ on all nodes :
.frame(), returning the first node defining a new local scope (i.e. .frame(), returning the first node defining a new local scope (i.e.
Module, Function or Class) Module, Function or Class)
.set_local(name, node), define an identifier <name> on the first parent frame, .set_local(name, node), define an identifier <name> on the first parent frame,
with the node defining it. This is used by the astng builder and should not with the node defining it. This is used by the astroid builder and should not
be used from out there. be used from out there.
on From and Import : on From and Import :
...@@ -39,15 +37,15 @@ on From and Import : ...@@ -39,15 +37,15 @@ on From and Import :
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
from logilab.astng.node_classes import Arguments, AssAttr, Assert, Assign, \ from astroid.node_classes import Arguments, AssAttr, Assert, Assign, \
AssName, AugAssign, Backquote, BinOp, BoolOp, Break, CallFunc, Compare, \ AssName, AugAssign, Backquote, BinOp, BoolOp, Break, CallFunc, Compare, \
Comprehension, Const, Continue, Decorators, DelAttr, DelName, Delete, \ Comprehension, Const, Continue, Decorators, DelAttr, DelName, Delete, \
Dict, Discard, Ellipsis, EmptyNode, ExceptHandler, Exec, ExtSlice, For, \ Dict, Discard, Ellipsis, EmptyNode, ExceptHandler, Exec, ExtSlice, For, \
From, Getattr, Global, If, IfExp, Import, Index, Keyword, \ From, Getattr, Global, If, IfExp, Import, Index, Keyword, \
List, Name, Nonlocal, Pass, Print, Raise, Return, Set, Slice, Starred, Subscript, \ List, Name, Nonlocal, Pass, Print, Raise, Return, Set, Slice, Starred, Subscript, \
TryExcept, TryFinally, Tuple, UnaryOp, While, With, Yield, \ TryExcept, TryFinally, Tuple, UnaryOp, While, With, Yield, YieldFrom, \
const_factory const_factory
from logilab.astng.scoped_nodes import Module, GenExpr, Lambda, DictComp, \ from astroid.scoped_nodes import Module, GenExpr, Lambda, DictComp, \
ListComp, SetComp, Function, Class ListComp, SetComp, Function, Class
ALL_NODE_CLASSES = ( ALL_NODE_CLASSES = (
...@@ -70,6 +68,6 @@ ALL_NODE_CLASSES = ( ...@@ -70,6 +68,6 @@ ALL_NODE_CLASSES = (
TryExcept, TryFinally, Tuple, TryExcept, TryFinally, Tuple,
UnaryOp, UnaryOp,
While, With, While, With,
Yield, Yield, YieldFrom
) )
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""this module contains a set of functions to handle python protocols for nodes """this module contains a set of functions to handle python protocols for nodes
where it makes sense. where it makes sense.
""" """
__doctype__ = "restructuredtext en" __doctype__ = "restructuredtext en"
from logilab.astng.exceptions import InferenceError, NoDefault from astroid.exceptions import InferenceError, NoDefault, NotFoundError
from logilab.astng.node_classes import unpack_infer from astroid.node_classes import unpack_infer
from logilab.astng.bases import copy_context, \ from astroid.bases import copy_context, \
raise_if_nothing_infered, yes_if_nothing_infered, Instance, Generator, YES raise_if_nothing_infered, yes_if_nothing_infered, Instance, YES
from logilab.astng.nodes import const_factory from astroid.nodes import const_factory
from logilab.astng import nodes from astroid import nodes
BIN_OP_METHOD = {'+': '__add__',
'-': '__sub__',
'/': '__div__',
'//': '__floordiv__',
'*': '__mul__',
'**': '__power__',
'%': '__mod__',
'&': '__and__',
'|': '__or__',
'^': '__xor__',
'<<': '__lshift__',
'>>': '__rshift__',
}
UNARY_OP_METHOD = {'+': '__pos__',
'-': '__neg__',
'~': '__invert__',
'not': None, # XXX not '__nonzero__'
}
# unary operations ############################################################ # unary operations ############################################################
...@@ -72,7 +90,7 @@ BIN_OP_IMPL = {'+': lambda a, b: a + b, ...@@ -72,7 +90,7 @@ BIN_OP_IMPL = {'+': lambda a, b: a + b,
'^': lambda a, b: a ^ b, '^': lambda a, b: a ^ b,
'<<': lambda a, b: a << b, '<<': lambda a, b: a << b,
'>>': lambda a, b: a >> b, '>>': lambda a, b: a >> b,
} }
for key, impl in BIN_OP_IMPL.items(): for key, impl in BIN_OP_IMPL.items():
BIN_OP_IMPL[key+'='] = impl BIN_OP_IMPL[key+'='] = impl
...@@ -135,6 +153,25 @@ def dict_infer_binary_op(self, operator, other, context): ...@@ -135,6 +153,25 @@ def dict_infer_binary_op(self, operator, other, context):
# XXX else log TypeError # XXX else log TypeError
nodes.Dict.infer_binary_op = yes_if_nothing_infered(dict_infer_binary_op) nodes.Dict.infer_binary_op = yes_if_nothing_infered(dict_infer_binary_op)
def instance_infer_binary_op(self, operator, other, context):
try:
methods = self.getattr(BIN_OP_METHOD[operator])
except (NotFoundError, KeyError):
# Unknown operator
yield YES
else:
for method in methods:
if not isinstance(method, nodes.Function):
continue
for result in method.infer_call_result(self, context):
if result is not YES:
yield result
# We are interested only in the first infered method,
# don't go looking in the rest of the methods of the ancestors.
break
Instance.infer_binary_op = yes_if_nothing_infered(instance_infer_binary_op)
# assignment ################################################################## # assignment ##################################################################
...@@ -168,7 +205,7 @@ def _resolve_looppart(parts, asspath, context): ...@@ -168,7 +205,7 @@ def _resolve_looppart(parts, asspath, context):
assigned = stmt.getitem(index, context) assigned = stmt.getitem(index, context)
except (AttributeError, IndexError): except (AttributeError, IndexError):
continue continue
except TypeError, exc: # stmt is unsubscriptable Const except TypeError: # stmt is unsubscriptable Const
continue continue
if not asspath: if not asspath:
# we achieved to resolved the assignment path, # we achieved to resolved the assignment path,
...@@ -233,10 +270,14 @@ def _arguments_infer_argname(self, name, context): ...@@ -233,10 +270,14 @@ def _arguments_infer_argname(self, name, context):
yield self.parent.parent.frame() yield self.parent.parent.frame()
return return
if name == self.vararg: if name == self.vararg:
yield const_factory(()) vararg = const_factory(())
vararg.parent = self
yield vararg
return return
if name == self.kwarg: if name == self.kwarg:
yield const_factory({}) kwarg = const_factory({})
kwarg.parent = self
yield kwarg
return return
# if there is a default value, yield it. And then yield YES to reflect # if there is a default value, yield it. And then yield YES to reflect
# we can't guess given argument value # we can't guess given argument value
...@@ -312,10 +353,13 @@ nodes.ExceptHandler.assigned_stmts = raise_if_nothing_infered(excepthandler_assi ...@@ -312,10 +353,13 @@ nodes.ExceptHandler.assigned_stmts = raise_if_nothing_infered(excepthandler_assi
def with_assigned_stmts(self, node, context=None, asspath=None): def with_assigned_stmts(self, node, context=None, asspath=None):
if asspath is None: if asspath is None:
for lst in self.vars.infer(context): for _, vars in self.items:
if isinstance(lst, (nodes.Tuple, nodes.List)): if vars is None:
for item in lst.nodes: continue
yield item for lst in vars.infer(context):
if isinstance(lst, (nodes.Tuple, nodes.List)):
for item in lst.nodes:
yield item
nodes.With.assigned_stmts = raise_if_nothing_infered(with_assigned_stmts) nodes.With.assigned_stmts = raise_if_nothing_infered(with_assigned_stmts)
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# copyright 2003-2010 Sylvain Thenault, all rights reserved.
# contact mailto:thenault@gmail.com
# #
# This file is part of logilab-astng. # This file is part of astroid.
# #
# logilab-astng is free software: you can redistribute it and/or modify it # astroid is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the # under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 2.1 of the License, or (at your # Free Software Foundation, either version 2.1 of the License, or (at your
# option) any later version. # option) any later version.
# #
# logilab-astng is distributed in the hope that it will be useful, but # astroid is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details. # for more details.
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with logilab-astng. If not, see <http://www.gnu.org/licenses/>. # with astroid. If not, see <http://www.gnu.org/licenses/>.
"""this module contains some utilities to navigate in the tree or to """this module contains some utilities to navigate in the tree or to
extract information from it extract information from it
""" """
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
from logilab.astng.exceptions import ASTNGBuildingException from astroid.exceptions import AstroidBuildingException
from astroid.builder import parse
class ASTWalker: class ASTWalker(object):
"""a walker visiting a tree in preorder, calling on the handler: """a walker visiting a tree in preorder, calling on the handler:
* visit_<class name> on entering a node, where class name is the class of * visit_<class name> on entering a node, where class name is the class of
...@@ -99,7 +98,7 @@ class LocalsVisitor(ASTWalker): ...@@ -99,7 +98,7 @@ class LocalsVisitor(ASTWalker):
if methods[0] is not None: if methods[0] is not None:
methods[0](node) methods[0](node)
if 'locals' in node.__dict__: # skip Instance and other proxy if 'locals' in node.__dict__: # skip Instance and other proxy
for name, local_node in node.items(): for local_node in node.values():
self.visit(local_node) self.visit(local_node)
if methods[1] is not None: if methods[1] is not None:
return methods[1](node) return methods[1](node)
...@@ -113,27 +112,25 @@ def _check_children(node): ...@@ -113,27 +112,25 @@ def _check_children(node):
print "Hm, child of %s is None" % node print "Hm, child of %s is None" % node
continue continue
if not hasattr(child, 'parent'): if not hasattr(child, 'parent'):
print " ERROR: %s has child %s %x with no parent" % (node, child, id(child)) print " ERROR: %s has child %s %x with no parent" % (
node, child, id(child))
elif not child.parent: elif not child.parent:
print " ERROR: %s has child %s %x with parent %r" % (node, child, id(child), child.parent) print " ERROR: %s has child %s %x with parent %r" % (
node, child, id(child), child.parent)
elif child.parent is not node: elif child.parent is not node:
print " ERROR: %s %x has child %s %x with wrong parent %s" % (node, print " ERROR: %s %x has child %s %x with wrong parent %s" % (
id(node), child, id(child), child.parent) node, id(node), child, id(child), child.parent)
else: else:
ok = True ok = True
if not ok: if not ok:
print "lines;", node.lineno, child.lineno print "lines;", node.lineno, child.lineno
print "of module", node.root(), node.root().name print "of module", node.root(), node.root().name
raise ASTNGBuildingException raise AstroidBuildingException
_check_children(child) _check_children(child)
from _ast import PyCF_ONLY_AST
def parse(string):
return compile(string, "<string>", 'exec', PyCF_ONLY_AST)
class TreeTester(object): class TreeTester(object):
'''A helper class to see _ast tree and compare with astng tree '''A helper class to see _ast tree and compare with astroid tree
indent: string for tree indent representation indent: string for tree indent representation
lineno: bool to tell if we should print the line numbers lineno: bool to tell if we should print the line numbers
...@@ -146,11 +143,11 @@ class TreeTester(object): ...@@ -146,11 +143,11 @@ class TreeTester(object):
. <Print> . <Print>
. . nl = True . . nl = True
. ] . ]
>>> print tester.astng_tree_repr() >>> print tester.astroid_tree_repr()
Module() Module()
body = [ body = [
Print() Print()
dest = dest =
values = [ values = [
] ]
] ]
...@@ -185,8 +182,8 @@ class TreeTester(object): ...@@ -185,8 +182,8 @@ class TreeTester(object):
if _done is None: if _done is None:
_done = set() _done = set()
if node in _done: if node in _done:
self._string += '\nloop in tree: %r (%s)' % (node, self._string += '\nloop in tree: %r (%s)' % (
getattr(node, 'lineno', None)) node, getattr(node, 'lineno', None))
return return
_done.add(node) _done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__ self._string += '\n' + indent + '<%s>' % node.__class__.__name__
...@@ -202,7 +199,7 @@ class TreeTester(object): ...@@ -202,7 +199,7 @@ class TreeTester(object):
continue continue
if a in ("lineno", "col_offset") and not self.lineno: if a in ("lineno", "col_offset") and not self.lineno:
continue continue
self._string +='\n' + indent + a + " = " + repr(attr) self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or (): for field in node._fields or ():
attr = node_dict[field] attr = node_dict[field]
if attr is None: if attr is None:
...@@ -224,16 +221,16 @@ class TreeTester(object): ...@@ -224,16 +221,16 @@ class TreeTester(object):
self._string += '\n' + indent + field + " = " + repr(attr) self._string += '\n' + indent + field + " = " + repr(attr)
def build_astng_tree(self): def build_astroid_tree(self):
"""build astng tree from the _ast tree """build astroid tree from the _ast tree
""" """
from logilab.astng.builder import ASTNGBuilder from astroid.builder import AstroidBuilder
tree = ASTNGBuilder().string_build(self.sourcecode) tree = AstroidBuilder().string_build(self.sourcecode)
return tree return tree
def astng_tree_repr(self, ids=False): def astroid_tree_repr(self, ids=False):
"""build the astng tree and return a nice tree representation""" """build the astroid tree and return a nice tree representation"""
mod = self.build_astng_tree() mod = self.build_astroid_tree()
return mod.repr_tree(ids) return mod.repr_tree(ids)
......
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
...@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This ...@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to the GNU Lesser General Public License instead.) You can apply it to
your programs, too. your programs, too.
When we speak of free software, we are referring to freedom, not When we speak of free software, we are referring to freedom, not
...@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all. ...@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
...@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: ...@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in and can be reasonably considered independent and separate works in
...@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent ...@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is otherwise to copy, modify, sublicense or distribute the Program is
...@@ -225,7 +225,7 @@ impose that choice. ...@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License original copyright holder who places the Program under this License
...@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ...@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest If you develop a new program, and you want it to be of the greatest
...@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. ...@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License along
along with this program; if not, write to the Free Software with this program; if not, write to the Free Software Foundation, Inc.,
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this If the program is interactive, make it output a short notice like this
when it starts in an interactive mode: when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details. under certain conditions; type `show c' for details.
...@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: ...@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. Public License instead of this License.
URL: http://www.logilab.org/project/logilab-common URL: http://www.logilab.org/project/logilab-common
Version: 0.57.1 Version: 0.63.1
License: GPL License: GPL
License File: LICENSE.txt License File: LICENSE.txt
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
:var IGNORED_EXTENSIONS: file extensions that may usually be ignored :var IGNORED_EXTENSIONS: file extensions that may usually be ignored
""" """
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
from six.moves import range
from logilab.common.__pkginfo__ import version as __version__ from logilab.common.__pkginfo__ import version as __version__
STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build') STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build')
...@@ -57,8 +60,9 @@ class dictattr(dict): ...@@ -57,8 +60,9 @@ class dictattr(dict):
class nullobject(object): class nullobject(object):
def __repr__(self): def __repr__(self):
return '<nullobject>' return '<nullobject>'
def __nonzero__(self): def __bool__(self):
return False return False
__nonzero__ = __bool__
class tempattr(object): class tempattr(object):
def __init__(self, obj, attr, value): def __init__(self, obj, attr, value):
......
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
# #
# This file is part of logilab-common. # This file is part of logilab-common.
...@@ -18,19 +18,19 @@ ...@@ -18,19 +18,19 @@
"""logilab.common packaging information""" """logilab.common packaging information"""
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
import sys import sys
import os
distname = 'logilab-common' distname = 'logilab-common'
modname = 'common' modname = 'common'
subpackage_of = 'logilab' subpackage_of = 'logilab'
subpackage_master = True subpackage_master = True
numversion = (0, 57, 1) numversion = (0, 63, 0)
version = '.'.join([str(num) for num in numversion]) version = '.'.join([str(num) for num in numversion])
license = 'LGPL' # 2.1 or later license = 'LGPL' # 2.1 or later
description = "collection of low-level Python packages and modules used by Logilab projects" description = "collection of low-level Python packages and modules used by Logilab projects"
web = "http://www.logilab.org/project/%s" % distname web = "http://www.logilab.org/project/%s" % distname
ftp = "ftp://ftp.logilab.org/pub/%s" % modname
mailinglist = "mailto://python-projects@lists.logilab.org" mailinglist = "mailto://python-projects@lists.logilab.org"
author = "Logilab" author = "Logilab"
author_email = "contact@logilab.fr" author_email = "contact@logilab.fr"
...@@ -40,6 +40,16 @@ from os.path import join ...@@ -40,6 +40,16 @@ from os.path import join
scripts = [join('bin', 'pytest')] scripts = [join('bin', 'pytest')]
include_dirs = [join('test', 'data')] include_dirs = [join('test', 'data')]
install_requires = [
'six >= 1.4.0',
]
if sys.version_info < (2, 7): if sys.version_info < (2, 7):
install_requires = ['unittest2 >= 0.5.1'] install_requires.append('unittest2 >= 0.5.1')
if os.name == 'nt':
install_requires.append('colorama')
classifiers = ["Topic :: Utilities",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
]
...@@ -49,6 +49,8 @@ __docformat__ = "restructuredtext en" ...@@ -49,6 +49,8 @@ __docformat__ = "restructuredtext en"
import sys import sys
from stat import S_IWRITE from stat import S_IWRITE
from six import string_types
BULLET = '*' BULLET = '*'
SUBBULLET = '-' SUBBULLET = '-'
INDENT = ' ' * 4 INDENT = ' ' * 4
...@@ -64,7 +66,7 @@ class Version(tuple): ...@@ -64,7 +66,7 @@ class Version(tuple):
correctly printing it as X.Y.Z correctly printing it as X.Y.Z
""" """
def __new__(cls, versionstr): def __new__(cls, versionstr):
if isinstance(versionstr, basestring): if isinstance(versionstr, string_types):
versionstr = versionstr.strip(' :') # XXX (syt) duh? versionstr = versionstr.strip(' :') # XXX (syt) duh?
parsed = cls.parse(versionstr) parsed = cls.parse(versionstr)
else: else:
...@@ -76,7 +78,7 @@ class Version(tuple): ...@@ -76,7 +78,7 @@ class Version(tuple):
versionstr = versionstr.strip(' :') versionstr = versionstr.strip(' :')
try: try:
return [int(i) for i in versionstr.split('.')] return [int(i) for i in versionstr.split('.')]
except ValueError, ex: except ValueError as ex:
raise ValueError("invalid literal for version '%s' (%s)"%(versionstr, ex)) raise ValueError("invalid literal for version '%s' (%s)"%(versionstr, ex))
def __str__(self): def __str__(self):
......
This diff is collapsed.
...@@ -44,7 +44,8 @@ Example:: ...@@ -44,7 +44,8 @@ Example::
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
from logilab.common.compat import raw_input, builtins from six.moves import builtins, input
if not hasattr(builtins, '_'): if not hasattr(builtins, '_'):
builtins._ = str builtins._ = str
...@@ -107,7 +108,7 @@ class CLIHelper: ...@@ -107,7 +108,7 @@ class CLIHelper:
"""loop on user input, exit on EOF""" """loop on user input, exit on EOF"""
while True: while True:
try: try:
line = raw_input('>>> ') line = input('>>> ')
except EOFError: except EOFError:
print print
break break
...@@ -194,7 +195,7 @@ class CLIHelper: ...@@ -194,7 +195,7 @@ class CLIHelper:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
print 'ERROR in help method %s'% ( print 'ERROR in help method %s'% (
command_help_method.func_name) command_help_method.__name__)
help_do_help = ("help", "help [topic|command]", help_do_help = ("help", "help [topic|command]",
_("print help message for the given topic/command or \ _("print help message for the given topic/command or \
......
This diff is collapsed.
This diff is collapsed.
...@@ -72,7 +72,7 @@ def register_object_name(object, namepath): ...@@ -72,7 +72,7 @@ def register_object_name(object, namepath):
name = [CosNaming.NameComponent(id, kind)] name = [CosNaming.NameComponent(id, kind)]
try: try:
context = context.bind_new_context(name) context = context.bind_new_context(name)
except CosNaming.NamingContext.AlreadyBound, ex: except CosNaming.NamingContext.AlreadyBound as ex:
context = context.resolve(name)._narrow(CosNaming.NamingContext) context = context.resolve(name)._narrow(CosNaming.NamingContext)
assert context is not None, \ assert context is not None, \
'test context exists but is not a NamingContext' 'test context exists but is not a NamingContext'
...@@ -81,7 +81,7 @@ def register_object_name(object, namepath): ...@@ -81,7 +81,7 @@ def register_object_name(object, namepath):
name = [CosNaming.NameComponent(id, kind)] name = [CosNaming.NameComponent(id, kind)]
try: try:
context.bind(name, object._this()) context.bind(name, object._this())
except CosNaming.NamingContext.AlreadyBound, ex: except CosNaming.NamingContext.AlreadyBound as ex:
context.rebind(name, object._this()) context.rebind(name, object._this())
def activate_POA(): def activate_POA():
......
This diff is collapsed.
This diff is collapsed.
...@@ -36,7 +36,8 @@ import os, os.path ...@@ -36,7 +36,8 @@ import os, os.path
import sys import sys
import csv import csv
import tempfile import tempfile
import ConfigParser
from six.moves import range
class Dbase: class Dbase:
def __init__(self): def __init__(self):
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#!/usr/bin/env python
import pylint
pylint.run_pylint()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment