123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import os
- from typing import Tuple as tTuple, 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: tTuple[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))
|