diff options
author | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-08-08 23:46:08 +0300 |
---|---|---|
committer | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-08-08 23:46:08 +0300 |
commit | 428ac8bc0699252fa9f7ab4feef2a2e692b84c85 (patch) | |
tree | 3eb2eb82c5aff601579588071351e9fa0ba65b02 /astroid/inference.py | |
parent | d1f1053cd22ec152b168d21b6482909eea4ee9c8 (diff) | |
download | astroid-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.py | 42 |
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)) |