improved subscribe

--HG--
branch : trunk
diff --git a/jinja2/compiler.py b/jinja2/compiler.py
index 4c250b5..6e05040 100644
--- a/jinja2/compiler.py
+++ b/jinja2/compiler.py
@@ -1264,7 +1264,11 @@
         self.visit(node.expr, frame)
 
     def visit_Subscript(self, node, frame):
-        if isinstance(node.arg, nodes.Slice):
+        # slices or integer subscriptions bypass the subscribe
+        # method if we can determine that at compile time.
+        if isinstance(node.arg, nodes.Slice) or \
+           (isinstance(node.arg, nodes.Const) and
+            isinstance(node.arg.value, (int, long))):
             self.visit(node.node, frame)
             self.write('[')
             self.visit(node.arg, frame)
diff --git a/jinja2/environment.py b/jinja2/environment.py
index 70fd344..d1206ef 100644
--- a/jinja2/environment.py
+++ b/jinja2/environment.py
@@ -278,13 +278,15 @@
 
     def subscribe(self, obj, argument):
         """Get an item or attribute of an object."""
-        try:
-            return getattr(obj, str(argument))
-        except (AttributeError, UnicodeError):
+        if isinstance(argument, basestring):
             try:
-                return obj[argument]
-            except (TypeError, LookupError):
-                return self.undefined(obj=obj, name=argument)
+                return getattr(obj, str(argument))
+            except (AttributeError, UnicodeError):
+                pass
+        try:
+            return obj[argument]
+        except (TypeError, LookupError):
+            return self.undefined(obj=obj, name=argument)
 
     def parse(self, source, filename=None):
         """Parse the sourcecode and return the abstract syntax tree.  This
diff --git a/jinja2/sandbox.py b/jinja2/sandbox.py
index 4b9ac13..c041a06 100644
--- a/jinja2/sandbox.py
+++ b/jinja2/sandbox.py
@@ -118,14 +118,15 @@
     def subscribe(self, obj, argument):
         """Subscribe an object from sandboxed code."""
         is_unsafe = False
-        try:
-            value = getattr(obj, str(argument))
-        except (AttributeError, UnicodeError):
-            pass
-        else:
-            if self.is_safe_attribute(obj, argument, value):
-                return value
-            is_unsafe = True
+        if isinstance(argument, basestring):
+            try:
+                value = getattr(obj, str(argument))
+            except (AttributeError, UnicodeError):
+                pass
+            else:
+                if self.is_safe_attribute(obj, argument, value):
+                    return value
+                is_unsafe = True
         try:
             return obj[argument]
         except (TypeError, LookupError):