From 958c47f1f3c39bff50d48308239eb75210d6f0eb Mon Sep 17 00:00:00 2001
From: Matthew Newville
Date: Sun, 19 Jan 2025 15:36:50 -0600
Subject: [PATCH] update docs
---
_sources/api.rst.txt | 2 +-
_sources/installation.rst.txt | 13 +--
_sources/motivation.rst.txt | 141 ++++++++++++++-----------
_static/basic.css | 15 +--
_static/bizstyle.css | 7 --
_static/bizstyle.js | 16 +--
_static/doctools.js | 7 --
_static/documentation_options.js | 2 +-
_static/language_data.js | 7 --
_static/pygments.css | 66 ++++++------
_static/searchtools.js | 38 ++++---
api.html | 74 ++++++-------
asteval.pdf | Bin 232840 -> 262734 bytes
asteval_doc.zip | Bin 1932121 -> 351892 bytes
basics.html | 22 ++--
genindex.html | 12 +--
index.html | 33 +++---
installation.html | 30 +++---
motivation.html | 171 +++++++++++++++++--------------
py-modindex.html | 12 +--
search.html | 12 +--
searchindex.js | 2 +-
22 files changed, 351 insertions(+), 331 deletions(-)
diff --git a/_sources/api.rst.txt b/_sources/api.rst.txt
index f095610..7c0f567 100644
--- a/_sources/api.rst.txt
+++ b/_sources/api.rst.txt
@@ -153,7 +153,7 @@ Interpreter methods and attributes
An Interpreter instance has many methods, but most of them are
implementation details for how to handle particular AST nodes, and should
-not be considered as part of the usable API. The methods described be low,
+not be considered as part of the usable API. The methods described below,
and the examples elsewhere in this documentation should be used as the
stable API.
diff --git a/_sources/installation.rst.txt b/_sources/installation.rst.txt
index 103c0da..796c1b4 100644
--- a/_sources/installation.rst.txt
+++ b/_sources/installation.rst.txt
@@ -11,7 +11,7 @@ Requirements
~~~~~~~~~~~~~~~
Asteval is a pure Python module. The latest stable version is |release|, which
-supports Python 3.8 through 3.12.
+supports Python 3.9 through 3.13.
Installing `asteval` requires `setuptools` and `setuptools_scm`. No other
libraries outside of the standard library are required. If `numpy`_ and
@@ -20,11 +20,12 @@ Running the test suite requires the `pytest`, `coverage`, and `pytest-cov`
modules, deployment uses `build` and `twine`, and building the documentation
requires `sphinx`.
-Python 3.8 through 3.12 are tested on Windows, MacOS, and Linux, with and
-without `numpy`_ installed. Older Python versions have generally been
-supported by `asteval` until they are well past the end of security fixes. That
-is, while `asteval` is no longer tested with Python 3.7, the latest release may
-continue to work with that version.
+Python 3.9 through 3.13 are tested on Windows, MacOS, and Linux, with
+and without `numpy`_ installed. Older Python versions have generally
+been supported by `asteval` until they are well past the end of
+security fixes. While `asteval` may continue to work with Python 3.8
+or even 3.7, these are not supported.
+
Support for new versions of the Python 3 series is not guaranteed until some
time after the official release of that version, as we may not start testing
diff --git a/_sources/motivation.rst.txt b/_sources/motivation.rst.txt
index df4c051..7e17815 100644
--- a/_sources/motivation.rst.txt
+++ b/_sources/motivation.rst.txt
@@ -52,18 +52,24 @@ approach the speed of `eval` and the `numexpr` modules.
How Safe is asteval?
=======================
-Asteval avoids all of the exploits we know about that make :py:func:`eval`
-dangerous. For reference, see, `Eval is really dangerous
-`_ and the
-comments and links therein. From this discussion it is apparent that not only
-is :py:func:`eval` unsafe, but that it is a difficult prospect to make any
-program that takes user input perfectly safe. In particular, if a user can
-cause Python to crash with a segmentation fault, safety cannot be guaranteed.
-Asteval explicitly forbids the exploits described in the above link, and works
-hard to prevent malicious code from crashing Python or accessing the
-underlying operating system. That said, we cannot guarantee that asteval is
-completely safe from malicious code. We claim only that it is safer than the
-builtin :py:func:`eval`, and that you might find it useful.
+Asteval avoids all of the exploits we know about that make
+:py:func:`eval` dangerous. For reference, see, `Eval is really
+dangerous
+`_
+and the comments and links therein. From this discussion it is
+apparent that not only is :py:func:`eval` unsafe, but that it is a
+difficult prospect to make any program that takes user input perfectly
+safe. In particular, if a user can cause Python to crash with a
+segmentation fault, safety cannot be guaranteed. Asteval explicitly
+forbids the exploits described in the above link, and works hard to
+prevent malicious code from crashing Python or accessing the
+underlying operating system. That said, we cannot guarantee that
+asteval is completely safe from malicious code. We claim only that it
+is safer than the builtin :py:func:`eval`, and that you might find it
+useful. We also note that several other Python libraries that
+evaluate user-supplied expressions, including `numexpr` and `sympy`
+use the builtin :py:func:`eval` as part of their processing.
+
Some of the things not allowed in the asteval interpreter for safety reasons include:
@@ -84,19 +90,22 @@ Some of the things not allowed in the asteval interpreter for safety reasons inc
In addition (and following the discussion in the link above), the following
attributes are blacklisted for all objects, and cannot be accessed:
- ``func_globals``, ``func_code``, ``func_closure``,
- ``im_class``, ``im_func``, ``im_self``,
- ``gi_code``, ``gi_frame``, ``f_locals``
+ ``func_globals``, ``func_code``, ``func_closure``, ``im_class``,
+ ``im_func``, ``im_self``, ``gi_code``, ``gi_frame``, ``f_locals``,
+ ``__mro__``, ``_mro``
-While this approach of making a blacklist cannot be guaranteed to be complete,
-it does eliminate entire classes of attacks known to be able to seg-fault the
-Python interpreter.
+[Note: this list may be incomplete - there may be other disallowed
+attributes]. While this approach of making a blacklist cannot be
+guaranteed to be complete, it does eliminate entire classes of attacks
+known to be able to seg-fault the Python interpreter or give access to
+the operating system.
-An important caveat is that asteval will typically expose numpy ``ufuncs`` from the
-numpy module. Several of these can seg-fault Python without too much trouble.
-If you are paranoid about safe user input that can never cause a segmentation
-fault, you may want to consider disabling the use of numpy, or take extra care
-to specify what can be used.
+An important caveat is that a typical use of asteval will import and
+expose numpy ``ufuncs`` from the numpy module. Several of these can
+seg-fault Python without too much trouble. If you safety from user
+input causing segmentation fault is a primary concern, you may want to
+consider disabling the use of numpy, or take extra care to specify
+what numpy functions can be used.
In 2024, an independent security audit of asteval done by Andrew Effenhauser,
Ayman Hammad, and Daniel Crowley in the X-Force Security Research division of
@@ -108,35 +117,46 @@ needed, these modules can be added to any Interpreter either using the
``user_symbols`` argument when creating it, or adding the needed symbols to the
symbol table after the Interpreter is created.
-There are important categories of safety that asteval may attempt to address,
-but cannot guarantee success. The most important of these is resource hogging,
-which might be used for a denial-of-service attack. There is no guaranteed
-timeout on any calculation, and so a reasonable looking calculation such as::
+In 2025, William Khem Marquez demonstrated two vulnerabilities: one
+from leaving some AST objects exposed within the interpreter for
+user-defined functions ("Procedures"), and one with f-string
+formatting. Both of these were fixed for version 1.0.6.
+
+There are other categories of safety that asteval may attempt to
+address, but cannot guarantee success. The most important of these is
+resource hogging, which might be used for a denial-of-service attack.
+There is no guaranteed timeout on any calculation, and so a reasonable
+looking calculation such as::
from asteval import Interpreter
aeval = Interpreter()
- txt = """nmax = 1e8
+ txt = """
+ nmax = 1e8
a = sqrt(arange(nmax)) # using numpy.sqrt() and numpy.arange()
"""
aeval.eval(txt)
-can take a noticeable amount of CPU time - if it does not, increasing that
-value of ``nmax`` almost certainly will, and can even crash the Python shell.
-
-As another example, consider the expression ``x**y**z``. For values
-``x=y=z=5``, the run time will be well under 0.001 seconds. For ``x=y=z=8``,
-run time will still be under 1 sec. Changing to ``x=8, y=9, z=9``, will cause
-the statement to take several seconds. With ``x=y=z=9``, executing that
-statement may take more than 1 hour on some machines. It is not hard to come
-up with short program that would run for hundreds of years, which probably
-exceeds anyones threshold for an acceptable run-time. There simply is not a
-good way to predict how long any code will take to run from the text of the
-code itself: run time cannot be determined lexically.
-
-To be clear, for the ``x**y**z`` exponentiation example, asteval will raise a
-runtime error, telling you that an exponent > 10,000 is not allowed. Several
-other attempts are made to prevent long-running operations or memory
-exhaustion. These checks will prevent:
+can take a noticeable amount of CPU time - if it does not, increasing
+that value of ``nmax`` almost certainly will, and can even crash the
+Python shell.
+
+As another example, and an illustration of the fundamental problem,
+consider the Python expression ``a = x**y**z``. For values
+``x=y=z=5``, the run time will be well under 0.001 seconds. For
+``x=y=z=8``, run time will still be under 1 sec. Changing to ``x=8,
+y=9, z=9``, Python will ake several seconds (the value is :math:`\sim
+10^{350,000,000}`) With ``x=y=z=9``, executing that statement may take
+more than 1 hour on some machines. It is not hard to come up with
+short program that would run for hundreds of years, which probably
+exceeds everyones threshold for an acceptable run-time. The point
+here is tha there simply is not a good way to predict how long any
+code will take to run from the text of the code itself: run time
+cannot be determined lexically.
+
+To be clear, for the ``x**y**z`` exponentiation example, asteval will
+raise a runtime error, telling you that an exponent > 10,000 is not
+allowed. Several other attempts are also made to prevent long-running
+operations or memory exhaustion. These checks will prevent:
* statements longer than 50,000 bytes.
* values of exponents (``p`` in ``x**p``) > 10,000.
@@ -145,11 +165,23 @@ exhaustion. These checks will prevent:
* more than 262144 open buffers
* opening a file with a mode other than ``'r'``, ``'rb'``, or ``'ru'``.
-These checks happen at runtime, not by analyzing the text of the code. As with
-the example above using ``numpy.arange``, very large arrays and lists can be
-created that might approach memory limits. There are countless other "clever
-ways" to have very long run times that cannot be readily predicted from the
-text.
+These checks happen at runtime, not by analyzing the text of the code.
+As with the example above using ``numpy.arange``, very large arrays
+and lists can be created that might approach memory limits. There are
+countless other "clever ways" to have very long run times that cannot
+be readily predicted from the text of the code.
+
+By default, the list of supported functions does include Python's
+``open()`` -- in read-only mode -- which will allow disk access to the
+untrusted user. If ``numpy`` is supported, its ``load()`` and
+``loadtxt()`` functions will also normally be supported. By itself,
+including these functions does not elevate permissions, and access is
+restricted to 'read-only mode'. Still, the user of the asteval
+interpreter would be able to read files with the privileges of the
+calling program. In some cases, this may not be desirable, and you
+may want to remove some of these functions from the symbol table,
+re-implement them, or ensure that your program cannot access
+information on disk that should be kept private.
The exponential example also highlights the issue that there is not a good way
to check for a long-running calculation within a single Python process. That
@@ -182,15 +214,6 @@ executing expressions, with a code like this::
with limited_recursion(100):
Interpreter().eval(...)
-A secondary security concern is that the default list of supported functions
-does include Python's ``open()`` which will allow disk access to the untrusted
-user. If ``numpy`` is supported, its ``load()`` and ``loadtxt()`` functions will
-also normally be supported. Including these functions does not elevate
-permissions, but it does allow the user of the asteval interpreter to read
-files with the privileges of the calling program. In some cases, this may not
-be desirable, and you may want to remove some of these functions from the
-symbol table, re-implement them, or ensure that your program cannot access
-information on disk that should be kept private.
In summary, while asteval attempts to be safe and is definitely safer than
using :py:func:`eval`, there may be ways that using asteval could lead to
diff --git a/_static/basic.css b/_static/basic.css
index f9cdda4..5e1cb13 100644
--- a/_static/basic.css
+++ b/_static/basic.css
@@ -1,12 +1,5 @@
/*
- * basic.css
- * ~~~~~~~~~
- *
* Sphinx stylesheet -- basic theme.
- *
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
*/
/* -- main layout ----------------------------------------------------------- */
@@ -115,15 +108,11 @@ img {
/* -- search page ----------------------------------------------------------- */
ul.search {
- margin: 10px 0 0 20px;
- padding: 0;
+ margin-top: 10px;
}
ul.search li {
- padding: 5px 0 5px 20px;
- background-image: url(file.png);
- background-repeat: no-repeat;
- background-position: 0 7px;
+ padding: 5px 0;
}
ul.search li a {
diff --git a/_static/bizstyle.css b/_static/bizstyle.css
index 7d42531..2b46ec3 100644
--- a/_static/bizstyle.css
+++ b/_static/bizstyle.css
@@ -1,12 +1,5 @@
/*
- * bizstyle.css_t
- * ~~~~~~~~~~~~~~
- *
* Sphinx stylesheet -- business style theme.
- *
- * :copyright: Copyright 2007-2024 by Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
*/
@import url("basic.css");
diff --git a/_static/bizstyle.js b/_static/bizstyle.js
index df6741c..a942f23 100644
--- a/_static/bizstyle.js
+++ b/_static/bizstyle.js
@@ -1,14 +1,8 @@
-//
-// bizstyle.js
-// ~~~~~~~~~~~
-//
-// Sphinx javascript -- for bizstyle theme.
-//
-// This theme was created by referring to 'sphinxdoc'
-//
-// :copyright: Copyright 2007-2024 by Sphinx team, see AUTHORS.
-// :license: BSD, see LICENSE for details.
-//
+/*
+ * Sphinx javascript -- for bizstyle theme.
+ *
+ * This theme was created by referring to 'sphinxdoc'
+ */
const initialiseBizStyle = () => {
if (navigator.userAgent.indexOf("iPhone") > 0 || navigator.userAgent.indexOf("Android") > 0) {
document.querySelector("li.nav-item-0 a").innerText = "Top"
diff --git a/_static/doctools.js b/_static/doctools.js
index 4d67807..0398ebb 100644
--- a/_static/doctools.js
+++ b/_static/doctools.js
@@ -1,12 +1,5 @@
/*
- * doctools.js
- * ~~~~~~~~~~~
- *
* Base JavaScript utilities for all Sphinx HTML documentation.
- *
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
*/
"use strict";
diff --git a/_static/documentation_options.js b/_static/documentation_options.js
index d0fab5f..23c8b44 100644
--- a/_static/documentation_options.js
+++ b/_static/documentation_options.js
@@ -1,5 +1,5 @@
const DOCUMENTATION_OPTIONS = {
- VERSION: '1.0.5',
+ VERSION: '1.0.6',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
diff --git a/_static/language_data.js b/_static/language_data.js
index 367b8ed..c7fe6c6 100644
--- a/_static/language_data.js
+++ b/_static/language_data.js
@@ -1,13 +1,6 @@
/*
- * language_data.js
- * ~~~~~~~~~~~~~~~~
- *
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
- *
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
*/
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
diff --git a/_static/pygments.css b/_static/pygments.css
index 0d49244..5f2b0a2 100644
--- a/_static/pygments.css
+++ b/_static/pygments.css
@@ -6,26 +6,26 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
-.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .err { border: 1px solid #F00 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
-.highlight .o { color: #666666 } /* Operator */
+.highlight .o { color: #666 } /* Operator */
.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
-.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .cs { color: #408090; background-color: #FFF0F0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
-.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gr { color: #F00 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
-.highlight .go { color: #333333 } /* Generic.Output */
-.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .go { color: #333 } /* Generic.Output */
+.highlight .gp { color: #C65D09; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .gt { color: #04D } /* Generic.Traceback */
.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
@@ -33,43 +33,43 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left:
.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #902000 } /* Keyword.Type */
.highlight .m { color: #208050 } /* Literal.Number */
-.highlight .s { color: #4070a0 } /* Literal.String */
-.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .s { color: #4070A0 } /* Literal.String */
+.highlight .na { color: #4070A0 } /* Name.Attribute */
.highlight .nb { color: #007020 } /* Name.Builtin */
-.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.highlight .no { color: #60add5 } /* Name.Constant */
-.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .nc { color: #0E84B5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60ADD5 } /* Name.Constant */
+.highlight .nd { color: #555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #D55537; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #007020 } /* Name.Exception */
-.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nf { color: #06287E } /* Name.Function */
.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
-.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nn { color: #0E84B5; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .nv { color: #BB60D5 } /* Name.Variable */
.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #208050 } /* Literal.Number.Bin */
.highlight .mf { color: #208050 } /* Literal.Number.Float */
.highlight .mh { color: #208050 } /* Literal.Number.Hex */
.highlight .mi { color: #208050 } /* Literal.Number.Integer */
.highlight .mo { color: #208050 } /* Literal.Number.Oct */
-.highlight .sa { color: #4070a0 } /* Literal.String.Affix */
-.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
-.highlight .sc { color: #4070a0 } /* Literal.String.Char */
-.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
-.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
-.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sa { color: #4070A0 } /* Literal.String.Affix */
+.highlight .sb { color: #4070A0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070A0 } /* Literal.String.Char */
+.highlight .dl { color: #4070A0 } /* Literal.String.Delimiter */
+.highlight .sd { color: #4070A0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070A0 } /* Literal.String.Double */
+.highlight .se { color: #4070A0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070A0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70A0D0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #C65D09 } /* Literal.String.Other */
.highlight .sr { color: #235388 } /* Literal.String.Regex */
-.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .s1 { color: #4070A0 } /* Literal.String.Single */
.highlight .ss { color: #517918 } /* Literal.String.Symbol */
.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.highlight .fm { color: #06287e } /* Name.Function.Magic */
-.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
-.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
-.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
+.highlight .fm { color: #06287E } /* Name.Function.Magic */
+.highlight .vc { color: #BB60D5 } /* Name.Variable.Class */
+.highlight .vg { color: #BB60D5 } /* Name.Variable.Global */
+.highlight .vi { color: #BB60D5 } /* Name.Variable.Instance */
+.highlight .vm { color: #BB60D5 } /* Name.Variable.Magic */
.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/_static/searchtools.js b/_static/searchtools.js
index b08d58c..2c774d1 100644
--- a/_static/searchtools.js
+++ b/_static/searchtools.js
@@ -1,12 +1,5 @@
/*
- * searchtools.js
- * ~~~~~~~~~~~~~~~~
- *
* Sphinx JavaScript utilities for the full-text search.
- *
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
*/
"use strict";
@@ -20,7 +13,7 @@ if (typeof Scorer === "undefined") {
// and returns the new score.
/*
score: result => {
- const [docname, title, anchor, descr, score, filename] = result
+ const [docname, title, anchor, descr, score, filename, kind] = result
return score
},
*/
@@ -47,6 +40,14 @@ if (typeof Scorer === "undefined") {
};
}
+// Global search result kind enum, used by themes to style search results.
+class SearchResultKind {
+ static get index() { return "index"; }
+ static get object() { return "object"; }
+ static get text() { return "text"; }
+ static get title() { return "title"; }
+}
+
const _removeChildren = (element) => {
while (element && element.lastChild) element.removeChild(element.lastChild);
};
@@ -64,9 +65,13 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
const contentRoot = document.documentElement.dataset.content_root;
- const [docName, title, anchor, descr, score, _filename] = item;
+ const [docName, title, anchor, descr, score, _filename, kind] = item;
let listItem = document.createElement("li");
+ // Add a class representing the item's type:
+ // can be used by a theme's CSS selector for styling
+ // See SearchResultKind for the class names.
+ listItem.classList.add(`kind-${kind}`);
let requestUrl;
let linkUrl;
if (docBuilder === "dirhtml") {
@@ -115,8 +120,10 @@ const _finishSearch = (resultCount) => {
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
);
else
- Search.status.innerText = _(
- "Search finished, found ${resultCount} page(s) matching the search query."
+ Search.status.innerText = Documentation.ngettext(
+ "Search finished, found one page matching the search query.",
+ "Search finished, found ${resultCount} pages matching the search query.",
+ resultCount,
).replace('${resultCount}', resultCount);
};
const _displayNextItem = (
@@ -138,7 +145,7 @@ const _displayNextItem = (
else _finishSearch(resultCount);
};
// Helper function used by query() to order search results.
-// Each input is an array of [docname, title, anchor, descr, score, filename].
+// Each input is an array of [docname, title, anchor, descr, score, filename, kind].
// Order the results by score (in opposite order of appearance, since the
// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
const _orderResultsByScoreThenName = (a, b) => {
@@ -248,6 +255,7 @@ const Search = {
searchSummary.classList.add("search-summary");
searchSummary.innerText = "";
const searchList = document.createElement("ul");
+ searchList.setAttribute("role", "list");
searchList.classList.add("search");
const out = document.getElementById("search-results");
@@ -318,7 +326,7 @@ const Search = {
const indexEntries = Search._index.indexentries;
// Collect multiple result groups to be sorted separately and then ordered.
- // Each is an array of [docname, title, anchor, descr, score, filename].
+ // Each is an array of [docname, title, anchor, descr, score, filename, kind].
const normalResults = [];
const nonMainIndexResults = [];
@@ -337,6 +345,7 @@ const Search = {
null,
score + boost,
filenames[file],
+ SearchResultKind.title,
]);
}
}
@@ -354,6 +363,7 @@ const Search = {
null,
score,
filenames[file],
+ SearchResultKind.index,
];
if (isMain) {
normalResults.push(result);
@@ -475,6 +485,7 @@ const Search = {
descr,
score,
filenames[match[0]],
+ SearchResultKind.object,
]);
};
Object.keys(objects).forEach((prefix) =>
@@ -585,6 +596,7 @@ const Search = {
null,
score,
filenames[file],
+ SearchResultKind.text,
]);
}
return results;
diff --git a/api.html b/api.html
index 234da23..e825d11 100644
--- a/api.html
+++ b/api.html
@@ -7,11 +7,11 @@
Asteval Reference — ASTEVAL: Minimal Python AST evaluator
-
-
+
+
-
-
+
+
@@ -69,16 +69,16 @@
nested_symtable (bool, optional) – whether to use a new-style nested symbol table instead of a plain dict [False]
+
nested_symtable (bool, optional) – whether to use a new-style nested symbol table instead of a plain dict [False]
user_symbols (dict or None) – dictionary of user-defined symbols to add to symbol table.
writer (file-like or None) – callable file-like object where standard output will be sent.
err_writer (file-like or None) – callable file-like object where standard error will be sent.
-
use_numpy (bool) – whether to use functions from numpy.
-
max_statement_length (int) – maximum length of expression allowed [50,000 characters]
+
use_numpy (bool) – whether to use functions from numpy.
+
max_statement_length (int) – maximum length of expression allowed [50,000 characters]
readonly_symbols (iterable or None) – symbols that the user can not assign to
-
builtins_readonly (bool) – whether to blacklist all symbols that are in the initial symtable
-
minimal (bool) – create a minimal interpreter: disable many nodes (see Note 1).
-
config (dict) – dictionay listing which nodes to support (see note 2))
+
builtins_readonly (bool) – whether to blacklist all symbols that are in the initial symtable
+
minimal (bool) – create a minimal interpreter: disable many nodes (see Note 1).
+
config (dict) – dictionay listing which nodes to support (see note 2))
@@ -94,13 +94,13 @@
The make_symbol_table()
that will include several standard python builtin functions, several functions
-from the math module and (if available and not turned off) several
+from the math module and (if available and not turned off) several
functions from numpy.
The writer argument can be used to provide a place to send all output
-that would normally go to sys.stdout. The default is, of
-course, to send output to sys.stdout. Similarly, err_writer
+that would normally go to sys.stdout. The default is, of
+course, to send output to sys.stdout. Similarly, err_writer
will be used for output that will otherwise be sent to
-sys.stderr.
An Interpreter instance has many methods, but most of them are
implementation details for how to handle particular AST nodes, and should
-not be considered as part of the usable API. The methods described be low,
+not be considered as part of the usable API. The methods described below,
and the examples elsewhere in this documentation should be used as the
stable API.
fromastevalimportInterpreter,make_symbol_table
+importnumpyasnp
+defcosd(x):"cos with angle in degrees"returnnp.cos(np.radians(x))
-defsind(x):
+defsind(x):"sin with angle in degrees"returnnp.sin(np.radians(x))
-deftand(x):
+deftand(x):"tan with angle in degrees"returnnp.tan(np.radians(x))
@@ -584,8 +584,8 @@