REF: move templated index.pyx code to non-template
diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx
index c919086701536..8cea529fbb07e 100644
--- a/pandas/_libs/index.pyx
+++ b/pandas/_libs/index.pyx
@@ -226,7 +226,13 @@ cdef class IndexEngine:
         return self.vgetter()
 
     def _call_monotonic(self, values):
-        raise NotImplementedError
+        return algos.is_monotonic(values, timelike=False)
+
+    def get_backfill_indexer(self, other, limit=None):
+        return algos.backfill(self._get_index_values(), other, limit=limit)
+
+    def get_pad_indexer(self, other, limit=None):
+        return algos.pad(self._get_index_values(), other, limit=limit)
 
     cdef _make_hash_table(self, n):
         raise NotImplementedError
@@ -371,6 +377,14 @@ cdef Py_ssize_t _bin_search(ndarray values, object val) except -1:
         return mid + 1
 
 
+cdef class ObjectEngine(IndexEngine):
+    """
+    Index Engine for use with object-dtype Index, namely the base class Index
+    """
+    cdef _make_hash_table(self, n):
+        return _hash.PyObjectHashTable(n)
+
+
 cdef class DatetimeEngine(Int64Engine):
 
     cdef _get_box_dtype(self):
diff --git a/pandas/_libs/index_class_helper.pxi.in b/pandas/_libs/index_class_helper.pxi.in
index 6383c1534fb44..3c9a096e7ecc0 100644
--- a/pandas/_libs/index_class_helper.pxi.in
+++ b/pandas/_libs/index_class_helper.pxi.in
@@ -21,7 +21,6 @@ dtypes = [('Float64', 'float64', 'float64_t', 'Float64', 'float64'),
           ('UInt32', 'uint32', 'uint32_t', 'UInt64', 'uint64'),
           ('UInt16', 'uint16', 'uint16_t', 'UInt64', 'uint64'),
           ('UInt8', 'uint8', 'uint8_t', 'UInt64', 'uint64'),
-          ('Object', 'object', 'object', 'PyObject', 'object'),
           ]
 }}
 
@@ -30,30 +29,15 @@ dtypes = [('Float64', 'float64', 'float64_t', 'Float64', 'float64'),
 
 cdef class {{name}}Engine(IndexEngine):
 
-    def _call_monotonic(self, values):
-        return algos.is_monotonic(values, timelike=False)
-
-    def get_backfill_indexer(self, other, limit=None):
-        return algos.backfill(self._get_index_values(), other, limit=limit)
-
-    def get_pad_indexer(self, other, limit=None):
-        return algos.pad(self._get_index_values(), other, limit=limit)
-
     cdef _make_hash_table(self, n):
         return _hash.{{hashtable_name}}HashTable(n)
 
-    {{if name not in {'Float64', 'Float32', 'Object'} }}
+    {{if name not in {'Float64', 'Float32'} }}
     cdef _check_type(self, object val):
-        hash(val)
-        if util.is_bool_object(val):
-            raise KeyError(val)
-        elif util.is_float_object(val):
-            raise KeyError(val)
-        elif not util.is_integer_object(val):
+        if not util.is_integer_object(val):
             raise KeyError(val)
     {{endif}}
 
-    {{if name != 'Object'}}
     cpdef _call_map_locations(self, values):
         # self.mapping is of type {{hashtable_name}}HashTable,
         # so convert dtype of values
@@ -87,6 +71,4 @@ cdef class {{name}}Engine(IndexEngine):
 
         raise KeyError(val)
 
-    {{endif}}
-
 {{endfor}}

Following cleanup of libalgos, we can get a little bit of code out of the tempita file.