[Python-modules-commits] [astroid] 01/06: Import astroid_1.4.1.orig.tar.gz
Sandro Tosi
morph at moszumanska.debian.org
Sat Jan 2 16:39:01 UTC 2016
This is an automated email from the git hooks/post-receive script.
morph pushed a commit to branch master
in repository astroid.
commit 96cc15de6306c30dc101738b4568febb362ecf9e
Author: Sandro Tosi <morph at debian.org>
Date: Sun Nov 29 22:13:00 2015 +0000
Import astroid_1.4.1.orig.tar.gz
---
ChangeLog | 211 ++-
PKG-INFO | 5 +-
README | 3 +-
astroid.egg-info/PKG-INFO | 5 +-
astroid.egg-info/SOURCES.txt | 29 +-
astroid.egg-info/requires.txt | 3 +-
astroid/__init__.py | 12 +-
astroid/__pkginfo__.py | 4 +-
astroid/arguments.py | 233 +++
astroid/as_string.py | 117 +-
astroid/bases.py | 290 ++--
...tin_inference.py => brain_builtin_inference.py} | 143 +-
astroid/brain/brain_dateutil.py | 15 +
astroid/brain/{py2gi.py => brain_gi.py} | 54 +-
.../brain/{py2mechanize.py => brain_mechanize.py} | 0
astroid/brain/{pynose.py => brain_nose.py} | 5 +-
astroid/brain/brain_numpy.py | 62 +
astroid/brain/{py2pytest.py => brain_pytest.py} | 2 +-
astroid/brain/brain_qt.py | 44 +
astroid/brain/{pysix_moves.py => brain_six.py} | 29 +-
astroid/brain/{py2stdlib.py => brain_stdlib.py} | 271 ++--
astroid/brain/py2qt4.py | 22 -
astroid/builder.py | 183 +--
astroid/context.py | 81 ++
astroid/decorators.py | 75 +
astroid/exceptions.py | 20 +
astroid/inference.py | 308 ++--
astroid/inspector.py | 273 ----
astroid/manager.py | 214 +--
astroid/mixins.py | 51 +-
astroid/modutils.py | 98 +-
astroid/node_classes.py | 394 +++--
astroid/nodes.py | 57 +-
astroid/objects.py | 182 +++
astroid/protocols.py | 213 +--
astroid/raw_building.py | 40 +-
astroid/rebuilder.py | 677 +++++----
astroid/scoped_nodes.py | 1026 +++++++------
astroid/test_utils.py | 25 +-
astroid/tests/resources.py | 2 +-
.../testdata/python2/data/SSL1/Connection1.py | 4 +-
.../testdata/python2/data/appl/myConnection.py | 3 +-
astroid/tests/testdata/python2/data/module.py | 10 +-
.../testdata/python2/data/module1abs/__init__.py | 4 +-
astroid/tests/testdata/python2/data/module2.py | 2 +-
astroid/tests/testdata/python2/data/nonregr.py | 4 +-
astroid/tests/testdata/python2/data/notall.py | 3 +-
astroid/tests/testdata/python3/data/module.py | 9 +-
astroid/tests/unittest_brain.py | 294 +++-
astroid/tests/unittest_builder.py | 221 +--
astroid/tests/unittest_inference.py | 1516 +++++++++++++-------
astroid/tests/unittest_inspector.py | 94 --
astroid/tests/unittest_lookup.py | 111 +-
astroid/tests/unittest_manager.py | 122 +-
astroid/tests/unittest_modutils.py | 60 +-
astroid/tests/unittest_nodes.py | 389 ++++-
astroid/tests/unittest_objects.py | 512 +++++++
astroid/tests/unittest_peephole.py | 5 +-
astroid/tests/unittest_protocols.py | 37 +-
astroid/tests/unittest_python3.py | 58 +-
astroid/tests/unittest_raw_building.py | 41 +-
astroid/tests/unittest_regrtest.py | 36 +-
astroid/tests/unittest_scoped_nodes.py | 683 ++++++---
astroid/tests/unittest_transforms.py | 245 ++++
astroid/tests/unittest_utils.py | 142 +-
astroid/transforms.py | 96 ++
astroid/util.py | 89 ++
astroid/utils.py | 239 ---
setup.cfg | 2 +-
tox.ini | 26 +-
70 files changed, 6929 insertions(+), 3606 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index bc6a2e9..494c09b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,215 @@
Change log for the astroid package (used to be astng)
=====================================================
+2015-11-29 -- 1.4.1
+
+
+ * Add support for handling Uninferable nodes when calling as_string
+
+ Some object, for instance List or Tuple can have, after inference,
+ Uninferable as their elements, happening when their components
+ weren't couldn't be inferred properly. This means that as_string
+ needs to cope with expecting Uninferable nodes part of the other
+ nodes coming for a string transformation. The patch adds a visit
+ method in AsString and ``accept`` on Yes / Uninferable nodes.
+ Closes issue #270.
+
+
+2015-11-29 -- 1.4.0
+
+ * Class.getattr('__mro__') returns the actual MRO. Closes issue #128.
+ * The logilab-common dependency is not needed anymore as the needed code
+ was integrated into astroid.
+
+ * Add 'assert_equals' method in nose.tools's brain plugin.
+
+ * Generated enum member stubs now support IntEnum and multiple
+ base classes.
+
+ * Add brain tips for multiprocessing.Manager and
+ multiprocessing.managers.SyncManager.
+
+ * Add brain tips for multiprocessing post Python 3.4+,
+ where the module level functions are retrieved with getattr
+ from a context object, leading to many no-member errors
+ in Pylint.
+
+ * The Generator objects inferred with `infer_call_result`
+ from functions have as parent the function from which they
+ are returned.
+
+ * Understand partially the 3-argument form of `type`.
+ The only change is that astroid understands members
+ passed in as dictionaries as the third argument.
+
+ * Improve the inference of Getattr nodes when dealing with
+ abstract properties from the abc module.
+
+ In astroid.bases.Instance._wrap_attr we had a detection
+ code for properties, which basically inferred whatever
+ a property returned, passing the results up the stack,
+ to the igetattr() method. It handled only the builtin property
+ but the new patch also handles a couple of other properties,
+ such as abc.abstractproperty.
+
+ * UnboundMethod.getattr calls the getattr of its _proxied object
+ and doesn't call super(...) anymore.
+
+ It previously crashed, since the first ancestor in its mro was
+ bases.Proxy and bases.Proxy doesn't implement the .getattr method.
+ Closes issue #91.
+
+ * Don't hard fail when calling .mro() on a class which has
+ combined both newstyle and old style classes. The class
+ in question is actually newstyle (and the __mro__ can be
+ retrieved using Python).
+
+ .mro() fallbacks to using .ancestors() in that case.
+
+ * Class.local_attr and Class.local_attr_ancestors uses internally
+ a mro lookup, using .mro() method, if they can.
+
+ That means for newstyle classes, when trying to lookup a member
+ using one of these functions, the first one according to the
+ mro will be returned. This reflects nicely the reality,
+ but it can have as a drawback the fact that it is a behaviour
+ change (the previous behaviour was incorrect though). Also,
+ having bases which can return multiple values when inferred
+ will not work with the new approach, because .mro() only
+ retrieves the first value inferred from a base.
+
+ * Expose a implicit_metaclass() method in Class. This will return
+ a builtins.type instance for newstyle classes.
+
+ * Add two new exceptions for handling MRO error cases. DuplicateBasesError
+ is emitted when duplicate bases are found in a class,
+ InconsistentMroError is raised when the method resolution is determined
+ to be inconsistent. They share a common class, MroError, which
+ is a subclass of ResolveError, meaning that this change is backwards
+ compatible.
+
+ * Classes aren't marked as interfaces anymore, in the `type` attribute.
+
+ * Class.has_dynamic_getattr doesn't return True for special methods
+ which aren't implemented in pure Python, as it is the case for extension modules.
+
+ Since most likely the methods were coming from a live object, this implies
+ that all of them will have __getattr__ and __getattribute__ present and it
+ is wrong to consider that those methods were actually implemented.
+
+ * Add `igetattr` method to scoped_nodes.Function.
+
+ * Add support for Python 3.5's MatMul operation: see PEP 465 for more
+ details.
+
+ * NotImplemented is detected properly now as being part of the
+ builtins module. Previously trying to infer the Name(NotImplemented)
+ returned an YES object.
+
+ * Add proper grammatical names for `infered` and `ass_type` methods,
+ namely `inferred` and `assign_type`.
+
+ The old methods will raise PendingDeprecationWarning, being slated
+ for removal in astroid 2.0.
+
+ * Add new AST names in order to be similar to the ones
+ from the builtin ast module.
+
+ With this change, Getattr becomes Attributes, Backquote becomes
+ Repr, Class is ClassDef, Function is FunctionDef, Discard is Expr,
+ CallFunc is Call, From is ImportFrom, AssName is AssignName
+ and AssAttr is AssignAttr. The old names are maintained for backwards
+ compatibility and they are interchangeable, in the sense that using
+ Discard will use Expr under the hood and the implemented visit_discard
+ in checkers will be called with Expr nodes instead. The AST does not
+ contain the old nodes, only the interoperability between them hides this
+ fact. Recommandations to move to the new nodes are emitted accordingly,
+ the old names will be removed in astroid 2.0.
+
+
+ * Star unpacking in assignments returns properly a list,
+ not the individual components. Closes issue #138.
+ * Lambdas found at class level, which have a `self` argument, are considered
+ * Add annotation support for function.as_string(). Closes issue #37.
+
+ * Add support for indexing bytes on Python 3.
+ BoundMethods when accessing them from instances of their class.
+
+ * Add support for inferring subscript on instances, which will
+ use __getitem__. Closes issue #124.
+
+ * Understand metaclasses added with six.add_metaclass decorator. Closes issue #129.
+
+ * Add a new convenience API, `astroid.parse`, which can be used to retrieve
+ an astroid AST from a source code string, similar to how ast.parse can be
+ used to obtain a Python AST from a source string. This is the test_utils.build_module
+ promoted to a public API.
+
+ * do_import_module passes the proper relative_only flag if the level is higher
+ than 1. This has the side effect that using `from .something import something`
+ in a non-package will finally result in an import-error on Pylint's side.
+ Until now relative_only was ignored, leading to the import of `something`,
+ if it was globally available.
+
+
+ * There's a new separate step for transforms.
+
+ Until now, the transforms were applied at the same time the tree was
+ being built. This was problematic if the transform functions were
+ using inference, since the inference was executed on a partially
+ constructed tree, which led to failures when post-building
+ information was needed (such as setting the _from_names
+ for the From imports).
+ Now there's a separate step for transforms, which are applied
+ using transform.TransformVisitor.
+ There's a couple of other related changes:
+
+ * astroid.parse and AstroidBuilder gained a new parameter
+ `apply_transforms`, which is a boolean flag, which will
+ control if the transforms are applied. We do this because
+ there are uses when the vanilla tree is wanted, without
+ any implicit modification.
+
+ * the transforms are also applied for builtin modules,
+ as a side effect of the fact that transform visiting
+ was moved in AstroidBuilder._post_build from
+ AstroidBuilder._data_build.
+
+ Closes issue #116.
+
+
+ * Add a new node, DictUnpack, which is used to represent the unpacking
+ of a dictionary into another dictionary, using PEP 448 specific syntax
+ ({1:2, **{2:3})
+
+ This is a different approach than what the builtin ast module does,
+ since it just uses None to represent this kind of operation,
+ which seems conceptually wrong, due to the fact the AST contains
+ non-AST nodes. Closes issue #206.
+
+ * Add a new type of node, called *inference objects*. Inference objects are similar with
+ AST nodes, but they can be obtained only after inference, so they can't be found
+ inside the AST tree. Their purpose is to handle at astroid level
+ some operations which can't be handled when using brain transforms.
+ For instance, the first object added is FrozenSet, which can be manipulated
+ at astroid's level (inferred, itered etc). Code such as this 'frozenset((1,2))'
+ will not return an Instance of frozenset, without having access to its
+ content, but a new objects.FrozenSet, which can be used just as a nodes.Set.
+
+
+ * Add a new *inference object* called Super, which also adds support for understanding
+ super calls. astroid understands the zero-argument form of super, specific to
+ Python 3, where the interpreter fills itself the arguments of the call. Also, we
+ are understanding the 2-argument form of super, both for bounded lookups
+ (super(X, instance)) as well as for unbounded lookups (super(X, Y)),
+ having as well support for validating that the object-or-type is a subtype
+ of the first argument. The unbounded form of super (one argument) is not
+ understood, since it's useless in practice and should be removed from
+ Python's specification. Closes issue #89.
+
+ * astroid.utils.ASTWalker and astroid.utils.LocalsVisitor
+ were moved to pylint.pyreverse.utils.
+
2015-08-02 -- 1.3.8
* Backport of 40e3176, which fixes issue #84.
@@ -10,7 +219,7 @@ Change log for the astroid package (used to be astng)
* Improve the inference of six.moves, especially when using `from ... import ...`
syntax. Also, we added a new fail import hook for six.moves, which fixes the
import-error false positive from pylint. Closes issue #107.
-
+
2015-03-14 -- 1.3.6
* Class.slots raises NotImplementedError for old style classes.
diff --git a/PKG-INFO b/PKG-INFO
index 450dfb2..4392e1e 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: astroid
-Version: 1.3.8
+Version: 1.4.1
Summary: A abstract syntax tree for Python with inference support.
Home-page: http://bitbucket.org/logilab/astroid
Author: Logilab
@@ -67,8 +67,7 @@ Description: .. image:: https://drone.io/bitbucket.org/logilab/astroid/status.pn
----
Tests are in the 'test' subdirectory. To launch the whole tests suite
- at once, you may use the 'pytest' utility from logilab-common (simply
- type 'pytest' from within this directory) or using unittest discover::
+ at once, you can use unittest discover::
python -m unittest discover -p "unittest*.py"
diff --git a/README b/README
index 1cca049..b19aca8 100644
--- a/README
+++ b/README
@@ -59,7 +59,6 @@ Test
----
Tests are in the 'test' subdirectory. To launch the whole tests suite
-at once, you may use the 'pytest' utility from logilab-common (simply
-type 'pytest' from within this directory) or using unittest discover::
+at once, you can use unittest discover::
python -m unittest discover -p "unittest*.py"
diff --git a/astroid.egg-info/PKG-INFO b/astroid.egg-info/PKG-INFO
index 450dfb2..4392e1e 100644
--- a/astroid.egg-info/PKG-INFO
+++ b/astroid.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: astroid
-Version: 1.3.8
+Version: 1.4.1
Summary: A abstract syntax tree for Python with inference support.
Home-page: http://bitbucket.org/logilab/astroid
Author: Logilab
@@ -67,8 +67,7 @@ Description: .. image:: https://drone.io/bitbucket.org/logilab/astroid/status.pn
----
Tests are in the 'test' subdirectory. To launch the whole tests suite
- at once, you may use the 'pytest' utility from logilab-common (simply
- type 'pytest' from within this directory) or using unittest discover::
+ at once, you can use unittest discover::
python -m unittest discover -p "unittest*.py"
diff --git a/astroid.egg-info/SOURCES.txt b/astroid.egg-info/SOURCES.txt
index 524ba84..00d4dc3 100644
--- a/astroid.egg-info/SOURCES.txt
+++ b/astroid.egg-info/SOURCES.txt
@@ -8,53 +8,60 @@ setup.py
tox.ini
astroid/__init__.py
astroid/__pkginfo__.py
+astroid/arguments.py
astroid/as_string.py
astroid/astpeephole.py
astroid/bases.py
astroid/builder.py
+astroid/context.py
+astroid/decorators.py
astroid/exceptions.py
astroid/inference.py
-astroid/inspector.py
astroid/manager.py
astroid/mixins.py
astroid/modutils.py
astroid/node_classes.py
astroid/nodes.py
+astroid/objects.py
astroid/protocols.py
astroid/raw_building.py
astroid/rebuilder.py
astroid/scoped_nodes.py
astroid/test_utils.py
-astroid/utils.py
+astroid/transforms.py
+astroid/util.py
astroid.egg-info/PKG-INFO
astroid.egg-info/SOURCES.txt
astroid.egg-info/dependency_links.txt
astroid.egg-info/requires.txt
astroid.egg-info/top_level.txt
-astroid/brain/builtin_inference.py
-astroid/brain/py2gi.py
-astroid/brain/py2mechanize.py
-astroid/brain/py2pytest.py
-astroid/brain/py2qt4.py
-astroid/brain/py2stdlib.py
-astroid/brain/pynose.py
-astroid/brain/pysix_moves.py
+astroid/brain/brain_builtin_inference.py
+astroid/brain/brain_dateutil.py
+astroid/brain/brain_gi.py
+astroid/brain/brain_mechanize.py
+astroid/brain/brain_nose.py
+astroid/brain/brain_numpy.py
+astroid/brain/brain_pytest.py
+astroid/brain/brain_qt.py
+astroid/brain/brain_six.py
+astroid/brain/brain_stdlib.py
astroid/tests/__init__.py
astroid/tests/resources.py
astroid/tests/unittest_brain.py
astroid/tests/unittest_builder.py
astroid/tests/unittest_inference.py
-astroid/tests/unittest_inspector.py
astroid/tests/unittest_lookup.py
astroid/tests/unittest_manager.py
astroid/tests/unittest_modutils.py
astroid/tests/unittest_nodes.py
+astroid/tests/unittest_objects.py
astroid/tests/unittest_peephole.py
astroid/tests/unittest_protocols.py
astroid/tests/unittest_python3.py
astroid/tests/unittest_raw_building.py
astroid/tests/unittest_regrtest.py
astroid/tests/unittest_scoped_nodes.py
+astroid/tests/unittest_transforms.py
astroid/tests/unittest_utils.py
astroid/tests/testdata/python2/data/MyPyPa-0.1.0-py2.5.egg
astroid/tests/testdata/python2/data/MyPyPa-0.1.0-py2.5.zip
diff --git a/astroid.egg-info/requires.txt b/astroid.egg-info/requires.txt
index 97f773c..e799148 100644
--- a/astroid.egg-info/requires.txt
+++ b/astroid.egg-info/requires.txt
@@ -1,2 +1,3 @@
-logilab-common>=0.63.0
six
+lazy_object_proxy
+wrapt
diff --git a/astroid/__init__.py b/astroid/__init__.py
index d4fd12c..8b7f73a 100644
--- a/astroid/__init__.py
+++ b/astroid/__init__.py
@@ -58,13 +58,15 @@ from astroid import inference
# more stuff available
from astroid import raw_building
-from astroid.bases import YES, Instance, BoundMethod, UnboundMethod
+from astroid.bases import Instance, BoundMethod, UnboundMethod
from astroid.node_classes import are_exclusive, unpack_infer
from astroid.scoped_nodes import builtin_lookup
+from astroid.builder import parse
+from astroid.util import YES
# make a manager instance (borg) as well as Project and Package classes
# accessible from astroid package
-from astroid.manager import AstroidManager, Project
+from astroid.manager import AstroidManager
MANAGER = AstroidManager()
del AstroidManager
@@ -100,7 +102,7 @@ def inference_tip(infer_function):
.. sourcecode:: python
- MANAGER.register_transform(CallFunc, inference_tip(infer_named_tuple),
+ MANAGER.register_transform(Call, inference_tip(infer_named_tuple),
predicate)
"""
def transform(node, infer_function=infer_function):
@@ -112,8 +114,8 @@ def inference_tip(infer_function):
def register_module_extender(manager, module_name, get_extension_mod):
def transform(node):
extension_module = get_extension_mod()
- for name, obj in extension_module.locals.items():
- node.locals[name] = obj
+ for name, obj in extension_module._locals.items():
+ node._locals[name] = obj
manager.register_transform(Module, transform, lambda n: n.name == module_name)
diff --git a/astroid/__pkginfo__.py b/astroid/__pkginfo__.py
index 3fb45aa..055be0f 100644
--- a/astroid/__pkginfo__.py
+++ b/astroid/__pkginfo__.py
@@ -20,10 +20,10 @@ distname = 'astroid'
modname = 'astroid'
-numversion = (1, 3, 8)
+numversion = (1, 4, 1)
version = '.'.join([str(num) for num in numversion])
-install_requires = ['logilab-common>=0.63.0', 'six']
+install_requires = ['six', 'lazy_object_proxy', 'wrapt']
license = 'LGPL'
diff --git a/astroid/arguments.py b/astroid/arguments.py
new file mode 100644
index 0000000..f05d48a
--- /dev/null
+++ b/astroid/arguments.py
@@ -0,0 +1,233 @@
+# copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact at logilab.fr
+#
+# This file is part of astroid.
+#
+# 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.
+#
+# 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 astroid. If not, see <http://www.gnu.org/licenses/>.
+
+from astroid import bases
+from astroid import context as contextmod
+from astroid import exceptions
+from astroid import nodes
+from astroid import util
+
+import six
+
+
+class CallSite(object):
+ """Class for understanding arguments passed into a call site
+
+ It needs a call context, which contains the arguments and the
+ keyword arguments that were passed into a given call site.
+ In order to infer what an argument represents, call
+ :meth:`infer_argument` with the corresponding function node
+ and the argument name.
+ """
+
+ def __init__(self, callcontext):
+ args = callcontext.args
+ keywords = callcontext.keywords
+ self.duplicated_keywords = set()
+ self._unpacked_args = self._unpack_args(args)
+ self._unpacked_kwargs = self._unpack_keywords(keywords)
+
+ self.positional_arguments = [
+ arg for arg in self._unpacked_args
+ if arg is not util.YES
+ ]
+ self.keyword_arguments = {
+ key: value for key, value in self._unpacked_kwargs.items()
+ if value is not util.YES
+ }
+
+ @classmethod
+ def from_call(cls, call_node):
+ """Get a CallSite object from the given Call node."""
+ callcontext = contextmod.CallContext(call_node.args,
+ call_node.keywords)
+ return cls(callcontext)
+
+ def has_invalid_arguments(self):
+ """Check if in the current CallSite were passed *invalid* arguments
+
+ This can mean multiple things. For instance, if an unpacking
+ of an invalid object was passed, then this method will return True.
+ Other cases can be when the arguments can't be inferred by astroid,
+ for example, by passing objects which aren't known statically.
+ """
+ return len(self.positional_arguments) != len(self._unpacked_args)
+
+ def has_invalid_keywords(self):
+ """Check if in the current CallSite were passed *invalid* keyword arguments
+
+ For instance, unpacking a dictionary with integer keys is invalid
+ (**{1:2}), because the keys must be strings, which will make this
+ method to return True. Other cases where this might return True if
+ objects which can't be inferred were passed.
+ """
+ return len(self.keyword_arguments) != len(self._unpacked_kwargs)
+
+ def _unpack_keywords(self, keywords):
+ values = {}
+ context = contextmod.InferenceContext()
+ for name, value in keywords:
+ if name is None:
+ # Then it's an unpacking operation (**)
+ try:
+ inferred = next(value.infer(context=context))
+ except exceptions.InferenceError:
+ values[name] = util.YES
+ continue
+
+ if not isinstance(inferred, nodes.Dict):
+ # Not something we can work with.
+ values[name] = util.YES
+ continue
+
+ for dict_key, dict_value in inferred.items:
+ try:
+ dict_key = next(dict_key.infer(context=context))
+ except exceptions.InferenceError:
+ values[name] = util.YES
+ continue
+ if not isinstance(dict_key, nodes.Const):
+ values[name] = util.YES
+ continue
+ if not isinstance(dict_key.value, six.string_types):
+ values[name] = util.YES
+ continue
+ if dict_key.value in values:
+ # The name is already in the dictionary
+ values[dict_key.value] = util.YES
+ self.duplicated_keywords.add(dict_key.value)
+ continue
+ values[dict_key.value] = dict_value
+ else:
+ values[name] = value
+ return values
+
+ @staticmethod
+ def _unpack_args(args):
+ values = []
+ context = contextmod.InferenceContext()
+ for arg in args:
+ if isinstance(arg, nodes.Starred):
+ try:
+ inferred = next(arg.value.infer(context=context))
+ except exceptions.InferenceError:
+ values.append(util.YES)
+ continue
+
+ if inferred is util.YES:
+ values.append(util.YES)
+ continue
+ if not hasattr(inferred, 'elts'):
+ values.append(util.YES)
+ continue
+ values.extend(inferred.elts)
+ else:
+ values.append(arg)
+ return values
+
+ def infer_argument(self, funcnode, name, context):
+ """infer a function argument value according to the call context"""
+ if name in self.duplicated_keywords:
+ raise exceptions.InferenceError(name)
+
+ # Look into the keywords first, maybe it's already there.
+ try:
+ return self.keyword_arguments[name].infer(context)
+ except KeyError:
+ pass
+
+ # Too many arguments given and no variable arguments.
+ if len(self.positional_arguments) > len(funcnode.args.args):
+ if not funcnode.args.vararg:
+ raise exceptions.InferenceError(name)
+
+ positional = self.positional_arguments[:len(funcnode.args.args)]
+ vararg = self.positional_arguments[len(funcnode.args.args):]
+ argindex = funcnode.args.find_argname(name)[0]
+ kwonlyargs = set(arg.name for arg in funcnode.args.kwonlyargs)
+ kwargs = {
+ key: value for key, value in self.keyword_arguments.items()
+ if key not in kwonlyargs
+ }
+ # If there are too few positionals compared to
+ # what the function expects to receive, check to see
+ # if the missing positional arguments were passed
+ # as keyword arguments and if so, place them into the
+ # positional args list.
+ if len(positional) < len(funcnode.args.args):
+ for func_arg in funcnode.args.args:
+ if func_arg.name in kwargs:
+ arg = kwargs.pop(func_arg.name)
+ positional.append(arg)
+
+ if argindex is not None:
+ # 2. first argument of instance/class method
+ if argindex == 0 and funcnode.type in ('method', 'classmethod'):
+ if context.boundnode is not None:
+ boundnode = context.boundnode
+ else:
+ # XXX can do better ?
+ boundnode = funcnode.parent.frame()
+ if funcnode.type == 'method':
+ if not isinstance(boundnode, bases.Instance):
+ boundnode = bases.Instance(boundnode)
+ return iter((boundnode,))
+ if funcnode.type == 'classmethod':
+ return iter((boundnode,))
+ # if we have a method, extract one position
+ # from the index, so we'll take in account
+ # the extra parameter represented by `self` or `cls`
+ if funcnode.type in ('method', 'classmethod'):
+ argindex -= 1
+ # 2. search arg index
+ try:
+ return self.positional_arguments[argindex].infer(context)
+ except IndexError:
+ pass
+
+ if funcnode.args.kwarg == name:
+ # It wants all the keywords that were passed into
+ # the call site.
+ if self.has_invalid_keywords():
+ raise exceptions.InferenceError
+ kwarg = nodes.Dict()
+ kwarg.lineno = funcnode.args.lineno
+ kwarg.col_offset = funcnode.args.col_offset
+ kwarg.parent = funcnode.args
+ items = [(nodes.const_factory(key), value)
+ for key, value in kwargs.items()]
+ kwarg.items = items
+ return iter((kwarg, ))
+ elif funcnode.args.vararg == name:
+ # It wants all the args that were passed into
+ # the call site.
+ if self.has_invalid_arguments():
+ raise exceptions.InferenceError
+ args = nodes.Tuple()
+ args.lineno = funcnode.args.lineno
+ args.col_offset = funcnode.args.col_offset
+ args.parent = funcnode.args
+ args.elts = vararg
+ return iter((args, ))
+
+ # Check if it's a default parameter.
+ try:
+ return funcnode.args.default_value(name).infer(context)
+ except exceptions.NoDefault:
+ pass
+ raise exceptions.InferenceError(name)
diff --git a/astroid/as_string.py b/astroid/as_string.py
index f627f9e..d7786fe 100644
--- a/astroid/as_string.py
+++ b/astroid/as_string.py
@@ -22,9 +22,10 @@
* :func:`dump` function return an internal representation of nodes found
in the tree, useful for debugging or understanding the tree structure
"""
-
import sys
+import six
+
INDENT = ' ' # 4 spaces ; keep indentation variable
@@ -89,9 +90,9 @@ class AsStringVisitor(object):
"""return an astroid.Function node as string"""
return node.format_args()
- def visit_assattr(self, node):
+ def visit_assignattr(self, node):
"""return an astroid.AssAttr node as string"""
- return self.visit_getattr(node)
+ return self.visit_attribute(node)
def visit_assert(self, node):
"""return an astroid.Assert node as string"""
@@ -100,7 +101,7 @@ class AsStringVisitor(object):
node.fail.accept(self))
return 'assert %s' % node.test.accept(self)
- def visit_assname(self, node):
+ def visit_assignname(self, node):
"""return an astroid.AssName node as string"""
return node.name
@@ -113,8 +114,8 @@ class AsStringVisitor(object):
"""return an astroid.AugAssign node as string"""
return '%s %s %s' % (node.target.accept(self), node.op, node.value.accept(self))
- def visit_backquote(self, node):
- """return an astroid.Backquote node as string"""
+ def visit_repr(self, node):
+ """return an astroid.Repr node as string"""
return '`%s`' % node.value.accept(self)
def visit_binop(self, node):
@@ -130,18 +131,20 @@ class AsStringVisitor(object):
"""return an astroid.Break node as string"""
return 'break'
- def visit_callfunc(self, node):
- """return an astroid.CallFunc node as string"""
+ def visit_call(self, node):
+ """return an astroid.Call node as string"""
expr_str = node.func.accept(self)
args = [arg.accept(self) for arg in node.args]
- if node.starargs:
- args.append('*' + node.starargs.accept(self))
- if node.kwargs:
- args.append('**' + node.kwargs.accept(self))
+ if node.keywords:
+ keywords = [kwarg.accept(self) for kwarg in node.keywords]
+ else:
+ keywords = []
+
+ args.extend(keywords)
return '%s(%s)' % (expr_str, ', '.join(args))
- def visit_class(self, node):
- """return an astroid.Class node as string"""
+ def visit_classdef(self, node):
+ """return an astroid.ClassDef node as string"""
decorate = node.decorators and node.decorators.accept(self) or ''
bases = ', '.join([n.accept(self) for n in node.bases])
if sys.version_info[0] == 2:
@@ -186,7 +189,7 @@ class AsStringVisitor(object):
def visit_delattr(self, node):
"""return an astroid.DelAttr node as string"""
- return self.visit_getattr(node)
+ return self.visit_attribute(node)
def visit_delname(self, node):
"""return an astroid.DelName node as string"""
@@ -198,16 +201,27 @@ class AsStringVisitor(object):
def visit_dict(self, node):
"""return an astroid.Dict node as string"""
- return '{%s}' % ', '.join(['%s: %s' % (key.accept(self),
- value.accept(self))
- for key, value in node.items])
+ return '{%s}' % ', '.join(self._visit_dict(node))
+
+ def _visit_dict(self, node):
+ for key, value in node.items:
+ key = key.accept(self)
+ value = value.accept(self)
+ if key == '**':
+ # It can only be a DictUnpack node.
+ yield key + value
+ else:
+ yield '%s: %s' % (key, value)
+
+ def visit_dictunpack(self, node):
+ return '**'
def visit_dictcomp(self, node):
"""return an astroid.DictComp node as string"""
return '{%s: %s %s}' % (node.key.accept(self), node.value.accept(self),
' '.join([n.accept(self) for n in node.generators]))
- def visit_discard(self, node):
+ def visit_expr(self, node):
"""return an astroid.Discard node as string"""
return node.value.accept(self)
@@ -258,24 +272,35 @@ class AsStringVisitor(object):
fors = '%s\nelse:\n%s' % (fors, self._stmt_list(node.orelse))
return fors
- def visit_from(self, node):
- """return an astroid.From node as string"""
+ def visit_importfrom(self, node):
+ """return an astroid.ImportFrom node as string"""
return 'from %s import %s' % ('.' * (node.level or 0) + node.modname,
_import_string(node.names))
- def visit_function(self, node):
+ def visit_functiondef(self, node):
"""return an astroid.Function node as string"""
decorate = node.decorators and node.decorators.accept(self) or ''
docs = node.doc and '\n%s"""%s"""' % (INDENT, node.doc) or ''
- return '\n%sdef %s(%s):%s\n%s' % (decorate, node.name, node.args.accept(self),
- docs, self._stmt_list(node.body))
-
- def visit_genexpr(self, node):
- """return an astroid.GenExpr node as string"""
+ return_annotation = ''
+ if six.PY3 and node.returns:
+ return_annotation = '->' + node.returns.as_string()
+ trailer = return_annotation + ":"
+ else:
+ trailer = ":"
+ def_format = "\n{decorators}def {name}({args}){trailer}{docs}\n{body}"
+ return def_format.format(decorators=decorate,
+ name=node.name,
+ args=node.args.accept(self),
+ trailer=trailer,
+ docs=docs,
+ body=self._stmt_list(node.body))
+
+ def visit_generatorexp(self, node):
+ """return an astroid.GeneratorExp node as string"""
return '(%s %s)' % (node.elt.accept(self),
' '.join([n.accept(self) for n in node.generators]))
- def visit_getattr(self, node):
+ def visit_attribute(self, node):
"""return an astroid.Getattr node as string"""
return '%s.%s' % (node.expr.accept(self), node.attrname)
@@ -302,6 +327,8 @@ class AsStringVisitor(object):
def visit_keyword(self, node):
"""return an astroid.Keyword node as string"""
+ if node.arg is None:
+ return '**%s' % node.value.accept(self)
return '%s=%s' % (node.arg, node.value.accept(self))
def visit_lambda(self, node):
@@ -438,6 +465,22 @@ class AsStringVisitor(object):
else:
return "(%s)" % (expr,)
+ def visit_starred(self, node):
+ """return Starred node as string"""
+ return "*" + node.value.accept(self)
+
+
+ # These aren't for real AST nodes, but for inference objects.
+
+ def visit_frozenset(self, node):
+ return node.parent.accept(self)
+
+ def visit_super(self, node):
+ return node.parent.accept(self)
+
+ def visit_yes(self, node):
+ return "Uninferable"
+
class AsStringVisitor3k(AsStringVisitor):
"""AsStringVisitor3k overwrites some AsStringVisitor methods"""
@@ -466,10 +509,6 @@ class AsStringVisitor3k(AsStringVisitor):
return 'raise %s' % node.exc.accept(self)
return 'raise'
- def visit_starred(self, node):
- """return Starred node as string"""
- return "*" + node.value.accept(self)
-
def visit_yieldfrom(self, node):
""" Return an astroid.YieldFrom node as string. """
yi_val = node.value and (" " + node.value.accept(self)) or ""
@@ -479,6 +518,19 @@ class AsStringVisitor3k(AsStringVisitor):
else:
return "(%s)" % (expr,)
+ def visit_asyncfunctiondef(self, node):
+ function = super(AsStringVisitor3k, self).visit_functiondef(node)
+ return 'async ' + function.strip()
+
+ def visit_await(self, node):
+ return 'await %s' % node.value.accept(self)
+
+ def visit_asyncwith(self, node):
+ return 'async %s' % self.visit_with(node)
+
+ def visit_asyncfor(self, node):
+ return 'async %s' % self.visit_for(node)
+
def _import_string(names):
"""return a list of (name, asname) formatted as a string"""
@@ -496,4 +548,3 @@ if sys.version_info >= (3, 0):
# this visitor is stateless, thus it can be reused
to_code = AsStringVisitor()
-
diff --git a/astroid/bases.py b/astroid/bases.py
index ee8ee1c..b90e1a4 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -18,22 +18,44 @@
"""This module contains base classes and functions for the nodes and some
inference utils.
"""
-
-__docformat__ = "restructuredtext en"
-
+import functools
import sys
-from contextlib import contextmanager
+import warnings
-from logilab.common.decorators import cachedproperty
+import wrapt
-from astroid.exceptions import (InferenceError, AstroidError, NotFoundError,
- UnresolvableName, UseInferenceDefault)
+from astroid import context as contextmod
... 15937 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/astroid.git
More information about the Python-modules-commits
mailing list