diff --git a/loopy/check.py b/loopy/check.py
index ab45de8b6f07469d903d35f794f1eb951cf361f2..70d16c2d3759bb0c265d91a448733a39a1bcc579 100644
--- a/loopy/check.py
+++ b/loopy/check.py
@@ -27,6 +27,7 @@ from islpy import dim_type
 import islpy as isl
 from loopy.symbolic import WalkMapper
 from loopy.diagnostic import LoopyError, WriteRaceConditionWarning, warn
+from loopy.tools import is_integer
 
 import logging
 logger = logging.getLogger(__name__)
@@ -36,7 +37,7 @@ logger = logging.getLogger(__name__)
 
 def check_temp_variable_shapes_are_constant(kernel):
     for tv in kernel.temporary_variables.itervalues():
-        if any(not isinstance(s_i, (int, long)) for s_i in tv.shape):
+        if any(not is_integer(s_i) for s_i in tv.shape):
             raise LoopyError("shape of temporary variable '%s' is not "
                     "constant (but has to be since the size of "
                     "the temporary needs to be known at build time). "
diff --git a/loopy/codegen/expression.py b/loopy/codegen/expression.py
index b5ff4aab46429b913d004e7384cd2678dd5d2756..a2415a72b58524ba68e0beb155d6fdbcbd2fa2be 100644
--- a/loopy/codegen/expression.py
+++ b/loopy/codegen/expression.py
@@ -34,6 +34,7 @@ import pyopencl as cl
 import pyopencl.array  # noqa
 from pytools import Record
 
+from loopy.tools import is_integer
 from loopy.diagnostic import TypeInferenceFailure, DependencyTypeInferenceFailure
 
 
@@ -84,7 +85,7 @@ class TypeInferenceMapper(CombineMapper):
         small_integer_dtypes = []
         for child in expr.children:
             dtype = self.rec(child)
-            if isinstance(child, (int, long, np.integer)) and abs(child) < 1024:
+            if is_integer(child) and abs(child) < 1024:
                 small_integer_dtypes.append(dtype)
             else:
                 dtypes.append(dtype)
@@ -109,7 +110,7 @@ class TypeInferenceMapper(CombineMapper):
             return self.combine([n_dtype, d_dtype])
 
     def map_constant(self, expr):
-        if isinstance(expr, (int, long)):
+        if is_integer(expr):
             for tp in [np.int32, np.int64]:
                 iinfo = np.iinfo(tp)
                 if iinfo.min <= expr <= iinfo.max:
@@ -626,7 +627,7 @@ class LoopyCCodeMapper(RecursiveMapper):
             elif type_context == "i":
                 return str(int(expr))
             else:
-                if isinstance(expr, (int, long)):
+                if is_integer(expr):
                     return str(expr)
 
                 raise RuntimeError("don't know how to generated code "
diff --git a/loopy/kernel/array.py b/loopy/kernel/array.py
index cd6fa658fc84c0c071da2076d61ad65756ea57fc..9b47636c2b668c6f3b419a379e7049b12d0bf13d 100644
--- a/loopy/kernel/array.py
+++ b/loopy/kernel/array.py
@@ -33,6 +33,7 @@ import pyopencl.array  # noqa
 import numpy as np
 
 from loopy.diagnostic import LoopyError
+from loopy.tools import is_integer
 
 
 # {{{ array dimension tags
@@ -286,7 +287,7 @@ def convert_computed_to_fixed_dim_tags(name, num_user_axes, num_target_axes,
                 # unable to normalize without known shape
                 return None
 
-            if not isinstance(shape[i], (int, long, np.integer)):
+            if not is_integer(shape[i]):
                 raise TypeError("shape along vector axis %d of array '%s' "
                         "must be an integer, not an expression"
                         % (i, name))
@@ -668,7 +669,7 @@ class ArrayBase(Record):
         for i, dim_tag in enumerate(self.dim_tags):
             if isinstance(dim_tag, VectorArrayDimTag):
                 shape_i = self.shape[i]
-                if not isinstance(shape_i, (int, long, np.integer)):
+                if not is_integer(shape_i):
                     raise LoopyError("shape of '%s' has non-constant-integer "
                             "length for vector axis %d (0-based)" % (
                                 self.name, i))
@@ -807,7 +808,7 @@ class ArrayBase(Record):
 
             elif isinstance(dim_tag, SeparateArrayArrayDimTag):
                 shape_i = self.shape[user_axis]
-                if not isinstance(shape_i, (int, long, np.integer)):
+                if not is_integer(shape_i):
                     raise LoopyError("shape of '%s' has non-constant "
                             "integer axis %d (0-based)" % (
                                 self.name, user_axis))
@@ -821,7 +822,7 @@ class ArrayBase(Record):
 
             elif isinstance(dim_tag, VectorArrayDimTag):
                 shape_i = self.shape[user_axis]
-                if not isinstance(shape_i, (int, long, np.integer)):
+                if not is_integer(shape_i):
                     raise LoopyError("shape of '%s' has non-constant "
                             "integer axis %d (0-based)" % (
                                 self.name, user_axis))
@@ -852,7 +853,7 @@ class ArrayBase(Record):
         sep_shape = []
         for shape_i, dim_tag in zip(self.shape, self.dim_tags):
             if isinstance(dim_tag, SeparateArrayArrayDimTag):
-                if not isinstance(shape_i, (int, long, np.integer)):
+                if not is_integer(shape_i):
                     raise TypeError("array '%s' has non-fixed-size "
                             "separate-array axis" % self.name)
 
@@ -945,7 +946,7 @@ def get_access_info(ary, index, eval_expr):
     for i, (idx, dim_tag) in enumerate(zip(index, ary.dim_tags)):
         if isinstance(dim_tag, SeparateArrayArrayDimTag):
             idx = eval_expr_wrapper(i, idx)
-            if not isinstance(idx, (int, long, np.integer)):
+            if not is_integer(idx):
                 raise LoopyError("subscript '%s[%s]' has non-constant "
                         "index for separate-array axis %d (0-based)" % (
                             ary.name, index, i))
@@ -961,7 +962,7 @@ def get_access_info(ary, index, eval_expr):
 
             stride = dim_tag.stride
 
-            if isinstance(stride, (int, long, np.integer)):
+            if is_integer(stride):
                 if not dim_tag.stride % vector_size == 0:
                     raise LoopyError("array '%s' has axis %d stride of "
                             "%d, which is not divisible by the size of the "
@@ -980,7 +981,7 @@ def get_access_info(ary, index, eval_expr):
         elif isinstance(dim_tag, VectorArrayDimTag):
             idx = eval_expr_wrapper(i, idx)
 
-            if not isinstance(idx, (int, long, np.integer)):
+            if not is_integer(idx):
                 raise LoopyError("subscript '%s[%s]' has non-constant "
                         "index for separate-array axis %d (0-based)" % (
                             ary.name, index, i))
diff --git a/loopy/tools.py b/loopy/tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..452a2ca9bc03e54fde9472057f3e63479621dfac
--- /dev/null
+++ b/loopy/tools.py
@@ -0,0 +1,29 @@
+from __future__ import division
+
+__copyright__ = "Copyright (C) 2012 Andreas Kloeckner"
+
+__license__ = """
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+import numpy as np
+
+
+def is_integer(obj):
+    return isinstance(obj, (int, long, np.integer))