summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2015-10-03 17:44:45 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2015-10-03 17:44:45 +0300
commitc9fdca3130d506a2762bdb5aafe55de34f30bcfe (patch)
tree4b6e77730a340880355cb4d62715b08a55da77f5
parent8d15769dfa80943e140a07704513c4cd26cd3ad0 (diff)
downloadastroid-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.py6
-rw-r--r--astroid/node_classes.py34
-rw-r--r--astroid/objects.py44
-rw-r--r--astroid/tests/unittest_inference.py2
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)