summaryrefslogtreecommitdiff
path: root/astroid/arguments.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2020-03-02 10:38:34 +0100
committerClaudiu Popa <pcmanticore@gmail.com>2020-03-02 10:38:34 +0100
commit9543362a3cf0a034c5d2c9e78149c7bf84c89c17 (patch)
tree602569219cadf6d1774482d4a58cb4ff3980247a /astroid/arguments.py
parent5bde219644af11bc44458b95443974fa50958e95 (diff)
downloadastroid-git-9543362a3cf0a034c5d2c9e78149c7bf84c89c17.tar.gz
Pass a context argument to ``astroid.Arguments`` to prevent recursion errors
Close PyCQA/pylint#3414
Diffstat (limited to 'astroid/arguments.py')
-rw-r--r--astroid/arguments.py41
1 files changed, 28 insertions, 13 deletions
diff --git a/astroid/arguments.py b/astroid/arguments.py
index 0a853605..55431237 100644
--- a/astroid/arguments.py
+++ b/astroid/arguments.py
@@ -20,20 +20,27 @@ class CallSite:
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.
+ In order to infer what an argument represents, call :meth:`infer_argument`
+ with the corresponding function node and the argument name.
+
+ :param callcontext:
+ An instance of :class:`astroid.context.CallContext`, that holds
+ the arguments for the call site.
+ :param argument_context_map:
+ Additional contexts per node, passed in from :attr:`astroid.context.Context.extra_context`
+ :param context:
+ An instance of :class:`astroid.context.Context`.
"""
- def __init__(self, callcontext, argument_context_map=None):
+ def __init__(self, callcontext, argument_context_map=None, context=None):
if argument_context_map is None:
argument_context_map = {}
self.argument_context_map = argument_context_map
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._unpacked_args = self._unpack_args(args, context=context)
+ self._unpacked_kwargs = self._unpack_keywords(keywords, context=context)
self.positional_arguments = [
arg for arg in self._unpacked_args if arg is not util.Uninferable
@@ -45,10 +52,18 @@ class CallSite:
}
@classmethod
- def from_call(cls, call_node):
- """Get a CallSite object from the given Call node."""
+ def from_call(cls, call_node, context=None):
+ """Get a CallSite object from the given Call node.
+
+ :param context:
+ An instance of :class:`astroid.context.Context` that will be used
+ to force a single inference path.
+ """
+
+ # Determine the callcontext from the given `context` object if any.
+ context = context or contextmod.InferenceContext()
callcontext = contextmod.CallContext(call_node.args, call_node.keywords)
- return cls(callcontext)
+ return cls(callcontext, context=context)
def has_invalid_arguments(self):
"""Check if in the current CallSite were passed *invalid* arguments
@@ -70,9 +85,9 @@ class CallSite:
"""
return len(self.keyword_arguments) != len(self._unpacked_kwargs)
- def _unpack_keywords(self, keywords):
+ def _unpack_keywords(self, keywords, context=None):
values = {}
- context = contextmod.InferenceContext()
+ context = context or contextmod.InferenceContext()
context.extra_context = self.argument_context_map
for name, value in keywords:
if name is None:
@@ -110,9 +125,9 @@ class CallSite:
values[name] = value
return values
- def _unpack_args(self, args):
+ def _unpack_args(self, args, context=None):
values = []
- context = contextmod.InferenceContext()
+ context = context or contextmod.InferenceContext()
context.extra_context = self.argument_context_map
for arg in args:
if isinstance(arg, nodes.Starred):