summaryrefslogtreecommitdiff
path: root/astroid/inference.py
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-08-08 23:46:08 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-08-08 23:46:08 +0300
commit428ac8bc0699252fa9f7ab4feef2a2e692b84c85 (patch)
tree3eb2eb82c5aff601579588071351e9fa0ba65b02 /astroid/inference.py
parentd1f1053cd22ec152b168d21b6482909eea4ee9c8 (diff)
downloadastroid-428ac8bc0699252fa9f7ab4feef2a2e692b84c85.tar.gz
Add CallFunc.keywords, instead of putting together args and kwargs in CallFunc.args
This patch improves the similarity with the Python's AST. Until now, CallFunc.args contained both the positional arguments and the keyword arguments, which was misleading and always it was required to filter out keywords when working with arguments.
Diffstat (limited to 'astroid/inference.py')
-rw-r--r--astroid/inference.py42
1 files changed, 20 insertions, 22 deletions
diff --git a/astroid/inference.py b/astroid/inference.py
index 4252e80..2ef1a91 100644
--- a/astroid/inference.py
+++ b/astroid/inference.py
@@ -40,25 +40,22 @@ MANAGER = AstroidManager()
class CallContext(object):
- """when inferring a function call, this class is used to remember values
- given as argument
- """
- def __init__(self, args, starargs, dstarargs):
- self.args = []
- self.nargs = {}
- for arg in args:
- if isinstance(arg, nodes.Keyword):
- self.nargs[arg.arg] = arg.value
- else:
- self.args.append(arg)
+
+ def __init__(self, args, keywords=None, starargs=None, kwargs=None):
+ self.args = args
+ if keywords:
+ self.keywords = {arg.arg: arg.value for arg in keywords}
+ else:
+ self.keywords = {}
+
self.starargs = starargs
- self.dstarargs = dstarargs
+ self.kwargs = kwargs
def infer_argument(self, funcnode, name, context):
"""infer a function argument value according to the call context"""
# 1. search in named keywords
try:
- return self.nargs[name].infer(context)
+ return self.keywords[name].infer(context)
except KeyError:
# Function.args.args can be None in astroid (means that we don't have
# information on argnames)
@@ -102,15 +99,15 @@ class CallContext(object):
continue
if its:
return itertools.chain(*its)
- # 4. XXX search in **kwargs (.dstarargs)
- if self.dstarargs is not None:
+ # 4. Search in **kwargs
+ if self.kwargs is not None:
its = []
- for infered in self.dstarargs.infer(context):
+ for infered in self.kwargs.infer(context=context):
if infered is YES:
its.append((YES,))
continue
try:
- its.append(infered.getitem(name, context).infer(context))
+ its.append(infered.getitem(name, context).infer(context=context))
except (InferenceError, AttributeError):
its.append((YES,))
except (IndexError, TypeError):
@@ -187,7 +184,10 @@ nodes.AssName.infer_lhs = infer_name # won't work with a path wrapper
def infer_callfunc(self, context=None):
"""infer a CallFunc node by trying to guess what the function returns"""
callcontext = context.clone()
- callcontext.callcontext = CallContext(self.args, self.starargs, self.kwargs)
+ callcontext.callcontext = CallContext(args=self.args,
+ keywords=self.keywords,
+ starargs=self.starargs,
+ kwargs=self.kwargs)
callcontext.boundnode = None
for callee in self.func.infer(context):
if callee is YES:
@@ -468,8 +468,7 @@ def _get_binop_contexts(context, left, right):
# left.__op__(right).
for arg in (right, left):
new_context = context.clone()
- new_context.callcontext = CallContext(
- [arg], starargs=None, dstarargs=None)
+ new_context.callcontext = CallContext(args=[arg])
new_context.boundnode = None
yield new_context
@@ -724,8 +723,7 @@ def instance_getitem(self, index, context=None):
context = new_context = InferenceContext()
# Create a new callcontext for providing index as an argument.
- new_context.callcontext = CallContext(
- args=[index], starargs=None, dstarargs=None)
+ new_context.callcontext = CallContext(args=[index])
new_context.boundnode = self
method = next(self.igetattr('__getitem__', context=context))