Coverage for /usr/lib/python3/dist-packages/sympy/external/gmpy.py: 58%
33 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1import os
2from typing import Tuple as tTuple, Type
4import mpmath.libmp as mlib
6from sympy.external import import_module
8__all__ = [
9 # GROUND_TYPES is either 'gmpy' or 'python' depending on which is used. If
10 # gmpy is installed then it will be used unless the environment variable
11 # SYMPY_GROUND_TYPES is set to something other than 'auto', 'gmpy', or
12 # 'gmpy2'.
13 'GROUND_TYPES',
15 # If HAS_GMPY is 0, no supported version of gmpy is available. Otherwise,
16 # HAS_GMPY will be 2 for gmpy2 if GROUND_TYPES is 'gmpy'. It used to be
17 # possible for HAS_GMPY to be 1 for gmpy but gmpy is no longer supported.
18 'HAS_GMPY',
20 # SYMPY_INTS is a tuple containing the base types for valid integer types.
21 # This is either (int,) or (int, type(mpz(0))) depending on GROUND_TYPES.
22 'SYMPY_INTS',
24 # MPQ is either gmpy.mpq or the Python equivalent from
25 # sympy.external.pythonmpq
26 'MPQ',
28 # MPZ is either gmpy.mpz or int.
29 'MPZ',
31 # Either the gmpy or the mpmath function
32 'factorial',
34 # isqrt from gmpy or mpmath
35 'sqrt',
36]
39#
40# SYMPY_GROUND_TYPES can be gmpy, gmpy2, python or auto
41#
42GROUND_TYPES = os.environ.get('SYMPY_GROUND_TYPES', 'auto').lower()
45#
46# Try to import gmpy2 by default. If gmpy or gmpy2 is specified in
47# SYMPY_GROUND_TYPES then warn if gmpy2 is not found. In all cases there is a
48# fallback based on pure Python int and PythonMPQ that should still work fine.
49#
50if GROUND_TYPES in ('auto', 'gmpy', 'gmpy2'):
52 # Actually import gmpy2
53 gmpy = import_module('gmpy2', min_module_version='2.0.0',
54 module_version_attr='version', module_version_attr_call_args=())
56 # Warn if user explicitly asked for gmpy but it isn't available.
57 if gmpy is None and GROUND_TYPES in ('gmpy', 'gmpy2'):
58 from warnings import warn
59 warn("gmpy library is not installed, switching to 'python' ground types")
61elif GROUND_TYPES == 'python':
63 # The user asked for Python so ignore gmpy2 module.
64 gmpy = None
66else:
68 # Invalid value for SYMPY_GROUND_TYPES. Ignore the gmpy2 module.
69 from warnings import warn
70 warn("SYMPY_GROUND_TYPES environment variable unrecognised. "
71 "Should be 'python', 'auto', 'gmpy', or 'gmpy2'")
72 gmpy = None
75#
76# At this point gmpy will be None if gmpy2 was not successfully imported or if
77# the environment variable SYMPY_GROUND_TYPES was set to 'python' (or some
78# unrecognised value). The two blocks below define the values exported by this
79# module in each case.
80#
81SYMPY_INTS: tTuple[Type, ...]
83if gmpy is not None:
85 HAS_GMPY = 2
86 GROUND_TYPES = 'gmpy'
87 SYMPY_INTS = (int, type(gmpy.mpz(0)))
88 MPZ = gmpy.mpz
89 MPQ = gmpy.mpq
91 factorial = gmpy.fac
92 sqrt = gmpy.isqrt
94else:
95 from .pythonmpq import PythonMPQ
97 HAS_GMPY = 0
98 GROUND_TYPES = 'python'
99 SYMPY_INTS = (int,)
100 MPZ = int
101 MPQ = PythonMPQ
103 factorial = lambda x: int(mlib.ifac(x))
104 sqrt = lambda x: int(mlib.isqrt(x))