gamspy 1.16.0__tar.gz → 1.17.1__tar.gz

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 (96) hide show
  1. {gamspy-1.16.0 → gamspy-1.17.1}/PKG-INFO +10 -9
  2. {gamspy-1.16.0 → gamspy-1.17.1}/README.md +1 -0
  3. {gamspy-1.16.0 → gamspy-1.17.1}/README_PYPI.md +1 -1
  4. {gamspy-1.16.0 → gamspy-1.17.1}/pyproject.toml +26 -31
  5. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/__init__.py +1 -1
  6. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/condition.py +1 -3
  7. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/domain.py +1 -3
  8. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/expression.py +21 -44
  9. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/operable.py +20 -24
  10. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/operation.py +14 -58
  11. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/backend.py +6 -18
  12. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/engine.py +103 -141
  13. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/neos.py +8 -23
  14. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/cli.py +4 -4
  15. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/gdx.py +142 -41
  16. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/install.py +89 -54
  17. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/list.py +9 -13
  18. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/probe.py +10 -8
  19. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/retrieve.py +11 -15
  20. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/run.py +37 -42
  21. gamspy-1.17.1/src/gamspy/_cli/show.py +255 -0
  22. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/uninstall.py +47 -23
  23. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/util.py +3 -7
  24. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_config.py +3 -5
  25. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_container.py +50 -56
  26. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_convert.py +33 -59
  27. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_database.py +3 -7
  28. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_extrinsic.py +4 -12
  29. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_miro.py +14 -34
  30. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_model.py +64 -59
  31. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_model_instance.py +21 -55
  32. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_options.py +115 -120
  33. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_serialization.py +9 -8
  34. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/alias.py +8 -12
  35. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/equation.py +12 -20
  36. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_equation.py +2 -4
  37. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_parameter.py +6 -4
  38. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_set.py +6 -11
  39. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_symbol.py +14 -20
  40. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_variable.py +7 -10
  41. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/parameter.py +15 -37
  42. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/set.py +18 -50
  43. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/symbol.py +19 -19
  44. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/universe_alias.py +7 -18
  45. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/variable.py +18 -42
  46. gamspy-1.17.1/src/gamspy/_types.py +7 -0
  47. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_validation.py +20 -49
  48. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_workspace.py +2 -7
  49. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/exceptions.py +2 -4
  50. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/__init__.py +12 -10
  51. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/decision_tree_struct.py +5 -17
  52. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/gradient_boosting.py +5 -13
  53. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/random_forest.py +4 -10
  54. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/regression_tree.py +19 -48
  55. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/avgpool2d.py +6 -18
  56. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/conv1d.py +12 -39
  57. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/conv2d.py +17 -39
  58. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/linear.py +7 -23
  59. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/maxpool2d.py +6 -4
  60. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/minpool2d.py +6 -4
  61. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/mpool2d.py +9 -23
  62. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/torch_sequential.py +13 -39
  63. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/piecewise.py +18 -45
  64. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/shape.py +2 -6
  65. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/utils.py +6 -19
  66. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/__init__.py +68 -66
  67. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/activation.py +74 -18
  68. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/matrix.py +9 -22
  69. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/misc.py +4 -10
  70. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/utils.py +62 -109
  71. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/PKG-INFO +10 -9
  72. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/requires.txt +7 -6
  73. {gamspy-1.16.0 → gamspy-1.17.1}/tests/test_gamspy.py +4 -24
  74. gamspy-1.16.0/src/gamspy/_cli/show.py +0 -46
  75. gamspy-1.16.0/src/gamspy/_types.py +0 -10
  76. {gamspy-1.16.0 → gamspy-1.17.1}/LICENSE +0 -0
  77. {gamspy-1.16.0 → gamspy-1.17.1}/setup.cfg +0 -0
  78. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/__main__.py +0 -0
  79. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/__init__.py +0 -0
  80. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/number.py +0 -0
  81. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/__init__.py +0 -0
  82. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/local.py +0 -0
  83. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/__init__.py +0 -0
  84. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/__init__.py +0 -0
  85. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/__init__.py +0 -0
  86. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/__init__.py +2 -2
  87. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/__init__.py +3 -3
  88. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/log_power.py +0 -0
  89. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/probability.py +0 -0
  90. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/trigonometric.py +0 -0
  91. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/py.typed +0 -0
  92. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/version.py +0 -0
  93. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/SOURCES.txt +0 -0
  94. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/dependency_links.txt +0 -0
  95. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/entry_points.txt +0 -0
  96. {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gamspy
3
- Version: 1.16.0
3
+ Version: 1.17.1
4
4
  Summary: Python-based algebraic modeling interface to GAMS
5
5
  Author-email: GAMS Development Corporation <support@gams.com>
6
6
  Project-URL: homepage, https://gams.com/sales/gamspy_facts/
@@ -28,19 +28,20 @@ Classifier: Operating System :: POSIX
28
28
  Classifier: Operating System :: Unix
29
29
  Classifier: Operating System :: MacOS
30
30
  Classifier: Operating System :: Microsoft :: Windows
31
- Requires-Python: >=3.9
31
+ Requires-Python: >=3.10
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
- Requires-Dist: gamsapi[transfer]>=51.1.0
35
- Requires-Dist: gamspy_base>=51.1.0
34
+ Requires-Dist: gamsapi<52.0.0,>=51.1.0
35
+ Requires-Dist: gamspy_base<52.0.0,>=51.1.0
36
+ Requires-Dist: pandas<2.4,>=2.2.2
36
37
  Requires-Dist: pydantic>=2.0
37
- Requires-Dist: certifi>=2022.09.14
38
- Requires-Dist: urllib3>=2.0.7
38
+ Requires-Dist: requests>=2.28.0
39
39
  Requires-Dist: typer>=0.16.0
40
40
  Provides-Extra: dev
41
- Requires-Dist: ruff==0.12.0; extra == "dev"
41
+ Requires-Dist: ruff>=0.13.0; extra == "dev"
42
42
  Requires-Dist: pre-commit>=3.5.0; extra == "dev"
43
- Requires-Dist: mypy>=1.11.1; extra == "dev"
43
+ Requires-Dist: mypy>=1.18.1; extra == "dev"
44
+ Requires-Dist: griffe>=1.14.0; extra == "dev"
44
45
  Provides-Extra: test
45
46
  Requires-Dist: coverage[toml]>=7.2.7; extra == "test"
46
47
  Requires-Dist: openpyxl>=3.1.2; extra == "test"
@@ -117,4 +118,4 @@ Here are just a few of the things that **gamspy** does well:
117
118
  ## Getting Help
118
119
 
119
120
  For usage questions, the best place to go to is [GAMSPy Documentation](https://gamspy.readthedocs.io/en/latest/index.html).
120
- General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com/c/gamspy-help).
121
+ General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com).
@@ -3,6 +3,7 @@
3
3
  -----------------
4
4
  [![PyPI version](https://img.shields.io/pypi/v/gamspy.svg?maxAge=3600)](https://gamspy.readthedocs.io/en/latest/)
5
5
  [![Downloads](https://static.pepy.tech/badge/gamspy)](https://pepy.tech/project/gamspy)
6
+ [![Supported versions](https://img.shields.io/pypi/pyversions/gamspy.svg)](https://pypi.python.org/pypi/gamspy)
6
7
  [![Documentation Status](https://readthedocs.org/projects/gamspy/badge/?version=latest)](https://gamspy.readthedocs.io/en/latest/)
7
8
 
8
9
  # GAMSPy: Algebraic Modeling Interface to GAMS
@@ -44,4 +44,4 @@ Here are just a few of the things that **gamspy** does well:
44
44
  ## Getting Help
45
45
 
46
46
  For usage questions, the best place to go to is [GAMSPy Documentation](https://gamspy.readthedocs.io/en/latest/index.html).
47
- General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com/c/gamspy-help).
47
+ General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com).
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gamspy"
7
- version = "1.16.0"
7
+ version = "1.17.1"
8
8
  authors = [
9
9
  { name = "GAMS Development Corporation", email = "support@gams.com" },
10
10
  ]
11
11
  readme = "README_PYPI.md"
12
12
  description = "Python-based algebraic modeling interface to GAMS"
13
- requires-python = ">=3.9"
13
+ requires-python = ">=3.10"
14
14
  license-files = ["LICENSE"]
15
15
  keywords = ["Optimization", "GAMS"]
16
16
  classifiers = [
@@ -36,11 +36,11 @@ classifiers = [
36
36
  "Operating System :: Microsoft :: Windows",
37
37
  ]
38
38
  dependencies = [
39
- "gamsapi[transfer] >= 51.1.0",
40
- "gamspy_base >= 51.1.0",
39
+ "gamsapi >= 51.1.0, < 52.0.0",
40
+ "gamspy_base >= 51.1.0, < 52.0.0",
41
+ "pandas >= 2.2.2, < 2.4",
41
42
  "pydantic >= 2.0",
42
- "certifi >= 2022.09.14",
43
- "urllib3 >= 2.0.7",
43
+ "requests >= 2.28.0",
44
44
  "typer >= 0.16.0",
45
45
  ]
46
46
 
@@ -53,9 +53,10 @@ changelog = "https://github.com/GAMS-dev/gamspy/blob/develop/CHANGELOG.md"
53
53
 
54
54
  [project.optional-dependencies]
55
55
  dev = [
56
- "ruff == 0.12.0",
56
+ "ruff >= 0.13.0",
57
57
  "pre-commit >= 3.5.0",
58
- "mypy >= 1.11.1",
58
+ "mypy >= 1.18.1",
59
+ "griffe >= 1.14.0",
59
60
  ]
60
61
 
61
62
  test = [
@@ -211,37 +212,31 @@ exclude = [
211
212
  "node_modules",
212
213
  "site-packages",
213
214
  "venv",
214
- "_cli",
215
- "_options.py"
216
215
  ]
217
216
 
218
- # Same as PEP8.
219
- line-length = 79
217
+ # Same as black.
218
+ line-length = 88
220
219
  indent-width = 4
221
220
 
222
- # Assume Python 9
223
- target-version = "py39"
221
+ # Assume Python 3.10
222
+ target-version = "py310"
224
223
 
225
224
  [tool.ruff.lint]
226
225
  select = [
227
- # pycodestyle
228
- "E",
229
- # Pyflakes
230
- "F",
231
- # pyupgrade
232
- "UP",
233
- # flake8-bugbear
234
- "B",
235
- # flake8-simplify
236
- "SIM",
237
- # isort
238
- "I",
239
- # flake8-pie
240
- "PIE",
241
- # Consider merging multiple comparisons
242
- "PLR1714",
226
+ "E", # pycodestyle error
227
+ "W", # pycodestyle warning
228
+ "F", # Pyflakes
229
+ "UP", # pyupgrade
230
+ "B", # flake8-bugbear
231
+ "SIM", # flake8-simplify
232
+ "I", # isort
233
+ "PIE", # flake8-pie
234
+ "PLR1714", # Consider merging multiple comparisons
235
+ "RUF", # Ruff-specific rules
236
+ "TC", # flake8-type-checking
237
+ "C4", # flake8-comprehensions
243
238
  ]
244
- ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006"]
239
+ ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006", "RUF005", "RUF022"]
245
240
 
246
241
  # Allow fix for all enabled rules (when `--fix`) is provided.
247
242
  fixable = ["ALL"]
@@ -50,7 +50,7 @@ from gamspy._symbols import (
50
50
 
51
51
  from .version import __version__
52
52
 
53
- _ctx_managers: dict[tuple[int, int], Container] = dict()
53
+ _ctx_managers: dict[tuple[int, int], Container] = {}
54
54
  _set_default_options()
55
55
 
56
56
  __all__ = [
@@ -96,9 +96,7 @@ class Condition(operable.Operable):
96
96
  statement = expression.Expression(lhs, op_type, rhs)
97
97
 
98
98
  if isinstance(self.conditioning_on, ImplicitSymbol):
99
- statement._validate_definition(
100
- utils._unpack(self.conditioning_on.domain)
101
- )
99
+ statement._validate_definition(utils._unpack(self.conditioning_on.domain))
102
100
 
103
101
  self.conditioning_on.container._add_statement(statement)
104
102
 
@@ -47,9 +47,7 @@ class Domain:
47
47
 
48
48
  def _sanity_check(self, sets: tuple[Set | Alias | ImplicitSet, ...]):
49
49
  if len(sets) < 2:
50
- error_message = (
51
- f"Domain requires at least 2 sets but found {len(sets)}. "
52
- )
50
+ error_message = f"Domain requires at least 2 sets but found {len(sets)}. "
53
51
  if len(sets) == 1:
54
52
  error_message += f"You can directly limit the domain with {sets[0].name}.where[<your_limitation>]."
55
53
  raise ValidationError(error_message)
@@ -20,8 +20,6 @@ from gamspy.exceptions import ValidationError
20
20
  from gamspy.math.misc import MathOp
21
21
 
22
22
  if TYPE_CHECKING:
23
- from numbers import Real
24
-
25
23
  import pandas as pd
26
24
 
27
25
  from gamspy import Alias, Set
@@ -150,7 +148,7 @@ def create_gams_expression(root_node: Expression) -> str:
150
148
  s1.append(node.right)
151
149
 
152
150
  # 2. Build the GAMS expression
153
- eval_stack: list[tuple[str, Real]] = []
151
+ eval_stack: list[tuple[str, float]] = []
154
152
  for node in reversed(post_order_nodes):
155
153
  if not isinstance(node, Expression):
156
154
  eval_stack.append((get_operand_gams_repr(node), LEAF_PRECEDENCE))
@@ -181,14 +179,10 @@ def create_gams_expression(root_node: Expression) -> str:
181
179
  right_str, right_prec = eval_stack.pop()
182
180
  left_str, left_prec = eval_stack.pop()
183
181
 
184
- if left_prec < op_prec or (
185
- left_prec == op_prec and op_assoc == "right"
186
- ):
182
+ if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
187
183
  left_str = f"({left_str})"
188
184
 
189
- if right_prec < op_prec or (
190
- right_prec == op_prec and op_assoc == "left"
191
- ):
185
+ if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
192
186
  right_str = f"({right_str})"
193
187
 
194
188
  # get around 80000 line length limitation in GAMS
@@ -241,7 +235,7 @@ def create_latex_expression(root_node: Expression) -> str:
241
235
  s1.append(node.right)
242
236
 
243
237
  # 2. Build the GAMS expression
244
- eval_stack: list[tuple[str, Real]] = []
238
+ eval_stack: list[tuple[str, float]] = []
245
239
  for node in reversed(post_order_nodes):
246
240
  if not isinstance(node, Expression):
247
241
  eval_stack.append((get_operand_latex_repr(node), LEAF_PRECEDENCE))
@@ -272,20 +266,14 @@ def create_latex_expression(root_node: Expression) -> str:
272
266
  right_str, right_prec = eval_stack.pop()
273
267
  left_str, left_prec = eval_stack.pop()
274
268
 
275
- if left_prec < op_prec or (
276
- left_prec == op_prec and op_assoc == "right"
277
- ):
269
+ if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
278
270
  left_str = f"({left_str})"
279
271
 
280
- if right_prec < op_prec or (
281
- right_prec == op_prec and op_assoc == "left"
282
- ):
272
+ if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
283
273
  right_str = f"({right_str})"
284
274
 
285
275
  if op == "/":
286
- eval_stack.append(
287
- (f"\\frac{{{left_str}}}{{{right_str}}}", op_prec)
288
- )
276
+ eval_stack.append((f"\\frac{{{left_str}}}{{{right_str}}}", op_prec))
289
277
  continue
290
278
 
291
279
  op = op_map.get(op, op)
@@ -334,16 +322,10 @@ class Expression(operable.Operable):
334
322
  operator: str,
335
323
  right: OperableType | str | None,
336
324
  ):
337
- self.left = (
338
- utils._map_special_values(left)
339
- if isinstance(left, float)
340
- else left
341
- )
325
+ self.left = utils._map_special_values(left) if isinstance(left, float) else left
342
326
  self.operator = operator
343
327
  self.right = (
344
- utils._map_special_values(right)
345
- if isinstance(right, float)
346
- else right
328
+ utils._map_special_values(right) if isinstance(right, float) else right
347
329
  )
348
330
 
349
331
  if operator == "=" and isinstance(right, Expression):
@@ -422,8 +404,8 @@ class Expression(operable.Operable):
422
404
 
423
405
  def __getitem__(self, indices):
424
406
  indices = validation.validate_domain(self, indices)
425
- left_domain = [d for d in self._left_domain]
426
- right_domain = [d for d in self._right_domain]
407
+ left_domain = list(self._left_domain)
408
+ right_domain = list(self._right_domain)
427
409
  for i, s in enumerate(indices):
428
410
  for lr, pos in self._shadow_domain[i].indices:
429
411
  if lr == "l":
@@ -654,16 +636,16 @@ class Expression(operable.Operable):
654
636
  symbols.append(node.alias_with.name)
655
637
 
656
638
  symbols.append(node.name)
657
- stack += node.domain
639
+ stack.extend(node.domain)
658
640
  node = None
659
641
  elif isinstance(node, ImplicitSymbol):
660
642
  if node.parent.name not in symbols:
661
643
  symbols.append(node.parent.name)
662
- stack += node.domain
663
- stack += node.container[node.parent.name].domain
644
+ stack.extend(node.domain)
645
+ stack.extend(node.container[node.parent.name].domain)
664
646
  node = None
665
647
  elif isinstance(node, operation.Operation):
666
- stack += node.op_domain
648
+ stack.extend(node.op_domain)
667
649
  node = node.rhs
668
650
  elif isinstance(node, condition.Condition):
669
651
  stack.append(node.conditioning_on)
@@ -680,10 +662,10 @@ class Expression(operable.Operable):
680
662
  if isinstance(node.elements[0], Expression):
681
663
  node = node.elements[0]
682
664
  else:
683
- stack += node.elements
665
+ stack.extend(node.elements)
684
666
  node = None
685
667
  elif isinstance(node, ExtrinsicFunction):
686
- stack += list(node.args)
668
+ stack.extend(list(node.args))
687
669
  node = None
688
670
  else:
689
671
  node = getattr(node, "right", None)
@@ -708,12 +690,12 @@ class Expression(operable.Operable):
708
690
  given_condition = node.condition
709
691
 
710
692
  if isinstance(given_condition, Expression):
711
- symbols += given_condition._find_all_symbols()
693
+ symbols.extend(given_condition._find_all_symbols())
712
694
  elif isinstance(given_condition, ImplicitSymbol):
713
695
  symbols.append(given_condition.parent.name)
714
696
 
715
697
  if isinstance(node, operation.Operation):
716
- stack += node.op_domain
698
+ stack.extend(node.op_domain)
717
699
  node = node.rhs
718
700
  else:
719
701
  node = getattr(node, "right", None)
@@ -725,9 +707,7 @@ class Expression(operable.Operable):
725
707
  def _validate_definition(
726
708
  self, control_stack: list[Set | Alias | ImplicitSet]
727
709
  ) -> None:
728
- if not get_option("DOMAIN_VALIDATION") or not get_option(
729
- "DOMAIN_VALIDATION"
730
- ):
710
+ if not get_option("DOMAIN_VALIDATION") or not get_option("DOMAIN_VALIDATION"):
731
711
  return
732
712
 
733
713
  stack = []
@@ -747,10 +727,7 @@ class Expression(operable.Operable):
747
727
  if hasattr(elem, "is_singleton") and elem.is_singleton:
748
728
  continue
749
729
 
750
- if (
751
- isinstance(elem, Symbol)
752
- and elem not in control_stack
753
- ):
730
+ if isinstance(elem, Symbol) and elem not in control_stack:
754
731
  raise ValidationError(
755
732
  f"Uncontrolled set `{elem}` entered as constant!"
756
733
  )
@@ -32,9 +32,9 @@ class Operable:
32
32
  ):
33
33
  return self.lead(other)
34
34
 
35
- if isinstance(
36
- self, (ImplicitSet, expression.SetExpression)
37
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
35
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
36
+ other, (ImplicitSet, expression.SetExpression)
37
+ ):
38
38
  return expression.SetExpression(self, "+", other)
39
39
 
40
40
  return expression.Expression(self, "+", other)
@@ -42,9 +42,9 @@ class Operable:
42
42
  def __radd__(self, other: OperableType):
43
43
  from gamspy._symbols.implicits import ImplicitSet
44
44
 
45
- if isinstance(
46
- self, (ImplicitSet, expression.SetExpression)
47
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
45
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
46
+ other, (ImplicitSet, expression.SetExpression)
47
+ ):
48
48
  return expression.SetExpression(other, "+", self)
49
49
 
50
50
  return expression.Expression(other, "+", self)
@@ -58,9 +58,9 @@ class Operable:
58
58
  ):
59
59
  return self.lag(other)
60
60
 
61
- if isinstance(
62
- self, (ImplicitSet, expression.SetExpression)
63
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
61
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
62
+ other, (ImplicitSet, expression.SetExpression)
63
+ ):
64
64
  return expression.SetExpression(self, "-", other)
65
65
 
66
66
  return expression.Expression(self, "-", other)
@@ -68,9 +68,9 @@ class Operable:
68
68
  def __rsub__(self, other: OperableType):
69
69
  from gamspy._symbols.implicits import ImplicitSet
70
70
 
71
- if isinstance(
72
- self, (ImplicitSet, expression.SetExpression)
73
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
71
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
72
+ other, (ImplicitSet, expression.SetExpression)
73
+ ):
74
74
  return expression.SetExpression(other, "-", self)
75
75
 
76
76
  return expression.Expression(other, "-", self)
@@ -87,9 +87,9 @@ class Operable:
87
87
  def __mul__(self, other: OperableType):
88
88
  from gamspy._symbols.implicits import ImplicitSet
89
89
 
90
- if isinstance(
91
- self, (ImplicitSet, expression.SetExpression)
92
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
90
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
91
+ other, (ImplicitSet, expression.SetExpression)
92
+ ):
93
93
  return expression.SetExpression(self, "*", other)
94
94
 
95
95
  return expression.Expression(self, "*", other)
@@ -97,9 +97,9 @@ class Operable:
97
97
  def __rmul__(self, other: OperableType):
98
98
  from gamspy._symbols.implicits import ImplicitSet
99
99
 
100
- if isinstance(
101
- self, (ImplicitSet, expression.SetExpression)
102
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
100
+ if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
101
+ other, (ImplicitSet, expression.SetExpression)
102
+ ):
103
103
  return expression.SetExpression(other, "*", self)
104
104
 
105
105
  return expression.Expression(other, "*", self)
@@ -178,12 +178,8 @@ class Operable:
178
178
  import gamspy._algebra.operation as operation
179
179
  from gamspy.math.matrix import _validate_matrix_mult_dims
180
180
 
181
- left_domain, right_domain, sum_domain = _validate_matrix_mult_dims(
182
- self, other
183
- )
184
- return operation.Sum(
185
- [sum_domain], self[left_domain] * other[right_domain]
186
- )
181
+ left_domain, right_domain, sum_domain = _validate_matrix_mult_dims(self, other)
182
+ return operation.Sum([sum_domain], self[left_domain] * other[right_domain])
187
183
 
188
184
  def gamsRepr(self):
189
185
  """Representation of the symbol in GAMS"""
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Sequence
4
3
  from typing import TYPE_CHECKING
5
4
 
6
5
  import gamspy._algebra.condition as condition
@@ -14,6 +13,8 @@ import gamspy.utils as utils
14
13
  from gamspy.exceptions import ValidationError
15
14
 
16
15
  if TYPE_CHECKING:
16
+ from collections.abc import Sequence
17
+
17
18
  import pandas as pd
18
19
 
19
20
  from gamspy._algebra import Domain
@@ -31,12 +32,7 @@ if TYPE_CHECKING:
31
32
  class Operation(operable.Operable):
32
33
  def __init__(
33
34
  self,
34
- domain: Set
35
- | Alias
36
- | ImplicitSet
37
- | Sequence[Set | Alias]
38
- | Domain
39
- | Condition,
35
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
40
36
  rhs: (
41
37
  Expression
42
38
  | Operation
@@ -75,7 +71,7 @@ class Operation(operable.Operable):
75
71
  self.domain.append(x)
76
72
 
77
73
  self.dimension: int = validation.get_dimension(self.domain)
78
- controlled_domain = [d for d in self._bare_op_domain]
74
+ controlled_domain = list(self._bare_op_domain)
79
75
  controlled_domain.extend(getattr(rhs, "controlled_domain", []))
80
76
  self.controlled_domain = list(set(controlled_domain))
81
77
 
@@ -160,9 +156,7 @@ class Operation(operable.Operable):
160
156
  for elem in self.raw_domain:
161
157
  if isinstance(elem, implicits.ImplicitSet):
162
158
  control_stack += [
163
- member
164
- for member in elem.domain
165
- if member not in control_stack
159
+ member for member in elem.domain if member not in control_stack
166
160
  ] + [elem.parent]
167
161
 
168
162
  if elem in control_stack:
@@ -178,11 +172,7 @@ class Operation(operable.Operable):
178
172
  if len(self.op_domain) == 1:
179
173
  return self.op_domain[0].gamsRepr()
180
174
 
181
- return (
182
- "("
183
- + ",".join([index.gamsRepr() for index in self.op_domain])
184
- + ")"
185
- )
175
+ return "(" + ",".join([index.gamsRepr() for index in self.op_domain]) + ")"
186
176
 
187
177
  def __eq__(self, other):
188
178
  return expression.Expression(self, "=e=", other)
@@ -266,9 +256,7 @@ class Operation(operable.Operable):
266
256
  if isinstance(self.rhs, (int, float, str))
267
257
  else self.rhs.latexRepr()
268
258
  )
269
- representation = (
270
- f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
271
- )
259
+ representation = f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
272
260
  return representation
273
261
 
274
262
 
@@ -305,12 +293,7 @@ class Sum(Operation):
305
293
 
306
294
  def __init__(
307
295
  self,
308
- domain: Set
309
- | Alias
310
- | ImplicitSet
311
- | Sequence[Set | Alias]
312
- | Domain
313
- | Condition,
296
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
314
297
  expression: Operation
315
298
  | Expression
316
299
  | MathOp
@@ -381,12 +364,7 @@ class Product(Operation):
381
364
 
382
365
  def __init__(
383
366
  self,
384
- domain: Set
385
- | Alias
386
- | ImplicitSet
387
- | Sequence[Set | Alias]
388
- | Domain
389
- | Condition,
367
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
390
368
  expression: Operation
391
369
  | Expression
392
370
  | MathOp
@@ -457,12 +435,7 @@ class Smin(Operation):
457
435
 
458
436
  def __init__(
459
437
  self,
460
- domain: Set
461
- | Alias
462
- | ImplicitSet
463
- | Sequence[Set | Alias]
464
- | Domain
465
- | Condition,
438
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
466
439
  expression: Operation
467
440
  | Expression
468
441
  | MathOp
@@ -533,12 +506,7 @@ class Smax(Operation):
533
506
 
534
507
  def __init__(
535
508
  self,
536
- domain: Set
537
- | Alias
538
- | ImplicitSet
539
- | Sequence[Set | Alias]
540
- | Domain
541
- | Condition,
509
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
542
510
  expression: Operation
543
511
  | Expression
544
512
  | MathOp
@@ -609,12 +577,7 @@ class Sand(Operation):
609
577
 
610
578
  def __init__(
611
579
  self,
612
- domain: Set
613
- | Alias
614
- | ImplicitSet
615
- | Sequence[Set | Alias]
616
- | Domain
617
- | Condition,
580
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
618
581
  expression: Operation
619
582
  | Expression
620
583
  | MathOp
@@ -684,12 +647,7 @@ class Sor(Operation):
684
647
 
685
648
  def __init__(
686
649
  self,
687
- domain: Set
688
- | Alias
689
- | ImplicitSet
690
- | Sequence[Set | Alias]
691
- | Domain
692
- | Condition,
650
+ domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
693
651
  expression: Operation
694
652
  | Expression
695
653
  | MathOp
@@ -746,9 +704,7 @@ class Ord(operable.Operable):
746
704
 
747
705
  def __new__(cls, symbol: Set | Alias):
748
706
  if not isinstance(symbol, (syms.Set, syms.Alias)):
749
- raise ValidationError(
750
- "Ord operation is only for Set and Alias objects!"
751
- )
707
+ raise ValidationError("Ord operation is only for Set and Alias objects!")
752
708
 
753
709
  if symbol.is_singleton:
754
710
  return 1
@@ -110,9 +110,7 @@ def _cast_values(
110
110
  num_variables: str,
111
111
  solver_time: str,
112
112
  ) -> tuple[float, int | float, int | float, float]:
113
- objective = (
114
- float("nan") if objective_value == "NA" else float(objective_value)
115
- )
113
+ objective = float("nan") if objective_value == "NA" else float(objective_value)
116
114
  equations = float("nan") if num_equations == "NA" else int(num_equations)
117
115
  variables = float("nan") if num_variables == "NA" else int(num_variables)
118
116
  time = float("nan") if solver_time == "NA" else float(solver_time)
@@ -193,9 +191,7 @@ class Backend(ABC):
193
191
  gdx_in = os.path.basename(gdx_in)
194
192
  elif self.backend_type == "neos":
195
193
  gdx_in = "in.gdx"
196
- gams_string = self.container._generate_gams_string(
197
- gdx_in, modified_names
198
- )
194
+ gams_string = self.container._generate_gams_string(gdx_in, modified_names)
199
195
  self.make_unmodified(modified_names)
200
196
 
201
197
  return gams_string
@@ -225,9 +221,7 @@ class Backend(ABC):
225
221
  symbols = filtered_names
226
222
 
227
223
  if len(symbols) != 0:
228
- self.container._load_records_from_gdx(
229
- self.container._gdx_out, symbols
230
- )
224
+ self.container._load_records_from_gdx(self.container._gdx_out, symbols)
231
225
  self.make_unmodified(symbols)
232
226
 
233
227
  if relaxed_domain_mapping:
@@ -237,11 +231,7 @@ class Backend(ABC):
237
231
 
238
232
  new_domain = []
239
233
  for elem in symbol.domain:
240
- if (
241
- type(elem) is str
242
- and elem != "*"
243
- and elem in self.container
244
- ):
234
+ if type(elem) is str and elem != "*" and elem in self.container:
245
235
  new_domain.append(self.container[elem])
246
236
  else:
247
237
  new_domain.append(elem)
@@ -293,10 +283,8 @@ class Backend(ABC):
293
283
  _,
294
284
  ) = line.split(",")
295
285
 
296
- objective_value, num_equations, num_variables, solver_time = (
297
- _cast_values(
298
- objective_value, num_equations, num_variables, solver_time
299
- )
286
+ objective_value, num_equations, num_variables, solver_time = _cast_values(
287
+ objective_value, num_equations, num_variables, solver_time
300
288
  )
301
289
 
302
290
  dataframe = pd.DataFrame(