Repository: sympy/sympy

Issue:
Permutation repr test failure in master 
```
$./bin/test repr perm
===================================================================================================== test process starts =====================================================================================================
executable:         /home/aaronmeurer/anaconda3/bin/python  (3.7.3-final-0) [CPython]
architecture:       64-bit
cache:              yes
ground types:       gmpy 2.1.0b1
numpy:              1.17.3
random seed:        57948523
hash randomization: on (PYTHONHASHSEED=372740668)

sympy/combinatorics/tests/test_perm_groups.py[57] ...............f...............f................w........                                                                                                                [OK]
sympy/combinatorics/tests/test_permutations.py[11] ...........                                                                                                                                                             [OK]
sympy/physics/quantum/tests/test_represent.py[9] .........                                                                                                                                                                 [OK]
sympy/printing/tests/test_lambdarepr.py[9] .........                                                                                                                                                                       [OK]
sympy/printing/tests/test_repr.py[41] ........................................F                                                                                                                                          [FAIL]

_______________________________________________________________________________________________________________________________________________________________________________________________________________________________
_____________________________________________________________________________________ sympy/printing/tests/test_repr.py:test_Permutation ______________________________________________________________________________________
Traceback (most recent call last):
  File "/home/aaronmeurer/Documents/python/sympy/sympy/sympy/printing/tests/test_repr.py", line 305, in test_Permutation
    sT(Permutation(1, 2), "Permutation(1, 2)", import_stmt)
  File "/home/aaronmeurer/Documents/python/sympy/sympy/sympy/printing/tests/test_repr.py", line 34, in sT
    assert srepr(expr) == string
AssertionError

==================================================================== tests finished: 123 passed, 1 failed, 1 skipped, 2 expected to fail, in 2.20 seconds =====================================================================
DO *NOT* COMMIT!
```

We can probably work around this by making sure print_cyclic is set correctly in the repr test. 

In the longer term, I think we should get rid of that flag https://github.com/sympy/sympy/issues/15201.

Discussion:

Patch:
diff --git a/sympy/functions/elementary/hyperbolic.py b/sympy/functions/elementary/hyperbolic.py
index 1eb6d089b5..4621764fcc 100644
--- a/sympy/functions/elementary/hyperbolic.py
+++ b/sympy/functions/elementary/hyperbolic.py
@@ -278,6 +278,53 @@ class cosh(HyperbolicFunction):
     sinh, tanh, acosh
     """
 
+    def _eval_is_positive(self):
+        arg = self.args[0]
+
+        if arg.is_real:
+            return True
+
+        re, im = arg.as_real_imag()
+        im_mod = im % (2*pi)
+
+        if im_mod == 0:
+            return True
+
+        if re == 0:
+            if im_mod < pi/2 or im_mod > 3*pi/2:
+                return True
+            elif im_mod >= pi/2 or im_mod <= 3*pi/2:
+                return False
+
+        return fuzzy_or([fuzzy_and([fuzzy_bool(Eq(re, 0)),
+                         fuzzy_or([fuzzy_bool(im_mod < pi/2),
+                                   fuzzy_bool(im_mod > 3*pi/2)])]),
+                         fuzzy_bool(Eq(im_mod, 0))])
+
+
+    def _eval_is_nonnegative(self):
+        arg = self.args[0]
+
+        if arg.is_real:
+            return True
+
+        re, im = arg.as_real_imag()
+        im_mod = im % (2*pi)
+
+        if im_mod == 0:
+            return True
+
+        if re == 0:
+            if im_mod <= pi/2 or im_mod >= 3*pi/2:
+                return True
+            elif im_mod > pi/2 or im_mod < 3*pi/2:
+                return False
+
+        return fuzzy_or([fuzzy_and([fuzzy_bool(Eq(re, 0)),
+                         fuzzy_or([fuzzy_bool(im_mod <= pi/2), fuzzy_bool(im_mod >= 3*pi/2)])]),
+                         fuzzy_bool(Eq(im_mod, 0))])
+
+
     def fdiff(self, argindex=1):
         if argindex == 1:
             return sinh(self.args[0])
@@ -425,64 +472,6 @@ def _eval_is_real(self):
         re, im = arg.as_real_imag()
         return (im%pi).is_zero
 
-    def _eval_is_positive(self):
-        # cosh(x+I*y) = cos(y)*cosh(x) + I*sin(y)*sinh(x)
-        # cosh(z) is positive iff it is real and the real part is positive.
-        # So we need sin(y)*sinh(x) = 0 which gives x=0 or y=n*pi
-        # Case 1 (y=n*pi): cosh(z) = (-1)**n * cosh(x) -> positive for n even
-        # Case 2 (x=0): cosh(z) = cos(y) -> positive when cos(y) is positive
-        z = self.args[0]
-
-        x, y = z.as_real_imag()
-        ymod = y % (2*pi)
-
-        yzero = ymod.is_zero
-        # shortcut if ymod is zero
-        if yzero:
-            return True
-
-        xzero = x.is_zero
-        # shortcut x is not zero
-        if xzero is False:
-            return yzero
-
-        return fuzzy_or([
-                # Case 1:
-                yzero,
-                # Case 2:
-                fuzzy_and([
-                    xzero,
-                    fuzzy_or([ymod < pi/2, ymod > 3*pi/2])
-                ])
-            ])
-
-
-    def _eval_is_nonnegative(self):
-        z = self.args[0]
-
-        x, y = z.as_real_imag()
-        ymod = y % (2*pi)
-
-        yzero = ymod.is_zero
-        # shortcut if ymod is zero
-        if yzero:
-            return True
-
-        xzero = x.is_zero
-        # shortcut x is not zero
-        if xzero is False:
-            return yzero
-
-        return fuzzy_or([
-                # Case 1:
-                yzero,
-                # Case 2:
-                fuzzy_and([
-                    xzero,
-                    fuzzy_or([ymod <= pi/2, ymod >= 3*pi/2])
-                ])
-            ])
-
     def _eval_is_finite(self):
         arg = self.args[0]
         return arg.is_finite
diff --git a/sympy/physics/hep/gamma_matrices.py b/sympy/physics/hep/gamma_matrices.py
index e70923d833..790b4bdad6 100644
--- a/sympy/physics/hep/gamma_matrices.py
+++ b/sympy/physics/hep/gamma_matrices.py
@@ -31,10 +31,10 @@
 from sympy.core.compatibility import range
 
 
-# DiracSpinorIndex = TensorIndexType('DiracSpinorIndex', dim=4, dummy_name="S")
+# DiracSpinorIndex = TensorIndexType('DiracSpinorIndex', dim=4, dummy_fmt="S")
 
 
-LorentzIndex = TensorIndexType('LorentzIndex', dim=4, dummy_name="L")
+LorentzIndex = TensorIndexType('LorentzIndex', dim=4, dummy_fmt="L")
 
 
 GammaMatrix = TensorHead("GammaMatrix", [LorentzIndex],
diff --git a/sympy/tensor/tensor.py b/sympy/tensor/tensor.py
index ca9aa48a46..e8f4d9b4ce 100644
--- a/sympy/tensor/tensor.py
+++ b/sympy/tensor/tensor.py
@@ -47,7 +47,6 @@
 from sympy.core.operations import AssocOp
 from sympy.matrices import eye
 from sympy.utilities.exceptions import SymPyDeprecationWarning
-from sympy.utilities.decorator import memoize_property
 import warnings
 
 
@@ -96,7 +95,7 @@ def from_indices(*indices):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, _IndexStructure
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz)
         >>> _IndexStructure.from_indices(m0, m1, -m1, m3)
         _IndexStructure([(m0, 0), (m3, 3)], [(1, 2)], [Lorentz, Lorentz, Lorentz, Lorentz])
@@ -131,7 +130,7 @@ def _free_dum_from_indices(*indices):
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, \
             _IndexStructure
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz)
         >>> _IndexStructure._free_dum_from_indices(m0, m1, -m1, m3)
         ([(m0, 0), (m3, 3)], [(1, 2)])
@@ -145,9 +144,9 @@ def _free_dum_from_indices(*indices):
         index_dict = {}
         dum = []
         for i, index in enumerate(indices):
-            name = index.name
+            name = index._name
             typ = index.tensor_index_type
-            contr = index.is_up
+            contr = index._is_up
             if (name, typ) in index_dict:
                 # found a pair of dummy indices
                 is_contr, pos = index_dict[(name, typ)]
@@ -169,7 +168,7 @@ def _free_dum_from_indices(*indices):
                 else:
                     dum.append((pos, i))
             else:
-                index_dict[(name, typ)] = index.is_up, i
+                index_dict[(name, typ)] = index._is_up, i
 
         free = [(index, i) for i, index in enumerate(indices) if free[i]]
         free.sort()
@@ -199,19 +198,20 @@ def generate_indices_from_free_dum_index_types(free, dum, index_types):
     @staticmethod
     def _get_generator_for_dummy_indices(free):
         cdt = defaultdict(int)
-        # if the free indices have names with dummy_name, start with an
+        # if the free indices have names with dummy_fmt, start with an
         # index higher than those for the dummy indices
         # to avoid name collisions
         for indx, ipos in free:
-            if indx.name.split('_')[0] == indx.tensor_index_type.dummy_name:
-                cdt[indx.tensor_index_type] = max(cdt[indx.tensor_index_type], int(indx.name.split('_')[1]) + 1)
+            if indx._name.split('_')[0] == indx.tensor_index_type.dummy_fmt[:-3]:
+                cdt[indx.tensor_index_type] = max(cdt[indx.tensor_index_type], int(indx._name.split('_')[1]) + 1)
 
-        def dummy_name_gen(tensor_index_type):
-            nd = str(cdt[tensor_index_type])
+        def dummy_fmt_gen(tensor_index_type):
+            fmt = tensor_index_type.dummy_fmt
+            nd = cdt[tensor_index_type]
             cdt[tensor_index_type] += 1
-            return tensor_index_type.dummy_name + '_' + nd
+            return fmt % nd
 
-        return dummy_name_gen
+        return dummy_fmt_gen
 
     @staticmethod
     def _replace_dummy_names(indices, free, dum):
@@ -312,18 +312,6 @@ def indices_canon_args(self):
         n = self._ext_rank
         g = [None]*n + [n, n+1]
 
-        # Converts the symmetry of the metric into msym from .canonicalize()
-        # method in the combinatorics module
-        def metric_symmetry_to_msym(metric):
-            if metric is None:
-                return None
-            sym = metric.symmetry
-            if sym == TensorSymmetry.fully_symmetric(2):
-                return 0
-            if sym == TensorSymmetry.fully_symmetric(-2):
-                return 1
-            return None
-
         # ordered indices: first the free indices, ordered by types
         # then the dummy indices, ordered by types and contravariant before
         # covariant
@@ -346,7 +334,7 @@ def metric_symmetry_to_msym(metric):
                     dummies.append(a)
                 a = [pos, pos + 1]
                 prev = typ
-                msym.append(metric_symmetry_to_msym(typ.metric))
+                msym.append(typ.metric_antisym)
             else:
                 a.extend([pos, pos + 1])
             pos += 2
@@ -367,10 +355,10 @@ def components_canon_args(components):
             numtyp.append([prev, 1])
     v = []
     for h, n in numtyp:
-        if h.comm == 0 or h.comm == 1:
-            comm = h.comm
+        if h._comm == 0 or h._comm == 1:
+            comm = h._comm
         else:
-            comm = TensorManager.get_comm(h.comm, h.comm)
+            comm = TensorManager.get_comm(h._comm, h._comm)
         v.append((h.symmetry.base, h.symmetry.generators, n, comm))
     return v
 
@@ -591,7 +579,7 @@ def __setitem__(self, key, value):
                 if indextype.data is None:
                     raise ValueError("index type {} has no components data"\
                     " associated (needed to raise/lower index)".format(indextype))
-                if not indextype.dim.is_number:
+                if indextype.dim is None:
                     continue
                 if dim != indextype.dim:
                     raise ValueError("wrong dimension of ndarray")
@@ -912,49 +900,53 @@ class TensorIndexType(Basic):
     ==========
 
     name : name of the tensor type
-    dummy_name : name of the head of dummy indices
+
+    metric : metric symmetry or metric object or ``None``
+
     dim : dimension, it can be a symbol or an integer or ``None``
+
     eps_dim : dimension of the epsilon tensor
-    metric_symmetry : integer that denotes metric symmetry or `None` for no metirc
-    metric_name : string with the name of the metric tensor
+
+    dummy_fmt : name of the head of dummy indices
 
     Attributes
     ==========
 
+    ``name``
+    ``metric_name`` : it is 'metric' or metric.name
+    ``metric_antisym``
     ``metric`` : the metric tensor
     ``delta`` : ``Kronecker delta``
     ``epsilon`` : the ``Levi-Civita epsilon`` tensor
+    ``dim``
+    ``eps_dim``
+    ``dummy_fmt``
     ``data`` : (deprecated) a property to add ``ndarray`` values, to work in a specified basis.
 
     Notes
     =====
 
-    The possible values of the `metric_symmetry` parameter are:
+    The ``metric`` parameter can be:
+    ``metric = False`` symmetric metric (in Riemannian geometry)
+
+    ``metric = True`` antisymmetric metric (for spinor calculus)
+
+    ``metric = None``  there is no metric
 
-        ``1``   :   metric tensor is fully symmetric
-        ``0``   :   metric tensor possesses no index symmetry
-        ``-1``  :   metric tensor is fully antisymmetric
-        ``None``:   there is no metric tensor (metric equals to `None`)
+    ``metric`` can be an object having ``name`` and ``antisym`` attributes.
 
-    The metric is assumed to be symmetric by default. It can also be set
-    to a custom tensor by the `.set_metric()` method.
 
     If there is a metric the metric is used to raise and lower indices.
 
-    In the case of non-symmetric metric, the following raising and
+    In the case of antisymmetric metric, the following raising and
     lowering conventions will be adopted:
 
     ``psi(a) = g(a, b)*psi(-b); chi(-a) = chi(b)*g(-b, -a)``
 
-    From these it is easy to find:
-
-    ``g(-a, b) = delta(-a, b)``
+    ``g(-a, b) = delta(-a, b); g(b, -a) = -delta(a, -b)``
 
     where ``delta(-a, b) = delta(b, -a)`` is the ``Kronecker delta``
     (see ``TensorIndex`` for the conventions on indices).
-    For antisymmetric metrics there is also the following equality:
-
-    ``g(a, -b) = -delta(a, -b)``
 
     If there is no metric it is not possible to raise or lower indices;
     e.g. the index of the defining representation of ``SU(N)``
@@ -969,121 +961,62 @@ class TensorIndexType(Basic):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> Lorentz.metric
     metric(Lorentz,Lorentz)
     """
 
-    def __new__(cls, name, dummy_name=None, dim=None, eps_dim=None,
-                metric_symmetry=1, metric_name='metric', **kwargs):
-        if 'dummy_fmt' in kwargs:
-            SymPyDeprecationWarning(useinstead="dummy_name",
-                                    feature="dummy_fmt", issue=17517,
-                                    deprecated_since_version="1.5").warn()
-            dummy_name = kwargs.get('dummy_fmt')
+    def __new__(cls, name, metric=False, dim=None, eps_dim=None,
+                dummy_fmt=None):
 
         if isinstance(name, string_types):
             name = Symbol(name)
-
-        if dummy_name is None:
-            dummy_name = str(name)[0]
-        if isinstance(dummy_name, string_types):
-            dummy_name = Symbol(dummy_name)
-
-        if dim is None:
-            dim = Symbol("dim_" + dummy_name.name)
+        obj = Basic.__new__(cls, name, S.One if metric else S.Zero)
+        obj._name = str(name)
+        if not dummy_fmt:
+            obj._dummy_fmt = '%s_%%d' % obj.name
         else:
-            dim = sympify(dim)
-
-        if eps_dim is None:
-            eps_dim = dim
+            obj._dummy_fmt = '%s_%%d' % dummy_fmt
+        if metric is None:
+            obj.metric_antisym = None
+            obj.metric = None
         else:
-            eps_dim = sympify(eps_dim)
-
-        metric_symmetry = sympify(metric_symmetry)
-
-        if isinstance(metric_name, string_types):
-            metric_name = Symbol(metric_name)
-
-        if 'metric' in kwargs:
-            SymPyDeprecationWarning(useinstead="metric_symmetry or .set_metric()",
-                                    feature="metric argument", issue=17517,
-                                    deprecated_since_version="1.5").warn()
-            metric = kwargs.get('metric')
-            if metric is not None:
-                if metric in (True, False, 0, 1):
-                    metric_name = 'metric'
-                    metric_antisym = metric
-                else:
-                    metric_name = metric.name
-                    metric_antisym = metric.antisym
-
-                if metric:
-                    metric_symmetry = -1
-                else:
-                    metric_symmetry = 1
-
-        obj = Basic.__new__(cls, name, dummy_name, dim, eps_dim,
-                            metric_symmetry, metric_name)
-
+            if metric in (True, False, 0, 1):
+                metric_name = 'metric'
+                obj.metric_antisym = metric
+            else:
+                metric_name = metric.name
+                obj.metric_antisym = metric.antisym
+            sym2 = TensorSymmetry(get_symmetric_group_sgs(2, obj.metric_antisym))
+            obj.metric = TensorHead(metric_name, [obj]*2, sym2)
+
+        obj._dim = dim
+        obj._delta = obj.get_kronecker_delta()
+        obj._eps_dim = eps_dim if eps_dim else dim
+        obj._epsilon = obj.get_epsilon()
         obj._autogenerated = []
         return obj
 
     @property
-    def name(self):
-        return self.args[0].name
-
-    @property
-    def dummy_name(self):
-        return self.args[1].name
+    @deprecated(useinstead="TensorIndex", issue=12857, deprecated_since_version="1.1")
+    def auto_right(self):
+        if not hasattr(self, '_auto_right'):
+            self._auto_right = TensorIndex("auto_right", self)
+        return self._auto_right
 
     @property
-    def dim(self):
-        return self.args[2]
+    @deprecated(useinstead="TensorIndex", issue=12857, deprecated_since_version="1.1")
+    def auto_left(self):
+        if not hasattr(self, '_auto_left'):
+            self._auto_left = TensorIndex("auto_left", self)
+        return self._auto_left
 
     @property
-    def eps_dim(self):
-        return self.args[3]
-
-    @memoize_property
-    def metric(self):
-        metric_symmetry = self.args[4]
-        metric_name = self.args[5]
-        if metric_symmetry is None:
-            return None
-
-        if metric_symmetry == 0:
-            symmetry = TensorSymmetry.no_symmetry(2)
-        elif metric_symmetry == 1:
-            symmetry = TensorSymmetry.fully_symmetric(2)
-        elif metric_symmetry == -1:
-            symmetry = TensorSymmetry.fully_symmetric(-2)
-
-        return TensorHead(metric_name, [self]*2, symmetry)
-
-    @memoize_property
-    def delta(self):
-        return TensorHead('KD', [self]*2, TensorSymmetry.fully_symmetric(2))
-
-    @memoize_property
-    def epsilon(self):
-        if not isinstance(self.eps_dim, (SYMPY_INTS, Integer)):
-            return None
-        symmetry = TensorSymmetry.fully_symmetric(-self.eps_dim)
-        return TensorHead('Eps', [self]*self.eps_dim, symmetry)
-
-    def set_metric(self, tensor):
-        self._metric = tensor
-
-    def __lt__(self, other):
-        return self.name < other.name
-
-    def __str__(self):
-        return self.name
-
-    __repr__ = __str__
-
-    # Everything below this line is deprecated
+    @deprecated(useinstead="TensorIndex", issue=12857, deprecated_since_version="1.1")
+    def auto_index(self):
+        if not hasattr(self, '_auto_index'):
+            self._auto_index = TensorIndex("auto_index", self)
+        return self._auto_index
 
     @property
     def data(self):
@@ -1102,7 +1035,7 @@ def data(self, data):
         if data.rank() > 2:
             raise ValueError("data have to be of rank 1 (diagonal metric) or 2.")
         if data.rank() == 1:
-            if self.dim.is_number:
+            if self.dim is not None:
                 nda_dim = data.shape[0]
                 if nda_dim != self.dim:
                     raise ValueError("Dimension mismatch")
@@ -1115,7 +1048,7 @@ def data(self, data):
         dim1, dim2 = data.shape
         if dim1 != dim2:
             raise ValueError("Non-square matrix tensor.")
-        if self.dim.is_number:
+        if self.dim is not None:
             if self.dim != dim1:
                 raise ValueError("Dimension mismatch")
         _tensor_data_substitution_dict[self] = data
@@ -1133,15 +1066,38 @@ def data(self):
         if self.metric in _tensor_data_substitution_dict:
             del _tensor_data_substitution_dict[self.metric]
 
-    @deprecated(useinstead=".delta", issue=17517,
-                deprecated_since_version="1.5")
+    def _get_matrix_fmt(self, number):
+        return ("m" + self.dummy_fmt) % (number)
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def dim(self):
+        return self._dim
+
+    @property
+    def delta(self):
+        return self._delta
+
+    @property
+    def eps_dim(self):
+        return self._eps_dim
+
+    @property
+    def epsilon(self):
+        return self._epsilon
+
+    @property
+    def dummy_fmt(self):
+        return self._dummy_fmt
+
     def get_kronecker_delta(self):
         sym2 = TensorSymmetry(get_symmetric_group_sgs(2))
         delta = TensorHead('KD', [self]*2, sym2)
         return delta
 
-    @deprecated(useinstead=".delta", issue=17517,
-                deprecated_since_version="1.5")
     def get_epsilon(self):
         if not isinstance(self._eps_dim, (SYMPY_INTS, Integer)):
             return None
@@ -1149,6 +1105,14 @@ def get_epsilon(self):
         epsilon = TensorHead('Eps', [self]*self._eps_dim, sym)
         return epsilon
 
+    def __lt__(self, other):
+        return self.name < other.name
+
+    def __str__(self):
+        return self.name
+
+    __repr__ = __str__
+
     def _components_data_full_destroy(self):
         """
         EXPERIMENTAL: do not rely on this API method.
@@ -1186,14 +1150,14 @@ class TensorIndex(Basic):
     ==========
 
     name : name of the index, or ``True`` if you want it to be automatically assigned
-    tensor_index_type : ``TensorIndexType`` of the index
+    tensortype : ``TensorIndexType`` of the index
     is_up :  flag for contravariant index (is_up=True by default)
 
     Attributes
     ==========
 
     ``name``
-    ``tensor_index_type``
+    ``tensortype``
     ``is_up``
 
     Notes
@@ -1205,8 +1169,7 @@ class TensorIndex(Basic):
     case it is represented prepending a ``-`` to the index name. Adding
     ``-`` to a covariant (is_up=False) index makes it contravariant.
 
-    Dummy indices have a name with head given by
-    ``tensor_inde_type.dummy_name`` with underscore and a number.
+    Dummy indices have a name with head given by ``tensortype._dummy_fmt``
 
     Similar to ``symbols`` multiple contravariant indices can be created
     at once using ``tensor_indices(s, typ)``, where ``s`` is a string
@@ -1217,7 +1180,7 @@ class TensorIndex(Basic):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType, TensorIndex, TensorHead, tensor_indices
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> mu = TensorIndex('mu', Lorentz, is_up=False)
     >>> nu, rho = tensor_indices('nu, rho', Lorentz)
     >>> A = TensorHead('A', [Lorentz, Lorentz])
@@ -1228,42 +1191,50 @@ class TensorIndex(Basic):
     >>> A(mu, -mu)
     A(-L_0, L_0)
     """
-    def __new__(cls, name, tensor_index_type, is_up=True):
+    def __new__(cls, name, tensortype, is_up=True):
         if isinstance(name, string_types):
             name_symbol = Symbol(name)
         elif isinstance(name, Symbol):
             name_symbol = name
         elif name is True:
-            name = "_i{0}".format(len(tensor_index_type._autogenerated))
+            name = "_i{0}".format(len(tensortype._autogenerated))
             name_symbol = Symbol(name)
-            tensor_index_type._autogenerated.append(name_symbol)
+            tensortype._autogenerated.append(name_symbol)
         else:
             raise ValueError("invalid name")
 
         is_up = sympify(is_up)
-        return Basic.__new__(cls, name_symbol, tensor_index_type, is_up)
+        obj = Basic.__new__(cls, name_symbol, tensortype, is_up)
+        obj._name = str(name)
+        obj._tensor_index_type = tensortype
+        obj._is_up = is_up
+        return obj
 
     @property
     def name(self):
-        return self.args[0].name
+        return self._name
+
+    @property
+    @deprecated(useinstead="tensor_index_type", issue=12857, deprecated_since_version="1.1")
+    def tensortype(self):
+        return self.tensor_index_type
 
     @property
     def tensor_index_type(self):
-        return self.args[1]
+        return self._tensor_index_type
 
     @property
     def is_up(self):
-        return self.args[2]
+        return self._is_up
 
     def _print(self):
-        s = self.name
-        if not self.is_up:
+        s = self._name
+        if not self._is_up:
             s = '-%s' % s
         return s
 
     def __lt__(self, other):
-        return ((self.tensor_index_type, self.name) <
-                (other.tensor_index_type, other.name))
+        return (self.tensor_index_type, self._name) < (other.tensor_index_type, other._name)
 
     def __neg__(self):
         t1 = TensorIndex(self.name, self.tensor_index_type,
@@ -1286,7 +1257,7 @@ def tensor_indices(s, typ):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
     """
     if isinstance(s, string_types):
@@ -1338,7 +1309,7 @@ class TensorSymmetry(Basic):
     Define a symmetric tensor of rank 2
 
     >>> from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, TensorHead
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> sym = TensorSymmetry(get_symmetric_group_sgs(2))
     >>> T = TensorHead('T', [Lorentz]*2, sym)
 
@@ -1360,20 +1331,8 @@ def __new__(cls, *args, **kw_args):
             base = Tuple(*base)
         if not isinstance(generators, Tuple):
             generators = Tuple(*generators)
-
-        return Basic.__new__(cls, base, generators, **kw_args)
-
-    @property
-    def base(self):
-        return self.args[0]
-
-    @property
-    def generators(self):
-        return self.args[1]
-
-    @property
-    def rank(self):
-        return self.generators[0].size - 2
+        obj = Basic.__new__(cls, base, generators, **kw_args)
+        return obj
 
     @classmethod
     def fully_symmetric(cls, rank):
@@ -1431,6 +1390,18 @@ def no_symmetry(cls, rank):
         """
         return TensorSymmetry([], [Permutation(rank+1)])
 
+    @property
+    def base(self):
+        return self.args[0]
+
+    @property
+    def generators(self):
+        return self.args[1]
+
+    @property
+    def rank(self):
+        return self.args[1][0].size - 2
+
 
 @deprecated(useinstead="TensorSymmetry class constructor and methods", issue=17108,
             deprecated_since_version="1.5")
@@ -1621,7 +1592,7 @@ class TensorHead(Basic):
     Define a fully antisymmetric tensor of rank 2:
 
     >>> from sympy.tensor.tensor import TensorIndexType, TensorHead, TensorSymmetry
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> asym2 = TensorSymmetry.fully_symmetric(-2)
     >>> A = TensorHead('A', [Lorentz, Lorentz], asym2)
 
@@ -1633,7 +1604,7 @@ class TensorHead(Basic):
 
     >>> from sympy.tensor.tensor import tensor_indices
     >>> from sympy import diag
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> i0, i1 = tensor_indices('i0:2', Lorentz)
 
     Specify a replacement dictionary to keep track of the arrays to use for
@@ -1708,8 +1679,10 @@ def __new__(cls, name, index_types, symmetry=None, comm=0):
         else:
             assert symmetry.rank == len(index_types)
 
+        comm2i = TensorManager.comm_symbols2i(comm)
+
         obj = Basic.__new__(cls, name_symbol, Tuple(*index_types), symmetry)
-        obj.comm = TensorManager.comm_symbols2i(comm)
+        obj._comm = comm2i
         return obj
 
     @property
@@ -1717,16 +1690,20 @@ def name(self):
         return self.args[0].name
 
     @property
-    def index_types(self):
-        return list(self.args[1])
+    def rank(self):
+        return len(self.args[1])
 
     @property
     def symmetry(self):
         return self.args[2]
 
     @property
-    def rank(self):
-        return len(self.index_types)
+    def comm(self):
+        return self._comm
+
+    @property
+    def index_types(self):
+        return self.args[1]
 
     def __lt__(self, other):
         return (self.name, self.index_types) < (other.name, other.index_types)
@@ -1737,7 +1714,7 @@ def commutes_with(self, other):
 
         Returns ``None`` if ``self`` and ``other`` neither commute nor anticommute.
         """
-        r = TensorManager.get_comm(self.comm, other.comm)
+        r = TensorManager.get_comm(self._comm, other._comm)
         return r
 
     def _print(self):
@@ -1759,7 +1736,7 @@ def __call__(self, *indices, **kw_args):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorSymmetry, TensorHead
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> a, b = tensor_indices('a,b', Lorentz)
         >>> A = TensorHead('A', [Lorentz]*2, TensorSymmetry.no_symmetry(2))
         >>> t = A(a, -b)
@@ -1770,8 +1747,6 @@ def __call__(self, *indices, **kw_args):
         tensor = Tensor(self, indices, **kw_args)
         return tensor.doit()
 
-    # Everything below this line is deprecated
-
     def __pow__(self, other):
         with warnings.catch_warnings():
             warnings.filterwarnings("ignore", category=SymPyDeprecationWarning)
@@ -1900,7 +1875,7 @@ def __mul__(self, other):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
         >>> g = Lorentz.metric
         >>> p, q = tensor_heads('p,q', [Lorentz])
@@ -2195,7 +2170,7 @@ def replace_with_arrays(self, replacement_dict, indices=None):
             else:
                 expected_shape = [index_type.dim for index_type in tensor.index_types]
             if len(expected_shape) != array.rank() or (not all([dim1 == dim2 if
-                dim1.is_number else True for dim1, dim2 in zip(expected_shape,
+                dim1 is not None else True for dim1, dim2 in zip(expected_shape,
                 array.shape)])):
                 raise ValueError("shapes for tensor %s expected to be %s, "\
                     "replacement array shape is %s" % (tensor, expected_shape,
@@ -2244,7 +2219,7 @@ class TensAdd(TensExpr, AssocOp):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType, tensor_heads, tensor_indices
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> a, b = tensor_indices('a,b', Lorentz)
     >>> p, q = tensor_heads('p,q', [Lorentz])
     >>> t = p(a) + q(a); t
@@ -2268,34 +2243,11 @@ class TensAdd(TensExpr, AssocOp):
 
     def __new__(cls, *args, **kw_args):
         args = [_sympify(x) for x in args if x]
-        args = TensAdd._tensAdd_flatten(args)
-        if not args:
-            return S.Zero
-        if len(args) == 1:
-            return args[0]
-
-        return Basic.__new__(cls, *args, **kw_args)
 
-    @memoize_property
-    def rank(self):
-        if isinstance(self.args[0], TensExpr):
-            return self.args[0].rank
-        else:
-            return 0
-
-    @memoize_property
-    def free_args(self):
-        if isinstance(self.args[0], TensExpr):
-            return self.args[0].free_args
-        else:
-            return []
+        args = TensAdd._tensAdd_flatten(args)
 
-    @memoize_property
-    def free_indices(self):
-        if isinstance(self.args[0], TensExpr):
-            return self.args[0].free_indices
-        else:
-            return set()
+        obj = Basic.__new__(cls, *args, **kw_args)
+        return obj
 
     def doit(self, **kwargs):
         deep = kwargs.get('deep', True)
@@ -2403,6 +2355,14 @@ def get_indices(self):
             indices.extend([i for i in get_indices(arg) if i not in indices])
         return indices
 
+    @property
+    def rank(self):
+        return self.args[0].rank
+
+    @property
+    def free_args(self):
+        return self.args[0].free_args
+
     def _expand(self, **hints):
         return TensAdd(*[_expand(i, **hints) for i in self.args])
 
@@ -2431,8 +2391,8 @@ def canon_bp(self):
 
     def equals(self, other):
         other = _sympify(other)
-        if isinstance(other, TensMul) and other.coeff == 0:
-            return all(x.coeff == 0 for x in self.args)
+        if isinstance(other, TensMul) and other._coeff == 0:
+            return all(x._coeff == 0 for x in self.args)
         if isinstance(other, TensExpr):
             if self.rank != other.rank:
                 return False
@@ -2446,9 +2406,9 @@ def equals(self, other):
             return t == 0
         else:
             if isinstance(t, TensMul):
-                return t.coeff == 0
+                return t._coeff == 0
             else:
-                return all(x.coeff == 0 for x in t.args)
+                return all(x._coeff == 0 for x in t.args)
 
     def __getitem__(self, item):
         deprecate_data()
@@ -2552,7 +2512,7 @@ class Tensor(TensExpr):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead
-    >>> Lorentz = TensorIndexType("Lorentz", dummy_name="L")
+    >>> Lorentz = TensorIndexType("Lorentz", dummy_fmt="L")
     >>> mu, nu = tensor_indices('mu nu', Lorentz)
     >>> A = TensorHead("A", [Lorentz, Lorentz])
     >>> A(mu, -nu)
@@ -2578,40 +2538,16 @@ def __new__(cls, tensor_head, indices, **kw_args):
         is_canon_bp = kw_args.pop('is_canon_bp', False)
         indices = cls._parse_indices(tensor_head, indices)
         obj = Basic.__new__(cls, tensor_head, Tuple(*indices), **kw_args)
+        obj.head = tensor_head
         obj._index_structure = _IndexStructure.from_indices(*indices)
-        obj.free = obj._index_structure.free[:]
-        obj.dum = obj._index_structure.dum[:]
-        obj.ext_rank = obj._index_structure._ext_rank
-        obj.coeff = S.One
-        obj.nocoeff = obj
-        obj.component = tensor_head
-        obj.components = [tensor_head]
+        obj._free_indices_set = set(obj._index_structure.get_free_indices())
         if tensor_head.rank != len(indices):
             raise ValueError("wrong number of indices")
-        obj.is_canon_bp = is_canon_bp
+        obj._indices = indices
+        obj._is_canon_bp = is_canon_bp
         obj._index_map = Tensor._build_index_map(indices, obj._index_structure)
         return obj
 
-    @property
-    def head(self):
-        return self.args[0]
-
-    @property
-    def indices(self):
-        return self.args[1]
-
-    @property
-    def free_indices(self):
-        return set(self._index_structure.get_free_indices())
-
-    @property
-    def index_types(self):
-        return self.head.index_types
-
-    @property
-    def rank(self):
-        return len(self.free_indices)
-
     @staticmethod
     def _build_index_map(indices, index_structure):
         index_map = {}
@@ -2660,14 +2596,38 @@ def _get_dummy_indices_set(self):
     def _get_indices_set(self):
         return set(self.args[1].args)
 
+    @property
+    def is_canon_bp(self):
+        return self._is_canon_bp
+
+    @property
+    def indices(self):
+        return self._indices
+
+    @property
+    def free(self):
+        return self._index_structure.free[:]
+
     @property
     def free_in_args(self):
         return [(ind, pos, 0) for ind, pos in self.free]
 
+    @property
+    def dum(self):
+        return self._index_structure.dum[:]
+
     @property
     def dum_in_args(self):
         return [(p1, p2, 0, 0) for p1, p2 in self.dum]
 
+    @property
+    def rank(self):
+        return len(self.free)
+
+    @property
+    def ext_rank(self):
+        return self._index_structure._ext_rank
+
     @property
     def free_args(self):
         return sorted([x[0] for x in self.free])
@@ -2695,7 +2655,7 @@ def perm2tensor(self, g, is_canon_bp=False):
         return perm2tensor(self, g, is_canon_bp)
 
     def canon_bp(self):
-        if self.is_canon_bp:
+        if self._is_canon_bp:
             return self
         expr = self.expand()
         g, dummies, msym = expr._index_structure.indices_canon_args()
@@ -2706,6 +2666,26 @@ def canon_bp(self):
         tensor = self.perm2tensor(can, True)
         return tensor
 
+    @property
+    def index_types(self):
+        return list(self.component.index_types)
+
+    @property
+    def coeff(self):
+        return S.One
+
+    @property
+    def nocoeff(self):
+        return self
+
+    @property
+    def component(self):
+        return self.args[0]
+
+    @property
+    def components(self):
+        return [self.args[0]]
+
     def split(self):
         return [self]
 
@@ -2740,7 +2720,7 @@ def substitute_indices(self, *index_tuples):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads, TensorSymmetry
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz)
         >>> A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
         >>> t = A(i, k)*B(-k, -j); t
@@ -2876,24 +2856,20 @@ def contract_metric(self, g):
         if len(self.free) != 0:
             return self
 
-        #antisym = g.index_types[0].metric_antisym
-        if g.symmetry == TensorSymmetry.fully_symmetric(-2):
-            antisym = 1
-        elif g.symmetry == TensorSymmetry.fully_symmetric(2):
-            antisym = 0
-        elif g.symmetry == TensorSymmetry.no_symmetry(2):
-            antisym = None
-        else:
-            raise NotImplementedError
+        antisym = g.index_types[0].metric_antisym
         sign = S.One
         typ = g.index_types[0]
 
         if not antisym:
             # g(i, -i)
-            sign = sign*typ.dim
+            if typ._dim is None:
+                raise ValueError('dimension not assigned')
+            sign = sign*typ._dim
         else:
             # g(i, -i)
-            sign = sign*typ.dim
+            if typ._dim is None:
+                raise ValueError('dimension not assigned')
+            sign = sign*typ._dim
 
             dp0, dp1 = self.dum[0]
             if dp0 < dp1:
@@ -2969,14 +2945,10 @@ def __new__(cls, *args, **kw_args):
 
         obj = TensExpr.__new__(cls, *args)
         obj._indices = indices
-        obj.index_types = index_types[:]
+        obj._index_types = index_types
         obj._index_structure = index_structure
-        obj.free = index_structure.free[:]
-        obj.dum = index_structure.dum[:]
-        obj.free_indices = set([x[0] for x in obj.free])
-        obj.rank = len(obj.free)
-        obj.ext_rank = len(obj._index_structure.free) + 2*len(obj._index_structure.dum)
-        obj.coeff = S.One
+        obj._ext_rank = len(obj._index_structure.free) + 2*len(obj._index_structure.dum)
+        obj._coeff = S.One
         obj._is_canon_bp = is_canon_bp
         return obj
 
@@ -3042,16 +3014,17 @@ def _tensMul_contract_indices(args, replace_indices=True):
 
         cdt = defaultdict(int)
 
-        def dummy_name_gen(tensor_index_type):
-            nd = str(cdt[tensor_index_type])
+        def dummy_fmt_gen(tensor_index_type):
+            fmt = tensor_index_type.dummy_fmt
+            nd = cdt[tensor_index_type]
             cdt[tensor_index_type] += 1
-            return tensor_index_type.dummy_name + '_' + nd
+            return fmt % nd
 
         if replace_indices:
             for old_index, pos1cov, pos1contra, pos2cov, pos2contra in dummy_data:
                 index_type = old_index.tensor_index_type
                 while True:
-                    dummy_name = dummy_name_gen(index_type)
+                    dummy_name = dummy_fmt_gen(index_type)
                     if dummy_name not in free_names:
                         break
                 dummy = TensorIndex(dummy_name, index_type, True)
@@ -3125,8 +3098,8 @@ def doit(self, **kwargs):
         obj = self.func(*args)
         obj._index_types = index_types
         obj._index_structure = index_structure
-        obj.ext_rank = len(obj._index_structure.free) + 2*len(obj._index_structure.dum)
-        obj.coeff = coeff
+        obj._ext_rank = len(obj._index_structure.free) + 2*len(obj._index_structure.dum)
+        obj._coeff = coeff
         obj._is_canon_bp = is_canon_bp
         return obj
 
@@ -3179,29 +3152,53 @@ def free_args(self):
     def components(self):
         return self._get_components_from_args(self.args)
 
+    @property
+    def free(self):
+        return self._index_structure.free[:]
+
     @property
     def free_in_args(self):
         arg_offset = self._get_position_offset_for_indices()
         argpos = self._get_indices_to_args_pos()
         return [(ind, pos-arg_offset[pos], argpos[pos]) for (ind, pos) in self.free]
 
+    @property
+    def coeff(self):
+        return self._coeff
+
     @property
     def nocoeff(self):
         return self.func(*[t for t in self.args if isinstance(t, TensExpr)]).doit()
 
+    @property
+    def dum(self):
+        return self._index_structure.dum[:]
+
     @property
     def dum_in_args(self):
         arg_offset = self._get_position_offset_for_indices()
         argpos = self._get_indices_to_args_pos()
         return [(p1-arg_offset[p1], p2-arg_offset[p2], argpos[p1], argpos[p2]) for p1, p2 in self.dum]
 
+    @property
+    def rank(self):
+        return len(self.free)
+
+    @property
+    def ext_rank(self):
+        return self._ext_rank
+
+    @property
+    def index_types(self):
+        return self._index_types[:]
+
     def equals(self, other):
         if other == 0:
             return self.coeff == 0
         other = _sympify(other)
         if not isinstance(other, TensExpr):
             assert not self.components
-            return self.coeff == other
+            return self._coeff == other
 
         return self.canon_bp() == other.canon_bp()
 
@@ -3218,7 +3215,7 @@ def get_indices(self):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
         >>> g = Lorentz.metric
         >>> p, q = tensor_heads('p,q', [Lorentz])
@@ -3242,7 +3239,7 @@ def get_free_indices(self):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
         >>> g = Lorentz.metric
         >>> p, q = tensor_heads('p,q', [Lorentz])
@@ -3267,7 +3264,7 @@ def split(self):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads, TensorSymmetry
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
         >>> A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
         >>> t = A(a,b)*B(-b,c)
@@ -3370,7 +3367,7 @@ def canon_bp(self):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead, TensorSymmetry
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
         >>> A = TensorHead('A', [Lorentz]*2, TensorSymmetry.fully_symmetric(-2))
         >>> t = A(m0,-m1)*A(m1,-m0)
@@ -3433,7 +3430,7 @@ def contract_metric(self, g):
         ========
 
         >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensor_heads
-        >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+        >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
         >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz)
         >>> g = Lorentz.metric
         >>> p, q = tensor_heads('p,q', [Lorentz])
@@ -3450,15 +3447,7 @@ def contract_metric(self, g):
         pos_map = self._get_indices_to_args_pos()
         args = list(self.args)
 
-        #antisym = g.index_types[0].metric_antisym
-        if g.symmetry == TensorSymmetry.fully_symmetric(-2):
-            antisym = 1
-        elif g.symmetry == TensorSymmetry.fully_symmetric(2):
-            antisym = 0
-        elif g.symmetry == TensorSymmetry.no_symmetry(2):
-            antisym = None
-        else:
-            raise NotImplementedError
+        antisym = g.index_types[0].metric_antisym
 
         # list of positions of the metric ``g`` inside ``args``
         gpos = [i for i, x in enumerate(self.args) if isinstance(x, Tensor) and x.component == g]
@@ -3528,7 +3517,9 @@ def contract_metric(self, g):
                     if pos_map[dp0] == pos_map[dp1]:
                         # g(i, -i)
                         typ = g.index_types[0]
-                        sign = sign*typ.dim
+                        if typ._dim is None:
+                            raise ValueError('dimension not assigned')
+                        sign = sign*typ._dim
 
                     else:
                         # g(i0, i1)*p(-i1)
@@ -3544,7 +3535,9 @@ def contract_metric(self, g):
                     if pos_map[dp0] == pos_map[dp1]:
                         # g(i, -i)
                         typ = g.index_types[0]
-                        sign = sign*typ.dim
+                        if typ._dim is None:
+                            raise ValueError('dimension not assigned')
+                        sign = sign*typ._dim
 
                         if dp0 < dp1:
                             # g(i, -i) = -D with antisymmetric metric
@@ -3794,7 +3787,7 @@ def riemann_cyclic(t2):
     ========
 
     >>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead, riemann_cyclic, TensorSymmetry
-    >>> Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz)
     >>> R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
     >>> t = R(i,j,k,l)*(R(-i,-j,-k,-l) - 2*R(-i,-k,-j,-l))


Test patch:
diff --git a/sympy/core/tests/test_args.py b/sympy/core/tests/test_args.py
index c810c648f9..8bed41576d 100644
--- a/sympy/core/tests/test_args.py
+++ b/sympy/core/tests/test_args.py
@@ -4085,7 +4085,7 @@ def test_sympy__tensor__indexed__IndexedBase():
 
 def test_sympy__tensor__tensor__TensorIndexType():
     from sympy.tensor.tensor import TensorIndexType
-    assert _test_args(TensorIndexType('Lorentz'))
+    assert _test_args(TensorIndexType('Lorentz', metric=False))
 
 
 @SKIP("deprecated class")
@@ -4100,14 +4100,14 @@ def test_sympy__tensor__tensor__TensorSymmetry():
 
 def test_sympy__tensor__tensor__TensorHead():
     from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, TensorHead
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     sym = TensorSymmetry(get_symmetric_group_sgs(1))
     assert _test_args(TensorHead('p', [Lorentz], sym, 0))
 
 
 def test_sympy__tensor__tensor__TensorIndex():
     from sympy.tensor.tensor import TensorIndexType, TensorIndex
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     assert _test_args(TensorIndex('i', Lorentz))
 
 @SKIP("abstract class")
@@ -4116,7 +4116,7 @@ def test_sympy__tensor__tensor__TensExpr():
 
 def test_sympy__tensor__tensor__TensAdd():
     from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, tensor_indices, TensAdd, tensor_heads
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b = tensor_indices('a,b', Lorentz)
     sym = TensorSymmetry(get_symmetric_group_sgs(1))
     p, q = tensor_heads('p,q', [Lorentz], sym)
@@ -4127,7 +4127,7 @@ def test_sympy__tensor__tensor__TensAdd():
 
 def test_sympy__tensor__tensor__Tensor():
     from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, tensor_indices, TensorHead
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b = tensor_indices('a,b', Lorentz)
     sym = TensorSymmetry(get_symmetric_group_sgs(1))
     p = TensorHead('p', [Lorentz], sym)
@@ -4136,7 +4136,7 @@ def test_sympy__tensor__tensor__Tensor():
 
 def test_sympy__tensor__tensor__TensMul():
     from sympy.tensor.tensor import TensorIndexType, TensorSymmetry, get_symmetric_group_sgs, tensor_indices, tensor_heads
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b = tensor_indices('a,b', Lorentz)
     sym = TensorSymmetry(get_symmetric_group_sgs(1))
     p, q = tensor_heads('p, q', [Lorentz], sym)
@@ -4154,7 +4154,7 @@ def test_sympy__tensor__tensor__TensorElement():
 def test_sympy__tensor__toperators__PartialDerivative():
     from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorHead
     from sympy.tensor.toperators import PartialDerivative
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b = tensor_indices('a,b', Lorentz)
     A = TensorHead("A", [Lorentz])
     assert _test_args(PartialDerivative(A(a), A(b)))
diff --git a/sympy/functions/elementary/tests/test_hyperbolic.py b/sympy/functions/elementary/tests/test_hyperbolic.py
index c54efdca09..82580eb094 100644
--- a/sympy/functions/elementary/tests/test_hyperbolic.py
+++ b/sympy/functions/elementary/tests/test_hyperbolic.py
@@ -1104,21 +1104,21 @@ def test_cosh_positive():
     k = symbols('k', real=True)
     n = symbols('n', integer=True)
 
-    assert cosh(k, evaluate=False).is_positive is True
-    assert cosh(k + 2*n*pi*I, evaluate=False).is_positive is True
-    assert cosh(I*pi/4, evaluate=False).is_positive is True
-    assert cosh(3*I*pi/4, evaluate=False).is_positive is False
+    assert cosh(k).is_positive is True
+    assert cosh(k + 2*n*pi*I).is_positive is True
+    assert cosh(I*pi/4).is_positive is True
+    assert cosh(3*I*pi/4).is_positive is False
 
 def test_cosh_nonnegative():
     x = symbols('x')
     k = symbols('k', real=True)
     n = symbols('n', integer=True)
 
-    assert cosh(k, evaluate=False).is_nonnegative is True
-    assert cosh(k + 2*n*pi*I, evaluate=False).is_nonnegative is True
-    assert cosh(I*pi/4, evaluate=False).is_nonnegative is True
-    assert cosh(3*I*pi/4, evaluate=False).is_nonnegative is False
-    assert cosh(S.Zero, evaluate=False).is_nonnegative is True
+    assert cosh(k).is_nonnegative is True
+    assert cosh(k + 2*n*pi*I).is_nonnegative is True
+    assert cosh(I*pi/4).is_nonnegative is True
+    assert cosh(3*I*pi/4).is_nonnegative is False
+    assert cosh(S.Zero).is_nonnegative is True
 
 def test_real_assumptions():
     z = Symbol('z', real=False)
diff --git a/sympy/printing/tests/test_repr.py b/sympy/printing/tests/test_repr.py
index dc9ce7bb58..301bf46596 100644
--- a/sympy/printing/tests/test_repr.py
+++ b/sympy/printing/tests/test_repr.py
@@ -302,4 +302,7 @@ def test_Cycle():
 
 def test_Permutation():
     import_stmt = "from sympy.combinatorics import Permutation"
+    print_cyclic = Permutation.print_cyclic
+    Permutation.print_cyclic = True
     sT(Permutation(1, 2), "Permutation(1, 2)", import_stmt)
+    Permutation.print_cyclic = print_cyclic
diff --git a/sympy/tensor/tests/test_tensor.py b/sympy/tensor/tests/test_tensor.py
index 4a2750a66e..941589b052 100644
--- a/sympy/tensor/tests/test_tensor.py
+++ b/sympy/tensor/tests/test_tensor.py
@@ -37,7 +37,7 @@ def _is_equal(arg1, arg2):
 #################### Tests from tensor_can.py #######################
 def test_canonicalize_no_slot_sym():
     # A_d0 * B^d0; T_c = A^d0*B_d0
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, d0, d1 = tensor_indices('a,b,d0,d1', Lorentz)
     A, B = tensor_heads('A,B', [Lorentz], TensorSymmetry.no_symmetry(1))
     t = A(-d0)*B(d0)
@@ -113,7 +113,7 @@ def test_canonicalize_no_slot_sym():
     assert str(tc) == 'A(L_0, L_1)*B(-a, -L_0)*C(-b, -L_1)'
 
 def test_canonicalize_no_dummies():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, c, d = tensor_indices('a, b, c, d', Lorentz)
 
     # A commuting
@@ -166,7 +166,7 @@ def test_no_metric_symmetry():
     # no metric symmetry; A no symmetry
     # A^d1_d0 * A^d0_d1
     # T_c = A^d0_d1 * A^d1_d0
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L', metric_symmetry=0)
+    Lorentz = TensorIndexType('Lorentz', metric=None, dummy_fmt='L')
     d0, d1, d2, d3 = tensor_indices('d:4', Lorentz)
     A = TensorHead('A', [Lorentz]*2, TensorSymmetry.no_symmetry(2))
     t = A(d1, -d0)*A(d0, -d1)
@@ -186,7 +186,7 @@ def test_no_metric_symmetry():
     assert str(tc) == 'A(L_0, -L_1)*A(L_1, -L_2)*A(L_2, -L_3)*A(L_3, -L_0)'
 
 def test_canonicalize1():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, a0, a1, a2, a3, b, d0, d1, d2, d3 = \
         tensor_indices('a,a0,a1,a2,a3,b,d0,d1,d2,d3', Lorentz)
 
@@ -266,7 +266,7 @@ def test_canonicalize1():
     # A anticommuting symmetric, B antisymmetric commuting, antisymmetric metric
     # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
     # T_c = -A^{d0 d1 d2} * A_{d0 d1}^d3 * B_{d2 d3}
-    Spinor = TensorIndexType('Spinor', dummy_name='S', metric_symmetry=-1)
+    Spinor = TensorIndexType('Spinor', metric=1, dummy_fmt='S')
     a, a0, a1, a2, a3, b, d0, d1, d2, d3 = \
         tensor_indices('a,a0,a1,a2,a3,b,d0,d1,d2,d3', Spinor)
     A = TensorHead('A', [Spinor]*3, TensorSymmetry.fully_symmetric(3), 1)
@@ -279,7 +279,7 @@ def test_canonicalize1():
     # no metric symmetry
     # A^{d0 d1 d2} * A_{d2 d3 d1} * B_d0^d3
     # T_c = A^{d0 d1 d2} * A_{d0 d1 d3} * B_d2^d3
-    Mat = TensorIndexType('Mat', metric_symmetry=0, dummy_name='M')
+    Mat = TensorIndexType('Mat', metric=None, dummy_fmt='M')
     a, a0, a1, a2, a3, b, d0, d1, d2, d3 = \
         tensor_indices('a,a0,a1,a2,a3,b,d0,d1,d2,d3', Mat)
     A = TensorHead('A', [Mat]*3, TensorSymmetry.fully_symmetric(3), 1)
@@ -313,7 +313,7 @@ def test_canonicalize1():
     # f^c_{d a} * f_{c e b} * A_mu^d * A_nu^a * A^{nu e} * A^{mu b}
     # g = [8,11,5, 9,13,7, 1,10, 3,4, 2,12, 0,6, 14,15]
     # T_c = -f^{a b c} * f_a^{d e} * A^mu_b * A_{mu d} * A^nu_c * A_{nu e}
-    Flavor = TensorIndexType('Flavor', dummy_name='F')
+    Flavor = TensorIndexType('Flavor', dummy_fmt='F')
     a, b, c, d, e, ff = tensor_indices('a,b,c,d,e,f', Flavor)
     mu, nu = tensor_indices('mu,nu', Lorentz)
     f = TensorHead('f', [Flavor]*3, TensorSymmetry.direct_product(1, -2))
@@ -333,7 +333,7 @@ def test_bug_correction_tensor_indices():
 
 
 def test_riemann_invariants():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11 = \
         tensor_indices('d0:12', Lorentz)
     # R^{d0 d1}_{d1 d0}; ord = [d0,-d0,d1,-d1]
@@ -356,7 +356,7 @@ def test_riemann_invariants():
     assert str(tc) == 'R(L_0, L_1, L_2, L_3)*R(-L_0, -L_1, L_4, L_5)*R(-L_2, -L_3, L_6, L_7)*R(-L_4, -L_5, L_8, L_9)*R(-L_6, -L_7, L_10, L_11)*R(-L_8, -L_9, -L_10, -L_11)'
 
 def test_riemann_products():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     d0, d1, d2, d3, d4, d5, d6 = tensor_indices('d0:7', Lorentz)
     a0, a1, a2, a3, a4, a5 = tensor_indices('a0:6', Lorentz)
     a, b = tensor_indices('a,b', Lorentz)
@@ -397,7 +397,7 @@ def test_riemann_products():
 
 def test_canonicalize2():
     D = Symbol('D')
-    Eucl = TensorIndexType('Eucl', metric_symmetry=1, dim=D, dummy_name='E')
+    Eucl = TensorIndexType('Eucl', metric=0, dim=D, dummy_fmt='E')
     i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14 = \
         tensor_indices('i0:15', Eucl)
     A = TensorHead('A', [Eucl]*3, TensorSymmetry.fully_symmetric(-3))
@@ -419,7 +419,7 @@ def test_canonicalize2():
 
 def test_canonicalize3():
     D = Symbol('D')
-    Spinor = TensorIndexType('Spinor', dim=D, metric_symmetry=-1, dummy_name='S')
+    Spinor = TensorIndexType('Spinor', dim=D, metric=True, dummy_fmt='S')
     a0,a1,a2,a3,a4 = tensor_indices('a0:5', Spinor)
     chi, psi = tensor_heads('chi,psi', [Spinor], TensorSymmetry.no_symmetry(1), 1)
 
@@ -432,10 +432,18 @@ def test_canonicalize3():
     assert t1 == -chi(a0)*psi(a1)
 
 
+class Metric(Basic):
+    def __new__(cls, name, antisym, **kwargs):
+        obj = Basic.__new__(cls, name, antisym, **kwargs)
+        obj.name = name
+        obj.antisym = antisym
+        return obj
+
+
 def test_TensorIndexType():
     D = Symbol('D')
-    Lorentz = TensorIndexType('Lorentz', metric_name='g', metric_symmetry=1,
-                              dim=D, dummy_name='L')
+    G = Metric('g', False)
+    Lorentz = TensorIndexType('Lorentz', metric=G, dim=D, dummy_fmt='L')
     m0, m1, m2, m3, m4 = tensor_indices('m0:5', Lorentz)
     sym2 = TensorSymmetry.fully_symmetric(2)
     sym2n = TensorSymmetry(*get_symmetric_group_sgs(2))
@@ -444,14 +452,14 @@ def test_TensorIndexType():
     assert str(g) == 'g(Lorentz,Lorentz)'
     assert Lorentz.eps_dim == Lorentz.dim
 
-    TSpace = TensorIndexType('TSpace', dummy_name = 'TSpace')
+    TSpace = TensorIndexType('TSpace')
     i0, i1 = tensor_indices('i0 i1', TSpace)
     g = TSpace.metric
     A = TensorHead('A', [TSpace]*2, sym2)
     assert str(A(i0,-i0).canon_bp()) == 'A(TSpace_0, -TSpace_0)'
 
 def test_indices():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
     assert a.tensor_index_type == Lorentz
     assert a != -a
@@ -483,7 +491,7 @@ def test_TensorSymmetry():
     assert sym.generators == Tuple(Permutation(0, 1)(3, 4), Permutation(1, 2)(3, 4))
 
 def test_TensExpr():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
     g = Lorentz.metric
     A, B = tensor_heads('A B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
@@ -509,10 +517,10 @@ def test_TensExpr():
 
 def test_TensorHead():
     # simple example of algebraic expression
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     A = TensorHead('A', [Lorentz]*2)
     assert A.name == 'A'
-    assert A.index_types == [Lorentz, Lorentz]
+    assert A.index_types == Tuple(Lorentz, Lorentz)
     assert A.rank == 2
     assert A.symmetry == TensorSymmetry.no_symmetry(2)
     assert A.comm == 0
@@ -521,7 +529,7 @@ def test_add1():
     assert TensAdd().args == ()
     assert TensAdd().doit() == 0
     # simple example of algebraic expression
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a,b,d0,d1,i,j,k = tensor_indices('a,b,d0,d1,i,j,k', Lorentz)
     # A, B symmetric
     A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
@@ -603,7 +611,7 @@ def test_add1():
 
 def test_special_eq_ne():
     # test special equality cases:
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, d0, d1, i, j, k = tensor_indices('a,b,d0,d1,i,j,k', Lorentz)
     # A, B symmetric
     A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
@@ -629,7 +637,7 @@ def test_special_eq_ne():
     assert _is_equal(A(a, b), A(b, a))
 
 def test_add2():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     m, n, p, q = tensor_indices('m,n,p,q', Lorentz)
     R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
     A = TensorHead('A', [Lorentz]*3, TensorSymmetry.fully_symmetric(-3))
@@ -646,7 +654,7 @@ def test_add2():
     assert t == 0
 
 def test_add3():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     i0, i1 = tensor_indices('i0:2', Lorentz)
     E, px, py, pz = symbols('E px py pz')
     A = TensorHead('A', [Lorentz])
@@ -667,7 +675,7 @@ def test_add3():
 
 def test_mul():
     from sympy.abc import x
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
     t = TensMul.from_data(S.One, [], [], [])
     assert str(t) == '1'
@@ -703,7 +711,7 @@ def test_mul():
     raises(ValueError, lambda: A(a, b)*A(a, c))
 
 def test_substitute_indices():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     i, j, k, l, m, n, p, q = tensor_indices('i,j,k,l,m,n,p,q', Lorentz)
     A, B = tensor_heads('A,B', [Lorentz]*2, TensorSymmetry.fully_symmetric(2))
 
@@ -740,7 +748,7 @@ def test_substitute_indices():
     assert t1 == t1a
 
 def test_riemann_cyclic_replace():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     m0, m1, m2, m3 = tensor_indices('m:4', Lorentz)
     R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
     t = R(m0, m2, m1, m3)
@@ -749,7 +757,7 @@ def test_riemann_cyclic_replace():
     assert t1 == t1a
 
 def test_riemann_cyclic():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     i, j, k, l, m, n, p, q = tensor_indices('i,j,k,l,m,n,p,q', Lorentz)
     R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
     t = R(i,j,k,l) + R(i,l,j,k) + R(i,k,l,j) - \
@@ -770,7 +778,7 @@ def test_riemann_cyclic():
 
 @XFAIL
 def test_div():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     m0, m1, m2, m3 = tensor_indices('m0:4', Lorentz)
     R = TensorHead('R', [Lorentz]*4, TensorSymmetry.riemann())
     t = R(m0,m1,-m1,m3)
@@ -785,7 +793,7 @@ def test_div():
 
 def test_contract_metric1():
     D = Symbol('D')
-    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_fmt='L')
     a, b, c, d, e = tensor_indices('a,b,c,d,e', Lorentz)
     g = Lorentz.metric
     p = TensorHead('p', [Lorentz])
@@ -822,14 +830,14 @@ def test_contract_metric1():
     t2 = t1.contract_metric(g)
     assert _is_equal(t2, A(a, -a))
     assert not t2.free
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
     a, b = tensor_indices('a,b', Lorentz)
     g = Lorentz.metric
-    assert _is_equal(g(a, -a).contract_metric(g), Lorentz.dim) # no dim
+    raises(ValueError, lambda: g(a, -a).contract_metric(g)) # no dim
 
 def test_contract_metric2():
     D = Symbol('D')
-    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_fmt='L')
     a, b, c, d, e, L_0 = tensor_indices('a,b,c,d,e,L_0', Lorentz)
     g = Lorentz.metric
     p, q = tensor_heads('p,q', [Lorentz])
@@ -896,7 +904,7 @@ def test_contract_metric2():
 
 def test_metric_contract3():
     D = Symbol('D')
-    Spinor = TensorIndexType('Spinor', dim=D, metric_symmetry=-1, dummy_name='S')
+    Spinor = TensorIndexType('Spinor', dim=D, metric=True, dummy_fmt='S')
     a0, a1, a2, a3, a4 = tensor_indices('a0:5', Spinor)
     C = Spinor.metric
     chi, psi = tensor_heads('chi,psi', [Spinor], TensorSymmetry.no_symmetry(1), 1)
@@ -993,7 +1001,7 @@ def test_metric_contract3():
 
 
 def test_epsilon():
-    Lorentz = TensorIndexType('Lorentz', dim=4, dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=4, dummy_fmt='L')
     a, b, c, d, e = tensor_indices('a,b,c,d,e', Lorentz)
     epsilon = Lorentz.epsilon
     p, q, r, s = tensor_heads('p,q,r,s', [Lorentz])
@@ -1031,14 +1039,14 @@ def test_epsilon():
     assert t1 == -2*epsilon(c,d,a,b)*p(-a)*q(-b)
 
     # Test that epsilon can be create with a SymPy integer:
-    Lorentz = TensorIndexType('Lorentz', dim=Integer(4), dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=Integer(4), dummy_fmt='L')
     epsilon = Lorentz.epsilon
     assert isinstance(epsilon, TensorHead)
 
 def test_contract_delta1():
     # see Group Theory by Cvitanovic page 9
     n = Symbol('n')
-    Color = TensorIndexType('Color', dim=n, dummy_name='C')
+    Color = TensorIndexType('Color', metric=None, dim=n, dummy_fmt='C')
     a, b, c, d, e, f = tensor_indices('a,b,c,d,e,f', Color)
     delta = Color.delta
 
@@ -1077,7 +1085,7 @@ def P2(a, b, c, d):
 @filter_warnings_decorator
 def test_fun():
     D = Symbol('D')
-    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_fmt='L')
     a, b, c, d, e = tensor_indices('a,b,c,d,e', Lorentz)
     g = Lorentz.metric
 
@@ -1104,8 +1112,8 @@ def test_fun():
     assert t(b,c,d) == q(d)*p(b)*q(c)
 
 def test_TensorManager():
-    Lorentz = TensorIndexType('Lorentz', dummy_name='L')
-    LorentzH = TensorIndexType('LorentzH', dummy_name='LH')
+    Lorentz = TensorIndexType('Lorentz', dummy_fmt='L')
+    LorentzH = TensorIndexType('LorentzH', dummy_fmt='LH')
     i, j = tensor_indices('i,j', Lorentz)
     ih, jh = tensor_indices('ih,jh', LorentzH)
     p, q = tensor_heads('p q', [Lorentz])
@@ -1143,7 +1151,7 @@ def test_TensorManager():
 
 def test_hash():
     D = Symbol('D')
-    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_name='L')
+    Lorentz = TensorIndexType('Lorentz', dim=D, dummy_fmt='L')
     a, b, c, d, e = tensor_indices('a,b,c,d,e', Lorentz)
     g = Lorentz.metric
 
@@ -1588,7 +1596,7 @@ def assign(A, dat):
 
 @filter_warnings_decorator
 def test_issue_10972_TensMul_data():
-    Lorentz = TensorIndexType('Lorentz', metric_symmetry=1, dummy_name='i', dim=2)
+    Lorentz = TensorIndexType('Lorentz', metric=False, dummy_fmt='i', dim=2)
     Lorentz.data = [-1, 1]
 
     mu, nu, alpha, beta = tensor_indices('\\mu, \\nu, \\alpha, \\beta',
@@ -1612,7 +1620,7 @@ def test_issue_10972_TensMul_data():
 
 @filter_warnings_decorator
 def test_TensMul_data():
-    Lorentz = TensorIndexType('Lorentz', metric_symmetry=1, dummy_name='L', dim=4)
+    Lorentz = TensorIndexType('Lorentz', metric=False, dummy_fmt='L', dim=4)
     Lorentz.data = [-1, 1, 1, 1]
 
     mu, nu, alpha, beta = tensor_indices('\\mu, \\nu, \\alpha, \\beta',
@@ -1669,7 +1677,7 @@ def test_TensMul_data():
 
 @filter_warnings_decorator
 def test_issue_11020_TensAdd_data():
-    Lorentz = TensorIndexType('Lorentz', metric_symmetry=1, dummy_name='i', dim=2)
+    Lorentz = TensorIndexType('Lorentz', metric=False, dummy_fmt='i', dim=2)
     Lorentz.data = [-1, 1]
 
     a, b, c, d = tensor_indices('a, b, c, d', Lorentz)
@@ -1699,7 +1707,7 @@ def test_issue_11020_TensAdd_data():
 
 
 def test_index_iteration():
-    L = TensorIndexType("Lorentz", dummy_name="L")
+    L = TensorIndexType("Lorentz", dummy_fmt="L")
     i0, i1, i2, i3, i4 = tensor_indices('i0:5', L)
     L0 = tensor_indices('L_0', L)
     L1 = tensor_indices('L_1', L)