Commit e642ee86 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.

We include the six module since not all bots have it, and it's small.

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/741503002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@292988 0039d316-1c4b-4281-b951-d872f2087c98
parent 8a57ce17
......@@ -61,7 +61,10 @@ load-plugins=
# W0603: Using the global statement
# W0703: Catch "Exception"
# 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]
......@@ -70,9 +73,6 @@ disable=C0103,C0111,C0302,I0010,I0011,R0801,R0901,R0902,R0903,R0904,R0911,R0912,
# (visual studio) and html
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
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
......
URL: http://www.logilab.org/project/logilab-astng
Version: 0.23.1
Version: 1.2.1
License: GPL
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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 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
The aim of this module is to provide a common base representation of
......@@ -27,7 +25,7 @@ governed by pylint's needs.
It extends class defined in the python's _ast module with some
additional methods and attributes. Instance attributes are added by a
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.
Main modules are:
......@@ -35,39 +33,86 @@ Main modules are:
* nodes and scoped_nodes for more information about methods and
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
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"
import sys
if sys.version_info >= (3, 0):
BUILTINS_MODULE = 'builtins'
else:
BUILTINS_MODULE = '__builtin__'
import re
from operator import attrgetter
# WARNING: internal imports order matters !
# make all exception classes accessible from astng package
from logilab.astng.exceptions import *
# make all exception classes accessible from astroid package
from astroid.exceptions import *
# make all node classes accessible from astng package
from logilab.astng.nodes import *
# make all node classes accessible from astroid package
from astroid.nodes import *
# trigger extra monkey-patching
from logilab.astng import inference
from astroid import inference
# more stuff available
from logilab.astng import raw_building
from logilab.astng.bases import YES, Instance, BoundMethod, UnboundMethod
from logilab.astng.node_classes import are_exclusive, unpack_infer
from logilab.astng.scoped_nodes import builtin_lookup
from astroid import raw_building
from astroid.bases import YES, Instance, BoundMethod, UnboundMethod
from astroid.node_classes import are_exclusive, unpack_infer
from astroid.scoped_nodes import builtin_lookup
# make a manager instance (borg) as well as Project and Package classes
# accessible from astng package
from logilab.astng.manager import ASTNGManager, Project
MANAGER = ASTNGManager()
del ASTNGManager
# accessible from astroid package
from astroid.manager import AstroidManager, Project
MANAGER = AstroidManager()
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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 logilab-astng. If not, see <http://www.gnu.org/licenses/>.
"""logilab.astng packaging information"""
# with astroid. If not, see <http://www.gnu.org/licenses/>.
"""astroid packaging information"""
distname = 'logilab-astng'
distname = 'astroid'
modname = 'astng'
subpackage_of = 'logilab'
modname = 'astroid'
numversion = (0, 23, 1)
numversion = (1, 2, 1)
version = '.'.join([str(num) for num in numversion])
install_requires = ['logilab-common >= 0.53.0']
install_requires = ['logilab-common >= 0.60.0']
license = 'LGPL'
author = 'Logilab'
author_email = 'python-projects@lists.logilab.org'
mailinglist = "mailto://%s" % author_email
web = "http://www.logilab.org/project/%s" % distname
ftp = "ftp://ftp.logilab.org/pub/%s" % modname
web = 'http://bitbucket.org/logilab/astroid'
description = "rebuild a new abstract syntax tree from Python's ast"
from os.path import join
include_dirs = [join('test', 'regrtest_data'),
join('test', 'data'), join('test', 'data2')]
include_dirs = ['brain',
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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 logilab-astng. If not, see <http://www.gnu.org/licenses/>.
"""The ASTNGBuilder makes astng from living object and / or from _ast
# with astroid. If not, see <http://www.gnu.org/licenses/>.
"""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
at the same time.
"""
from __future__ import with_statement
__docformat__ = "restructuredtext en"
import sys, re
from os.path import splitext, basename, dirname, exists, abspath
import sys
from os.path import splitext, basename, exists, abspath
from logilab.common.modutils import modpath_from_file
from logilab.astng.exceptions import ASTNGBuildingException, InferenceError
from logilab.astng.raw_building import InspectBuilder
from logilab.astng.rebuilder import TreeRebuilder
from logilab.astng.manager import ASTNGManager
from logilab.astng.bases import YES, Instance
from astroid.exceptions import AstroidBuildingException, InferenceError
from astroid.raw_building import InspectBuilder
from astroid.rebuilder import TreeRebuilder
from astroid.manager import AstroidManager
from astroid.bases import YES, Instance
from astroid.modutils import modpath_from_file
from _ast import PyCF_ONLY_AST
def parse(string):
......@@ -44,21 +42,21 @@ if sys.version_info >= (3, 0):
from tokenize import detect_encoding
def open_source_file(filename):
byte_stream = open(filename, 'bU')
encoding = detect_encoding(byte_stream.readline)[0]
stream = open(filename, 'U', encoding=encoding)
with open(filename, 'rb') as byte_stream:
encoding = detect_encoding(byte_stream.readline)[0]
stream = open(filename, 'rU', encoding=encoding)
try:
data = stream.read()
except UnicodeError, uex: # wrong encodingg
except UnicodeError: # wrong encodingg
# detect_encoding returns utf-8 if no encoding specified
msg = 'Wrong (%s) or no encoding specified' % encoding
raise ASTNGBuildingException(msg)
raise AstroidBuildingException(msg)
return stream, encoding, data
else:
import re
_ENCODING_RGX = re.compile("\s*#+.*coding[:=]\s*([-\w.]+)")
_ENCODING_RGX = re.compile(r"\s*#+.*coding[:=]\s*([-\w.]+)")
def _guess_encoding(string):
"""get encoding from a python file as string or return None if not found
......@@ -81,17 +79,17 @@ else:
# ast NG builder ##############################################################
MANAGER = ASTNGManager()
MANAGER = AstroidManager()
class ASTNGBuilder(InspectBuilder):
"""provide astng building methods"""
rebuilder = TreeRebuilder()
class AstroidBuilder(InspectBuilder):
"""provide astroid building methods"""
def __init__(self, manager=None):
InspectBuilder.__init__(self)
self._manager = manager or MANAGER
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
path = getattr(module, '__file__', None)
......@@ -103,46 +101,59 @@ class ASTNGBuilder(InspectBuilder):
# this is a built-in module
# get a partial representation by introspection
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
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
"""
try:
stream, encoding, data = open_source_file(path)
_, encoding, data = open_source_file(path)
except IOError, exc:
msg = 'Unable to load file %r (%s)' % (path, exc)
raise ASTNGBuildingException(msg)
raise AstroidBuildingException(msg)
except SyntaxError, exc: # py3k encoding specification error
raise ASTNGBuildingException(exc)
raise AstroidBuildingException(exc)
except LookupError, exc: # unknown encoding
raise ASTNGBuildingException(exc)
raise AstroidBuildingException(exc)
# get module name if necessary
if modname is None:
try:
modname = '.'.join(modpath_from_file(path))
except ImportError:
modname = splitext(basename(path))[0]
# build astng representation
node = self.string_build(data, modname, path)
node.file_encoding = encoding
return node
# build astroid representation
module = self._data_build(data, modname, path)
return self._post_build(module, encoding)
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)
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:
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)
# handle delayed assattr nodes
for delayed in module._delayed_assattr:
self.delayed_assattr(delayed)
if modname:
for transformer in self._manager.transformers:
transformer(module)
return module
def _data_build(self, data, modname, path):
......@@ -158,11 +169,11 @@ class ASTNGBuilder(InspectBuilder):
package = True
else:
package = path and path.find('__init__.py') > -1 or False
self.rebuilder.init()
module = self.rebuilder.visit_module(node, modname, package)
rebuilder = TreeRebuilder(self._manager)
module = rebuilder.visit_module(node, modname, package)
module.file = module.path = node_file
module._from_nodes = self.rebuilder._from_nodes
module._delayed_assattr = self.rebuilder._delayed_assattr
module._from_nodes = rebuilder._from_nodes
module._delayed_assattr = rebuilder._delayed_assattr
return module
def add_from_names_to_locals(self, node):
......@@ -176,8 +187,8 @@ class ASTNGBuilder(InspectBuilder):
for (name, asname) in node.names:
if name == '*':
try:
imported = node.root().import_module(node.modname)
except ASTNGBuildingException:
imported = node.do_import_module()
except InferenceError:
continue
for name in imported.wildcard_import_names():
node.parent.set_local(name, node)
......
# This program 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 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.
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 logilab-astng. If not, see <http://www.gnu.org/licenses/>.
"""this module contains exceptions used in the astng library
# with astroid. If not, see <http://www.gnu.org/licenses/>.
"""this module contains exceptions used in the astroid library
"""
__doctype__ = "restructuredtext en"
class ASTNGError(Exception):
"""base exception class for all astng related exceptions"""
class AstroidError(Exception):
"""base exception class for all astroid related exceptions"""
class ASTNGBuildingException(ASTNGError):
"""exception class when we are unable to build an astng representation"""
class AstroidBuildingException(AstroidError):
"""exception class when we are unable to build an astroid representation"""
class ResolveError(ASTNGError):
"""base class of astng resolution/inference error"""
class ResolveError(AstroidError):
"""base class of astroid resolution/inference error"""
class NotFoundError(ResolveError):
"""raised when we are unable to resolve a name"""
......@@ -50,10 +36,15 @@ class NotFoundError(ResolveError):
class InferenceError(ResolveError):
"""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):
"""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
no default value
"""
......
# This program 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 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.
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 logilab-astng. If not, see <http://www.gnu.org/licenses/>.
"""visitor doing some postprocessing on the astng tree.
# with astroid. If not, see <http://www.gnu.org/licenses/>.
"""visitor doing some postprocessing on the astroid tree.
Try to resolve definitions (namespace) dictionary, relationship...
This module has been imported from pyreverse
......@@ -39,25 +25,23 @@ __docformat__ = "restructuredtext en"
from os.path import dirname
from logilab.common.modutils import get_module_part, is_relative, \
is_standard_module
import astroid
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
from logilab.astng.exceptions import InferenceError
from logilab.astng.utils import LocalsVisitor
class IdGeneratorMixIn:
class IdGeneratorMixIn(object):
"""
Mixin adding the ability to generate integer uid
"""
def __init__(self, start_value=0):
self.id_count = start_value
def init_counter(self, start_value=0):
"""init the id counter
"""
self.id_count = start_value
def generate_id(self):
"""generate a new identifier
"""
......@@ -68,26 +52,26 @@ class IdGeneratorMixIn:
class Linker(IdGeneratorMixIn, LocalsVisitor):
"""
walk on the project tree and resolve relationships.
According to options the following attributes may be added to visited nodes:
* uid,
a unique identifier for the node (on astng.Project, astng.Module,
astng.Class and astng.locals_type). Only if the linker has been instantiated
a unique identifier for the node (on astroid.Project, astroid.Module,
astroid.Class and astroid.locals_type). Only if the linker has been instantiated
with tag=True parameter (False by default).
* Function
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,
astng.Class and astng.Function).
constant like a string or an integer, or an astroid node (on astroid.Module,
astroid.Class and astroid.Function).
* 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,
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):
IdGeneratorMixIn.__init__(self)
LocalsVisitor.__init__(self)
......@@ -98,30 +82,30 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
# visited project
self.project = project
def visit_project(self, node):
"""visit an astng.Project node
"""visit an astroid.Project node
* optionally tag the node with a unique id
"""
if self.tag:
node.uid = self.generate_id()
for module in node.modules:
self.visit(module)
def visit_package(self, node):
"""visit an astng.Package node
"""visit an astroid.Package node
* optionally tag the node with a unique id
"""
if self.tag:
node.uid = self.generate_id()
for subelmt in node.values():
self.visit(subelmt)
def visit_module(self, node):
"""visit an astng.Module node
"""visit an astroid.Module node
* set the locals_type mapping
* set the depends mapping
* optionally tag the node with a unique id
......@@ -132,10 +116,10 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.depends = []
if self.tag:
node.uid = self.generate_id()
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 implements list and build it
* optionally tag the node with a unique id
......@@ -162,8 +146,8 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.implements = ()
def visit_function(self, node):
"""visit an astng.Function node
"""visit an astroid.Function node
* set the locals_type mapping
* optionally tag the node with a unique id
"""
......@@ -172,14 +156,14 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
node.locals_type = {}
if self.tag:
node.uid = self.generate_id()
link_project = visit_project
link_module = visit_module
link_class = visit_class
link_function = visit_function
def visit_assname(self, node):
"""visit an astng.AssName node
"""visit an astroid.AssName node
handle locals_type
"""
......@@ -192,7 +176,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
frame = node.frame()
else:
# 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
frame = node.root()
try:
......@@ -204,11 +188,11 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
already_infered.append(valnode)
except KeyError:
frame.locals_type[node.name] = values
except astng.InferenceError:
except astroid.InferenceError:
pass
def handle_assattr_type(self, node, parent):
"""handle an astng.AssAttr node
"""handle an astroid.AssAttr node
handle instance_attrs_type
"""
......@@ -221,23 +205,23 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
already_infered.append(valnode)
except KeyError:
parent.instance_attrs_type[node.attrname] = values
except astng.InferenceError:
except astroid.InferenceError:
pass
def visit_import(self, node):
"""visit an astng.Import node
"""visit an astroid.Import node
resolve module dependencies
"""
context_file = node.root().file
for name in node.names:
relative = is_relative(name[0], context_file)
self._imported_module(node, name[0], relative)
def visit_from(self, node):
"""visit an astng.From node
"""visit an astroid.From node
resolve module dependencies
"""
basename = node.modname
......@@ -254,13 +238,13 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
if fullname.find('.') > -1:
try:
# XXX: don't use get_module_part, missing package precedence
fullname = get_module_part(fullname)
fullname = get_module_part(fullname, context_file)
except ImportError:
continue
if fullname != basename:
self._imported_module(node, fullname, relative)
def compute_module(self, context_name, mod_path):
"""return true if the module should be added to dependencies"""
package_dir = dirname(self.project.path)
......@@ -269,7 +253,7 @@ class Linker(IdGeneratorMixIn, LocalsVisitor):
elif is_standard_module(mod_path, (package_dir,)):
return 1
return 0
# protected methods ########################################################
def _imported_module(self, node, mod_path, relative):
......
# This program 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 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.
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 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.
"""
from logilab.astng.exceptions import (ASTNGBuildingException, InferenceError,
NotFoundError)
from astroid.exceptions import (AstroidBuildingException, InferenceError,
NotFoundError)
class BlockRangeMixIn(object):
......@@ -55,6 +41,7 @@ class BlockRangeMixIn(object):
return lineno, orelse[0].fromlineno - 1
return lineno, last or self.tolineno
class FilterStmtsMixin(object):
"""Mixin for statement filtering and assignment type"""
......@@ -92,14 +79,13 @@ class ParentAssignTypeMixin(AssignTypeMixin):
return self.parent.ass_type()
class FromImportMixIn(FilterStmtsMixin):
"""MixIn for From and Import Nodes"""
def _infer_name(self, frame, 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>
"""
# handle special case where we are on a package node importing a module
......@@ -108,6 +94,8 @@ class FromImportMixIn(FilterStmtsMixin):
# XXX: no more needed ?
mymodule = self.root()
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
# importing itself: modname and mymodule.name be relative or absolute
if mymodule.relative_to_absolute_name(modname, level) == mymodule.name:
......@@ -115,7 +103,7 @@ class FromImportMixIn(FilterStmtsMixin):
return mymodule
try:
return mymodule.import_module(modname, level=level)
except ASTNGBuildingException:
except AstroidBuildingException:
raise InferenceError(modname)
except SyntaxError, ex:
raise InferenceError(str(ex))
......@@ -132,5 +120,3 @@ class FromImportMixIn(FilterStmtsMixin):
return name
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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 logilab-astng. If not, see <http://www.gnu.org/licenses/>.
# with astroid. If not, see <http://www.gnu.org/licenses/>.
"""
on all nodes :
.is_statement, returning true if the node should be considered as a
......@@ -28,7 +26,7 @@ on all nodes :
.frame(), returning the first node defining a new local scope (i.e.
Module, Function or Class)
.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.
on From and Import :
......@@ -39,15 +37,15 @@ on From and Import :
__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, \
Comprehension, Const, Continue, Decorators, DelAttr, DelName, Delete, \
Dict, Discard, Ellipsis, EmptyNode, ExceptHandler, Exec, ExtSlice, For, \
From, Getattr, Global, If, IfExp, Import, Index, Keyword, \
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
from logilab.astng.scoped_nodes import Module, GenExpr, Lambda, DictComp, \
from astroid.scoped_nodes import Module, GenExpr, Lambda, DictComp, \
ListComp, SetComp, Function, Class
ALL_NODE_CLASSES = (
......@@ -70,6 +68,6 @@ ALL_NODE_CLASSES = (
TryExcept, TryFinally, Tuple,
UnaryOp,
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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 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
where it makes sense.
"""
__doctype__ = "restructuredtext en"
from logilab.astng.exceptions import InferenceError, NoDefault
from logilab.astng.node_classes import unpack_infer
from logilab.astng.bases import copy_context, \
raise_if_nothing_infered, yes_if_nothing_infered, Instance, Generator, YES
from logilab.astng.nodes import const_factory
from logilab.astng import nodes
from astroid.exceptions import InferenceError, NoDefault, NotFoundError
from astroid.node_classes import unpack_infer
from astroid.bases import copy_context, \
raise_if_nothing_infered, yes_if_nothing_infered, Instance, YES
from astroid.nodes import const_factory
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 ############################################################
......@@ -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,
}
}
for key, impl in BIN_OP_IMPL.items():
BIN_OP_IMPL[key+'='] = impl
......@@ -135,6 +153,25 @@ def dict_infer_binary_op(self, operator, other, context):
# XXX else log TypeError
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 ##################################################################
......@@ -168,7 +205,7 @@ def _resolve_looppart(parts, asspath, context):
assigned = stmt.getitem(index, context)
except (AttributeError, IndexError):
continue
except TypeError, exc: # stmt is unsubscriptable Const
except TypeError: # stmt is unsubscriptable Const
continue
if not asspath:
# we achieved to resolved the assignment path,
......@@ -233,10 +270,14 @@ def _arguments_infer_argname(self, name, context):
yield self.parent.parent.frame()
return
if name == self.vararg:
yield const_factory(())
vararg = const_factory(())
vararg.parent = self
yield vararg
return
if name == self.kwarg:
yield const_factory({})
kwarg = const_factory({})
kwarg.parent = self
yield kwarg
return
# if there is a default value, yield it. And then yield YES to reflect
# we can't guess given argument value
......@@ -312,10 +353,13 @@ nodes.ExceptHandler.assigned_stmts = raise_if_nothing_infered(excepthandler_assi
def with_assigned_stmts(self, node, context=None, asspath=None):
if asspath is None:
for lst in self.vars.infer(context):
if isinstance(lst, (nodes.Tuple, nodes.List)):
for item in lst.nodes:
yield item
for _, vars in self.items:
if vars is None:
continue
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)
# 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
# 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
# Free Software Foundation, either version 2.1 of the License, or (at your
# 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
# 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 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
extract information from it
"""
__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:
* visit_<class name> on entering a node, where class name is the class of
......@@ -99,7 +98,7 @@ class LocalsVisitor(ASTWalker):
if methods[0] is not None:
methods[0](node)
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)
if methods[1] is not None:
return methods[1](node)
......@@ -113,27 +112,25 @@ def _check_children(node):
print "Hm, child of %s is None" % node
continue
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:
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:
print " ERROR: %s %x has child %s %x with wrong parent %s" % (node,
id(node), child, id(child), child.parent)
print " ERROR: %s %x has child %s %x with wrong parent %s" % (
node, id(node), child, id(child), child.parent)
else:
ok = True
if not ok:
print "lines;", node.lineno, child.lineno
print "of module", node.root(), node.root().name
raise ASTNGBuildingException
raise AstroidBuildingException
_check_children(child)
from _ast import PyCF_ONLY_AST
def parse(string):
return compile(string, "<string>", 'exec', PyCF_ONLY_AST)
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
lineno: bool to tell if we should print the line numbers
......@@ -146,11 +143,11 @@ class TreeTester(object):
. <Print>
. . nl = True
. ]
>>> print tester.astng_tree_repr()
>>> print tester.astroid_tree_repr()
Module()
body = [
Print()
dest =
dest =
values = [
]
]
......@@ -185,8 +182,8 @@ class TreeTester(object):
if _done is None:
_done = set()
if node in _done:
self._string += '\nloop in tree: %r (%s)' % (node,
getattr(node, 'lineno', None))
self._string += '\nloop in tree: %r (%s)' % (
node, getattr(node, 'lineno', None))
return
_done.add(node)
self._string += '\n' + indent + '<%s>' % node.__class__.__name__
......@@ -202,7 +199,7 @@ class TreeTester(object):
continue
if a in ("lineno", "col_offset") and not self.lineno:
continue
self._string +='\n' + indent + a + " = " + repr(attr)
self._string += '\n' + indent + a + " = " + repr(attr)
for field in node._fields or ():
attr = node_dict[field]
if attr is None:
......@@ -224,16 +221,16 @@ class TreeTester(object):
self._string += '\n' + indent + field + " = " + repr(attr)
def build_astng_tree(self):
"""build astng tree from the _ast tree
def build_astroid_tree(self):
"""build astroid tree from the _ast tree
"""
from logilab.astng.builder import ASTNGBuilder
tree = ASTNGBuilder().string_build(self.sourcecode)
from astroid.builder import AstroidBuilder
tree = AstroidBuilder().string_build(self.sourcecode)
return tree
def astng_tree_repr(self, ids=False):
"""build the astng tree and return a nice tree representation"""
mod = self.build_astng_tree()
def astroid_tree_repr(self, ids=False):
"""build the astroid tree and return a nice tree representation"""
mod = self.build_astroid_tree()
return mod.repr_tree(ids)
......
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
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
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
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.
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.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
......@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
......@@ -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
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
......@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
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
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
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
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'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
......@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
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.
URL: http://www.logilab.org/project/logilab-common
Version: 0.57.1
Version: 0.63.1
License: GPL
License File: LICENSE.txt
......
......@@ -25,6 +25,9 @@
:var IGNORED_EXTENSIONS: file extensions that may usually be ignored
"""
__docformat__ = "restructuredtext en"
from six.moves import range
from logilab.common.__pkginfo__ import version as __version__
STD_BLACKLIST = ('CVS', '.svn', '.hg', 'debian', 'dist', 'build')
......@@ -57,8 +60,9 @@ class dictattr(dict):
class nullobject(object):
def __repr__(self):
return '<nullobject>'
def __nonzero__(self):
def __bool__(self):
return False
__nonzero__ = __bool__
class tempattr(object):
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
#
# This file is part of logilab-common.
......@@ -18,19 +18,19 @@
"""logilab.common packaging information"""
__docformat__ = "restructuredtext en"
import sys
import os
distname = 'logilab-common'
modname = 'common'
subpackage_of = 'logilab'
subpackage_master = True
numversion = (0, 57, 1)
numversion = (0, 63, 0)
version = '.'.join([str(num) for num in numversion])
license = 'LGPL' # 2.1 or later
description = "collection of low-level Python packages and modules used by Logilab projects"
web = "http://www.logilab.org/project/%s" % distname
ftp = "ftp://ftp.logilab.org/pub/%s" % modname
mailinglist = "mailto://python-projects@lists.logilab.org"
author = "Logilab"
author_email = "contact@logilab.fr"
......@@ -40,6 +40,16 @@ from os.path import join
scripts = [join('bin', 'pytest')]
include_dirs = [join('test', 'data')]
install_requires = [
'six >= 1.4.0',
]
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"
import sys
from stat import S_IWRITE
from six import string_types
BULLET = '*'
SUBBULLET = '-'
INDENT = ' ' * 4
......@@ -64,7 +66,7 @@ class Version(tuple):
correctly printing it as X.Y.Z
"""
def __new__(cls, versionstr):
if isinstance(versionstr, basestring):
if isinstance(versionstr, string_types):
versionstr = versionstr.strip(' :') # XXX (syt) duh?
parsed = cls.parse(versionstr)
else:
......@@ -76,7 +78,7 @@ class Version(tuple):
versionstr = versionstr.strip(' :')
try:
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))
def __str__(self):
......
This diff is collapsed.
......@@ -44,7 +44,8 @@ Example::
__docformat__ = "restructuredtext en"
from logilab.common.compat import raw_input, builtins
from six.moves import builtins, input
if not hasattr(builtins, '_'):
builtins._ = str
......@@ -107,7 +108,7 @@ class CLIHelper:
"""loop on user input, exit on EOF"""
while True:
try:
line = raw_input('>>> ')
line = input('>>> ')
except EOFError:
print
break
......@@ -194,7 +195,7 @@ class CLIHelper:
import traceback
traceback.print_exc()
print 'ERROR in help method %s'% (
command_help_method.func_name)
command_help_method.__name__)
help_do_help = ("help", "help [topic|command]",
_("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):
name = [CosNaming.NameComponent(id, kind)]
try:
context = context.bind_new_context(name)
except CosNaming.NamingContext.AlreadyBound, ex:
except CosNaming.NamingContext.AlreadyBound as ex:
context = context.resolve(name)._narrow(CosNaming.NamingContext)
assert context is not None, \
'test context exists but is not a NamingContext'
......@@ -81,7 +81,7 @@ def register_object_name(object, namepath):
name = [CosNaming.NameComponent(id, kind)]
try:
context.bind(name, object._this())
except CosNaming.NamingContext.AlreadyBound, ex:
except CosNaming.NamingContext.AlreadyBound as ex:
context.rebind(name, object._this())
def activate_POA():
......
This diff is collapsed.
This diff is collapsed.
......@@ -36,7 +36,8 @@ import os, os.path
import sys
import csv
import tempfile
import ConfigParser
from six.moves import range
class Dbase:
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.
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