diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-03 17:44:45 +0300 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2015-10-03 17:44:45 +0300 |
commit | c9fdca3130d506a2762bdb5aafe55de34f30bcfe (patch) | |
tree | 4b6e77730a340880355cb4d62715b08a55da77f5 | |
parent | 8d15769dfa80943e140a07704513c4cd26cd3ad0 (diff) | |
download | astroid-c9fdca3130d506a2762bdb5aafe55de34f30bcfe.tar.gz |
Move objects.Slice back into nodes.Slice
We did this because objects.Slice had more capabilities than
nodes.Slice, such as inferring the slice attributes (start, stop,
step) and it was used mostly for inferring the slice() builtin.
-rw-r--r-- | astroid/brain/builtin_inference.py | 6 | ||||
-rw-r--r-- | astroid/node_classes.py | 34 | ||||
-rw-r--r-- | astroid/objects.py | 44 | ||||
-rw-r--r-- | astroid/tests/unittest_inference.py | 2 |
4 files changed, 37 insertions, 49 deletions
diff --git a/astroid/brain/builtin_inference.py b/astroid/brain/builtin_inference.py index 5f06dc3..022a009 100644 --- a/astroid/brain/builtin_inference.py +++ b/astroid/brain/builtin_inference.py @@ -452,9 +452,9 @@ def infer_slice(node, context=None): # Make sure we have 3 arguments. args.extend([None] * (3 - len(args))) - slice_node = objects.Slice(lineno=node.lineno, - col_offset=node.col_offset, - parent=node.parent) + slice_node = nodes.Slice(lineno=node.lineno, + col_offset=node.col_offset, + parent=node.parent) slice_node.postinit(*args) return slice_node diff --git a/astroid/node_classes.py b/astroid/node_classes.py index 3ac5f40..62b481b 100644 --- a/astroid/node_classes.py +++ b/astroid/node_classes.py @@ -28,11 +28,13 @@ from astroid import bases from astroid import context as contextmod from astroid import decorators from astroid import exceptions +from astroid import manager from astroid import mixins from astroid import util BUILTINS = six.moves.builtins.__name__ +MANAGER = manager.AstroidManager() def unpack_infer(stmt, context=None): @@ -1132,7 +1134,37 @@ class Slice(bases.NodeNG): def postinit(self, lower=None, upper=None, step=None): self.lower = lower self.upper = upper - self.step = step + self.step = step + + def _wrap_attribute(self, attr): + """Wrap the empty attributes of the Slice in a Const node.""" + if not attr: + const = const_factory(attr) + const.parent = self + return const + return attr + + @decorators.cachedproperty + def _proxied(self): + builtins = MANAGER.astroid_cache[BUILTINS] + return builtins.getattr('slice')[0] + + def pytype(self): + return '%s.slice' % BUILTINS + + def igetattr(self, attrname, context=None): + if attrname == 'start': + yield self._wrap_attribute(self.lower) + elif attrname == 'stop': + yield self._wrap_attribute(self.upper) + elif attrname == 'step': + yield self._wrap_attribute(self.step) + else: + for value in self.getattr(attrname, context=context): + yield value + + def getattr(self, attrname, context=None): + return self._proxied.getattr(attrname, context) class Starred(mixins.ParentAssignTypeMixin, bases.NodeNG): diff --git a/astroid/objects.py b/astroid/objects.py index b11e3bc..f80cf54 100644 --- a/astroid/objects.py +++ b/astroid/objects.py @@ -23,24 +23,6 @@ original AST tree. For instance, inferring the following frozenset use, leads to an inferred FrozenSet: Call(func=Name('frozenset'), args=Tuple(...)) - - -This distinction might help for understanding better where to use -an AST node and where to use an inference object: - - * if the AST node can be used on its own, e.g. List, Tuple, etc, - then the AST can be used. - They have a syntactic display and can be written on its own, - e.g. "[]" is a valid list. That's why the inference of their - respective builtins (list, tuple, set etc) returns an AST node - when inferring. - - * if the AST node is part of syntax and can't be used - on its own. This is the case for slices for instance, e.g "[2:3:4]". - In this case, trying to write "2:3:4" on its own will fail. - The respective builtin (slice) returns a custom object when inferring - and not an AST node per se. - """ import six @@ -72,32 +54,6 @@ class FrozenSet(node_classes._BaseContainer): return builtins.getattr('frozenset')[0] -class Slice(node_classes.Slice): - """Custom object for representing slices internally.""" - - @decorators.cachedproperty - def _proxied(self): - builtins = MANAGER.astroid_cache[BUILTINS] - return builtins.getattr('slice')[0] - - def pytype(self): - return '%s.slice' % BUILTINS - - def igetattr(self, attrname, context=None): - if attrname == 'start': - yield self.lower - elif attrname == 'stop': - yield self.upper - elif attrname == 'step': - yield self.step - else: - for value in self.getattr(attrname, context=context): - yield value - - def getattr(self, attrname, context=None): - return self._proxied.getattr(attrname, context) - - class Super(bases.NodeNG): """Proxy class over a super call. diff --git a/astroid/tests/unittest_inference.py b/astroid/tests/unittest_inference.py index ef8888e..8b6d143 100644 --- a/astroid/tests/unittest_inference.py +++ b/astroid/tests/unittest_inference.py @@ -3662,7 +3662,7 @@ class SliceTest(unittest.TestCase): lower, upper, step = values node = test_utils.extract_node(code) inferred = next(node.infer()) - self.assertIsInstance(inferred, objects.Slice) + self.assertIsInstance(inferred, nodes.Slice) lower_value = next(inferred.igetattr('start')) self.assertIsInstance(lower_value, nodes.Const) self.assertEqual(lower_value.value, lower) |