modelx v0.25.0 (2024年2月18日)#

本次发布包含以下功能增强、不兼容变更及错误修复。

要更新到 modelx v0.25.0,请使用以下命令:

>>> pip install modelx --upgrade

Anaconda用户应改用conda命令:

>>> conda update modelx

功能增强#

新属性Model.path的简介#

本次发布为Model类引入了一个新属性path。 该属性保存了模型加载或保存的路径, 表示为pathlib.Path对象。 在公式中可以通过特殊引用_model.path来访问该属性。

该属性使得公式能够通过使用相对于模型位置的路径来定位外部文件。

Python 3.12 支持#

modelx 现已支持 Python 3.12。

向后不兼容的变更#

由于避免C级递归导致的规格变更#

本次发布引入了以下两项规范变更:

  • 在公式中使用订阅操作[]调用单元格的功能将被移除。 该功能主要是语法糖,因此用户可以调整他们的模型改用调用操作()

  • Cells上的其他方法,例如match()将不再可用。 如果需要,仍然可以通过_space.cell_name直接访问单元格,其中cell_name是单元格的具体名称。

向后不兼容变更的缘由

在Python 3.11之前的版本中,Python的递归机制会触发C层级的递归,这意味着Python中的递归深度受限于C栈的大小。

在Python 3.11版本中,出现了一个重要的变化: 纯Python递归将不再引发C层级的递归。 这种分离最初似乎解决了该问题。 然而,Python 3.12版本中对C层级递归引入的硬编码限制表明, 某些双下划线方法,如__call____getitem__,仍然会引发C层级的递归。

由于modelx严重依赖单元格对象通过公式中的__call____getitem__调用其他单元格, modelx公式的递归限制实际上受限于C语言级别的递归限制。 尽管Python核心开发者计划在未来版本中提高硬编码的C语言级别递归限制, 但这并不能完全解决核心问题:modelx的递归限制仍然受限于C栈大小, 而该大小在不同平台上存在差异。例如,在Windows上默认C栈大小较小且线程启动后无法修改。我们通过为公式执行启动一个具有更大栈大小的新线程来规避此限制。相比之下,Linux允许动态增加C栈大小。

为解决这一问题,我们引入了一项不向后兼容的变更: 在与modelx空间关联的命名空间中,单元格名称现在将绑定到CellsImpl.call方法, 绕过Cells.__call__方法。这一调整有效地将modelx递归与C语言层面的递归分离, 使得modelx在所有支持平台(Windows、MacOS、Linux)上的递归能力几乎不受限制。

这次重构旨在使modelx能够适应未来不同Python版本和操作系统中的递归限制。

Bug修复#

  • 使用Python 3.12导出时出现AssertionError错误(GH93

  • 在Windows上由于已知问题导致read_model()中出现PermissionError。