text: import os
  from typing import Tuple, Type
  
  import mpmath.libmp as mlib
  
  from sympy.external import import_module
  
  __all__ = [
      # GROUND_TYPES is either 'gmpy' or 'python' depending on which is used. If
      # gmpy is installed then it will be used unless the environment variable
      # SYMPY_GROUND_TYPES is set to something other than 'auto', 'gmpy', or
      # 'gmpy2'.
      'GROUND_TYPES',
  
      # If HAS_GMPY is 0, no supported version of gmpy is available. Otherwise,
      # HAS_GMPY will be 2 for gmpy2 if GROUND_TYPES is 'gmpy'. It used to be
      # possible for HAS_GMPY to be 1 for gmpy but gmpy is no longer supported.
      'HAS_GMPY',
  
      # SYMPY_INTS is a tuple containing the base types for valid integer types.
      # This is either (int,) or (int, type(mpz(0))) depending on GROUND_TYPES.
      'SYMPY_INTS',
  
      # MPQ is either gmpy.mpq or the Python equivalent from
      # sympy.external.pythonmpq
      'MPQ',
  
      # MPZ is either gmpy.mpz or int.
      'MPZ',
  
      # Either the gmpy or the mpmath function
      'factorial',
  
      # isqrt from gmpy or mpmath
      'sqrt',
  ]
  
  
  #
  # SYMPY_GROUND_TYPES can be gmpy, gmpy2, python or auto
  #
  GROUND_TYPES = os.environ.get('SYMPY_GROUND_TYPES', 'auto').lower()
  
  
  #
  # Try to import gmpy2 by default. If gmpy or gmpy2 is specified in
  # SYMPY_GROUND_TYPES then warn if gmpy2 is not found. In all cases there is a
  # fallback based on pure Python int and PythonMPQ that should still work fine.
  #
  if GROUND_TYPES in ('auto', 'gmpy', 'gmpy2'):
  
      # Actually import gmpy2
      gmpy = import_module('gmpy2', min_module_version='2.0.0',
                  module_version_attr='version', module_version_attr_call_args=())
  
      # Warn if user explicitly asked for gmpy but it isn't available.
      if gmpy is None and GROUND_TYPES in ('gmpy', 'gmpy2'):
          from warnings import warn
          warn("gmpy library is not installed, switching to 'python' ground types")
  
  elif GROUND_TYPES == 'python':
  
      # The user asked for python so ignore gmpy2 module.
      gmpy = None
  
  else:
  
      # Invalid value for SYMPY_GROUND_TYPES. Ignore the gmpy2 module.
      from warnings import warn
      warn("SYMPY_GROUND_TYPES environment variable unrecognised. "
           "Should be 'python', 'auto', 'gmpy', or 'gmpy2'")
      gmpy = None
  
  
  #
  # At this point gmpy will be None if gmpy2 was not successfully imported or if
  # the environment variable SYMPY_GROUND_TYPES was set to 'python' (or some
  # unrecognised value). The two blocks below define the values exported by this
  # module in each case.
  #
  SYMPY_INTS: Tuple[Type, ...]
  
  if gmpy is not None:
  
      HAS_GMPY = 2
      GROUND_TYPES = 'gmpy'
      SYMPY_INTS = (int, type(gmpy.mpz(0)))
      MPZ = gmpy.mpz
      MPQ = gmpy.mpq
  
      factorial = gmpy.fac
      sqrt = gmpy.isqrt
  
  else:
      from .pythonmpq import PythonMPQ
  
      HAS_GMPY = 0
      GROUND_TYPES = 'python'
      SYMPY_INTS = (int,)
      MPZ = int
      MPQ = PythonMPQ
  
      factorial = lambda x: int(mlib.ifac(x))
      sqrt = lambda x: int(mlib.isqrt(x))
  