Closed fumitoh closed 4 months ago
The modelx
library is fundamentally recursion-oriented, which presents a unique challenge: enabling practically unlimited recursion.
This challenge has been a focal point since the library's early development stages. In Python versions prior to 3.11, Python's recursion mechanism triggered C-level recursion, meaning the recursion depth in Python was constrained by the size of the C-stack.
With Python 3.11, there was a significant change: Pure Python recursion won't induce C-level recursion anymore. This separation appeared to address the issue initially. However, the introduction of a hardcoded limit on C-level recursion in Python 3.12
revealed that certain dunder methods, like __call__
and __getitem__
, still induce C-level recursion.
Since modelx
heavily relies on cells objects calling other cells through __call__
or __getitem__
in their formulas, the recursion limit for modelx
formulas is effectively bound by the C-level recursion limit.
Although Python core developers have plans to increase the hardcoded limit on C-level recursion in future Python releases, it doesn't fully resolve the core issue: the modelx
recursion limit remains constrained by the C-stack size, which varies across different platforms. For instance, on Windows, the default C-stack size is smaller and can't be altered after thread initiation. This limitation has been circumvented by initiating a new thread with a larger stack size for formula execution. In contrast, Linux allows dynamic increase of the C-stack size.
To address this issue comprehensively, a backward-incompatible change is proposed:
In the namespace associated with a modelx
space, cell names will now be bound to the CellsImpl.call
method, bypassing the Cells.__call__
method. This adjustment effectively detaches modelx
recursion from C-level recursion, rendering the recursion in modelx
virtually limitless on all supported platforms (Windows, MacOS, Linux).
However, this change comes with some backward compatibility issues:
[]
will be removed. This feature was primarily syntactic sugar, so users can adapt their models to use the call operation ()
instead.Cells
, such as match
, will not be available anymore. If needed, cells can still be accessed directly using _space.cell_name
, where cell_name
is the specific name of the cells.This restructuring aims to future-proof modelx
against recursion limits across different future Python versions and operating systems.
In Python 3.12, C level recusion limit is introduced: https://github.com/python/cpython/issues/112215 As a result, the maximum number of formula recusions in modelx is significantly lowered from 100,000+ down to slightly less than 500.
Workaound in modelx may be implemented, but Python core developers have intension to introduce a mechanism that adjust the limit according to the available C stack size. modelx users should be advised not to upgrade Python to 3.12 at the moment.