diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2014-08-13 18:07:11 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2014-08-13 18:07:11 +0300 |
commit | d8b19eae5e855b5453f399858aadeb7cf218ee70 (patch) | |
tree | 8361c6365dce7f5ccbbc50afff201b400c0af115 /protocols.py | |
parent | 52ae161026cdc83721d5c4af7d34a9f9131966f7 (diff) | |
download | astroid-git-d8b19eae5e855b5453f399858aadeb7cf218ee70.tar.gz |
The inference engine handles binary operations (add, mul etc.) between instances.
Diffstat (limited to 'protocols.py')
-rw-r--r-- | protocols.py | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/protocols.py b/protocols.py index d621ffb6..e7703a06 100644 --- a/protocols.py +++ b/protocols.py @@ -21,13 +21,33 @@ where it makes sense. __doctype__ = "restructuredtext en" -from astroid.exceptions import InferenceError, NoDefault +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 ############################################################ def tl_infer_unary_op(self, operator): @@ -133,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 ################################################################## |