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

1import os 

2from typing import Tuple as tTuple, Type 

3 

4import mpmath.libmp as mlib 

5 

6from sympy.external import import_module 

7 

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', 

14 

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', 

19 

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', 

23 

24 # MPQ is either gmpy.mpq or the Python equivalent from 

25 # sympy.external.pythonmpq 

26 'MPQ', 

27 

28 # MPZ is either gmpy.mpz or int. 

29 'MPZ', 

30 

31 # Either the gmpy or the mpmath function 

32 'factorial', 

33 

34 # isqrt from gmpy or mpmath 

35 'sqrt', 

36] 

37 

38 

39# 

40# SYMPY_GROUND_TYPES can be gmpy, gmpy2, python or auto 

41# 

42GROUND_TYPES = os.environ.get('SYMPY_GROUND_TYPES', 'auto').lower() 

43 

44 

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'): 

51 

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=()) 

55 

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") 

60 

61elif GROUND_TYPES == 'python': 

62 

63 # The user asked for Python so ignore gmpy2 module. 

64 gmpy = None 

65 

66else: 

67 

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 

73 

74 

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, ...] 

82 

83if gmpy is not None: 

84 

85 HAS_GMPY = 2 

86 GROUND_TYPES = 'gmpy' 

87 SYMPY_INTS = (int, type(gmpy.mpz(0))) 

88 MPZ = gmpy.mpz 

89 MPQ = gmpy.mpq 

90 

91 factorial = gmpy.fac 

92 sqrt = gmpy.isqrt 

93 

94else: 

95 from .pythonmpq import PythonMPQ 

96 

97 HAS_GMPY = 0 

98 GROUND_TYPES = 'python' 

99 SYMPY_INTS = (int,) 

100 MPZ = int 

101 MPQ = PythonMPQ 

102 

103 factorial = lambda x: int(mlib.ifac(x)) 

104 sqrt = lambda x: int(mlib.isqrt(x))