ccxt 4.3.70__py2.py3-none-any.whl → 4.3.71__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/paradex.py +40 -0
  3. ccxt/async_support/__init__.py +3 -1
  4. ccxt/async_support/base/exchange.py +1 -1
  5. ccxt/async_support/paradex.py +1966 -0
  6. ccxt/async_support/woo.py +4 -2
  7. ccxt/base/exchange.py +58 -1
  8. ccxt/paradex.py +1966 -0
  9. ccxt/pro/__init__.py +3 -1
  10. ccxt/pro/bequant.py +4 -0
  11. ccxt/pro/paradex.py +340 -0
  12. ccxt/static_dependencies/__init__.py +1 -1
  13. ccxt/static_dependencies/lark/__init__.py +38 -0
  14. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  15. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  16. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  17. ccxt/static_dependencies/lark/common.py +86 -0
  18. ccxt/static_dependencies/lark/exceptions.py +292 -0
  19. ccxt/static_dependencies/lark/grammar.py +130 -0
  20. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  21. ccxt/static_dependencies/lark/indenter.py +143 -0
  22. ccxt/static_dependencies/lark/lark.py +658 -0
  23. ccxt/static_dependencies/lark/lexer.py +678 -0
  24. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  25. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  26. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  27. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  28. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  29. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  30. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  31. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  32. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  33. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  34. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  35. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  36. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  37. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  38. ccxt/static_dependencies/lark/py.typed +0 -0
  39. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  40. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  41. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  42. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  43. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  44. ccxt/static_dependencies/lark/tree.py +267 -0
  45. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  46. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  47. ccxt/static_dependencies/lark/utils.py +343 -0
  48. ccxt/static_dependencies/lark/visitors.py +596 -0
  49. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  50. ccxt/static_dependencies/marshmallow/base.py +65 -0
  51. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  52. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  53. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  54. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  55. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  56. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  57. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  58. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  59. ccxt/static_dependencies/marshmallow/types.py +12 -0
  60. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  61. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  62. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  63. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  64. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  65. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  66. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  67. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  68. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  69. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  70. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  71. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  72. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  73. ccxt/static_dependencies/starknet/__init__.py +0 -0
  74. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  75. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  76. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  77. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  78. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  79. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  80. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  81. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  82. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  83. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  84. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  85. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  86. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  87. ccxt/static_dependencies/starknet/common.py +15 -0
  88. ccxt/static_dependencies/starknet/constants.py +39 -0
  89. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  90. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  91. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  92. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  93. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  94. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  95. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  96. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  97. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  98. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  99. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  100. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  101. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  102. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  103. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  104. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  105. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  106. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  107. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  108. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  109. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  110. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  111. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  112. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  113. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  114. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  115. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  116. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  117. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  118. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  119. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  120. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  121. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  122. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  123. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  124. ccxt/static_dependencies/sympy/__init__.py +0 -0
  125. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  126. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  127. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  128. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  129. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  130. ccxt/static_dependencies/typing_extensions/__init__.py +0 -0
  131. ccxt/static_dependencies/typing_extensions/typing_extensions.py +3839 -0
  132. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  133. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  134. ccxt/test/tests_async.py +43 -1
  135. ccxt/test/tests_sync.py +43 -1
  136. ccxt/woo.py +4 -2
  137. {ccxt-4.3.70.dist-info → ccxt-4.3.71.dist-info}/METADATA +7 -6
  138. {ccxt-4.3.70.dist-info → ccxt-4.3.71.dist-info}/RECORD +141 -16
  139. {ccxt-4.3.70.dist-info → ccxt-4.3.71.dist-info}/LICENSE.txt +0 -0
  140. {ccxt-4.3.70.dist-info → ccxt-4.3.71.dist-info}/WHEEL +0 -0
  141. {ccxt-4.3.70.dist-info → ccxt-4.3.71.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,182 @@
1
+ from dataclasses import dataclass
2
+ from typing import Dict, List, Union, cast
3
+
4
+ from ...marshmallow import Schema, fields, post_load
5
+
6
+ from ..cairo.felt import encode_shortstring
7
+ from ..hash.selector import get_selector_from_name
8
+ from ..hash.utils import compute_hash_on_elements
9
+ from ..models.typed_data import StarkNetDomainDict, TypedDataDict
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class Parameter:
14
+ """
15
+ Dataclass representing a Parameter object
16
+ """
17
+
18
+ name: str
19
+ type: str
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class TypedData:
24
+ """
25
+ Dataclass representing a TypedData object
26
+ """
27
+
28
+ types: Dict[str, List[Parameter]]
29
+ primary_type: str
30
+ domain: StarkNetDomainDict
31
+ message: dict
32
+
33
+ @staticmethod
34
+ def from_dict(data: TypedDataDict) -> "TypedData":
35
+ """
36
+ Create TypedData dataclass from dictionary.
37
+
38
+ :param data: TypedData dictionary.
39
+ :return: TypedData dataclass instance.
40
+ """
41
+ return cast(TypedData, TypedDataSchema().load(data))
42
+
43
+ def _is_struct(self, type_name: str) -> bool:
44
+ return type_name in self.types
45
+
46
+ def _encode_value(self, type_name: str, value: Union[int, str, dict, list]) -> int:
47
+ if is_pointer(type_name) and isinstance(value, list):
48
+ type_name = strip_pointer(type_name)
49
+
50
+ if self._is_struct(type_name):
51
+ return compute_hash_on_elements(
52
+ [self.struct_hash(type_name, data) for data in value]
53
+ )
54
+ return compute_hash_on_elements([int(get_hex(val), 16) for val in value])
55
+
56
+ if self._is_struct(type_name) and isinstance(value, dict):
57
+ return self.struct_hash(type_name, value)
58
+
59
+ value = cast(Union[int, str], value)
60
+ return int(get_hex(value), 16)
61
+
62
+ def _encode_data(self, type_name: str, data: dict) -> List[int]:
63
+ values = []
64
+ for param in self.types[type_name]:
65
+ encoded_value = self._encode_value(param.type, data[param.name])
66
+ values.append(encoded_value)
67
+
68
+ return values
69
+
70
+ def _get_dependencies(self, type_name: str) -> List[str]:
71
+ if type_name not in self.types:
72
+ # type_name is a primitive type, has no dependencies
73
+ return []
74
+
75
+ dependencies = set()
76
+
77
+ def collect_deps(type_name: str) -> None:
78
+ for param in self.types[type_name]:
79
+ fixed_type = strip_pointer(param.type)
80
+ if fixed_type in self.types and fixed_type not in dependencies:
81
+ dependencies.add(fixed_type)
82
+ # recursive call
83
+ collect_deps(fixed_type)
84
+
85
+ # collect dependencies into a set
86
+ collect_deps(type_name)
87
+ return [type_name, *list(dependencies)]
88
+
89
+ def _encode_type(self, type_name: str) -> str:
90
+ primary, *dependencies = self._get_dependencies(type_name)
91
+ types = [primary, *sorted(dependencies)]
92
+
93
+ def make_dependency_str(dependency):
94
+ lst = [f"{t.name}:{t.type}" for t in self.types[dependency]]
95
+ return f"{dependency}({','.join(lst)})"
96
+
97
+ return "".join([make_dependency_str(x) for x in types])
98
+
99
+ def type_hash(self, type_name: str) -> int:
100
+ """
101
+ Calculate the hash of a type name.
102
+
103
+ :param type_name: Name of the type.
104
+ :return: Hash of the type name.
105
+ """
106
+ return get_selector_from_name(self._encode_type(type_name))
107
+
108
+ def struct_hash(self, type_name: str, data: dict) -> int:
109
+ """
110
+ Calculate the hash of a struct.
111
+
112
+ :param type_name: Name of the type.
113
+ :param data: Data defining the struct.
114
+ :return: Hash of the struct.
115
+ """
116
+ return compute_hash_on_elements(
117
+ [self.type_hash(type_name), *self._encode_data(type_name, data)]
118
+ )
119
+
120
+ def message_hash(self, account_address: int) -> int:
121
+ """
122
+ Calculate the hash of the message.
123
+
124
+ :param account_address: Address of an account.
125
+ :return: Hash of the message.
126
+ """
127
+ message = [
128
+ encode_shortstring("StarkNet Message"),
129
+ self.struct_hash("StarkNetDomain", cast(dict, self.domain)),
130
+ account_address,
131
+ self.struct_hash(self.primary_type, self.message),
132
+ ]
133
+
134
+ return compute_hash_on_elements(message)
135
+
136
+
137
+ def get_hex(value: Union[int, str]) -> str:
138
+ if isinstance(value, int):
139
+ return hex(value)
140
+ if value[:2] == "0x":
141
+ return value
142
+ if value.isnumeric():
143
+ return hex(int(value))
144
+ return hex(encode_shortstring(value))
145
+
146
+
147
+ def is_pointer(value: str) -> bool:
148
+ return len(value) > 0 and value[-1] == "*"
149
+
150
+
151
+ def strip_pointer(value: str) -> str:
152
+ if is_pointer(value):
153
+ return value[:-1]
154
+ return value
155
+
156
+
157
+ # pylint: disable=unused-argument
158
+ # pylint: disable=no-self-use
159
+
160
+
161
+ class ParameterSchema(Schema):
162
+ name = fields.String(data_key="name", required=True)
163
+ type = fields.String(data_key="type", required=True)
164
+
165
+ @post_load
166
+ def make_dataclass(self, data, **kwargs) -> Parameter:
167
+ return Parameter(**data)
168
+
169
+
170
+ class TypedDataSchema(Schema):
171
+ types = fields.Dict(
172
+ data_key="types",
173
+ keys=fields.Str(),
174
+ values=fields.List(fields.Nested(ParameterSchema())),
175
+ )
176
+ primary_type = fields.String(data_key="primaryType", required=True)
177
+ domain = fields.Dict(data_key="domain", required=True)
178
+ message = fields.Dict(data_key="message", required=True)
179
+
180
+ @post_load
181
+ def make_dataclass(self, data, **kwargs) -> TypedData:
182
+ return TypedData(**data)
File without changes
File without changes
@@ -0,0 +1,345 @@
1
+ import os
2
+ from ctypes import c_long, sizeof
3
+ from functools import reduce
4
+ from typing import Tuple as tTuple, Type
5
+ from warnings import warn
6
+
7
+ from .importtools import import_module
8
+
9
+ from .pythonmpq import PythonMPQ
10
+
11
+ from .ntheory import (
12
+ # bit_scan1 as python_bit_scan1,
13
+ # bit_scan0 as python_bit_scan0,
14
+ # remove as python_remove,
15
+ # factorial as python_factorial,
16
+ # sqrt as python_sqrt,
17
+ # sqrtrem as python_sqrtrem,
18
+ # gcd as python_gcd,
19
+ # lcm as python_lcm,
20
+ gcdext as python_gcdext,
21
+ # is_square as python_is_square,
22
+ # invert as python_invert,
23
+ # legendre as python_legendre,
24
+ # jacobi as python_jacobi,
25
+ # kronecker as python_kronecker,
26
+ # iroot as python_iroot,
27
+ # is_fermat_prp as python_is_fermat_prp,
28
+ # is_euler_prp as python_is_euler_prp,
29
+ # is_strong_prp as python_is_strong_prp,
30
+ # is_fibonacci_prp as python_is_fibonacci_prp,
31
+ # is_lucas_prp as python_is_lucas_prp,
32
+ # is_selfridge_prp as python_is_selfridge_prp,
33
+ # is_strong_lucas_prp as python_is_strong_lucas_prp,
34
+ # is_strong_selfridge_prp as python_is_strong_selfridge_prp,
35
+ # is_bpsw_prp as python_is_bpsw_prp,
36
+ # is_strong_bpsw_prp as python_is_strong_bpsw_prp,
37
+ )
38
+
39
+
40
+ __all__ = [
41
+ # GROUND_TYPES is either 'gmpy' or 'python' depending on which is used. If
42
+ # gmpy is installed then it will be used unless the environment variable
43
+ # SYMPY_GROUND_TYPES is set to something other than 'auto', 'gmpy', or
44
+ # 'gmpy2'.
45
+ 'GROUND_TYPES',
46
+
47
+ # If HAS_GMPY is 0, no supported version of gmpy is available. Otherwise,
48
+ # HAS_GMPY will be 2 for gmpy2 if GROUND_TYPES is 'gmpy'. It used to be
49
+ # possible for HAS_GMPY to be 1 for gmpy but gmpy is no longer supported.
50
+ 'HAS_GMPY',
51
+
52
+ # SYMPY_INTS is a tuple containing the base types for valid integer types.
53
+ # This is either (int,) or (int, type(mpz(0))) depending on GROUND_TYPES.
54
+ 'SYMPY_INTS',
55
+
56
+ # MPQ is either gmpy.mpq or the Python equivalent from
57
+ # sympy.external.pythonmpq
58
+ 'MPQ',
59
+
60
+ # MPZ is either gmpy.mpz or int.
61
+ 'MPZ',
62
+
63
+ # 'bit_scan1',
64
+ # 'bit_scan0',
65
+ # 'remove',
66
+ # 'factorial',
67
+ # 'sqrt',
68
+ # 'is_square',
69
+ # 'sqrtrem',
70
+ # 'gcd',
71
+ # 'lcm',
72
+ 'gcdext',
73
+ # 'invert',
74
+ # 'legendre',
75
+ # 'jacobi',
76
+ # 'kronecker',
77
+ # 'iroot',
78
+ # 'is_fermat_prp',
79
+ # 'is_euler_prp',
80
+ # 'is_strong_prp',
81
+ # 'is_fibonacci_prp',
82
+ # 'is_lucas_prp',
83
+ # 'is_selfridge_prp',
84
+ # 'is_strong_lucas_prp',
85
+ # 'is_strong_selfridge_prp',
86
+ # 'is_bpsw_prp',
87
+ # 'is_strong_bpsw_prp',
88
+ ]
89
+
90
+
91
+ #
92
+ # Tested python-flint version. Future versions might work but we will only use
93
+ # them if explicitly requested by SYMPY_GROUND_TYPES=flint.
94
+ #
95
+ _PYTHON_FLINT_VERSION_NEEDED = "0.6.*"
96
+
97
+
98
+ def _flint_version_okay(flint_version):
99
+ flint_ver = flint_version.split('.')[:2]
100
+ needed_ver = _PYTHON_FLINT_VERSION_NEEDED.split('.')[:2]
101
+ return flint_ver == needed_ver
102
+
103
+ #
104
+ # We will only use gmpy2 >= 2.0.0
105
+ #
106
+ _GMPY2_MIN_VERSION = '2.0.0'
107
+
108
+
109
+ def _get_flint(sympy_ground_types):
110
+ if sympy_ground_types not in ('auto', 'flint'):
111
+ return None
112
+
113
+ try:
114
+ import flint
115
+ # Earlier versions of python-flint may not have __version__.
116
+ from flint import __version__ as _flint_version
117
+ except ImportError:
118
+ if sympy_ground_types == 'flint':
119
+ warn("SYMPY_GROUND_TYPES was set to flint but python-flint is not "
120
+ "installed. Falling back to other ground types.")
121
+ return None
122
+
123
+ if _flint_version_okay(_flint_version):
124
+ return flint
125
+ elif sympy_ground_types == 'auto':
126
+ warn(f"python-flint {_flint_version} is installed but only version "
127
+ f"{_PYTHON_FLINT_VERSION_NEEDED} will be used by default. "
128
+ f"Falling back to other ground types. Use "
129
+ f"SYMPY_GROUND_TYPES=flint to force the use of python-flint.")
130
+ return None
131
+ else:
132
+ warn(f"Using python-flint {_flint_version} because SYMPY_GROUND_TYPES "
133
+ f"is set to flint but this version of SymPy has only been tested "
134
+ f"with python-flint {_PYTHON_FLINT_VERSION_NEEDED}.")
135
+ return flint
136
+
137
+
138
+ def _get_gmpy2(sympy_ground_types):
139
+ if sympy_ground_types not in ('auto', 'gmpy', 'gmpy2'):
140
+ return None
141
+
142
+ gmpy = import_module('gmpy2', min_module_version=_GMPY2_MIN_VERSION,
143
+ module_version_attr='version', module_version_attr_call_args=())
144
+
145
+ if sympy_ground_types != 'auto' and gmpy is None:
146
+ warn("gmpy2 library is not installed, switching to 'python' ground types")
147
+
148
+ return gmpy
149
+
150
+
151
+ #
152
+ # SYMPY_GROUND_TYPES can be flint, gmpy, gmpy2, python or auto (default)
153
+ #
154
+ _SYMPY_GROUND_TYPES = os.environ.get('SYMPY_GROUND_TYPES', 'auto').lower()
155
+ _flint = None
156
+ _gmpy = None
157
+
158
+ #
159
+ # First handle auto-detection of flint/gmpy2. We will prefer flint if available
160
+ # or otherwise gmpy2 if available and then lastly the python types.
161
+ #
162
+ if _SYMPY_GROUND_TYPES in ('auto', 'flint'):
163
+ _flint = _get_flint(_SYMPY_GROUND_TYPES)
164
+ if _flint is not None:
165
+ _SYMPY_GROUND_TYPES = 'flint'
166
+ else:
167
+ _SYMPY_GROUND_TYPES = 'auto'
168
+
169
+ if _SYMPY_GROUND_TYPES in ('auto', 'gmpy', 'gmpy2'):
170
+ _gmpy = _get_gmpy2(_SYMPY_GROUND_TYPES)
171
+ if _gmpy is not None:
172
+ _SYMPY_GROUND_TYPES = 'gmpy'
173
+ else:
174
+ _SYMPY_GROUND_TYPES = 'python'
175
+
176
+ if _SYMPY_GROUND_TYPES not in ('flint', 'gmpy', 'python'):
177
+ warn("SYMPY_GROUND_TYPES environment variable unrecognised. "
178
+ "Should be 'auto', 'flint', 'gmpy', 'gmpy2' or 'python'.")
179
+ _SYMPY_GROUND_TYPES = 'python'
180
+
181
+ #
182
+ # At this point _SYMPY_GROUND_TYPES is either flint, gmpy or python. The blocks
183
+ # below define the values exported by this module in each case.
184
+ #
185
+
186
+ #
187
+ # In gmpy2 and flint, there are functions that take a long (or unsigned long)
188
+ # argument. That is, it is not possible to input a value larger than that.
189
+ #
190
+ LONG_MAX = (1 << (8*sizeof(c_long) - 1)) - 1
191
+
192
+ #
193
+ # Type checkers are confused by what SYMPY_INTS is. There may be a better type
194
+ # hint for this like Type[Integral] or something.
195
+ #
196
+ SYMPY_INTS: tTuple[Type, ...]
197
+
198
+ if _SYMPY_GROUND_TYPES == 'gmpy':
199
+
200
+ assert _gmpy is not None
201
+
202
+ flint = None
203
+ gmpy = _gmpy
204
+
205
+ HAS_GMPY = 2
206
+ GROUND_TYPES = 'gmpy'
207
+ SYMPY_INTS = (int, type(gmpy.mpz(0)))
208
+ MPZ = gmpy.mpz
209
+ MPQ = gmpy.mpq
210
+
211
+ # bit_scan1 = gmpy.bit_scan1
212
+ # bit_scan0 = gmpy.bit_scan0
213
+ # remove = gmpy.remove
214
+ # factorial = gmpy.fac
215
+ # sqrt = gmpy.isqrt
216
+ # is_square = gmpy.is_square
217
+ # sqrtrem = gmpy.isqrt_rem
218
+ # gcd = gmpy.gcd
219
+ # lcm = gmpy.lcm
220
+ gcdext = gmpy.gcdext
221
+ # invert = gmpy.invert
222
+ # legendre = gmpy.legendre
223
+ # jacobi = gmpy.jacobi
224
+ # kronecker = gmpy.kronecker
225
+
226
+ # def iroot(x, n):
227
+ # # In the latest gmpy2, the threshold for n is ULONG_MAX,
228
+ # # but adjust to the older one.
229
+ # if n <= LONG_MAX:
230
+ # return gmpy.iroot(x, n)
231
+ # return python_iroot(x, n)
232
+
233
+ # is_fermat_prp = gmpy.is_fermat_prp
234
+ # is_euler_prp = gmpy.is_euler_prp
235
+ # is_strong_prp = gmpy.is_strong_prp
236
+ # is_fibonacci_prp = gmpy.is_fibonacci_prp
237
+ # is_lucas_prp = gmpy.is_lucas_prp
238
+ # is_selfridge_prp = gmpy.is_selfridge_prp
239
+ # is_strong_lucas_prp = gmpy.is_strong_lucas_prp
240
+ # is_strong_selfridge_prp = gmpy.is_strong_selfridge_prp
241
+ # is_bpsw_prp = gmpy.is_bpsw_prp
242
+ # is_strong_bpsw_prp = gmpy.is_strong_bpsw_prp
243
+
244
+ elif _SYMPY_GROUND_TYPES == 'flint':
245
+
246
+ assert _flint is not None
247
+
248
+ flint = _flint
249
+ gmpy = None
250
+
251
+ HAS_GMPY = 0
252
+ GROUND_TYPES = 'flint'
253
+ SYMPY_INTS = (int, flint.fmpz) # type: ignore
254
+ MPZ = flint.fmpz # type: ignore
255
+ MPQ = flint.fmpq # type: ignore
256
+
257
+ # bit_scan1 = python_bit_scan1
258
+ # bit_scan0 = python_bit_scan0
259
+ # remove = python_remove
260
+ # factorial = python_factorial
261
+
262
+ # def sqrt(x):
263
+ # return flint.fmpz(x).isqrt()
264
+
265
+ # def is_square(x):
266
+ # if x < 0:
267
+ # return False
268
+ # return flint.fmpz(x).sqrtrem()[1] == 0
269
+
270
+ # def sqrtrem(x):
271
+ # return flint.fmpz(x).sqrtrem()
272
+
273
+ # def gcd(*args):
274
+ # return reduce(flint.fmpz.gcd, args, flint.fmpz(0))
275
+
276
+ # def lcm(*args):
277
+ # return reduce(flint.fmpz.lcm, args, flint.fmpz(1))
278
+
279
+ gcdext = python_gcdext
280
+ # invert = python_invert
281
+ # legendre = python_legendre
282
+
283
+ # def jacobi(x, y):
284
+ # if y <= 0 or not y % 2:
285
+ # raise ValueError("y should be an odd positive integer")
286
+ # return flint.fmpz(x).jacobi(y)
287
+
288
+ # kronecker = python_kronecker
289
+
290
+ # def iroot(x, n):
291
+ # if n <= LONG_MAX:
292
+ # y = flint.fmpz(x).root(n)
293
+ # return y, y**n == x
294
+ # return python_iroot(x, n)
295
+
296
+ # is_fermat_prp = python_is_fermat_prp
297
+ # is_euler_prp = python_is_euler_prp
298
+ # is_strong_prp = python_is_strong_prp
299
+ # is_fibonacci_prp = python_is_fibonacci_prp
300
+ # is_lucas_prp = python_is_lucas_prp
301
+ # is_selfridge_prp = python_is_selfridge_prp
302
+ # is_strong_lucas_prp = python_is_strong_lucas_prp
303
+ # is_strong_selfridge_prp = python_is_strong_selfridge_prp
304
+ # is_bpsw_prp = python_is_bpsw_prp
305
+ # is_strong_bpsw_prp = python_is_strong_bpsw_prp
306
+
307
+ elif _SYMPY_GROUND_TYPES == 'python':
308
+
309
+ flint = None
310
+ gmpy = None
311
+
312
+ HAS_GMPY = 0
313
+ GROUND_TYPES = 'python'
314
+ SYMPY_INTS = (int,)
315
+ MPZ = int
316
+ MPQ = PythonMPQ
317
+
318
+ # bit_scan1 = python_bit_scan1
319
+ # bit_scan0 = python_bit_scan0
320
+ # remove = python_remove
321
+ # factorial = python_factorial
322
+ # sqrt = python_sqrt
323
+ # is_square = python_is_square
324
+ # sqrtrem = python_sqrtrem
325
+ # gcd = python_gcd
326
+ # lcm = python_lcm
327
+ gcdext = python_gcdext
328
+ # invert = python_invert
329
+ # legendre = python_legendre
330
+ # jacobi = python_jacobi
331
+ # kronecker = python_kronecker
332
+ # iroot = python_iroot
333
+ # is_fermat_prp = python_is_fermat_prp
334
+ # is_euler_prp = python_is_euler_prp
335
+ # is_strong_prp = python_is_strong_prp
336
+ # is_fibonacci_prp = python_is_fibonacci_prp
337
+ # is_lucas_prp = python_is_lucas_prp
338
+ # is_selfridge_prp = python_is_selfridge_prp
339
+ # is_strong_lucas_prp = python_is_strong_lucas_prp
340
+ # is_strong_selfridge_prp = python_is_strong_selfridge_prp
341
+ # is_bpsw_prp = python_is_bpsw_prp
342
+ # is_strong_bpsw_prp = python_is_strong_bpsw_prp
343
+
344
+ else:
345
+ assert False