diff --git a/doc/Makefile b/doc/Makefile index 668e7c82a2c11d5800679c56dac0f388fdc13ee0..4da073efd8411593498b12e1cdde6c2e524f2d91 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -3,7 +3,7 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = sphinx-build +SPHINXBUILD = python `which sphinx-build` PAPER = BUILDDIR = _build diff --git a/doc/_static/akdoc.css b/doc/_static/akdoc.css index e83c3b72c2b03cb6bfcd5ed746afa7dd18bbdbf6..d8b61e3ff7a358e5d5c0f132b5040ec7c3f43e42 100644 --- a/doc/_static/akdoc.css +++ b/doc/_static/akdoc.css @@ -1,5 +1,5 @@ pre { - line-height: 100%; + line-height: 110%; } .footer { @@ -23,17 +23,17 @@ code { } h1 { - padding-bottom:5px; + padding-bottom:7px; border-bottom: 1px solid #ccc; } h2 { - padding-bottom:1px; + padding-bottom:5px; border-bottom: 1px solid #ccc; } h3 { - padding-bottom:1px; + padding-bottom:5px; border-bottom: 1px solid #ccc; } diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html index 0fed238faf1fc27457ad8672017577f055e7edf0..400e7ec1d49677537aff6bf744e2803ef5c01e9e 100644 --- a/doc/_templates/layout.html +++ b/doc/_templates/layout.html @@ -1,2 +1,2 @@ {% extends "!layout.html" %} -{% set css_files = css_files + ['_static/akdoc.css']%} +{% set bootswatch_css_custom = ['_static/akdoc.css']%} diff --git a/doc/conf.py b/doc/conf.py index c2dfa23d37d322f4d2562c3268ea65f9af428e2c..d57aa798b5bcc822fd3944b566ea54c0b9a57b33 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -31,7 +31,7 @@ extensions = [ 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.mathjax', - 'sphinx.ext.viewcode' + #'sphinx.ext.viewcode' ] # Add any paths that contain templates here, relative to this directory. diff --git a/pymbolic/__init__.py b/pymbolic/__init__.py index 4f1101f99f8dae4aef8fa5f578fada7ec371b739..740febc7dcd600a13c7067abf216ce9122d9da72 100644 --- a/pymbolic/__init__.py +++ b/pymbolic/__init__.py @@ -134,7 +134,7 @@ import pymbolic.mapper.distributor import pymbolic.mapper.flattener import pymbolic.primitives -from pymbolic.polynomial import Polynomial +from pymbolic.polynomial import Polynomial # noqa var = pymbolic.primitives.Variable variables = pymbolic.primitives.variables diff --git a/pymbolic/mapper/__init__.py b/pymbolic/mapper/__init__.py index 8f7c6ae2a7abf2866c1c80ce6df225f11cfbd473..e0c0d23028d09c5bcd485f4c5181a3d2e4265a9d 100644 --- a/pymbolic/mapper/__init__.py +++ b/pymbolic/mapper/__init__.py @@ -334,7 +334,7 @@ class IdentityMapper(Mapper): ) def map_subscript(self, expr, *args): - return expr.__class__( + return type(expr)( self.rec(expr.aggregate, *args), self.rec(expr.index, *args)) diff --git a/pymbolic/primitives.py b/pymbolic/primitives.py index 84ce880e2153d135bebbcd06045c9bdbaadd7561..74727a5cd0f38cf52ad2e41fd6d59aa6648b7511 100644 --- a/pymbolic/primitives.py +++ b/pymbolic/primitives.py @@ -25,6 +25,8 @@ THE SOFTWARE. import pymbolic.traits as traits __doc__ = """ +.. autofunction:: disable_subscript_by_getitem + Expression base class --------------------- @@ -37,6 +39,13 @@ Expression base class The :class:`pymbolic.mapper.Mapper` method called for objects of this type. + .. method:: __getitem__ + + Deprecated, see :func:`disable_subscript_by_getitem`. Use :meth:`index` + instead. + + .. automethod:: index + .. automethod:: stringifier .. automethod:: __eq__ @@ -178,10 +187,32 @@ _SUBSCRIPT_BY_GETITEM = True def disable_subscript_by_getitem(): + """In prior versions of :mod:`pymbolic`, directly subscripting an :class:`Expression` + subclass generated a :class:`Subscript`. For various reasons, this was a + very bad idea. For example, the following code snippet would result in an + infinite loop:: + + for el in expr: + print(el) + + :mod:`numpy` does similar things under the hodd, leading to hard-to-debug + infinite loops. As a result, this behavior is being deprecated. In Pymbolic + 2016.x, it will disappear entirely. It can also be disabled by this + function. Once disabled, it cannot be reenabled. + + See also :meth:`Expression.index`. + + .. versionadded:: 2014.3 + """ + global _SUBSCRIPT_BY_GETITEM _SUBSCRIPT_BY_GETITEM = False - del Expression.__getitem__ + try: + del Expression.__getitem__ + except AttributeError: + # Yay, somebody did the sane thing before us. + pass class Expression(object): @@ -395,6 +426,11 @@ class Expression(object): return NotImplemented def index(self, subscript): + """Return an expression representing ``self[subscript]``. + + .. versionadded:: 2014.3 + """ + if subscript == (): return self else: diff --git a/pymbolic/version.py b/pymbolic/version.py index 5849b3919bdd6ab84a8aa20bf8921894e6f6c8f0..e98c37ce6fd59334a71a8c2031e9448d6f5219c3 100644 --- a/pymbolic/version.py +++ b/pymbolic/version.py @@ -1,3 +1,3 @@ -VERSION = (2014, 2) +VERSION = (2014, 3) VERSION_STATUS = "" VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS diff --git a/test/test_pymbolic.py b/test/test_pymbolic.py index e5c32d0d47ddc05ae59432ebaef73a469931c4f6..48c4740d4b14bd89dfbf3d6a96bc5807b8020801 100644 --- a/test/test_pymbolic.py +++ b/test/test_pymbolic.py @@ -22,9 +22,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +import pymbolic import pymbolic.primitives as prim import pytest + from pymbolic.mapper import IdentityMapper try: @@ -33,6 +35,8 @@ except NameError: from functools import reduce +pymbolic.disable_subscript_by_getitem() + def test_integer_power(): from pymbolic.algorithm import integer_power @@ -250,6 +254,7 @@ def test_mappers(): WalkMapper()(expr) DependencyMapper()(expr) + # {{{ geometric algebra @pytest.mark.parametrize("dims", [2, 3, 4, 5])