diff --git a/.github/workflows/test-core.yml b/.github/workflows/test-core.yml new file mode 100644 index 00000000..d3dfb3a7 --- /dev/null +++ b/.github/workflows/test-core.yml @@ -0,0 +1,60 @@ +name: Test scikits-odes-core + +on: [push, pull_request] + +jobs: + tests: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + #- python-version: "3.7" + # tox-env: py37 + #- python-version: "3.8" + # tox-env: py38 + #- python-version: "3.9" + # tox-env: py39 + #- python-version: "3.10" + # tox-env: py310 + #- python-version: "3.11" + # tox-env: py311 + #- python-version: "3.12" + # tox-env: py312 + - python-version: "3.11" + tox-env: check-manifest + #- python-version: "3.11" + # tox-env: checkreadme + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-1 + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade tox + + - name: Run tests + run: | + cd packages/scikits-odes-core && tox + env: + TOXENV: ${{ matrix.tox-env }} diff --git a/.github/workflows/test-daepack.yml b/.github/workflows/test-daepack.yml new file mode 100644 index 00000000..59f9c029 --- /dev/null +++ b/.github/workflows/test-daepack.yml @@ -0,0 +1,59 @@ +name: Test scikits-odes-daepack + +on: [push, pull_request] + +jobs: + tests: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - python-version: "3.7" + tox-env: py37 + - python-version: "3.8" + tox-env: py38 + - python-version: "3.9" + tox-env: py39 + - python-version: "3.10" + tox-env: py310 + - python-version: "3.11" + tox-env: py311 + - python-version: "3.12" + tox-env: py312 + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install build dependencies + run: sudo apt-get install gfortran + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-1 + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade tox + + - name: Run tests + run: | + cd packages/scikits-odes-daepack && tox + env: + TOXENV: ${{ matrix.tox-env }} diff --git a/.github/workflows/test-namespace.yml b/.github/workflows/test-namespace.yml new file mode 100644 index 00000000..21f96a21 --- /dev/null +++ b/.github/workflows/test-namespace.yml @@ -0,0 +1,121 @@ +name: Test scikits-odes + +on: [push, pull_request] + +jobs: + tests: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + #- python-version: "3.7" + # sundials-version: "6.5.0" + # tox-env: py37 + # sundials-precision: double + # sundials-index-size: 64 + - python-version: "3.8" + sundials-version: "6.5.0" + tox-env: py38 + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.9" + sundials-version: "6.5.0" + tox-env: py39 + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.10" + sundials-version: "6.5.0" + tox-env: py310 + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311 + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.12" + sundials-version: "6.5.0" + tox-env: py312 + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: check-manifest + sundials-precision: double + sundials-index-size: 64 + #- python-version: "3.11" + # sundials-version: "6.5.0" + # tox-env: checkreadme + # sundials-precision: double + # sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311 + sundials-precision: double + sundials-index-size: 32 + #- python-version: "3.11" + # sundials-version: "6.5.0" + # tox-env: py311 + # sundials-precision: single + # sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311 + sundials-precision: extended + sundials-index-size: 64 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install build dependencies + run: sudo apt-get install gfortran liblapack-dev + + - name: Sundials cache + uses: actions/cache@v2 + with: + path: ~/sundials + key: ${{ runner.os }}-sundials-${{ matrix.sundials-version }} + restore-keys: | + ${{ runner.os }}-sundials- + + - name: Install sundials + run: | + source ci_support/ensure_sundials_installed.sh && + printf "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH\n export LIBRARY_PATH=$LIBRARY_PATH\n export CPATH=$CPATH" > sundials_env.sh + env: + SUNDIALS_VERSION: ${{ matrix.sundials-version }} + SUNDIALS_PRECISION: ${{ matrix.sundials-precision }} + SUNDIALS_INDEX_SIZE: ${{ matrix.sundials-index-size }} + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-1 + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade tox + + - name: Run tests + run: | + cat sundials_env.sh + source sundials_env.sh && + env && + cd packages/scikits-odes && + tox + env: + TOXENV: ${{ matrix.tox-env }} diff --git a/.github/workflows/test-overall.yml b/.github/workflows/test-overall.yml new file mode 100644 index 00000000..b2d4ab73 --- /dev/null +++ b/.github/workflows/test-overall.yml @@ -0,0 +1,126 @@ +name: Python package + +on: [push, pull_request] + +jobs: + tests: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + #- python-version: "3.7" + # sundials-version: "6.5.0" + # tox-env: py37-test + # sundials-precision: double + # sundials-index-size: 64 + - python-version: "3.8" + sundials-version: "6.5.0" + tox-env: py38-test + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.9" + sundials-version: "6.5.0" + tox-env: py39-test + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.10" + sundials-version: "6.5.0" + tox-env: py310-test + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311-test + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.12" + sundials-version: "6.5.0" + tox-env: py312-test + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: doctr + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: docs + sundials-precision: double + sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311-test + sundials-precision: double + sundials-index-size: 32 + #- python-version: "3.11" + # sundials-version: "6.5.0" + # tox-env: py311-test + # sundials-precision: single + # sundials-index-size: 64 + - python-version: "3.11" + sundials-version: "6.5.0" + tox-env: py311-test + sundials-precision: extended + sundials-index-size: 64 + #- python-version: "3.12" + # sundials-version: "6.5.0" + # tox-env: py312-notebooks + # sundials-precision: double + # sundials-index-size: 64 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install build dependencies + run: sudo apt-get install gfortran liblapack-dev + + - name: Sundials cache + uses: actions/cache@v2 + with: + path: ~/sundials + key: ${{ runner.os }}-sundials-${{ matrix.sundials-version }} + restore-keys: | + ${{ runner.os }}-sundials- + + - name: Install sundials + run: | + source ci_support/ensure_sundials_installed.sh && + printf "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH\n export LIBRARY_PATH=$LIBRARY_PATH\n export CPATH=$CPATH" > sundials_env.sh + env: + SUNDIALS_VERSION: ${{ matrix.sundials-version }} + SUNDIALS_PRECISION: ${{ matrix.sundials-precision }} + SUNDIALS_INDEX_SIZE: ${{ matrix.sundials-index-size }} + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: pip cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-pip-1 + restore-keys: | + ${{ runner.os }}-pip- + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install "setuptools<=64.0.0" + python -m pip install --upgrade tox + + - name: Run tests + run: | + cat sundials_env.sh + source sundials_env.sh && + env && + tox + env: + TOXENV: ${{ matrix.tox-env }} diff --git a/.github/workflows/tests.yml b/.github/workflows/test-sundials.yml similarity index 77% rename from .github/workflows/tests.yml rename to .github/workflows/test-sundials.yml index 287d42fb..59c580af 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/test-sundials.yml @@ -1,4 +1,4 @@ -name: Python package +name: Test scikits-odes-sundials on: [push, pull_request] @@ -10,11 +10,11 @@ jobs: fail-fast: false matrix: include: - - python-version: "3.7" - sundials-version: "6.5.0" - tox-env: py37 - sundials-precision: double - sundials-index-size: 64 + #- python-version: "3.7" + # sundials-version: "6.5.0" + # tox-env: py37 + # sundials-precision: double + # sundials-index-size: 64 - python-version: "3.8" sundials-version: "6.5.0" tox-env: py38 @@ -40,36 +40,26 @@ jobs: tox-env: py312 sundials-precision: double sundials-index-size: 64 - - python-version: "3.11" - sundials-version: "6.5.0" - tox-env: doctr - sundials-precision: double - sundials-index-size: 64 - - python-version: "3.11" - sundials-version: "6.5.0" - tox-env: docs - sundials-precision: double - sundials-index-size: 64 - python-version: "3.11" sundials-version: "6.5.0" tox-env: check-manifest sundials-precision: double sundials-index-size: 64 - - python-version: "3.11" - sundials-version: "6.5.0" - tox-env: checkreadme - sundials-precision: double - sundials-index-size: 64 + #- python-version: "3.11" + # sundials-version: "6.5.0" + # tox-env: checkreadme + # sundials-precision: double + # sundials-index-size: 64 - python-version: "3.11" sundials-version: "6.5.0" tox-env: py311 sundials-precision: double sundials-index-size: 32 - - python-version: "3.11" - sundials-version: "6.5.0" - tox-env: py311 - sundials-precision: single - sundials-index-size: 64 + #- python-version: "3.11" + # sundials-version: "6.5.0" + # tox-env: py311 + # sundials-precision: single + # sundials-index-size: 64 - python-version: "3.11" sundials-version: "6.5.0" tox-env: py311 @@ -126,6 +116,7 @@ jobs: cat sundials_env.sh source sundials_env.sh && env && + cd packages/scikits-odes-sundials && tox env: TOXENV: ${{ matrix.tox-env }} diff --git a/.gitignore b/.gitignore index ecef08dc..39f6dc1e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ *swp *.egg *.ipynb_checkpoints* -scikits.odes.egg-info/* +*.egg-info build* .emacs.desktop* dist @@ -22,3 +22,4 @@ _configtest.o.d .cache .eggs .pytest_cache +.mesonpy* diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 2d28f9dc..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,16 +0,0 @@ -include common.py setup_build.py -recursive-include scikits *.pyx *.pxd *.pyf *.f - -include CONTRIBUTING.md README.md LICENSE.txt -include tox.ini -include pyproject.toml - -prune ci_support -prune docs -prune apidocs -prune paper -prune ipython_examples - -exclude *.enc -exclude upload_api_docs.sh -exclude .readthedocs.yaml diff --git a/apidocs/conf.py b/apidocs/conf.py index 9ceb081b..de3cbc26 100644 --- a/apidocs/conf.py +++ b/apidocs/conf.py @@ -18,8 +18,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('..')) -import common +import scikits.odes # -- General configuration ------------------------------------------------ @@ -65,9 +64,9 @@ # built documents. # # The short X.Y version. -version = common.VERSION +version = scikits.odes.__version__ # The full version, including alpha/beta/rc tags. -release = common.VERSION +release = scikits.odes.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/common.py b/common.py deleted file mode 100644 index 58bb6d4f..00000000 --- a/common.py +++ /dev/null @@ -1,61 +0,0 @@ -descr = """ -Odes is a scikit toolkit for scipy to add extra ode solvers. -Specifically it interfaces the Sundials solvers cvode, cvodes, ida and idas. -It this way it provides extra modern ode and dae solvers you can use, -extending the capabilities offered in scipy.integrade.ode. - -LICENSE: the license of odes is the same as scipy, new BSD. -""" - -DISTNAME = 'scikits.odes' -DESCRIPTION = 'A python module for ordinary differential equation and'+\ - ' differential algebraic equation solvers' -LONG_DESCRIPTION = descr -MAINTAINER = 'maintainer of odes is B. Malengier' -MAINTAINER_EMAIL = 'benny.malengier@gmail.org' -URL = 'https://github.com/bmcage/odes' -LICENSE = 'new BSD' - -DOWNLOAD_URL = URL - -INSTALL_REQUIRES = ['scipy'] -BUILD_REQUIRES = ['numpy', 'cython<3.0.0a8'] # This is need for older pip - -MAJOR = 2 -MINOR = 7 -MICRO = 0 -DEV = False - -CLASSIFIERS = [ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Topic :: Scientific/Engineering', - 'Programming Language :: Python :: 3', - "Programming Language :: Python :: 3 :: Only", - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', -] - -def build_verstring(): - return '%d.%d.%d' % (MAJOR, MINOR, MICRO) - -def build_fverstring(): - if DEV: - return build_verstring() + '.dev0' - else: - return build_verstring() - -def write_version(fname): - f = open(fname, "w") - f.writelines("version = '%s'\n" % build_verstring()) - f.writelines("dev =%s\n" % DEV) - f.writelines("full_version = '%s'\n" % build_fverstring()) - f.close() - -VERSION = build_fverstring() diff --git a/docs/conf.py b/docs/conf.py index bda538e7..3b00f7fc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,8 +18,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('..')) -import common +import scikits.odes # -- General configuration ------------------------------------------------ @@ -68,9 +67,9 @@ # built documents. # # The short X.Y version. -version = common.VERSION +version = scikits.odes.__version__ # The full version, including alpha/beta/rc tags. -release = common.VERSION +release = scikits.odes.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ipython_examples/Cython cvode speedup.ipynb b/ipython_examples/Cython cvode speedup.ipynb index 953bb725..21af045f 100644 --- a/ipython_examples/Cython cvode speedup.ipynb +++ b/ipython_examples/Cython cvode speedup.ipynb @@ -2,28 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "IPython.notebook.set_autosave_interval(600000)" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Autosaving every 600 seconds\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "import numpy as np\n", "%autosave 600" @@ -31,9 +17,12 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -42,194 +31,26 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Help on function odeint in module scikits.odes.odeint:\n", - "\n", - "odeint(rhsfun, tout, y0, method='bdf', **options)\n", - " Integrate a system of ordinary differential equations.\n", - " *odeint* is a wrapper around the ode class, as a confenience function to\n", - " quickly integrate a system of ode.\n", - " Solves the initial value problem for stiff or non-stiff systems\n", - " of first order ode's:\n", - " \n", - " rhs = dy/dt = fun(t, y)\n", - " \n", - " where y can be a vector, then rhsfun must be a function computing rhs with\n", - " signature:\n", - " \n", - " rhsfun(t, y, rhs)\n", - " \n", - " storing the computated dy/dt in the rhs array passed to the function\n", - " \n", - " Parameters\n", - " ----------\n", - " rhsfun : callable(t, y, out)\n", - " Computes the derivative at dy/dt in terms of t and y, and stores in out\n", - " y0 : array\n", - " Initial condition on y (can be a vector).\n", - " t : array\n", - " A sequence of time points for which to solve for y. The initial\n", - " value point should be the first element of this sequence.\n", - " method : string, solution method to use.\n", - " Available are all the ode class solvers as well as some convenience\n", - " shorthands:\n", - " \n", - " ======= ==============================================================\n", - " Method Meaning\n", - " ======= ==============================================================\n", - " bdf This uses the 'cvode' solver in default from, which is a\n", - " variable step, variable coefficient Backward Differentiation\n", - " Formula solver, good for stiff ODE. Newton iterations are\n", - " used to solve the nonlinear system.\n", - " admo This uses the 'cvode' solver with option lmm_type='ADAMS',\n", - " which is a variable step Adams-Moulton method (linear\n", - " multistep method), good for non-stiff ODE. Functional\n", - " iterations are used to solve the nonlinear system.\n", - " rk5 This uses the 'dopri5' solver, which is a variable step\n", - " Runge-Kutta method of order (4)5 (use for non-stiff ODE)\n", - " rk8 This uses the 'dop853' solver, which is a variable step\n", - " Runge-Kutta method of order 8(5,3)\n", - " ======= ==============================================================\n", - " \n", - " For educational purposes, you can also access following methods:\n", - " \n", - " ======= ==============================================================\n", - " Method Meaning\n", - " ======= ==============================================================\n", - " beuler This is the Implicit Euler (backward Euler) method (order 1),\n", - " which is obtained via the 'bdf' method, setting the order\n", - " option to 1, setting large tolerances, and fixing the\n", - " stepsize.\n", - " Use option 'step' to change stepsize, default: step=0.05.\n", - " Use option 'rtol' and 'atol' to use more strict tolerances\n", - " Note: this is not completely the backward Euler method, as\n", - " the cvode solver has added control options!\n", - " trapz This is the Trapezoidal Rule method (order 2), which is\n", - " obtained via the 'admo' method, setting option order to 2,\n", - " setting large tolerances and fixing the stepsize.\n", - " Use option 'step' to change stepsize, default: step=0.05.\n", - " Use option 'rtol' and 'atol' to use more strict tolerances\n", - " Note: The cvode solver might change the order to 1 internally\n", - " in which case this becomes beuler method. Set atol, rtol\n", - " options as strict as possible.\n", - " ======= ==============================================================\n", - " \n", - " You can also access the solvers of ode via their names:\n", - " \n", - " ======= ==============================================================\n", - " Method Meaning\n", - " ======= ==============================================================\n", - " cvode This uses the 'cvode' solver\n", - " dopri5 This uses the 'dopri5' solver\n", - " dop853 This uses the 'dop853' solver\n", - " ======= ==============================================================\n", - " \n", - " options : extra solver options, optional\n", - " Every solver has it's own extra options, see the ode class and the\n", - " details of the solvers available there to know the options possible per\n", - " solver\n", - " \n", - " Returns\n", - " -------\n", - " solution : named tuple\n", - " A single named tuple is returned containing the result of the\n", - " integration.\n", - " \n", - " ======== ==========================================\n", - " Field Meaning\n", - " ======== ==========================================\n", - " flag An integer flag\n", - " values Named tuple with fields t and y\n", - " errors Named tuple with fields t and y\n", - " roots Named tuple with fields t and y\n", - " tstop Named tuple with fields t and y\n", - " message String with message in case of an error\n", - " ======== ==========================================\n", - " \n", - " See Also\n", - " --------\n", - " ode : a more object-oriented integrator in scikits.odes\n", - " dae : a solver for differential-algebraic equations in scikits.odes\n", - " quad : for finding the area under a curve, part of scipy.\n", - " \n", - " Examples\n", - " --------\n", - " The second order differential equation for the angle `theta` of a\n", - " pendulum acted on by gravity with friction can be written:\n", - " \n", - " .. math:: \\theta''(t) + b \\theta'(t) + c \\sin(\\theta(t)) = 0\n", - " \n", - " where `b` and `c` are positive constants, and a prime (') denotes a\n", - " derivative. To solve this equation with `odeint`, we must first convert\n", - " it to a system of first order equations. By defining the angular\n", - " velocity ``omega(t) = theta'(t)``, we obtain the system:\n", - " \n", - " .. math:: \\theta'(t) = \\omega(t)\n", - " \\omega'(t) = -b \\omega(t) - c \\sin(\\theta(t))\n", - " \n", - " We assume the constants are `b` = 0.25 and `c` = 5.0:\n", - " \n", - " >>> b = 0.25\n", - " >>> c = 5.0\n", - " \n", - " Let `y` be the vector [`theta`, `omega`]. We implement this system\n", - " in python as:\n", - " \n", - " >>> def pend(t, y, out):\n", - " ... theta, omega = y\n", - " ... out[:] = [omega, -b*omega - c*np.sin(theta)]\n", - " ...\n", - " \n", - " In case you want b and c easily changable, make pend a class method, and\n", - " consider attributes b and c accessible via `self.b` and `self.c`.\n", - " For initial conditions, we assume the pendulum is nearly vertical\n", - " with `theta(0)` = `pi` - 0.1, and it initially at rest, so\n", - " `omega(0)` = 0. Then the vector of initial conditions is\n", - " \n", - " >>> y0 = [np.pi - 0.1, 0.0]\n", - " \n", - " We generate a solution 101 evenly spaced samples in the interval\n", - " 0 <= `t` <= 10. So our array of times is\n", - " \n", - " >>> t = np.linspace(0, 10, 101)\n", - " \n", - " Call `odeint` to generate the solution.\n", - " \n", - " >>> from scikits.odes.odeint import odeint\n", - " >>> sol = odeint(pend, t, y0)\n", - " \n", - " The solution is a named tuple `sol`. sol.values.y is an array with shape (101, 2).\n", - " The first column is `theta(t)`, and the second is `omega(t)`.\n", - " The following code plots both components.\n", - " \n", - " >>> import matplotlib.pyplot as plt\n", - " >>> plt.plot(sol.values.t, sol.values.y[:, 0], 'b', label='theta(t)')\n", - " >>> plt.plot(sol.values.t, sol.values.y[:, 1], 'g', label='omega(t)')\n", - " >>> plt.legend(loc='best')\n", - " >>> plt.xlabel('t')\n", - " >>> plt.grid()\n", - " >>> plt.show()\n", - "\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "help(odeint)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -245,30 +66,22 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.5/dist-packages/Cython/Distutils/old_build_ext.py:30: UserWarning: Cython.Distutils.old_build_ext does not properly handle dependencies and is deprecated.\n", - " \"Cython.Distutils.old_build_ext does not properly handle dependencies \"\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "%load_ext Cython" ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "def fun(t, y, out):\n", @@ -279,10 +92,8 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "def jac(t, y, out):\n", @@ -294,10 +105,8 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "%%cython\n", @@ -309,9 +118,12 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -335,9 +147,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -347,9 +162,12 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -358,84 +176,40 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " " - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "stats = %prun -r -q odeint(fun, outtimes, y0, method='cvode')" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 15637 function calls in 0.062 seconds\n", - "\n", - " Ordered by: internal time\n", - " List reduced from 47 to 20 due to restriction <20>\n", - "\n", - " ncalls tottime percall cumtime percall filename:lineno(function)\n", - " 1 0.045 0.045 0.062 0.062 {method 'solve' of 'scikits.odes.sundials.cvode.CVODE' objects}\n", - " 15534 0.017 0.000 0.017 0.000 :1(fun)\n", - " 1 0.000 0.000 0.062 0.062 {built-in method builtins.exec}\n", - " 1 0.000 0.000 0.000 0.000 inspect.py:2065(_signature_from_function)\n", - " 2 0.000 0.000 0.000 0.000 copy.py:67(copy)\n", - " 1 0.000 0.000 0.000 0.000 inspect.py:1052(getfullargspec)\n", - " 1 0.000 0.000 0.062 0.062 :1()\n", - " 1 0.000 0.000 0.000 0.000 ode.py:220(__init__)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method _warnings.warn}\n", - " 1 0.000 0.000 0.000 0.000 inspect.py:1027(getargspec)\n", - " 2 0.000 0.000 0.000 0.000 {built-in method numpy.core.multiarray.array}\n", - " 1 0.000 0.000 0.000 0.000 inspect.py:2146(_signature_from_callable)\n", - " 1 0.000 0.000 0.062 0.062 odeint.py:13(odeint)\n", - " 3 0.000 0.000 0.000 0.000 inspect.py:2399(__init__)\n", - " 1 0.000 0.000 0.000 0.000 inspect.py:2664(__init__)\n", - " 7 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0xa3ddc0}\n", - " 1 0.000 0.000 0.000 0.000 :12(__new__)\n", - " 1 0.000 0.000 0.000 0.000 enum.py:215(__call__)\n", - " 1 0.000 0.000 0.000 0.000 ode.py:445(find_ode_integrator)\n", - " 2 0.000 0.000 0.000 0.000 numeric.py:2064(isscalar)\n", - "\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "stats.print_stats(20)" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -444,214 +218,53 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " " - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "stats = %prun -r -q odeint(RhsFunction(), outtimes, y0, method='cvode')" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 49 function calls in 0.042 seconds\n", - "\n", - " Ordered by: internal time\n", - " List reduced from 27 to 20 due to restriction <20>\n", - "\n", - " ncalls tottime percall cumtime percall filename:lineno(function)\n", - " 1 0.041 0.041 0.042 0.042 {method 'solve' of 'scikits.odes.sundials.cvode.CVODE' objects}\n", - " 2 0.000 0.000 0.000 0.000 copy.py:67(copy)\n", - " 1 0.000 0.000 0.042 0.042 {built-in method builtins.exec}\n", - " 1 0.000 0.000 0.042 0.042 :1()\n", - " 1 0.000 0.000 0.000 0.000 ode.py:220(__init__)\n", - " 4 0.000 0.000 0.000 0.000 :12(__new__)\n", - " 2 0.000 0.000 0.000 0.000 {built-in method numpy.core.multiarray.array}\n", - " 1 0.000 0.000 0.042 0.042 odeint.py:13(odeint)\n", - " 1 0.000 0.000 0.000 0.000 {method 'match' of '_sre.SRE_Pattern' objects}\n", - " 2 0.000 0.000 0.000 0.000 numeric.py:414(asarray)\n", - " 1 0.000 0.000 0.000 0.000 enum.py:215(__call__)\n", - " 5 0.000 0.000 0.000 0.000 fromnumeric.py:2362(alen)\n", - " 1 0.000 0.000 0.000 0.000 ode.py:445(find_ode_integrator)\n", - " 2 0.000 0.000 0.000 0.000 numeric.py:2064(isscalar)\n", - " 1 0.000 0.000 0.000 0.000 enum.py:459(__new__)\n", - " 1 0.000 0.000 0.000 0.000 re.py:160(match)\n", - " 1 0.000 0.000 0.042 0.042 ode.py:282(solve)\n", - " 1 0.000 0.000 0.000 0.000 re.py:278(_compile)\n", - " 2 0.000 0.000 0.000 0.000 fromnumeric.py:1574(shape)\n", - " 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0xa3ddc0}\n", - "\n", - "\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "stats.print_stats(20)" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " 0 2 2\n", - " 10 1.85832 1.85832\n", - " 20 1.69338 1.69338\n", - " 30 1.4849 1.4849\n", - " 40 1.09322 1.09322\n", - " 50 -1.87714 -1.87714\n", - " 60 -1.71581 -1.71581\n", - " 70 -1.51498 -1.51498\n", - " 80 -1.18599 -1.18599\n", - " 90 1.89563 1.89563\n", - " 100 1.73766 1.73766\n", - " 110 1.54362 1.54362\n", - " 120 1.24882 1.24882\n", - " 130 -1.9138 -1.9138\n", - " 140 -1.75896 -1.75896\n", - " 150 -1.57099 -1.57099\n", - " 160 -1.2998 -1.2998\n", - " 170 1.93167 1.93167\n", - " 180 1.77978 1.77978\n", - " 190 1.5973 1.5973\n", - " 200 1.34404 1.34404\n", - " 210 -1.94927 -1.94927\n", - " 220 -1.80014 -1.80014\n", - " 230 -1.62265 -1.62265\n", - " 240 -1.38373 -1.38373\n", - " 250 1.9666 1.9666\n", - " 260 1.82008 1.82008\n", - " 270 1.64715 1.64715\n", - " 280 1.4201 1.4201\n", - " 290 -1.98367 -1.98367\n", - " 300 -1.83962 -1.83962\n", - " 310 -1.67088 -1.67088\n", - " 320 -1.45391 -1.45391\n", - " 330 2.00049 2.00049\n", - " 340 1.85878 1.85878\n", - " 350 1.69392 1.69392\n", - " 360 1.48565 1.48565\n", - " 370 1.09628 1.09628\n", - " 380 -1.87759 -1.87759\n", - " 390 -1.71633 -1.71633\n", - " 400 -1.51568 -1.51568\n", - " 410 -1.18771 -1.18771\n", - " 420 1.89607 1.89607\n", - " 430 1.73817 1.73817\n", - " 440 1.54428 1.54428\n", - " 450 1.25013 1.25013\n", - " 460 -1.91423 -1.91423\n", - " 470 -1.75947 -1.75947\n", - " 480 -1.57164 -1.57164\n", - " 490 -1.30094 -1.30094\n", - " 500 1.93211 1.93211\n", - " 510 1.78028 1.78028\n", - " 520 1.59792 1.59792\n", - " 530 1.34505 1.34505\n", - " 540 -1.94969 -1.94969\n", - " 550 -1.80063 -1.80063\n", - " 560 -1.62325 -1.62325\n", - " 570 -1.38465 -1.38465\n", - " 580 1.96701 1.96701\n", - " 590 1.82056 1.82056\n", - " 600 1.64773 1.64773\n", - " 610 1.42095 1.42095\n", - " 620 -1.98408 -1.98408\n", - " 630 -1.84008 -1.84008\n", - " 640 -1.67145 -1.67145\n", - " 650 -1.4547 -1.4547\n", - " 660 2.0009 2.0009\n", - " 670 1.85924 1.85924\n", - " 680 1.69447 1.69447\n", - " 690 1.48639 1.48639\n", - " 700 1.09929 1.09929\n", - " 710 -1.87804 -1.87804\n", - " 720 -1.71687 -1.71687\n", - " 730 -1.51639 -1.51639\n", - " 740 -1.18943 -1.18943\n", - " 750 1.89652 1.89652\n", - " 760 1.7387 1.7387\n", - " 770 1.54496 1.54496\n", - " 780 1.25148 1.25148\n", - " 790 -1.91467 -1.91467\n", - " 800 -1.75998 -1.75998\n", - " 810 -1.5723 -1.5723\n", - " 820 -1.30209 -1.30209\n", - " 830 1.93254 1.93254\n", - " 840 1.78078 1.78078\n", - " 850 1.59855 1.59855\n", - " 860 1.34606 1.34606\n", - " 870 -1.95012 -1.95012\n", - " 880 -1.80113 -1.80113\n", - " 890 -1.62387 -1.62387\n", - " 900 -1.38558 -1.38558\n", - " 910 1.96744 1.96744\n", - " 920 1.82105 1.82105\n", - " 930 1.64833 1.64833\n", - " 940 1.42182 1.42182\n", - " 950 -1.9845 -1.9845\n", - " 960 -1.84056 -1.84056\n", - " 970 -1.67203 -1.67203\n", - " 980 -1.45551 -1.45551\n", - " 990 2.00131 2.00131\n", - "1000 1.85971 1.85971\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "#verify the two solutions are equal\n", "for t, u1, u2 in zip(sol1.values.t, sol1.values.y, sol2.values.y):\n", " print('{0:>4.0f} {1:15.6g} {2:15.6g}'.format(t, u1[0], u2[0]) )" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -665,9 +278,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 4 } diff --git a/ipython_examples/Double Pendulum as DAE with roots.ipynb b/ipython_examples/Double Pendulum as DAE with roots.ipynb index fd442110..420d712d 100644 --- a/ipython_examples/Double Pendulum as DAE with roots.ipynb +++ b/ipython_examples/Double Pendulum as DAE with roots.ipynb @@ -2,10 +2,8 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" @@ -87,10 +85,8 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function, division\n", @@ -114,10 +110,8 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "#data of the pendulum\n", @@ -203,10 +197,8 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "# we now consider the residual and jacobian functions\n", @@ -312,10 +304,8 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "# a root function has a specific signature. Result will be of size nr_rootfns, and must be filled with the result of the \n", @@ -334,9 +324,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -367,21 +360,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "test 5.0 0 [ 5. 0. 7. 0. 0. 0. 0. 0. 0. 0.]\n", - "Error in solver, breaking solution at time 263.88\n", - "Could not reach endpoint\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "#storage of solution\n", "x1t = np.empty(len(problem.stop_t), float)\n", @@ -444,32 +430,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "# quick plot:\n", "plt.figure(1)\n", @@ -495,7 +463,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "source": [ "From the total energy we can see the deviation from the true solution.\n", @@ -505,120 +476,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "We have found 99 crossings of the Y axis\n", - "Some of the different configutations when crossing the Y axis are:\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD7CAYAAABKWyniAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAD1NJREFUeJzt3X+MVfWZx/H3x9EBHJQqtQUFlJqBtBhJtbpELY4tGkJc2K1u2CbVtU23G9cfpOnaiiaVNNkfppvW1k3TRIWs2zXVUGLq1qJkK6zR1p8oorgOWhEUCkoUQYUh8+wf9w474MzcgXPOPXPP9/NKTLhzT87zwPUz59x77nm+igjMLC1Hld2AmTWfg2+WIAffLEEOvlmCHHyzBDn4Zgk6uugCkny90KwkEaGBft6UI35EFPrfLbfcUngN13TNVqs5FJ/qmyXIwTdLUCWC39XV5Zqu6ZqHQY3eC2QuIEXRNczs4yQRZX64Z2Yji4NvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJyhx8SZ+QtFzSBkkvSZqVR2NmVpw8hm3+BHgwIi6XdDTQkcM+zaxAmQZxSBoHrI2IzwyxjQdxmJWgyEEcU4EdkpZJelbSHZKOzbhPMytY1lP9o4GzgGsj4ilJtwE3At/vv9GSJUsO/Lmrq6vUWWNmVbV69WpWr149rG2znupPAH4fEVPrjy8AboyIS/tt41N9sxIUdqofEduAzZKm1X80B3gxyz7NrHiZp+xKmgncCbQDrwJfj4j3+j3vI75ZCYY64nu8tllFeby2mR3EwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBuQRfUpuktZIeyGN/ZlasvI74i4CXAI/TNWsBeSyTPQmYR222/oCjfM1sZMnjiP9j4AagN4d9mVkTZFo0U9KlwPaIWCupa7DtvGimWfGauWjmPwFXAPuB0cDxwK8i4sp+23glHbMSNGUJLUkXAv8QEX9+yM8dfLMSNHMJLSfcrAV40UyzivKimWZ2EAffLEEOvlmCHHyzBDn4Zgly8M0S5OCbJcjBN0uQg2+WIAffLEEOvlmCHHyzBDn4Zgly8M0S5OCbJcjBN0uQg2+WIAffLEEOvlmCHHyzBOWxhNZkSY9IelHSeknX59GYmRUn85RdSROACRHxnKSxwDPAX0TEhvrznrJrVoJCp+xGxLaIeK7+593ABuDkrPs1s+Lk+h5f0mnA54En8tyvmeUr06KZ/dVP85cDi+pH/gO8aKZZ8Zq2aOaBnUjHAP8F/DYibjvkOb/HNytBoYtmShLw78A7EfHtAZ538M1KUHTwLwD+B1jH/y+auTgiVtafd/DNStCUZbKHKO7gm5XAi2aa2UEcfLMEOfhmCXLwzRLk4JslyME3S5CDb5YgB98sQQ6+WYIcfLMEOfhmCXLwzRLk4JslyME3S5CDb5YgB98sQQ6+WYIcfLMEOfhmCXLwzRKUx6KZcyW9LKlb0vfyaMrMipVpyq6kNuB/gTnAm8BTwFf7Fsysb+Mpu2YlKHLK7rnAxoh4PSJ6gF8CCzLu08wKljX4pwCb+z3eUv+ZVcCaNWvo7u4uuw0rQNZFM4d1Du9FM1tTV1cXV111FcuWLSu7FRuGpi2aKWkWsCQi5tYfLwZ6I+LWftv4PX6LksQ555zDk08+WXYrdgSKfI//NNAp6TRJ7cBC4NcZ92kjyJYtW8puwQqQ6VQ/IvZLuhZ4CGgD7ur/ib61vq1bt5bdghXAi2baoCZOnMi2bdvw69eavGimHZHJkyeX3YIVxMG3QU2ZMqXsFqwgDr4Nykf86nLwbVAOfnU5+DaoU06pfQnTH+5Vj4NvgzrppJMA+Oijj0ruxPLm4Nugjj/+eADee++9kjuxvDn4Nqhx48YBsGvXrpI7sbw5+DaoviO+g189Dr4Nyqf61eXg26BGjx4NwI4dO0ruxPLm4NugpNrXvH2HXvU4+NaQg189Dr41tHnz5sYbWUtx8K2hTZs2ld2C5czBt4Z8ql89HsRhQ+r7gM+vYevxIA47Yn036li1OPg2JN+aW00Ovg3Jwa+mTMGX9ENJGyQ9L2mFpHF5NWYjg4NfTVmP+A8DMyJiJvAKsDh7SzaSOPjVlCn4EbEqInrrD58AJmVvyUaSSZNqL6k/1a+WPN/jfwN4MMf92Qgwfvx4AD744IOSO7E8NVxJR9IqYMIAT90UEQ/Ut7kZ2BcR9wy0Dy+a2br6D+Po6OgouRsbStMWzQSQdBXwt8CXI+Jjw9n8BZ7WtnHjRjo7O3n55ZeZPn162e3YYRjqCzyZ1s6TNBe4AbhwoNBb6/MUnmrK+h7/dmAssErSWkk/y6EnG0E8haeasq6W25lXIzYy9U3h2b59e8mdWJ78zT0bFt+hVy0Ovg2Lh3FUi4Nvw+LgV4uDb8PyxhtvlN2C5cjBt2Hxe/xq8QQea6itrY3e3l5/X7/FeAKPZeIpPNXj4FtDvjW3ehx8a2jKlCllt2A5c/CtIR/xq8fBt4b6hnFYdTj41lDfh3v+VL86HHxrqG8Kz549e0ruxPLi4FtD/afwWDU4+NaQh3FUj4NvDXkYR/U4+NaQg189Dr41NGrUKMBTeKrEwbdh8x161eHg27B5GEd1ZA6+pO9I6pV0Yh4N2cjl4FdH1tVyJwMXA5vyacdGMk/hqY6sR/wfAd/NoxEb+XzEr44jDr6kBcCWiFiXYz82Qh1zzDHs3Lmz7DYsJ0MuqDHEgpk3A4uBS/pvPth+vGhm6zv55JPZtMnv6EaywhfNlHQG8N9A39rJk4A3gXMjYvsh23rmXgXMnj2bRx991HfotZDcF82MiPXAp/sV+CNwdkT4XLCiPIyjWvK6ju/DQMU5+NWSadHMPhHxmTz2YyOXp/BUi7+5Z8PSF/ze3t6SO7E8OPg2LCeeWPtipqfwVIODb8PiYRzV4uDbsPie/Gpx8G1YfMSvFgffhsVH/Gpx8K2hXbt2seSmmwBY9K1vsWzpUn+Dr8V5mWwbUk9PD1886yxO7+7mnr17+RrwQkcH86+5hh/cemvZ7dkQvEy2HbEVK1Yw+vXX+cXevQB0AA/t2cPtP/0pb7/9drnN2RFz8G1I69et48Lduw/cevkMtZs0Tm9vp7u7u8TOLAsH34Z0emcnz3Z0HLgZ46+AXcBr+/YxderUEjuzLBx8G9LChQt55YQTWNTWBsCngK8ceywLFy5kwoSBRjVYK3DwbUhjxoxh9ZNP0j17NgBLPvlJum64gdvvvLPkziyLXO7Os2qbOHEil152GSsfeYQ/bt+ONOiwJWsRPuLbsKxcuRLAoa8IX8e3YWlvb6enp8df3Gkhvo5vmfX09HDeeeeV3YblxMG3YZs3b17ZLVhOHHxr6N133wXg/PPPL7kTy4uDbw29+uqrAHR2dpbcieUl69p510naIGm9JN+xUVFr164FaotqWDUc8XV8SRcB84EzI6JH0kn5tWUjiS/lVc8RX86TdB/w84j4XYPtfDmvxY0dO5Y9e/b4Ul6LKepyXicwW9IfJK2W9IUM+7IRbM+ePZx99tllt2E5yrJo5tHACRExS9I5wH3AgAtreNHM1udLeSNf4YtmAkj6LfAvEbGm/ngj8GcR8c4h2/lUv4Xt3r2b4447jlWrVjFnzpyy27HDUNSp/v3Al+oFpgHth4beWl/fpbxp06aV3InlKcvdeUuBpZJeAPYBV+bTko0k69atA7x2XtUccfAjoge4IsdebAR6+OGHATjqKH/Xq0p8d54Nafz48ezcudOX8lqQ786zI7Zz505mzJhRdhuWMwffGvKlvOpx8G1QH374IQAXXXRRyZ1Y3hx8G9Rrr70GwPTp00vuxPLm4NuAIoLHHnsMgClTppTcjeXNwbePefzxx/ncqady/dVXA3DFZZfx/vvvl9yV5cnBt4O89dZbLLjkEv5x82ZO7O0FYMxDD/E3l19ecmeWJwffDvIfd9/N5T09fAXYSu2uq5/t3cvqNWvYunVryd1ZXhx8O8jbf/oTU/btA+Avge8Co4FPtbfzzju+FaMqHHw7yPkXXsjyjg72ASuAvwOeBt6VPHOvQhx8O8j8+fM59YILmN3Rwc+BHxx1FPPGjOH2O+5g1KhRZbdnOfF39e1j9u/fz7333ssjv/kN48aP58pvfpOZM2eW3ZYdpqG+q+/gm1WUb9Ixs4M4+GYJqkTwhztg0DVdM/WafRx813TNhGr2qUTwzezwOPhmCWrK5bxCC5jZoEq7jm9mI49P9c0S5OCbJagywZd0naQNktZLurWJdb8jqVfSiU2q98P63/N5SSskjSuozlxJL0vqlvS9ImocUm+ypEckvVh/Da8vuma/2m2S1kp6oEn1PiFpef11fEnSrGbU7a8SwZd0ETAfODMizgD+tUl1JwMXA5uaUa/uYWBGRMwEXgEW511AUhvwb8Bc4HPAVyV9Nu86h+gBvh0RM4BZwDVNqNlnEfAS0KwPvH4CPBgRnwXOBDY0qe4BlQg+cDXwz/VlvYiIHU2q+yNqsyqaJiJWRURv/eETQBGL2p0LbIyI1+v/pr8EFhRQ54CI2BYRz9X/vJtaGE4usiaApEnAPOBOYMBPwHOuNw74YkQsBYiI/RHxXtF1D1WV4HcCsyX9QdJqSV8ouqCkBcCWiFhXdK0hfAN4sID9ngJs7vd4S/1nTSHpNODz1H6xFe3HwA1Ab6MNczIV2CFpmaRnJd0h6dgm1T4gy2q5TSVpFTBhgKdupvb3OCEiZkk6B7iP2ri4ImsuBi7pv3nWesOoe1NEPFDf5mZgX0Tck1fdfkq7xitpLLAcWFQ/8hdZ61Jge0SsldRVZK1+jgbOAq6NiKck3QbcCHy/SfUPNNESIuLiwZ6TdDW1SVHU/zF7JY2PiExD4garKekMar+5n5cEtdPtZySdGxHbs9Qcqm6/+ldROz39ctZag3gTmNzv8WRqR/1CSToG+BXwi4i4v+h6wHnAfEnzqI0WPF7S3RFR5JLvW6idKT5Vf7ycWvCbqiqn+vcDXwKQNA1ozxr6oUTE+oj4dERMjYip1F7Ms/IIfSOS5lI7NV0QER8VVOZpoFPSaZLagYXArwuqBYBqv0HvAl6KiNuKrNUnIm6KiMn11/Cvgd8VHHoiYhuwuf7/KcAc4MUiaw6kZY74DSwFlkp6AdgHFPriDaCZp8a3A+3AqvrZxu8j4u/zLBAR+yVdCzwEtAF3RUTRnzyfD3wNWCdpbf1niyNiZcF1+2vW63gd8J/1X6qvAl9vUt0D/JVdswRV5VTfzA6Dg2+WIAffLEEOvlmCHHyzBDn4Zgly8M0S5OCbJej/AP7bpzABCCv3AAAAAElFTkSuQmCC", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD7CAYAAABKWyniAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAD81JREFUeJzt3X2MVfWdx/H3h0FFHgqKWB+gMirPBIVWl7hFaNWGuD7sH262TVZp3WjiLtY0rq1oUs3+0Wq6qTbdbGLaWiXd2q3UGh94kG0dralYtYCVGeVBMQPVgJqoFFkY5rt/zB064Dzc4Z5zz9zz+7wSE+7ck/v94uUz59xzz/l9FRGYWVqGFd2AmdWfg2+WIAffLEEOvlmCHHyzBDn4ZgkanncBSf6+0KwgEaHefl6XPX5E5PrfHXfckXsN13TNRqvZHx/qmyXIwTdLUCmCv2jRItd0TdccBA30WaDmAlLkXcPMPkkSUeTJPTMbWhx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLUM3BlzRO0gpJbZJaJc3PojEzy08Wi23+AFgZEVdJGg6MyuA1zSxHNS3EIWkssD4izuxnGy/EYVaAPBfiaAZ2S/qppD9K+pGkkTW+ppnlrNZD/eHAPGBpRLwo6V7gVuDbPTe68847D/150aJFha41ZlZWLS0ttLS0VLVtrYf6pwDPR0Rz5fHngVsj4rIe2/hQ36wAuR3qR8Q7QLukqZUfXQxsquU1zSx/Na+yK+kc4MfAscA24GsR8UGP573HNytAf3t8L69tVlJeXtvMDuPgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvlqBMgi+pSdJ6SY9n8Xpmlq+s9vg3Aa2Al9M1awBZjMmeCFxK19r6vS7la2ZDSxZ7/HuAW4DODF7LzOqgpqGZki4DdkXEekmL+trOQzPN8lfPoZnfAa4GOoARwKeAX0XENT228SQdswLUZYSWpIXAv0XE5Uf83ME3K0A9R2g54WYNwEMzzUrKQzPN7DAOvlmCHHyzBDn4Zgly8M0S5OCbJcjBN0uQg2+WIAffLEEOvlmCHHyzBDn4Zgly8M0S5OCbJcjBN0uQg2+WIAffLEEOvlmCHHyzBDn4ZgnKYoTWJElPS9ok6VVJX8+iMTPLT82r7Eo6BTglIjZIGg28DPx9RLRVnvcqu2YFyHWV3Yh4JyI2VP68B2gDTqv1dc0sP5l+xpc0GZgLvJDl65pZtmoamtlT5TB/BXBTZc9/iIdmmuWvbkMzD72IdAzwBLAqIu494jl/xjcrQK5DMyUJeBB4LyK+0cvzDr5ZAfIO/ueBZ4FX+OvQzGURsbryvINvVoC6jMnup7iDb1YAD800s8M4+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyXIwTdLkINvliAH3yxBDr5Zghx8swQ5+GYJcvDNEuTgmyUoi6GZiyW9JmmLpG9l0ZSZ5aumVXYlNQGvAxcDO4EXga90D8ysbONVds0KkOcqu+cDWyNie0QcAH4BXFnja5pZzmoN/ulAe4/HOyo/sxJ45pln2LJlS9FtWA5qHZpZ1TG8h2Y2pkWLFnH11VezfPnyoluxKtRtaKak+cCdEbG48ngZ0BkRd/fYxp/xG5Qkpk+fTltb28Ab25CT2wgtScPpOrl3EfBn4A/45F5pSGLYsGEcPHiw6FbsKOR2ci8iOoClwBqgFfifnqG3xtbc3ExnZ2fRbVgOav2MT0SsAlZl0IsNMTNnzuTNN98sug3Lga/csz5Nnz696BYsJw6+9cnBLy8H3/o0efJkAD7++ONiG7HMOfjWpwkTJgDw3nvvFdyJZc3Btz6ddNJJALz77rsFd2JZc/CtT+PHjwdg9+7dBXdiWXPwrU8jRowA8Fd6JeTg24Bee+21oluwjDn4NiBfq18+Dr4NqLW1tegWLGM13aRTVQHfpNPQjjnmGDo6OvB72HjyXIHHSm7q1KlFt2A5cPCtXzNnziy6BcuBg2/9mjFjRtEtWA4cfOvXtGnTAPwZv2QcfOvXpEmTANizZ0/BnViWHHzrl6/XLycH3/rl4JeTg2/9OvHEEwHYtWtXwZ1Ylhx869fw4V3LMm7durXgTixLNQVf0vcktUnaKOkRSWOzasyGFl+vXy617vGfAmZFxDnAZmBZ7S3ZUOTgl0ut6+qvjYjuhddfACbW3pINRQ5+uWT5Gf9aYGWGr2dDxJgxY7wKT8kMOFBD0lrglF6eui0iHq9sczuwPyJ+3ttreGhmY5s2bRovvfRS0W3YAOo2NBNA0leB64CLImJfL8/7ttwGt2TJEpYvX+7LdhtMf7fl1jRCS9Ji4BZgYW+ht3LwYI3yqfUz/g+B0cBaSesl/VcGPdkQ031PvgdolkdNe/yImJJVIzZ0nXrqqQB88MEHnHDCCQV3Y1nwlXs2IF+vXz4Ovg2oO/j+Sq88HHwb0Lhx4wB4++23C+7EsuLg24CGDev6Z7J58+aCO7GsOPhWNU/UKQ8H36rmwRrl4YEaVhVJjBkzhg8//LDoVqxKHqhhNZswYQIfffRR0W1YRhx8q4rX1y8XB9+q4uCXi4NvVfGNOuXi4FtVpkzpui2jo6Oj4E4sCw6+VeXkk08G4P333y+4E8uCg29V8Y065eLgW1Uc/HJx8K0qo0ePBqC9vb3gTiwLDr5VReq6AOz1118vuBPLgoNvg+IbdcrBwbdB2bRpU9EtWAZ8k45VTRLDhw/nwIEDRbdiVcj1Jh1JN0vqlHRira9lQ9sZZ5zhC3hKotZpuZOAS4C3smnHhjJfr18ete7xvw98M4tGbOhz8MvjqIMv6UpgR0S8kmE/NoT5Rp3y6HegRj8DM28HlgFf6rl5X6/joZnl0NzcDMC+ffsYMWJEwd3YkXIfmilpNvAbYG/lRxOBncD5EbHriG19Vr8kNmzYwNy5c9mxYwenn3560e3YADI/qx8Rr0bEpyOiOSKagR3AvCNDb+Xi6/XLI6sLeLxLT8D48eMBT9Qpg5qGZnaLiDOzeB0b2o4//ngAtm/fXmwjVjNfsmuD5uv1G5+Db4PW1tZWdAtWIwffBs3Bb3y+SccGpampic7OTvyeDn2epGOZmTp1atEtWAYcfBuUmTNnFt2CZcDBt6qtWrWKdc8+C8CCc8/l6aefLrgjO1oOvlVlzZo1/PNVV/EPlav2bty4kS9fdhnPPfdcwZ3Z0fDJPavKwrlzuWnDBsYCFwMfASuAhxcs4MnKUYANLT65ZzXb9tZbzAO65+i0Ap8F3njjjeKasqPm4FtVZs+YQQvQ/Q3+eUCLxKzZs4tryo6aD/WtKuvWreOKiy7i//bu5UPgHonvjBzJ//7+98yZM6fo9qwXPtS3ms2fP5/Vv/sdHwKjjjuOP1x+Ob95/nmHvkF5j29V279/P8cddxwPPPAAS5YsKbodG4D3+JaJ7mEaF154YcGdWK0cfKvaE088AcDkyZOLbcRq5kN9q9rEiRPZuXOnb9BpED7Ut0zs3LmTCy64oOg2LAMOvlWle17eddddV3AnlgUH36riE3vlUuvsvBsltUl6VdLdWTVlQ8+TTz4J/HWohjW2oz65J+kLwG3ApRFxQNKEiPjEuss+uVcOn/nMZ2hvb/eJvQaS18m9G4DvRsQBgN5Cb+XR3t7O/Pnzi27DMlJL8KcAF0paJ6lF0ueyasqGFp/YK59ahmYOB06IiPmSzgN+CfQ6WMNDMxtba2srAAsXLiy4E+tP7kMzASStAu6KiGcqj7cCfxMR7x2xnT/jN7i77rqLZcuW0dnZidTnUGQbYvL6jP8o8MVKganAsUeG3srhvvvuA3DoS6SW2Xn3A/dL+hOwH7gmm5ZsqNm+fTvnnXde0W1Yho46+JWz+Vdn2IsNQR0dHQBcf/31BXdiWfKVe9av7nFZPiFbLg6+9Wv16tUAnHXWWQV3YlnybbnWr7PPPptt27b5ir0G5Nty7aht27aNefPmFd2GZczBtz75xF551fJ1npXYunXreOihhwC8km4J+TO+HSYiuHnpUh554AGa9+2jpbOT8aNG8etVq1iwYEHR7dkg+DO+Va2lpYXHHnyQDXv38ufOTgAe/MtfuOaqqw4d+lvjc/DtMGtWrmTJ3r2MAzbTNSrr74CmvXvZsmVLsc1ZZvwZ3w4zctQoPmhqgo4OHgMmAQeBjzo6GDlyZMHdWVb8Gd8Os3nzZi4491zWfPwxnwU6gX9vauK3c+bwzMsv+0adBtLfZ3wH3z5hxcMPc8O119I8bBi7Dx7k5MmT+fVTT3HaaacV3ZoNgoNvg7Znzx42btzI2LFjmTVrlvf0DcjBN0uQv84zs8M4+GYJKkXwq11g0DVdM/Wa3Rx813TNhGp2K0XwzWxwHHyzBNXl67xcC5hZnwr7Ht/Mhh4f6pslyME3S1Bpgi/pRkltkl6VdHcd694sqVPSiXWq973K33OjpEckjc2pzmJJr0naIulbedQ4ot4kSU9L2lR5D7+ed80etZskrZf0eJ3qjZO0ovI+tkqq+/zxUgRf0heAK4A5ETEb+I861Z0EXAK8VY96FU8BsyLiHLrWyliWdQFJTcB/AouBmcBXJM3Ius4RDgDfiIhZwHzgX+tQs9tNQCtQrxNePwBWRsQMYA7QVqe6h5Qi+MANwHcrY72IiN11qvt94Jt1qgVARKyNiM7KwxeAiTmUOR/YGhHbK/9PfwFcmUOdQyLinYjYUPnzHrrCkPt9wJImApcCPwZyvwWxcoS2ICLuB4iIjoj4IO+6RypL8KcAF0paJ6lF0ufyLijpSmBHRLySd61+XAuszOF1TwfaezzeUflZXUiaDMyl6xdb3u4BbqFrzZF6aAZ2S/qppD9K+pGkui9t1DBLb0laC5zSy1O30/X3OCEi5ks6D/glcGbONZcBX+q5ea31qqh7W0Q8XtnmdmB/RPw8q7o9FPYdr6TRwArgpsqeP89alwG7ImK9pEV51uphODAPWBoRL0q6F7gV+Had6h9qoiFExCV9PSfpBuCRynYvVk62jY+I9/KoKWk2Xb+5N1YWqJgIvCzp/IjYVUvN/ur2qP9Vug5PL6q1Vh920rXcXrdJdO31cyXpGOBXwM8i4tG86wEXAFdIuhQYAXxK0vKIyHPk+w66jhRfrDxeQVfw66osh/qPAl8EkDQVOLbW0PcnIl6NiE9HRHNENNP1Zs7LIvQDkbSYrkPTKyNiX05lXgKmSJos6VjgH4HHcqoFgLp+g/4EaI2Ie/Os1S0ibouISZX38MvAb3MOPRHxDtBe+XcKcDGwKc+avWmYPf4A7gful/QnYD+Q65vXi3oeGv8QOBZYWznaeD4i/iXLAhHRIWkpsAZoAn4SEXmfef5b4J+AVyStr/xsWUSszrluT/V6H28E/rvyS3Ub8LU61T3El+yaJagsh/pmNggOvlmCHHyzBDn4Zgly8M0S5OCbJcjBN0uQg2+WoP8HgokjrtKWk7kAAAAASUVORK5CYII=", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD7CAYAAABKWyniAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAADiZJREFUeJzt3X+MVeWdx/H3h6FIWFKtq5YgWH8EE1bF6LaU7HYrUmmIoizJJthkJbTJ/iGrdbWliqZKk2Zd47alcd2kP4S0tQ1pp8StDVaJC7v9Qw1axOJQ24HSAFmDcRNTQskA890/5g47g4cDzD3nnrnP83klJJx7T873wcfPPc85c+d8FRGYWV4mND0AM+s8B98sQw6+WYYcfLMMOfhmGXLwzTI0se4CkvzzQrOGRISKXu/IGT8iav3zyCOP1F7DNV2z22qW8VLfLEMOvlmGkgj+/PnzXdM1XfMs6HTXAm0XkKLuGmb2fpKIJm/umdn44uCbZcjBN8uQg2+WIQffLEMOvlmGHHyzDDn4Zhly8M0y5OCbZcjBN8uQg2+WIQffLEMOvlmG2g6+pPMk9UraJalP0rwqBmZm9aniYZvfBDZFxN9Jmgj8WQXHNLMatfUgDknnAtsj4vKSffwgDrMG1PkgjsuAdyStl/QrSd+RNKXNY5pZzdpd6k8ErgfuiohtktYCDwAPj9xpzZo1J/4+f/78Rp81ZpaqrVu3snXr1jPat92l/jTgpYi4rLX9CeCBiFg8Yh8v9c0aUNtSPyLeBvZJurL10k3Am+0c08zq1/ZTdiVdC3wXmATsBj4bEe+NeN9nfLMGlJ3x/Xhts0T58dpmNoqDb5YhB98sQw6+WYYcfLMMOfhmGXLwzTLk4JtlyME3y5CDb5YhB98sQw6+WYYcfLMMOfhmGXLwzTLk4JtlyME3y5CDb5YhB98sQw6+WYYqCb6kHknbJT1bxfHMrF5VnfHvAfoAP07XrAtU0SZ7BnAzQ8/WL3yUr5mNL1Wc8b8BrAIGKziWmXVAW00zJS0GDkbEdknzT7Wfm2aa1a+TTTP/GbgDOAZMBj4I/DQilo/Yx510zBrQkRZakm4AvhgRt570uoNv1oBOttByws26gJtmmiXKTTPNbBQH3yxDDr5Zhhx8sww5+GYZcvDNMuTgm2XIwTfLkINvliEH3yxDDr5Zhhx8sww5+GYZcvDNMuTgm2XIwTfLkINvliEH3yxDDr5Zhhx8swxV0UJrpqQtkt6UtFPS56sYmJnVp+2n7EqaBkyLiNclTQVeA/42Ina13vdTds0aUOtTdiPi7Yh4vfX3Q8AuYHq7xzWz+lR6jS/pUuA64JUqj2tm1WqraeZIrWV+L3BP68x/gptmmtWvY00zTxxE+gDwc+C5iFh70nu+xjdrQK1NMyUJ+B7wbkTcW/C+g2/WgLqD/wngv4E3+P+mmasj4het9x18swZ0pE12SXEH36wBbpppZqM4+GYZcvDNMuTgm2XIwTfLkINvliEH3yxDDr5Zhhx8sww5+GYZcvDNMuTgm2XIwTfLkINvliEH3yxDDr5Zhhx8sww5+GYZcvDNMuTgm2WoiqaZiyT9RtLvJN1fxaDMrF5tPWVXUg/wFnATcADYBnxmuGFmax8/ZdesAXU+ZXcu0B8ReyPiKLABWNLmMc2sZu0G/2Jg34jt/a3XLAFbtmyhv7+/6WFYDdptmnlGa3g3zexOCxYsYOXKlTz55JNND8XOQMeaZkqaB6yJiEWt7dXAYEQ8NmIfX+N3KUmsWLGC9evXNz0UG4M6r/FfBWZJulTSJGAZ8LM2j2njSE9PT9NDsBq0tdSPiGOS7gKeB3qAp0be0bfu5+Cnqd1rfCLiOeC5CsZi49CECf6OV4o8q1bKwU+TZ9VKeamfJgffSvmMnybPqpXyGT9NDr6V8hk/TZ5VK+Xgp8mzaqW81E+Tg2+lHPw0OfhWykv9NHlWrZSDnybPqpVy8NPkWbVSvsZPk4NvpRz8NDn4VspL/TR5Vq2Ug58mz6qV8lI/TQ6+lXLw0+TgWykv9dPkWbVSDn6aPKtWysFPU1uzKulxSbsk7ZC0UdK5VQ3Mxgdf46ep3Y/zF4CrIuJa4LfA6vaHZOOJg5+mtoIfEZsjYrC1+Qowo/0h2XjipX6aqpzVzwGbKjyejQMOfppO21BD0mZgWsFbD0bEs619HgIGIuJHRcdw08zu5aV+9+hY00wASSuAfwA+FRFHCt5308wuJYkNGzawbNmypodiY1DWNLOtFlqSFgGrgBuKQm/dz0v9NLU7q08AU4HNkrZL+vcKxmTjiIOfpna75c6qaiA2PvkaP03+OLdSDn6aHHwr5aV+mjyrVmj4JzFS4U1h63IOvhUaHBz6QqaDnyYH3woNn/G91E+TZ9UKeamfNgffCjn4aXPwrZCv8dPm4FshX+OnzbNqhbzUT5uDb4Uc/LQ5+FbIwU+bg2+FfHMvbQ6+FfLNvbR5Vq2Ql/ppc/CtkIOfNgffCjn4aXPwrdDwzT1f46fJs2qFfMZPm4NvhRz8tLUdfElfkDQo6fwqBmTjg4Oftna75c4EFgJ/qGY4Nl44+Glr94z/deBLVQzExhff3EvbmGdV0hJgf0S8UeF4bJzwGT9tpQ01ShpmPgSsBj49cvdTHcdNM7uPg999am+aKelq4EXgcOulGcABYG5EHDxpXzfN7EL79u3jkksuYceOHcyZM6fp4dgYVN40MyJ2Ah8eUeD3wF9GxP+ObYg23vgaP21VzapP6YnxUj9tbTXNHBYRl1dxHBs/HPy0eR1nhRz8tDn4VsjBT5uDb4V8cy9tnlUr5DN+2hx8K+Tgp83Bt0IOftocfHufvXv38uhXvgLAY1/9KgcOHGh4RFY1B99G6evr4+Nz5jDpJz8BYPDpp5l7zTXs2bOn4ZFZlcb0Xf2zKuDv6neVpQsXcuOLL7IggmuAvcD3e3roX7qU77U+DKw7lH1X32d8G2Xba6+xJILft7YPArcdP86rL7/c5LCsYg6+jTL9oot4C7i4tX0e8BYwffr05gZllXPwbZT71qxh5ZQp7G1t7wC+OGUK//Twww2OyqpWyS/pWDpuv/12Dv/xj6xctQree497zz+fx594gltuuaXpoVmFfHPPCu3Zs4crrriCvr4+Zs+e3fRwbAx8c8/OWk9PDwDHjx9veCRWBwffCjn4aXPwrZCDnzYH3wo5+Glz8K2Qg582B98KOfhpa7d33t2SdknaKemxqgZlzXPw0zbmL/BIuhG4DZgTEUclXVjdsKxpDn7a2jnj3wk8GhFHASLinWqGZOOBg5+2doI/C/ikpJclbZX00aoGZc1z8NPWTtPMicCHImKepI8BPwYKG2u4aWb3GQ7+0aNHGx6Jnanam2YCSHoO+JeI+K/Wdj/w8Yh496T9/F39LiWJjRs3snTp0qaHYmNQ13f1nwEWtApcCUw6OfTW/QYGBpoegtWgnV/LXQesk/RrYABYXs2QbDxx8NM05uC37ubfUeFYbBxy8NPkb+5ZKQc/TQ6+lXLw0+TgWykHP00OvpVy8NPk4FspBz9NDr6VcvDT5ODb+xw5coS1X/saAP/R28uWLVsaHpFVzcG3UY4dO8bNN9zA81/+MgAX9fezfPFinvr2txsemVXJwbdRent7OdrXx8//9CcArgReOHyY+++7j8OHDzc7OKuMg2+jvPrSSyw+dIie1vZUYDZw4YQJ7N69u8GRWZXcQstGmf6Rj7Bz8mQ4coR+hppmHgL+Z2CAadOKfkPbupHP+DbK8uXL2XTOOXwLuAQ4CiyfPJklt97KhRf66WqpcPBtlAsuuIDNv/wlP7zuOqb29DDrnHOYcccdfOsHP2h6aFYhN820UxoYGGDixIlMmODzQzcqexCHg2+WKHfLNbNRkgj+mT5g0DVdM/eawxx813TNjGoOSyL4ZnZ2HHyzDHXkrn6tBczslBr7cZ6ZjT9e6ptlyME3y1AywZd0t6RdknZKeqyDdb8gaVDS+R2q93jr37lD0kZJ59ZUZ5Gk30j6naT766hxUr2ZkrZIerM1h5+vu+aI2j2Stkt6tkP1zpPU25rHPknzOlF3pCSCL+lG4DZgTkRcDfxrh+rOBBYCf+hEvZYXgKsi4lrgt8DqqgtI6gH+DVgE/AXwGUmzq65zkqPAvRFxFTAP+McO1Bx2D9AHdOqG1zeBTRExG5gD7OpQ3ROSCD5wJ/Boq60XEfFOh+p+HfhSh2oBEBGbI2KwtfkKMKOGMnOB/ojY2/pvugFYUkOdEyLi7Yh4vfX3QwyFYXqdNQEkzQBuBr4LFN4Br7jeucDfRMQ6gIg4FhHv1V33ZKkEfxbwSUkvS9oq6aN1F5S0BNgfEW/UXavE54BNNRz3YmDfiO39rdc6QtKlwHUMfbDV7RvAKmDwdDtW5DLgHUnrJf1K0nckTelQ7RO65gk8kjYDRY+AeYihf8eHImKepI8BPwYur7nmauDTI3dvt94Z1H0wIp5t7fMQMBARP6qq7giN/YxX0lSgF7indeavs9Zi4GBEbJc0v85aI0wErgfuiohtktYCDwAPd6j+iUF0hYhYeKr3JN0JbGztt611s+3PI+LdOmpKupqhT+4dkmBouf2apLkRcbCdmmV1R9RfwdDy9FPt1jqFA8DMEdszGTrr10rSB4CfAk9HxDN11wP+CrhN0s3AZOCDkr4fEXW2fN/P0EpxW2u7l6Hgd1QqS/1ngAUAkq4EJrUb+jIRsTMiPhwRl0XEZQxN5vVVhP50JC1iaGm6JCKO1FTmVWCWpEslTQKWAT+rqRYAGvoEfQroi4i1ddYaFhEPRsTM1hzeDvxnzaEnIt4G9rX+PwW4CXizzppFuuaMfxrrgHWSfg0MALVOXoFOLo2fACYBm1urjZciYmWVBSLimKS7gOeBHuCpiKj7zvNfA38PvCFpe+u11RHxi5rrjtSpebwb+GHrQ3U38NkO1T3BX9k1y1AqS30zOwsOvlmGHHyzDDn4Zhly8M0y5OCbZcjBN8uQg2+Wof8D/kk6bzao+a0AAAAASUVORK5CYII=", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD7CAYAAABKWyniAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAEOBJREFUeJzt3XuQlNWZx/HvIzCgcg8QMBAYFZGoIYhBSrIIRhANG1HXDdENpZZbFF5CWSwLiOIlVBSzqJSaaCkkm1qzUcFLcME4BgdKE1kit8XBRaIIeJtRcQoLZIbpZ/+YZnaAYUC73/f09Pl9qqyiu996nweb3/Q5b79zjrk7IhKXY0I3ICLpU/BFIqTgi0RIwReJkIIvEiEFXyRCrZMuYGb6vlAkEHe3pp5P5RPf3RP977bbbku8hmqqZkur2RwN9UUipOCLRKgogj9y5EjVVE3V/BLsSHOBnAuYedI1RORQZoaHvLgnIoVFwReJkIIvEiEFXyRCCr5IhBR8kQgp+CIRUvBFIqTgi0RIwReJkIIvEiEFXyRCCr5IhBR8kQjlHHwz62xmi8xsk5lVmNmwfDQmIsnJx2Kb84Gl7v4PZtYaOD4P5xSRBOW0EIeZdQLWuvuJzRyjhThEAkhyIY5SoMrMfm1ma8zsUTM7LsdzikjCch3qtwbOBG5w99Vmdj8wA5jd+KDbb7+94c8jR44MutaYSLEqLy+nvLz8qI7NdajfE/iLu5dmH38PmOHu4xodo6G+SACJDfXd/UNgu5mdkn3qfOCNXM4pIsnLeZVdMxsEPAaUAH8Drnb36kav6xNfJIDmPvG1vLZIkdLy2iJyAAVfJEIKvkiEFHyRCCn4IhFS8EUipOCLREjBF4mQgi8SIQVfJEIKvkiEFHyRCCn4IhFS8EUipOCLREjBF4mQgi8SIQVfJEIKvkiEFHyRCOUl+GbWyszWmtmSfJxPRJKVr0/8KUAFoOV0RVqAfGyT3Ru4iPq19ZtcyldECks+PvHvA6YBmTycS0RSkNOmmWY2Dqh097VmNvJwx2nTTJHkpblp5s+BnwD7gHZAR2Cxu09sdIx20hEJIJUttMzsXOBf3P3vD3pewRcJIM0ttJRwkRZAm2aKFCltmikiB1DwRSKk4ItESMEXiZCCLxIhBV8kQgq+SIQUfJEIKfgiEVLwRSKk4ItESMEXiZCCLxIhBV8kQgq+SIQUfJEIKfgiEVLwRSKk4ItESMEXiVA+ttDqY2Yvm9kbZrbRzH6aj8ZEJDk5r7JrZj2Bnu6+zszaA68D4919U/Z1rbIrEkCiq+y6+4fuvi7758+BTcAJuZ5XRJKT1zm+mfUDBgOr8nleEcmvnDbNbCw7zF8ETMl+8jfQppkiyUtt08yGk5i1AZ4Hlrn7/Qe9pjm+SACJbpppZgb8O/CJu9/UxOsKvkgASQf/e8BKYAP/v2nmTHd/Ifu6gi8SQCrbZDdTXMEXCUCbZorIARR8kQgp+CIRUvBFIqTgi0RIwReJkIIvEiEFXyRCCr5IhBR8kQgp+CIRUvBFIqTgi0RIwReJkIIvEiEFXyRCCr5IhBR8kQgp+CIRUvBFIpSPTTPHmtmbZvaWmU3PR1MikqycVtk1s1bA/wLnA+8Bq4Ef798wM3uMVtkVCSDJVXaHAlvcfau71wK/By7O8ZwikrBcg/8NYHujxzuyz0kRKCsrY8eOHaHbkATkumnmUY3htWlmy5PJZBgzZgz33nsvN910yM5oUoBS2zTTzIYBt7v72OzjmUDG3ec2OkZz/BZozZo1DBkyhLfeeouTTz45dDvyFSQ5x/8r0N/M+plZCfAj4A85nlMKwIMPPgjASSedFLgTSUI+Ns28ELgfaAUscPe7Dnpdn/gtkJnRuXNndu7cGboV+Yqa+8TPdY6Puy8DluV6HikcNTU1AMyZMydwJ5IU3bknh3j11VcBuPTSSwN3IklR8OUQ99xzDwC9evUK3IkkJec5/hELaI7f4pgZAwYM4M033wzdiuQgyav6UmR27doFwB133BG4E0mSgi8HePHFFwEYO3Zs4E4kSRrqywEGDRrEhg0b0HvW8mmoL0dtw4YNjBo1KnQbkjAFXxpUVlYCMGPGjMCdSNIUfGnw7LPPAjBixIjAnUjSNMeXBj169KCqqkrz+yKhOb4claqqKq644orQbUgKFHwB4J133gFgypQpgTuRNCj4AsDjjz8OwJAhQwJ3ImnQHF+A+vkgoPl9EdEcX5q1P+zTpk0L3ImkRcEXNm7cCMDVV18duBNJi4IvPPzwwwCceuqpgTuRtGiOL5gZbdu25YsvvgjdiuSR5vhyWLW1tYCW2YqNgh+5VatWATBhwoTAnUiacgq+mf3CzDaZ2Xoze9rMOuWrMUnHvHnzAOjdu3fgTiRNuW6oMRr4k7tnzOxuAHefcdAxmuMXMDOjb9++bN26NXQrkmeJzfHdvczdM9mHqwB9bLQgu3fvBuDOO+8M3ImkLZ9z/GuApXk8nyRs+fLlAIwbNy5wJ5K2I26oYWZlQM8mXrrZ3Zdkj5kF1Lj775o6hzbNLEz7r+R37do1cCeSD6ltmglgZlcB/wx8390P+SJYc/zCZWacffbZvPbaa6FbkQQktoWWmY0FpgHnNhV6KVyffvopALfcckvgTiSEXOf4DwDtgTIzW2tmv8xDT5KCJUuWAHDeeecF7kRC0C27kerbty/btm3Tr+EWMd2yK4fYtm0bl1xySeg2JBAFP0Lbt28HYOrUqYE7kVAU/Ag98cQTAAwdOjRwJxKK5vgRateuHXv37tX8vshpji8N3J29e/dy3XXXhW5FAlLwI7N/z/tJkyYF7kRCUvAjs2DBAgDOOOOMwJ1ISJrjR0bLaMdDc3wBoK6uDtAyW6LgR+X1118H0P54ouDHZP78+QCUlpYG7kRC0xw/ImZG9+7dqaysDN2KpEBzfGlYM1/zewEFPxorV64EYPz48YE7kUKgoX4kRo0aRXl5ub7Gi0hzQ30FPxJmxqBBg1i3bl3oViQlmuNHrrq6GoDZs2cH7kQKhYIfgWXLlgEwevTowJ1IodBQPwIDBgxg8+bNmt9HRkP9yG3evJkLLrggdBtSQHIOvplNNbOMmWlXhgL0wQcfADB9+vTAnUghyXW33D7AaODd/LQj+bZ48WIAzjnnnMCdSCHJdbfcp4CfAc8BQ9z90yaO0Rw/oM6dO1NdXa35fYQSmeOb2cXADnff8JU7k0S5O9XV1VxzzTWhW5EC0+wWWs1smDkLmAmMaXz44c6jTTPD2LJlCwDXX3994E4kDYlvmmlmpwN/AnZnn+oNvAcMdffKg47VUD+QW2+9lTlz5lBXV8cxx+gLnNgkfsuumb2D5vgFR8tsxS2N7/H1L6vAZDIZAGbNmhW4EylEOW2TvZ+7n5iP80j+rF+/HoCJEycG7kQKkSZ+Reqhhx4CoH///oE7kUKke/WLlJnRsWPHht/Mk/joXv3I1NTUAFpmSw5PwS8ymUym4ddwL7vsssDdSKFS8IuEuzPv7rvp1qEDl11yCQDLX3opcFdSqBT8IvHIr37Fb3/2M/57927q3PkmcPPkybzwwguhW5MCpIt7ReJbffqwYMcOzgA6AI9Tf3PFf44YwfMrVoRtToLQxb0IfLRzJycCK7OPlwMnAh9lfx9fpDEFv0gMGzKEp8y4CJgKLAB+3qoVw849N3BnUojycueehDf3oYc4f/hwtu7Zw3dqa+loxvN1dazUnXvSBM3xi8j27dv55fz5vF1RwcAhQ7gj+z3+Z599RqdOnQJ3J2nThhqRqqqqokePHgDs27ePVq1aBe5I0qSLe5Hq3r07q1evBrSmvhxIwS9yZ511Fo888ggvv/wy8+bNC92OFAgN9SMxfvx4nnvuOV555RWGDx8euh1Jgeb4QiaToU2bNmQyGd5//3169eoVuiVJmIIvAHz++ed06NABgD179tCuXbvAHUmSdHFPAGjfvj1vv/02AP369dNafBFT8CNTWlrK0qVL+eijj5g0aVLodiQQBT9CF154ITNmzODRRx/lySefDN2OBJDrFlo3AtcBdcB/ufshOzNqjl+4TjvtNCoqKqioqGDgwIGh25E8S+TinpmNAm4GLnL3WjPr7u5VTRyn4Beo2tpaSkpKANi5cyedO3cO3JHkU1IX9yYDd7l7LUBToZfC1qZNG6qq6t+2Ll26UFdXF7gjSUsuwe8PjDCz18ys3MzOyldTkp5u3bqxZs0aAO1pGJFcNs1sDXRx92Fm9l3gSerXfjiENs0sbIMHD+axxx7j2muvZe7cuUyffsilGmkBEt80E8DMlgF3u/uK7OMtwNnu/slBx2mO30JcfvnlLFq0iBUrVjBixIjQ7UiOkrq4Nwk4wd1vM7NTgJfc/ZtNHKfgtxDuzrHHHsvevXu57777WP/nP9Oxa1eumjSJwYMHh25PvqSkgt8GWAh8B6gBprp7eRPHKfgtyK5du+jYsSMADwCfmfFAu3Y8sHAh/zhhQtjm5EvRvfpy1J555hlmX3klG/fs4WtAFbAWuLBDB96trNT9/S2I7tWXo/bqihVcuWcPfwQ+AX4DnAl0AbZs2RKyNckjBV8O0KNXL7aWlDCG+iW6JwB7gMqaGrp16xa2OckbBV8O8JOJE1lcUsJTwEhgHzC5bVvOGzWKnj2b+mZXWiIFXw7Qq1cvlpSVcUffvnRt25avt25N3Q9+wG+eeip0a5JHurgnTXJ3Pv74Y44//niOO+640O3IV6Cr+iIR0lV9ETmAgi8SIQVfJEIKvkiEFHyRCCn4IhFS8EUipOCLREjBF4mQgi8SoaII/tEuMKiaqhl7zf0UfNVUzYhq7lcUwReRL0fBF4lQKr+Wm2gBETmsYL+PLyKFR0N9kQgp+CIRKprgm9mNZrbJzDaa2dwU6041s4yZdU2p3i+yf8/1Zva0mXVKqM5YM3vTzN4ys8R30TSzPmb2spm9kX0Pf5p0zUa1W5nZWjNbklK9zma2KPs+VpjZsDTqNlYUwTezUcAPgW+7++nAv6VUtw8wGng3jXpZLwKnufsgYDMwM98FzKwV8CAwFvgW8GMzG5jvOgepBW5y99OAYcD1KdTcbwpQAaR1wWs+sNTdBwLfBjalVLdBUQQfmAzc5e61AO5elVLde4F/TakWAO5e5u6Z7MNVQO8EygwFtrj71uz/098DFydQp4G7f+ju67J//pz6MJyQZE0AM+sNXAQ8BjR5BTzP9ToBf+fuCwHcfZ+7Vydd92DFEvz+wAgze83Mys3srKQLmtnFwA5335B0rWZcAyxN4LzfALY3erwj+1wqzKwfMJj6H2xJuw+YBmSOdGCelAJVZvZrM1tjZo+aWerrl7dOu+BXZWZlQFNbucyi/u/Rxd2Hmdl3gSeBExOuORMY0/jwXOsdRd2b3X1J9phZQI27/y5fdRsJ9h2vmbUHFgFTsp/8SdYaB1S6+1ozG5lkrUZaU78d4Q3uvtrM7gdmALNTqt/QRIvg7qMP95qZTQaezh63Onux7Wvu/kkSNc3sdOp/cq83M6gfbr9uZkPdvTKXms3VbVT/KuqHp9/PtdZhvAf0afS4D/Wf+onKbr2+GPgPd3826XrAOcAPzewioB3Q0cx+6+4TE6y5g/qR4urs40XUBz9VxTLUfxY4D8DMTgFKcg19c9x9o7t/3d1L3b2U+jfzzHyE/kjMbCz1Q9OL3f2LhMr8FehvZv3MrAT4EfCHhGoBYPU/QRcAFe5+f5K19nP3m929T/Y9nAAsTzj0uPuHwPbsv1OA84E3kqzZlBbziX8EC4GFZvY/QA2Q6JvXhDSHxg8AJUBZdrTxF3e/Lp8F3H2fmd0A/BFoBSxw96SvPA8H/gnYYGZrs8/NdPcXEq7bWFrv443A49kfqn8Drk6pbgPdsisSoWIZ6ovIl6Dgi0RIwReJkIIvEiEFXyRCCr5IhBR8kQgp+CIR+j9UwPPQfLLofwAAAABJRU5ErkJggg==", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "%run 'mpl_animation_html.ipynb'\n", "\n", @@ -647,7 +512,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "# Animation of the double pendulum\n", @@ -656,10 +524,8 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "%run 'mpl_animation_html.ipynb'\n", @@ -670,9 +536,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -685,584 +554,14 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "
\n", - " \n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " Once \n", - " Loop \n", - " Reflect \n", - "
\n", - "
\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "# First set up the figure, and the axis we want to animate\n", "fig = plt.figure()\n", @@ -1290,36 +589,27 @@ "#one frame every 100 milliseconds\n", "animation.ArtistAnimation(fig, ims, interval=1000/frames_per_second, blit=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 } diff --git a/ipython_examples/Performance tests.ipynb b/ipython_examples/Performance tests.ipynb index 1859932d..3dbbace6 100644 --- a/ipython_examples/Performance tests.ipynb +++ b/ipython_examples/Performance tests.ipynb @@ -2,57 +2,37 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "IPython.notebook.set_autosave_interval(600000)" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Autosaving every 600 seconds\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ - "import time\n", "from collections import OrderedDict, namedtuple\n", + "import time\n", + "\n", + "import ggplot as gg\n", "import numpy as np\n", "from numpy import linspace\n", "from pandas import DataFrame\n", "from scipy.integrate import odeint, ode\n", - "import ggplot as gg\n", + "\n", "%autosave 600" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "HAS_SOLVEIVP = False\n", "try:\n", @@ -71,22 +51,14 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "HAS_ODES = False\n", "try:\n", @@ -107,10 +79,8 @@ }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "class egfngf_model:\n", @@ -296,29 +266,26 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.5/dist-packages/Cython/Distutils/old_build_ext.py:30: UserWarning: Cython.Distutils.old_build_ext does not properly handle dependencies and is deprecated.\n", - " \"Cython.Distutils.old_build_ext does not properly handle dependencies \"\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "%load_ext Cython" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -524,9 +491,12 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -546,10 +516,8 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "class scipy_ode_int:\n", @@ -634,10 +602,8 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "methods = [\n", @@ -669,237 +635,15 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { "collapsed": false, + "jupyter": { + "outputs_hidden": false + }, "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Gold standard for egfngf\n", - "Gold standard for egfngf_cython\n", - "method: odeint model: egfngf rtol: 1e-09 err: 7.494591409340501e-10 toc: 0.35076093673706055\n", - "method: odeint model: egfngf rtol: 1e-08 err: 3.5497856151778252e-09 toc: 0.29200196266174316\n", - "method: odeint model: egfngf rtol: 1e-07 err: 3.1049782798315086e-08 toc: 0.1904611587524414\n", - "method: odeint model: egfngf rtol: 1e-06 err: 2.503034344408661e-07 toc: 0.17496275901794434\n", - "method: odeint model: egfngf rtol: 1e-05 err: 2.5149287212601244e-06 toc: 0.1682443618774414\n", - "method: odeint model: egfngf rtol: 0.0001 err: 8.5922166040109e-06 toc: 0.16126561164855957\n", - "method: odeint model: egfngf rtol: 0.001 err: 0.00038126556983120586 toc: 0.07489609718322754\n", - "method: odeint model: egfngf rtol: 0.01 err: 0.0012045689673627687 toc: 0.07285642623901367\n", - "method: odeint model: egfngf rtol: 0.1 err: 0.008254680445357905 toc: 0.07691764831542969\n", - "method: odeint model: egfngf_cython rtol: 1e-09 err: 7.494591409340501e-10 toc: 0.05883359909057617\n", - "method: odeint model: egfngf_cython rtol: 1e-08 err: 3.5497856151778252e-09 toc: 0.04954171180725098\n", - "method: odeint model: egfngf_cython rtol: 1e-07 err: 3.1049782798315086e-08 toc: 0.03227996826171875\n", - "method: odeint model: egfngf_cython rtol: 1e-06 err: 2.503034344408661e-07 toc: 0.029372215270996094\n", - "method: odeint model: egfngf_cython rtol: 1e-05 err: 2.5149287212601244e-06 toc: 0.02083730697631836\n", - "method: odeint model: egfngf_cython rtol: 0.0001 err: 8.5922166040109e-06 toc: 0.054701805114746094\n", - "method: odeint model: egfngf_cython rtol: 0.001 err: 0.00038126556983120586 toc: 0.015133380889892578\n", - "method: odeint model: egfngf_cython rtol: 0.01 err: 0.0012045689673627687 toc: 0.02105879783630371\n", - "method: odeint model: egfngf_cython rtol: 0.1 err: 0.008254680445357905 toc: 0.01078653335571289\n", - "method: vode bdf model: egfngf rtol: 1e-09 err: 1.582705740778086e-08 toc: 1.3630039691925049\n", - "method: vode bdf model: egfngf rtol: 1e-08 err: 7.414737328266103e-08 toc: 1.3709888458251953\n", - "method: vode bdf model: egfngf rtol: 1e-07 err: 2.6406813733046877e-07 toc: 1.329686164855957\n", - "method: vode bdf model: egfngf rtol: 1e-06 err: 2.173654429070666e-06 toc: 1.4558334350585938\n", - "method: vode bdf model: egfngf rtol: 1e-05 err: 4.7244020594807805e-05 toc: 1.1136410236358643\n", - "method: vode bdf model: egfngf rtol: 0.0001 err: 0.0003194977287663884 toc: 1.0986061096191406\n", - "method: vode bdf model: egfngf rtol: 0.001 err: 0.0005875247020684765 toc: 1.0350258350372314\n", - "method: vode bdf model: egfngf rtol: 0.01 err: 0.0006779951775676454 toc: 1.0145373344421387\n", - "method: vode bdf model: egfngf rtol: 0.1 err: 0.0007534157881480254 toc: 1.005566120147705\n", - "method: vode bdf model: egfngf_cython rtol: 1e-09 err: 1.582705740778086e-08 toc: 0.2337808609008789\n", - "method: vode bdf model: egfngf_cython rtol: 1e-08 err: 7.414737328266103e-08 toc: 0.23300743103027344\n", - "method: vode bdf model: egfngf_cython rtol: 1e-07 err: 2.6406813733046877e-07 toc: 0.2381274700164795\n", - "method: vode bdf model: egfngf_cython rtol: 1e-06 err: 2.173654429070666e-06 toc: 0.2519502639770508\n", - "method: vode bdf model: egfngf_cython rtol: 1e-05 err: 4.7244020594807805e-05 toc: 0.19704341888427734\n", - "method: vode bdf model: egfngf_cython rtol: 0.0001 err: 0.0003194977287663884 toc: 0.19471335411071777\n", - "method: vode bdf model: egfngf_cython rtol: 0.001 err: 0.0005875247020684765 toc: 0.181898832321167\n", - "method: vode bdf model: egfngf_cython rtol: 0.01 err: 0.0006779951775676454 toc: 0.1848597526550293\n", - "method: vode bdf model: egfngf_cython rtol: 0.1 err: 0.0007534157881480254 toc: 0.17755579948425293\n", - "method: vode adams model: egfngf rtol: 1e-09 err: 1.1494973053534825e-09 toc: 0.8964440822601318\n", - "method: vode adams model: egfngf rtol: 1e-08 err: 2.755623655199694e-08 toc: 0.9457309246063232\n", - "method: vode adams model: egfngf rtol: 1e-07 err: 9.030623788324496e-08 toc: 3.319200277328491\n", - "method: vode adams model: egfngf rtol: 1e-06 err: 2.1279329442101396e-06 toc: 1.3783111572265625\n", - "method: vode adams model: egfngf rtol: 1e-05 err: 2.7317312334683568e-05 toc: 1.0065898895263672\n", - "method: vode adams model: egfngf rtol: 0.0001 err: 0.00015762923472056477 toc: 1.0114195346832275\n", - "method: vode adams model: egfngf rtol: 0.001 err: 0.00043566122939189274 toc: 1.0354232788085938\n", - "method: vode adams model: egfngf rtol: 0.01 err: 0.0007342446711998006 toc: 1.0209317207336426\n", - "method: vode adams model: egfngf rtol: 0.1 err: 0.0007754136760953892 toc: 1.012150526046753\n", - "method: vode adams model: egfngf_cython rtol: 1e-09 err: 1.1494973053534825e-09 toc: 0.16318130493164062\n", - "method: vode adams model: egfngf_cython rtol: 1e-08 err: 2.755623655199694e-08 toc: 0.1711866855621338\n", - "method: vode adams model: egfngf_cython rtol: 1e-07 err: 9.030623788324496e-08 toc: 0.6225242614746094\n", - "method: vode adams model: egfngf_cython rtol: 1e-06 err: 2.1279329442101396e-06 toc: 0.2435927391052246\n", - "method: vode adams model: egfngf_cython rtol: 1e-05 err: 2.7317312334683568e-05 toc: 0.17838668823242188\n", - "method: vode adams model: egfngf_cython rtol: 0.0001 err: 0.00015762923472056477 toc: 0.17899847030639648\n", - "method: vode adams model: egfngf_cython rtol: 0.001 err: 0.00043566122939189274 toc: 0.18297147750854492\n", - "method: vode adams model: egfngf_cython rtol: 0.01 err: 0.0007342446711998006 toc: 0.18081426620483398\n", - "method: vode adams model: egfngf_cython rtol: 0.1 err: 0.0007754136760953892 toc: 0.18032503128051758\n", - "method: lsoda model: egfngf rtol: 1e-09 err: 7.9299759818241e-10 toc: 0.30083489418029785\n", - "method: lsoda model: egfngf rtol: 1e-08 err: 2.9678468126803637e-09 toc: 0.2960207462310791\n", - "method: lsoda model: egfngf rtol: 1e-07 err: 4.500059920246713e-08 toc: 0.27411675453186035\n", - "method: lsoda model: egfngf rtol: 1e-06 err: 1.0189701929145183e-07 toc: 0.15819025039672852\n", - "method: lsoda model: egfngf rtol: 1e-05 err: 1.3192638509887426e-06 toc: 0.20678973197937012\n", - "method: lsoda model: egfngf rtol: 0.0001 err: 1.3745593086108177e-05 toc: 0.129103422164917\n", - "method: lsoda model: egfngf rtol: 0.001 err: 0.00025077333410454837 toc: 0.15668439865112305\n", - "method: lsoda model: egfngf rtol: 0.01 err: 0.0017300367523133658 toc: 0.11679291725158691\n", - "method: lsoda model: egfngf rtol: 0.1 err: 0.001518197812709744 toc: 0.26616454124450684\n", - "method: lsoda model: egfngf_cython rtol: 1e-09 err: 7.9299759818241e-10 toc: 0.1106269359588623\n", - "method: lsoda model: egfngf_cython rtol: 1e-08 err: 2.9678468126803637e-09 toc: 0.05040550231933594\n", - "method: lsoda model: egfngf_cython rtol: 1e-07 err: 4.500059920246713e-08 toc: 0.08156490325927734\n", - "method: lsoda model: egfngf_cython rtol: 1e-06 err: 1.0189701929145183e-07 toc: 0.02878880500793457\n", - "method: lsoda model: egfngf_cython rtol: 1e-05 err: 1.3192638509887426e-06 toc: 0.03278160095214844\n", - "method: lsoda model: egfngf_cython rtol: 0.0001 err: 1.3745593086108177e-05 toc: 0.02436351776123047\n", - "method: lsoda model: egfngf_cython rtol: 0.001 err: 0.00025077333410454837 toc: 0.021378040313720703\n", - "method: lsoda model: egfngf_cython rtol: 0.01 err: 0.0017300367523133658 toc: 0.014645576477050781\n", - "method: lsoda model: egfngf_cython rtol: 0.1 err: 0.001518197812709744 toc: 0.013463258743286133\n", - "method: dopri5 model: egfngf rtol: 1e-09 err: 3.487213689368218e-11 toc: 1.1242473125457764\n", - "method: dopri5 model: egfngf rtol: 1e-08 err: 3.0333498822680366e-10 toc: 0.8492116928100586\n", - "method: dopri5 model: egfngf rtol: 1e-07 err: 1.4577740997386476e-09 toc: 0.7640457153320312\n", - "method: dopri5 model: egfngf rtol: 1e-06 err: 3.179589143352738e-08 toc: 0.7960407733917236\n", - "method: dopri5 model: egfngf rtol: 1e-05 err: 1.7986466224707935e-07 toc: 0.84712815284729\n", - "method: dopri5 model: egfngf rtol: 0.0001 err: 2.3582500277264748e-06 toc: 0.7310514450073242\n", - "method: dopri5 model: egfngf rtol: 0.001 err: 2.2133255557008247e-05 toc: 0.7199337482452393\n", - "method: dopri5 model: egfngf rtol: 0.01 err: 0.0002418223835189565 toc: 0.7273342609405518\n", - "method: dopri5 model: egfngf rtol: 0.1 err: 0.003087030920236963 toc: 0.7233633995056152\n", - "method: dopri5 model: egfngf_cython rtol: 1e-09 err: 3.487213689368218e-11 toc: 0.16988801956176758\n", - "method: dopri5 model: egfngf_cython rtol: 1e-08 err: 3.0333498822680366e-10 toc: 0.13481640815734863\n", - "method: dopri5 model: egfngf_cython rtol: 1e-07 err: 1.4577740997386476e-09 toc: 0.12070393562316895\n", - "method: dopri5 model: egfngf_cython rtol: 1e-06 err: 3.179589143352738e-08 toc: 0.12108230590820312\n", - "method: dopri5 model: egfngf_cython rtol: 1e-05 err: 1.7986466224707935e-07 toc: 0.12436628341674805\n", - "method: dopri5 model: egfngf_cython rtol: 0.0001 err: 2.3582500277264748e-06 toc: 0.11689949035644531\n", - "method: dopri5 model: egfngf_cython rtol: 0.001 err: 2.2133255557008247e-05 toc: 0.12184667587280273\n", - "method: dopri5 model: egfngf_cython rtol: 0.01 err: 0.0002418223835189565 toc: 0.11848235130310059\n", - "method: dopri5 model: egfngf_cython rtol: 0.1 err: 0.003087030920236963 toc: 0.11866450309753418\n", - "method: dop853 model: egfngf rtol: 1e-09 err: 1.25751830637455e-11 toc: 1.3260033130645752\n", - "method: dop853 model: egfngf rtol: 1e-08 err: 6.61048970111248e-11 toc: 1.14265775680542\n", - "method: dop853 model: egfngf rtol: 1e-07 err: 8.888388742889219e-10 toc: 1.0359838008880615\n", - "method: dop853 model: egfngf rtol: 1e-06 err: 4.66497442327333e-09 toc: 0.960273027420044\n", - "method: dop853 model: egfngf rtol: 1e-05 err: 1.2721465764722477e-07 toc: 0.9472723007202148\n", - "method: dop853 model: egfngf rtol: 0.0001 err: 1.1252778214596523e-06 toc: 0.9492876529693604\n", - "method: dop853 model: egfngf rtol: 0.001 err: 2.291165946985075e-05 toc: 0.9411609172821045\n", - "method: dop853 model: egfngf rtol: 0.01 err: 9.271624730080172e-05 toc: 0.8935632705688477\n", - "method: dop853 model: egfngf rtol: 0.1 err: 0.0016197589501836288 toc: 0.8565003871917725\n", - "method: dop853 model: egfngf_cython rtol: 1e-09 err: 1.25751830637455e-11 toc: 0.2147822380065918\n", - "method: dop853 model: egfngf_cython rtol: 1e-08 err: 6.61048970111248e-11 toc: 0.18518447875976562\n", - "method: dop853 model: egfngf_cython rtol: 1e-07 err: 8.888388742889219e-10 toc: 0.17031097412109375\n", - "method: dop853 model: egfngf_cython rtol: 1e-06 err: 4.66497442327333e-09 toc: 0.14084482192993164\n", - "method: dop853 model: egfngf_cython rtol: 1e-05 err: 1.2721465764722477e-07 toc: 0.1377122402191162\n", - "method: dop853 model: egfngf_cython rtol: 0.0001 err: 1.1252778214596523e-06 toc: 0.13886094093322754\n", - "method: dop853 model: egfngf_cython rtol: 0.001 err: 2.291165946985075e-05 toc: 0.13952231407165527\n", - "method: dop853 model: egfngf_cython rtol: 0.01 err: 9.271624730080172e-05 toc: 0.1342453956604004\n", - "method: dop853 model: egfngf_cython rtol: 0.1 err: 0.0016197589501836288 toc: 0.1288437843322754\n", - "method: RK45 model: egfngf rtol: 1e-09 err: 3.6439984493578474e-11 toc: 1.4232659339904785\n", - "method: RK45 model: egfngf rtol: 1e-08 err: 6.912577130909388e-10 toc: 1.2879347801208496\n", - "method: RK45 model: egfngf rtol: 1e-07 err: 6.694102315426183e-09 toc: 1.196589469909668\n", - "method: RK45 model: egfngf rtol: 1e-06 err: 8.223089846372508e-08 toc: 1.3194856643676758\n", - "method: RK45 model: egfngf rtol: 1e-05 err: 2.2819689641437435e-07 toc: 1.329404354095459\n", - "method: RK45 model: egfngf rtol: 0.0001 err: 3.917911855702793e-06 toc: 1.3202934265136719\n", - "method: RK45 model: egfngf rtol: 0.001 err: 1.639140348158738e-05 toc: 1.3200581073760986\n", - "method: RK45 model: egfngf rtol: 0.01 err: 0.00034920415170319453 toc: 1.3547723293304443\n", - "method: RK45 model: egfngf rtol: 0.1 err: 0.0036178664214251087 toc: 1.3747754096984863\n", - "method: RK45 model: egfngf_cython rtol: 1e-09 err: 3.6439984493578474e-11 toc: 0.5883312225341797\n", - "method: RK45 model: egfngf_cython rtol: 1e-08 err: 6.912577130909388e-10 toc: 0.5303034782409668\n", - "method: RK45 model: egfngf_cython rtol: 1e-07 err: 6.694102315426183e-09 toc: 0.48837947845458984\n", - "method: RK45 model: egfngf_cython rtol: 1e-06 err: 8.223089846372508e-08 toc: 0.536247730255127\n", - "method: RK45 model: egfngf_cython rtol: 1e-05 err: 2.2819689641437435e-07 toc: 0.5374157428741455\n", - "method: RK45 model: egfngf_cython rtol: 0.0001 err: 3.917911855702793e-06 toc: 0.5388848781585693\n", - "method: RK45 model: egfngf_cython rtol: 0.001 err: 1.639140348158738e-05 toc: 0.5385806560516357\n", - "method: RK45 model: egfngf_cython rtol: 0.01 err: 0.00034920415170319453 toc: 0.5404636859893799\n", - "method: RK45 model: egfngf_cython rtol: 0.1 err: 0.0036178664214251087 toc: 0.5524845123291016\n", - "method: RK23 model: egfngf rtol: 1e-09 err: 6.681408073442678e-10 toc: 1.2001097202301025\n", - "method: RK23 model: egfngf rtol: 1e-08 err: 4.8487383658842495e-09 toc: 1.1402056217193604\n", - "method: RK23 model: egfngf rtol: 1e-07 err: 1.279591483277424e-08 toc: 1.0618393421173096\n", - "method: RK23 model: egfngf rtol: 1e-06 err: 1.1492905757525781e-07 toc: 1.0311594009399414\n", - "method: RK23 model: egfngf rtol: 1e-05 err: 1.6930524190926614e-06 toc: 1.027500867843628\n", - "method: RK23 model: egfngf rtol: 0.0001 err: 1.2193154355724498e-05 toc: 1.0268914699554443\n", - "method: RK23 model: egfngf rtol: 0.001 err: 0.0001278426051552712 toc: 1.0209898948669434\n", - "method: RK23 model: egfngf rtol: 0.01 err: 0.002285091844560026 toc: 0.9941794872283936\n", - "method: RK23 model: egfngf rtol: 0.1 err: 0.0527168081924734 toc: 0.8237001895904541\n", - "method: RK23 model: egfngf_cython rtol: 1e-09 err: 6.681408073442678e-10 toc: 0.5616023540496826\n", - "method: RK23 model: egfngf_cython rtol: 1e-08 err: 4.8487383658842495e-09 toc: 0.5162637233734131\n", - "method: RK23 model: egfngf_cython rtol: 1e-07 err: 1.279591483277424e-08 toc: 0.49440717697143555\n", - "method: RK23 model: egfngf_cython rtol: 1e-06 err: 1.1492905757525781e-07 toc: 0.4908134937286377\n", - "method: RK23 model: egfngf_cython rtol: 1e-05 err: 1.6930524190926614e-06 toc: 0.48294854164123535\n", - "method: RK23 model: egfngf_cython rtol: 0.0001 err: 1.2193154355724498e-05 toc: 0.4840507507324219\n", - "method: RK23 model: egfngf_cython rtol: 0.001 err: 0.0001278426051552712 toc: 0.48421287536621094\n", - "method: RK23 model: egfngf_cython rtol: 0.01 err: 0.002285091844560026 toc: 0.47213268280029297\n", - "method: RK23 model: egfngf_cython rtol: 0.1 err: 0.0527168081924734 toc: 0.3859896659851074\n", - "method: Radau model: egfngf rtol: 1e-09 err: 6.652087904512882e-11 toc: 1.3415403366088867\n", - "method: Radau model: egfngf rtol: 1e-08 err: 5.170814498948554e-10 toc: 1.1088793277740479\n", - "method: Radau model: egfngf rtol: 1e-07 err: 4.258043093917271e-09 toc: 0.8848395347595215\n", - "method: Radau model: egfngf rtol: 1e-06 err: 3.060537681449205e-08 toc: 0.5140721797943115\n", - "method: Radau model: egfngf rtol: 1e-05 err: 3.409584565088153e-07 toc: 0.41588926315307617\n", - "method: Radau model: egfngf rtol: 0.0001 err: 4.311698737486343e-06 toc: 0.28522610664367676\n", - "method: Radau model: egfngf rtol: 0.001 err: 2.4120030381309335e-05 toc: 0.13965725898742676\n", - "method: Radau model: egfngf rtol: 0.01 err: 0.0004926898438409504 toc: 0.16023492813110352\n", - "method: Radau model: egfngf rtol: 0.1 err: 0.0024953513627397478 toc: 0.0989832878112793\n", - "method: Radau model: egfngf_cython rtol: 1e-09 err: 6.652087904512882e-11 toc: 0.7576034069061279\n", - "method: Radau model: egfngf_cython rtol: 1e-08 err: 5.170814498948554e-10 toc: 0.5407040119171143\n", - "method: Radau model: egfngf_cython rtol: 1e-07 err: 4.258043093917271e-09 toc: 0.41968345642089844\n", - "method: Radau model: egfngf_cython rtol: 1e-06 err: 3.060537681449205e-08 toc: 0.28287482261657715\n", - "method: Radau model: egfngf_cython rtol: 1e-05 err: 3.409584565088153e-07 toc: 0.1735553741455078\n", - "method: Radau model: egfngf_cython rtol: 0.0001 err: 4.311698737486343e-06 toc: 0.1346416473388672\n", - "method: Radau model: egfngf_cython rtol: 0.001 err: 2.4120030381309335e-05 toc: 0.08444905281066895\n", - "method: Radau model: egfngf_cython rtol: 0.01 err: 0.0004926898438409504 toc: 0.05977010726928711\n", - "method: Radau model: egfngf_cython rtol: 0.1 err: 0.0024953513627397478 toc: 0.05173158645629883\n", - "method: BDF model: egfngf rtol: 1e-09 err: 3.1390972920538235e-09 toc: 0.5705592632293701\n", - "method: BDF model: egfngf rtol: 1e-08 err: 1.2343679627520033e-08 toc: 0.5837991237640381\n", - "method: BDF model: egfngf rtol: 1e-07 err: 8.442730720465382e-08 toc: 0.4266855716705322\n", - "method: BDF model: egfngf rtol: 1e-06 err: 5.070871530430547e-07 toc: 0.327714204788208\n", - "method: BDF model: egfngf rtol: 1e-05 err: 3.766178151369483e-06 toc: 0.32501935958862305\n", - "method: BDF model: egfngf rtol: 0.0001 err: 3.5510810666213124e-05 toc: 0.3260772228240967\n", - "method: BDF model: egfngf rtol: 0.001 err: 0.00017855276159510443 toc: 0.22342371940612793\n", - "method: BDF model: egfngf rtol: 0.01 err: 0.0032314630305983884 toc: 0.13854002952575684\n", - "method: BDF model: egfngf rtol: 0.1 err: 0.009260776487288725 toc: 0.17409443855285645\n", - "method: BDF model: egfngf_cython rtol: 1e-09 err: 3.1390972920538235e-09 toc: 0.3882126808166504\n", - "method: BDF model: egfngf_cython rtol: 1e-08 err: 1.2343679627520033e-08 toc: 0.36484789848327637\n", - "method: BDF model: egfngf_cython rtol: 1e-07 err: 8.442730720465382e-08 toc: 0.2005314826965332\n", - "method: BDF model: egfngf_cython rtol: 1e-06 err: 5.070871530430547e-07 toc: 0.18695449829101562\n", - "method: BDF model: egfngf_cython rtol: 1e-05 err: 3.766178151369483e-06 toc: 0.1921083927154541\n", - "method: BDF model: egfngf_cython rtol: 0.0001 err: 3.5510810666213124e-05 toc: 0.1263880729675293\n", - "method: BDF model: egfngf_cython rtol: 0.001 err: 0.00017855276159510443 toc: 0.12924456596374512\n", - "method: BDF model: egfngf_cython rtol: 0.01 err: 0.0032314630305983884 toc: 0.06199479103088379\n", - "method: BDF model: egfngf_cython rtol: 0.1 err: 0.009260776487288725 toc: 0.04790949821472168\n", - "method: cvode BDF model: egfngf rtol: 1e-09 err: 1.832806059004118e-09 toc: 0.11520576477050781\n", - "method: cvode BDF model: egfngf rtol: 1e-08 err: 1.2058996459624419e-08 toc: 0.06452536582946777\n", - "method: cvode BDF model: egfngf rtol: 1e-07 err: 1.2075101544420856e-07 toc: 0.05853128433227539\n", - "method: cvode BDF model: egfngf rtol: 1e-06 err: 5.660151867535509e-07 toc: 0.04850339889526367\n", - "method: cvode BDF model: egfngf rtol: 1e-05 err: 2.1248663150133023e-06 toc: 0.03807353973388672\n", - "method: cvode BDF model: egfngf rtol: 0.0001 err: 8.0369563686448e-06 toc: 0.03027200698852539\n", - "method: cvode BDF model: egfngf rtol: 0.001 err: 0.0006223608369100838 toc: 0.02919483184814453\n", - "method: cvode BDF model: egfngf rtol: 0.01 err: 0.0019098949502052468 toc: 0.01840806007385254\n", - "method: cvode BDF model: egfngf rtol: 0.1 err: 1532623.092336226 toc: 0.037409305572509766\n", - "method: cvode BDF model: egfngf_cython rtol: 1e-09 err: 1.832806059004118e-09 toc: 0.01679062843322754\n", - "method: cvode BDF model: egfngf_cython rtol: 1e-08 err: 1.2058996459624419e-08 toc: 0.013664960861206055\n", - "method: cvode BDF model: egfngf_cython rtol: 1e-07 err: 1.2075101544420856e-07 toc: 0.015189647674560547\n", - "method: cvode BDF model: egfngf_cython rtol: 1e-06 err: 5.660151867535509e-07 toc: 0.012308835983276367\n", - "method: cvode BDF model: egfngf_cython rtol: 1e-05 err: 2.1248663150133023e-06 toc: 0.008781194686889648\n", - "method: cvode BDF model: egfngf_cython rtol: 0.0001 err: 8.0369563686448e-06 toc: 0.007406711578369141\n", - "method: cvode BDF model: egfngf_cython rtol: 0.001 err: 0.0006223608369100838 toc: 0.004948139190673828\n", - "method: cvode BDF model: egfngf_cython rtol: 0.01 err: 0.0019098949502052468 toc: 0.004040956497192383\n", - "method: cvode BDF model: egfngf_cython rtol: 0.1 err: 1532623.092336226 toc: 0.006505489349365234\n", - "method: cvode ADAMS model: egfngf rtol: 1e-09 err: 1.9099610896470648e-09 toc: 0.24017071723937988\n", - "method: cvode ADAMS model: egfngf rtol: 1e-08 err: 7.36613825817282e-09 toc: 0.21523308753967285\n", - "method: cvode ADAMS model: egfngf rtol: 1e-07 err: 8.801648077981857e-08 toc: 0.13567042350769043\n", - "method: cvode ADAMS model: egfngf rtol: 1e-06 err: 1.1504714326777807e-06 toc: 0.08283209800720215\n", - "method: cvode ADAMS model: egfngf rtol: 1e-05 err: 4.671290605377484e-06 toc: 0.07387781143188477\n", - "method: cvode ADAMS model: egfngf rtol: 0.0001 err: 1.0608413538041836e-05 toc: 0.058342933654785156\n", - "method: cvode ADAMS model: egfngf rtol: 0.001 err: 0.00012178687288246389 toc: 0.052404165267944336\n", - "method: cvode ADAMS model: egfngf rtol: 0.01 err: 0.0011556670401549067 toc: 0.04270744323730469\n", - "method: cvode ADAMS model: egfngf rtol: 0.1 err: 0.005974432620540139 toc: 0.03546285629272461\n", - "method: cvode ADAMS model: egfngf_cython rtol: 1e-09 err: 1.9099610896470648e-09 toc: 0.05116581916809082\n", - "method: cvode ADAMS model: egfngf_cython rtol: 1e-08 err: 7.36613825817282e-09 toc: 0.036460161209106445\n", - "method: cvode ADAMS model: egfngf_cython rtol: 1e-07 err: 8.801648077981857e-08 toc: 0.029713153839111328\n", - "method: cvode ADAMS model: egfngf_cython rtol: 1e-06 err: 1.1504714326777807e-06 toc: 0.01849055290222168\n", - "method: cvode ADAMS model: egfngf_cython rtol: 1e-05 err: 4.671290605377484e-06 toc: 0.015970945358276367\n", - "method: cvode ADAMS model: egfngf_cython rtol: 0.0001 err: 1.0608413538041836e-05 toc: 0.014380693435668945\n", - "method: cvode ADAMS model: egfngf_cython rtol: 0.001 err: 0.00012178687288246389 toc: 0.011634111404418945\n", - "method: cvode ADAMS model: egfngf_cython rtol: 0.01 err: 0.0011556670401549067 toc: 0.00951528549194336\n", - "method: cvode ADAMS model: egfngf_cython rtol: 0.1 err: 0.005974432620540139 toc: 0.007592439651489258\n" - ] - } - ], + "outputs": [], "source": [ "\n", "rtols = 10 ** np.arange(-9.0, 0.0)\n", @@ -948,46 +692,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABCEAAAL2CAYAAAB/mYxTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3Xl4ZFWB///3ubfWpCpL7+l0Nw1N080izdLDKkqDyoDg\nKCqDgODGzxnnYdTh589xZr4zjPob5+eMC4w6o/KMIILyCIqyI6vsKKAssvVOd6fTnc5aqfXee35/\n3Eol6aS7kyapSief1/PUk6pbt+45dSqp1P3UWYy11iIiIiIiIiIiMsmcWldARERERERERGYGhRAi\nIiIiIiIiUhUKIURERERERESkKhRCiIiIiIiIiEhVKIQQERERERERkapQCCEiIiIiIiIiVaEQQkRE\nRERERESqQiGEiIiIiIiIiFSFQggRERERERERqQqFECIiIgcAx3H48pe/PO7Hbdq0Ccdx+PGPfzwJ\ntdq3e+65h2OPPZZkMonruvT29k5aWTfccAOHH344sViMWbNmTVo5IiIisv8UQoiIiIzR9ddfj+M4\nOI7DE088Meo+ixcvxnEc3ve+91W5dlNPZ2cnf/mXf0ldXR3f+973uOGGG6ivr5+Usl577TU+/vGP\ns3z5cq699lp+8IMfTEo5IiIi8tZEal0BERGRA00ymeSmm27ilFNOGbb9kUceYevWrSQSiRrVbGr5\n3e9+RyaT4atf/Spr1qyZ1LIefvhhrLVcffXVHHzwwZNaloiIiOw/9YQQEREZp3POOYef//znBEEw\nbPtNN93E6tWrWbBgQY1qNrW0t7cD0NjYWLWyGhoaJr0sERER2X8KIURERMbBGMNHPvIRdu3axW9+\n85vK9lKpxC233MJFF12EtXbE47LZLFdeeSVLliwhkUiwcuVKvvGNb4zYr1gs8vnPf5558+bR0NDA\n+9//frZu3TpqXbZt28YnPvEJFixYQCKR4KijjuJHP/rRfj+3np4ePve5z1XquHz5cr7+9a+PeD6d\nnZ189KMfpbGxkebmZj7+8Y/zwgsvDJt7Ys2aNXzsYx8DYPXq1TiOwyc+8QkATj/9dI4++mheeeUV\n1qxZQ319PYsWLeI//uM/RtRp8+bNvO997yOVSjF//nz+7u/+jvvuuw/Hcfjtb38LwMEHH8xVV10F\nwNy5c/d7/gwRERGZfBqOISIiMk5Lly7lpJNO4qc//SlnnXUWAHfddRe9vb1ceOGFXH311SMec955\n5/HII4/wqU99ilWrVnHvvffyhS98gW3btg0LIz75yU9y0003cfHFF3PyySfz4IMP8t73vhdjzLDj\n7dixgxNPPBHXdfnbv/1b5syZw913380nP/lJ+vr6+Nu//dtxPadcLsc73vEO2tra+Ku/+isWL17M\nE088wZe+9CW2b9/ON7/5TQCstZx77rn8/ve/5zOf+QwrVqzgV7/6FZdddtmwOv7TP/0TK1as4Ic/\n/CFf/epXWbp0KcuWLQPCIKezs5Ozzz6b888/nwsvvJBbbrmFv//7v+foo4+utGk2m2XNmjW0t7fz\nuc99jvnz53PTTTfx0EMPDSvr6quv5vrrr+e2227j+9//PvX19Rx99NHjev4iIiJSJVZERETG5Lrr\nrrOO49hnn33Wfve737WNjY02n89ba6294IIL7JlnnmmttXbp0qX2vPPOqzzutttus8YY+7WvfW3Y\n8T784Q9b13Xt+vXrrbXW/vGPf7TGGHvFFVcM2+/iiy+2juPYf/3Xf61s++QnP2lbW1ttV1fXsH0/\n8pGP2Obm5kq9Nm7caI0x9vrrr9/rc/vKV75i0+m0Xbdu3bDtX/rSl2w0GrVbtmyx1lp76623WmOM\n/a//+q9h+5155pnWcZxh5Qxtr6FOP/106ziOvfHGGyvbisWibWlpsR/+8Icr277xjW9Yx3Hs7bff\nXtlWKBTs4Ycfbh3HsY888khl+1VXXWUdx7G7du3a6/MUERGR2tJwDBERkf1wwQUXkM1mueOOO8hk\nMtxxxx1cfPHFo+579913E4lEuOKKK4Ztv/LKKwmCgLvvvhuAO++8E2PMiP0+97nPjRgS8Ytf/ILz\nzjsP3/fZtWtX5fKe97yHnp4ennvuuXE9n1tuuYXTTjuNxsbGYcc788wz8TyvMvThnnvuIRaL8alP\nfWrY4//mb/5m1GEoe5JKpbjooosqt6PRKCeccALr16+vbLv33ntpbW3l3HPPrWyLxWJcfvnl43pu\nIiIiMnVoOIaIiMh+mDNnDu9617u46aab6O/vJwgCPvShD42676ZNm1i4cOGI5SkPP/zwyv0Qzn/g\nOE5l2MKAFStWDLu9c+dOuru7+cEPfsD3v//9EeUZY9ixY8e4ns8bb7zBiy++yNy5c/d6vM2bN9PS\n0jJiBZBDDz10XOUtWrRoxLbm5mZefPHFyu1NmzaNaIv9KUtERESmDoUQIiIi++miiy7i8ssvp62t\njbPPPpt0Ol2VcgdW5bjkkku47LLLRt1nvHMiBEHAu9/9br74xS+O2qPhsMMOG39F98J13VG3j6c3\nhYiIiBx4FEKIiIjspw984AN8+tOf5umnn+bmm2/e434HHXQQDzzwAP39/cN6Q7zyyitAONHlwH5B\nELBu3TqWL19e2e/VV18ddry5c+eSTqfxfZ8zzjhjQp7LsmXLyGQyrFmzZq/7HXTQQTz88MPk8/lh\nvSHeeOONCanH7mUNtNFQk1GWiIiIVIfmhBAREdlP9fX1/M///A9XXXUV55133h73O+ecc/A8j+98\n5zvDtn/rW9/CcRz+/M//HICzzz4bay3XXHPNsP2+/e1vD1sNwnEcPvjBD3Lrrbfy8ssvjyivo6Nj\n3M/lggsu4Mknn+S+++4bcV9PT0+l98VZZ51FsVjkhz/8YeV+ay3f/e53R6zg8VadddZZbN26ldtv\nv72yLZ/Pc+21105oOSIiIlI96gkhIiIyDrsPF/joRz+6z8ecd955rFmzhn/8x39kw4YNlSU6b7/9\ndj7/+c9z8MEHA7Bq1So+8pGP8L3vfY/u7m5OOeUUHnjgAdatWzei3H//93/n4Ycf5sQTT+Tyyy/n\niCOOoLOzk2effZYHH3xw3EHEF77wBX79619z7rnn8rGPfYzjjz+e/v5+XnjhBX7xi1+wceNGZs2a\nxfvf/35OOOEErrzySt544w1WrlzJr3/9a7q7uwFGBBFvZXjFpz/9ab7zne9w4YUX8tnPfpaWlhZu\nvPFGksnkqGWJiIjI1KcQQkREZBzGcuJrjBm2nzGG22+/nX/+53/m5ptv5rrrrmPp0qX853/+J5//\n/OeHPfZHP/oR8+bN48Ybb+RXv/oVZ555JnfeeSeLFy8edsx58+bxzDPP8OUvf5lf/vKX/Pd//zez\nZ8/myCOP5Otf//q465xMJvntb3/Lv/3bv/Hzn/+cG264gYaGBg477DC+/OUv09jYCIS9MO666y4+\n+9nP8uMf/xjHcTj//PP5l3/5F0499dQRE1buqeyxbK+vr+ehhx7iiiuu4JprriGVSnHZZZdx0kkn\n8aEPfWhEWSIiIjL1GasZoEREROQtuu222/jgBz/IY489xsknnzypZX3729/myiuvZMuWLbS0tExq\nWSIiIjKxFEKIiIjIuOw+KeXAyhrPPfcc27dvJx6PT1pZ+XyeY489FmvtiAk7RUREZOrTcAwREREZ\nlyuuuIJcLsfJJ59MoVDg1ltv5amnnuJrX/vahAYQAOeffz5LlizhmGOOobu7m5/85Ce8/vrr3HTT\nTRNajoiIiFSHekKIiIjIuPz0pz/lm9/8JmvXriWfz3PooYfymc98hr/+67+e8LKuueYarr32WjZu\n3Ijv+xxxxBF88Ytf5EMf+tCElyUiIiKTTyGEiIiIiIiIiFSFU+sKiIiIiIiIiMjMoBBCRERERERE\nRKpCIYSIiIiIiIiIVIVCCBERERERERGpCoUQIiIiIiIiIlIVCiFEREREREREpCoUQoiIiIiIiIhI\nVSiEEBEREREREZGqUAghIiIiIiIiIlWhEEJEREREREREqkIhhIiIiIiIiIhUhUIIEREREREREakK\nhRAiIiIiIiIiUhUKIURERERERESkKhRCiIiIiIiIiEhVKIQQERERERERkapQCCEiIiIiIiIiVaEQ\nQkRERERERESqQiGEiIiIiIiIiFSFQggRERERERERqQqFECIiIiIiIiJSFQohRERERERERKQqFEKI\niIiIiIiISFUohBARERERERGRqlAIISIiIiIiIiJVoRBCRERERERERKpCIYSIiIiIiIiIVEWk1hWY\nzn72s5+xceNGDjnkEC644IJaV0dERERERESkptQTYhKddNJJnH/++bWuhoiIiIiIiMiUoBBiEi1d\nupRYLFbraoiIiIiIiIhMCQohRERERERERKQqNCfEKDZt2sTjjz9OW1sbfX19XHjhhaxcuXLYPs88\n8wxPPPEEmUyG+fPnc84559Da2lqjGouIiIiIiIhMfeoJMYpisciCBQt473vfizFmxP0vvfQS9957\nL6effjqf/vSnWbBgATfccAP9/f01qK2IiIiIiIjIgUEhxCiWL1/OGWecwcqVK7HWjrj/ySefZPXq\n1RxzzDHMnTuXc889l2g0yvPPPz9i39EeLyIiIiIiIjITaTjGOPm+T1tbG6eddlplmzGGQw45hC1b\ntgzb98c//jHt7e0Ui0W++c1vcsEFF7Bo0aLK/V/5ylf2WM7/+T//Z+IrLyIiIiIiIlJDCiHGKZvN\nEgQBqVRq2PZUKsWuXbuGbbv00kv3uxz1oBARERERmXlGGw4uMp0ohKihvfV2sNbS1tZWtbqkUiky\nmUzVypuoMsd7jLHs39LSAlDV9ge9BgPU/pN7DLX/xJY5Xd6D1P6D9DcwucfQe9DElqn2r22Zk/ke\nJDKdaU6Icaqrq8NxnBFvIJlMZkTvCBEREREREREZpBBinFzXpaWlhQ0bNlS2WWvZsGEDixcvrmHN\nRERERERERKY2DccYRbFYpLOzszIvQ1dXF9u3byeZTNLY2MjJJ5/MbbfdRktLC62trTz11FOUSiWO\nOeaYGtdcREREREREZOpSCDGKbdu2cd1112GMwRjDfffdB8CqVat4//vfz1FHHUU2m+Whhx6iv7+f\nBQsWcMkll1BfX1/jmouIiIiIiIhMXQohRrF06VKuuuqqve5zwgkncMIJJ1SnQiIiIiIiIiLTgLFa\nC3JK6uvr0zKdNTKwLJLavzbU/rWl9q89vQa1pfavLbV/ban9a88YQzqdrnU1RCaVQogpSkt0Ts4x\ntDzbxJep5cFqW6bav7ZlTpf3ILX/IP0NTO4x9B40sWWq/Wtb5mS9Bw2EQSLTlVbHEBEREREREZGq\nUAghIiIiIiIiIlWhEEJEREREREREqkIhhIiIiIiIiIhUhUIIEREREREREakKhRAiIiIiIiIiUhVa\nonOK6uvr0xrNNaI1smtL7V9bav/a02tQW2r/2lL715bav/aMMaTT6VpXQ2RSKYSYoqy1WiN+Eo6h\nNeInvkytUV7bMtX+tS1zurwHqf0H6W9gco+h96CJLVPtX9syJ+s9aCAMEpmuNBxDRERERERERKpC\nIYSIiIiIiIiIVIVCCBERERERERGpCoUQIiIiIiIiIlIVCiFEREREREREpCoUQoiIiIiIiIhIVSiE\nEBEREREREZGqMNZaW+tKyEh9fX3opamNgbWZ1f61ofavLbV/7ek1qC21f22p/WtL7V97xhjS6XSt\nqyEyqRRCTFHWWtra2qpWXiqVIpPJVK28iSpzvMcYy/4tLS0AVW1/0GswQO0/ucdQ+09smdPlPUjt\nP0h/A5N7DL0HTWyZav/aljlZ70EDYZDIdKXhGCIiIiIiIiJSFQohRERERERERKQqFEKIiIiIiIiI\nSFUohBARERERERGRqlAIISIiIiIiIiJVoRBCRERERERERKpCIYSIiIiIiIiIVIVCCBERERERERGp\nCmOttbWuhIzU19eHXpraMMYAqP1rRO1fW2r/2tNrUFtq/9pS+9eW2r/2jDGk0+laV0NkUimEmKKs\ntbS1tVWtvFQqRSaTqVp5E1XmeI8xlv1bWloAqtr+oNdggNp/co+h9p/YMqfLe5Daf5D+Bib3GHoP\nmtgy1f61LXOy3oMGwiCR6UrDMURERERERESkKhRCiIiIiIiIiEhVKIQQERERERERkapQCCEiIiIi\nIiIiVaEQQkRERERERESqQiGEiIiIiIiIiFSFQggRERERERERqQqFECIiIiIiIiJSFQohRERERERE\nRKQqFEKIiIiIiIiISFUohBARERERERGRqjDWWlvrSshIfX196KWpDWMMgNq/RtT+taX2rz29BrWl\n9q8ttX9tqf1rzxhDOp2udTVEJpVCiCnKWktbW1vVykulUmQymaqVN1FljvcYY9m/paUFoKrtD3oN\nBqj9J/cYav+JLXO6vAep/Qfpb2Byj6H3oIktU+1f2zIn6z1oIAwSma40HENEREREREREqkIhhIiI\niIiIiIhUhUIIEREREREREakKhRAiIiIiIiIiUhUKIURERERERESkKhRCiIiIiIiIiEhVKIQQERER\nERERkapQCCEiIiIiIiIiVaEQQkRERERERESqQiGEiIiIiIiIiFSFQggRERERERERqQqFECIiIiIi\nIiJSFQohRERERERERKQqjLXW1roSMlJfXx96aWrDGAOg9q8RtX9tqf1rT69Bban9a0vtX1tq/9oz\nxpBOp2tdDZFJpRBiirLW0tbWVrXyUqkUmUymauVNVJnjPcZY9m9paQGoavuDXoMBav/JPYbaf2LL\nnC7vQWr/QfobmNxj6D1oYstU+9e2zMl6DxoIg0SmKw3HEBEREREREZGqUAghIiIiIiIiIlWhEEJE\nREREREREqkIhhIiIiIiIiIhURaTWFRARkRoJwPSFV20axdIiIiIiMukUQoiIzDRFiD8O8d+B0x1u\n8puheALY8y0mplm5RURERGRyKIQQEZlJcpbUtRDZMnyz2wXJe6G4dhexL8yqTd1EREREZNpT51sR\nkRnE+WVhRAAxVLCuROnmvupVSERERERmFIUQIiIzhMmCedbb537+EznIV6FCIiIiIjLjKIQQEZkh\nImvBlMawY8ESWT/p1RERERGRGUghhIjITLHvThAVYworRERERETGSSGEiMgMEcwZ+762bvLqISIi\nIiIzl0IIEZEZwl8CduEY3vYN1N8AyV+A0z759RIRERGRmUMhhIjIDBKcF8OavezgQvQzTeTPhOhr\n0HA11F8XzieBrVIlRURERGTaitS6AiIiUj32yAiFUyHx2Mj7gjpIfLIZ97gEhdZuCqdC9IVw39T/\n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\nNFW6JhoAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABCEAAAL2CAYAAAB/mYxTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzs3XecVPW9P/7XOWd6295Z+tKbgChiAYldjDFq7CUmMdfE\nGOMvNzHfFNtNchNjotHcaLw3JAa83qBRsYENREEsgCBSl2VhC7B9d/rMOZ/fH2dmdmZntsHuzO7y\nej4ey+58zmc+n8/5TGHOez5FEkIIEBERERERERENMjnTDSAiIiIiIiKikwODEERERERERESUFgxC\nEBEREREREVFaMAhBRERERERERGnBIAQRERERERERpQWDEERERERERESUFgxCEBEREREREVFaMAhB\nRERERERERGnBIAQRERERERERpQWDEERERL2QZRkPPPBAv+9XXV0NWZbx97//fRBa1bs33ngDp5xy\nCqxWKxRFQXt7+6DV9cwzz2Dq1KkwmUzIzc0dtHqOhyzL+N73vpfpZhAREREYhCAiomHib3/7G2RZ\nhizL2LhxY8o85eXlkGUZl112WZpbN/Q0Nzfja1/7Gmw2G/70pz/hmWeegd1uH5S69uzZg1tvvRUV\nFRV4+umn8dRTTw1KPT3ZtGkT7r///kENtBAREdGJM2S6AURERP1htVqxcuVKnHHGGQnp69evR21t\nLSwWS4ZaNrR8/PHHcLvdeOihh7BkyZJBrWvdunUQQuDRRx/FuHHjBrWu7mzcuBEPPPAAbr31Vrhc\nroy0gYiIiHrHkRBERDSsXHzxxfjnP/8JTdMS0leuXIn58+ejuLg4Qy0bWo4ePQoAyMrKSltdmbz4\nF0JkrG4iIiLqOwYhiIho2JAkCddeey2amprw5ptvxtJDoRBWrVqF6667LuXFqNfrxT333IPRo0fD\nYrFgypQp+N3vfpeULxgM4u6770ZhYSFcLhcuv/xy1NbWpmxLXV0dvv71r6O4uBgWiwUzZszAX//6\n1+M+t7a2Nnz/+9+PtbGiogK/+c1vks6nubkZN954I7KyspCTk4Nbb70V27dvT1h7YsmSJbjlllsA\nAPPnz4csy/j6178OAFi8eDFmzZqFXbt2YcmSJbDb7Rg1ahR++9vfJrXp0KFDuOyyy+BwOFBUVIQf\n/OAHWLt2LWRZxnvvvQcAGDduHO677z4AQEFBQb/Xz6irq8Ntt92GsrIyWCwWjB8/HnfccQfC4TCq\nqqogyzIeffTRpPtt3LgRsizjueeew/33349///d/BwCMHTsWsixDURQcOnQo4T4vvfQSZs6cGXu8\n1qxZk1Tu1q1bcdFFFyErKwtOpxNf+tKXsHnz5oQ80alBGzduxA9+8AMUFhbC4XDgiiuuQFNTU5/P\nnYiI6GTE6RhERDSsjB07FqeffjqeffZZXHDBBQCA1157De3t7bjmmmtSXrAuW7YM69evxze+8Q3M\nnj0ba9aswQ9/+EPU1dUlBCNuu+02rFy5Etdffz0WLlyId955B5dccgkkSUoo79ixYzjttNOgKAq+\n973vIT8/H6+//jpuu+02dHR09HsRRJ/Ph7PPPhv19fX49re/jfLycmzcuBH33nsvjhw5gkceeQSA\n/m3/pZdeik8++QR33HEHJk+ejJdeegk333xzQht/+tOfYvLkyfjLX/6Chx56CGPHjsWECRMA6IGc\n5uZmXHTRRbjiiitwzTXXYNWqVfjxj3+MWbNmxfrU6/ViyZIlOHr0KL7//e+jqKgIK1euxLvvvptQ\n16OPPoq//e1vePHFF/Hkk0/Cbrdj1qxZfTrv+vp6nHrqqWhvb8ftt9+OyZMno7a2FqtWrYLX68W4\nceOwaNEirFixAnfddVfCfVesWAGXy4Uvf/nLmDZtGvbu3Yv//d//xaOPPoq8vDwAelAkasOGDXjh\nhRdwxx13wOl04rHHHsOVV16JQ4cOIScnBwDwxRdf4Oyzz0ZWVhZ+/OMfw2Aw4Mknn8TixYvx3nvv\n4dRTT01ow5133onc3Fzcd999OHjwIH7/+9/ju9/9Lp599tk+nT8REdFJSRAREQ0Dy5cvF7Isi08/\n/VQ88cQTIisrS/j9fiGEEFdffbVYunSpEEKIsWPHimXLlsXu9+KLLwpJksSvfvWrhPKuuuoqoSiK\nOHDggBBCiM8++0xIkiTuvPPOhHzXX3+9kGVZ3H///bG02267TZSVlYmWlpaEvNdee63IycmJtevg\nwYNCkiTxt7/9rcdze/DBB4XT6RSVlZUJ6ffee68wGo2ipqZGCCHE888/LyRJEn/84x8T8i1dulTI\nspxQT3x/xVu8eLGQZVmsWLEilhYMBkVJSYm46qqrYmm/+93vhCzLYvXq1bG0QCAgpk6dKmRZFuvX\nr4+l33fffUKWZdHU1NTjeXZ10003CYPBILZs2dJtnqeeekrIsiz27NkTSwuFQqKgoEB8/etfj6U9\n/PDDQpZlUV1dnVSGJEnCYrGIqqqqWNr27duFJEniiSeeiKVdfvnlwmKxiIMHD8bS6uvrhcvlEosX\nL46lLV++XEiSJC644IKEen7wgx8Io9Eo2tvb+9YBREREJyFOxyAiomHn6quvhtfrxSuvvAK3241X\nXnkF119/fcq8r7/+OgwGA+68886E9HvuuQeapuH1118HALz66quQJCkp3/e///2kKREvvPACli1b\nBlVV0dTUFPs5//zz0dbWhi1btvTrfFatWoWzzjoLWVlZCeUtXboU4XA4NvXhjTfegMlkwje+8Y2E\n+3/nO9/p15oIDocD1113Xey20WjEggULcODAgVjamjVrUFZWhksvvTSWZjKZ8M1vfrNf59YdIQRe\neuklXHbZZTjllFO6zXf11VfDbDZjxYoVsbQ33ngDTU1NuOGGG/pc33nnnYexY8fGbs+cORMulyt2\nzpqm4c0338RXvvIVjBkzJpavuLgY1113Hd5//3243e5YuiRJ+Na3vpVQx1lnnQVVVVFdXd3ndhER\nEZ1sOB2DiIiGnfz8fHzpS1/CypUr4fF4oGkarrzyypR5q6urUVpamrQ95dSpU2PHAX39A1mWY9MW\noiZPnpxwu6GhAa2trXjqqafw5JNPJtUnSRKOHTvWr/PZt28fduzYkTB9IFV5hw4dQklJSdIOIBMn\nTuxXfaNGjUpKy8nJwY4dO2K3q6urk/rieOrqTkNDA9rb2zF9+vQe82VlZWHZsmVYuXIl7r//fgD6\nVIyysrJ+7fpRXl6elJaTk4OWlpZYe7xeLyZNmpSUb+rUqdA0DYcPH449b1KVGZ3WES2TiIiIkjEI\nQUREw9J1112Hb37zm6ivr8dFF10Ep9OZlnqju3LccMMNuPnmm1Pm6euaCPFlnnfeefjRj36UckRD\nqgvjE6EoSsr0/oymSKebbroJq1atwocffogZM2Zg9erV+O53v9uvMgbjnIdbPxIREQ0FDEIQEdGw\n9JWvfAW33347Nm/ejOeee67bfGPGjMHbb78Nj8eTMBpi165dABAboj9mzBhomobKykpUVFTE8u3e\nvTuhvIKCAjidTqiqinPPPXdAzmXChAlwu929frM/ZswYrFu3Dn6/P2E0xL59+wakHV3rivZRvIGq\nq6CgAC6XC59//nmveS+88ELk5+djxYoVWLBgAXw+X9JUjK6Lhx5Pe2w2G/bs2ZN0bNeuXZBlOeVo\n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\nBx98UDfccEOz1y655JLwYxXvvvuuhgwZotTUVF188cXasWNHeL8tW7Zo0KBB6tKli2655RaFQqHw\ntlAopHnz5qlHjx7yer265557mm0/0euvv66BAwcqOTlZffv21YoVK8LbKisr9ZOf/ERdu3bVsGHD\n9Pnnnzd776RJk5SVlaX09HRNmTJFhw8fliQVFRXJ5XLp8ccfl9frVU5OjlatWqVXX31VvXr1UlZW\nlpYuXRpuZ+nSperRo4eSk5P1ve99T++8806r6nimCCEAAAAAAJ1GYWGhVq1apWAwKEn66quvtGXL\nFl111VWqqKjQlVdeqXnz5unAgQOaMGGCrrjiCoVCIdXV1WnSpEm69dZbVV5ergEDBmjDhg3hdv/w\nhz9o/fr12rp1q3bu3KmtW7dq8eLFpxxDcnKyVq5cqaNHj+rPf/6zpk+frv3790uS7r//fh04cECl\npaV69tln9dRTTzV776RJk1RUVKTdu3crEAjoN7/5TXhbMBjUF198oZKSEv32t7/VzJkz9fLLL+uT\nTz7R8uXL9Ytf/EKVlZWqrKzUnXfeqbfffltHjx7V6tWrlZ+fH+lSnxIhBAAAAACg0+jdu7d69Oih\n1atXS5JWrFihyy67TImJiXrjjTc0aNAgXXnllXI6nbrrrrtUVVWlLVu2aOPGjXK5XLrpppvkdDp1\n2223yes9/hjI0qVL9cADDyg1NVXJycmaPXu2XnzxxVOOYcyYMSooKJAkXX755TrnnHP0r3/9Kzye\nuXPnKikpSX379tV1113X7L3XXHON4uPj5fF4dMcdd2jdunXhbYZh6N5771VMTIwKCwt14MAB3Xnn\nnYqPj9dFF12kpKQkffHFF5Ikh8Oh7du3q7a2Vnl5eYQQAAAAAABEQ2FhoZYvXy5JWr58uQoLCyVJ\nZWVl6t69e3g/wzDUrVs3lZWVyefzqVu3bs3aOfH74uJijRs3TqmpqeratauuvfZaHTx48JT9r1u3\nTqNHj1ZaWpq6du2q999/X+Xl5ZJ0Uj95eXnhr4PBoO644w716NFDXbp00eTJk8PvkySn06mUlBRJ\nUnx8vCQpIyMjvD0hIUGBQECJiYl6/vnn9ec//1nZ2dkqLCyUz+drRQXPHCEEAAAAAKBTmTJlilat\nWqXdu3frww8/1MSJEyVJOTk5KioqarZvSUmJcnJy5PV6VVJS0mxbaWlp+Otu3bppzZo1qqio0KFD\n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\n71f//v01ZswYu4fV6Tz55JMyAT2mnwAACUpJREFUDEMjRozgkTyLrV69WpdeeqlKSkrsHkqnVV1d\nrb/97W+qqKjQpZdeqsTERLuH1CmVlZXJNE0lJyfbPRSgVQghoqSoqEjr16+Xz+eT3+/X1VdffdLz\n0ps3b9aGDRsUCASUlZWl8ePHKzc316YRd1yRPhcZGRkaMWKEli1bpvj4eOXl5ckwDCsOpV2KdP2r\nqqq0a9cu3XnnnYqJidEzzzyjoqIi5efnW3E47VK0rkc1NTUqKSnR5MmTozn8di/S9Q+FQiouLtbN\nN9+sxMREPfPMM8rNzVXPnj2tOJx2Jxp//mfMmCGPxyO/36+nnnpKWVlZysrKivahtEuRrv+OHTuU\nnp6utLQ0QogWisZnID4+XrfccouOHTumF154Qf379+euxNOI1t/BlZWVevnll3XllVdGc/hAVHD/\nZpTU1tYqOztbEyZMOOUPqNu3b9dbb72liy66SLNmzVJ2draefvppHTt2LLzP5s2btXjxYi1evFj1\n9fWn7evrdz58/c6Izi4a52Lo0KGaNWuWrrvuOjkcDqWlpVl5SO1KpOu/a9cupaWlKT4+XjExMSoo\nKFBpaamVh9TuROt6tGPHDvXq1UsxMeTZ3yTS9U9OTlZOTo6Sk5PDn4F9+/ZZeUjtSjT+/Df9Hevx\neFRQUCCfz2fZ8bQ3ka5/UVGRtm/frj/96U9avXq1tm7dqrVr11p5SO1ONP9NmpSUpOzsbBUVFVly\nLO1RNOpfX1+v5cuXa8yYMcyJhXaJfzlGSUFBgQoKCiSd+jm5jRs3atiwYRo8eLAkaeLEidq1a5c+\n+OADjR49WpI0fPhwDR8+vNn7TtVWbm6uDhw4IL/fr9jYWH3xxRe68MILI31I7VY0zsWxY8eUlJSk\ngwcPau/evZo4caIFR9I+Rbr+paWl2rRpk+rr6+VwOLRnzx4NGzbMoqNpn6J1Pfrkk0+ofQtEuv6h\nUEjHjh1TdXW1YmNjVVRUxHn4BpGuf21trWpqahQXF6eamhrt3r1bZ599tkVH0/5E4/rz/7d356BR\ntWscwJ8ZrzFx4VPUxJhE3AUVLUSCYBUhYiGIgoWIiiumSKWNCBFtxMLWpdBgI4IbWFgpKggiKDYB\nO5fCJa4hiRglmVt8OFyJer9vTN6Dk98PpplzMjzzPJmQ+Z/lXb16dUREPHr0KDo7O/3P838M9Qx6\n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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "for model in models:\n", " \n", @@ -1012,16 +724,14 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -1035,9 +745,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/ipython_examples/Planar Pendulum as DAE.ipynb b/ipython_examples/Planar Pendulum as DAE.ipynb index 081715ee..91705d16 100644 --- a/ipython_examples/Planar Pendulum as DAE.ipynb +++ b/ipython_examples/Planar Pendulum as DAE.ipynb @@ -2,10 +2,8 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "%matplotlib inline" @@ -54,13 +52,10 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ - "from __future__ import print_function, division\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from scikits.odes import dae" @@ -68,10 +63,8 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "#data of the pendulum\n", @@ -106,10 +99,8 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "def residual(t, x, xdot, result):\n", @@ -131,9 +122,12 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -150,24 +144,14 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " t Solution\n", - "----------------------\n", - " 0 0.866025 \n", - " 1 0.592663 \n", - " 2 -0.304225 \n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "print('\\n t Solution')\n", "print('----------------------')\n", @@ -188,24 +172,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Error: Could not reach endpoint Error at time 15.7411967287\n", - "Computed Solutions:\n", - "\n", - " t Solution \n", - "-----------------------\n", - " 2 -0.304225\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "#Solve over the next hour by continuation\n", "times = np.linspace(0, 3600, 61)\n", @@ -229,83 +203,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Computed Solutions:\n", - "\n", - " t Solution\n", - "----------------------\n", - " 2 -0.304225 \n", - " 60 0.748758 \n", - " 120 0.304114 \n", - " 180 -0.371785 \n", - " 240 -0.791746 \n", - " 300 -0.859838 \n", - " 360 -0.628585 \n", - " 420 0.0639543 \n", - " 480 0.7327 \n", - " 540 0.859553 \n", - " 600 0.346761 \n", - " 660 -0.681437 \n", - " 720 -0.827876 \n", - " 780 0.245997 \n", - " 840 0.874605 \n", - " 900 -0.403099 \n", - " 960 -0.69528 \n", - "1020 0.895303 \n", - "1080 -0.696907 \n", - "1140 0.417578 \n", - "1200 -0.335093 \n", - "1260 0.513395 \n", - "1320 -0.812889 \n", - "1380 0.926238 \n", - "1440 -0.405328 \n", - "1500 -0.789546 \n", - "1560 0.649514 \n", - "1620 0.903153 \n", - "1680 0.197514 \n", - "1740 -0.540406 \n", - "1800 -0.824258 \n", - "1860 -0.885005 \n", - "1920 -0.808702 \n", - "1980 -0.440341 \n", - "2040 0.406477 \n", - "2100 0.9957 \n", - "2160 0.349396 \n", - "2220 -0.997113 \n", - "2280 0.252089 \n", - "2340 0.620979 \n", - "2400 -0.925843 \n", - "2460 0.975331 \n", - "2520 -0.873387 \n", - "2580 0.373025 \n", - "2640 0.686289 \n", - "2700 -0.989182 \n", - "2760 -0.574528 \n", - "2820 0.66487 \n", - "2880 1.0753 \n", - "2940 1.04512 \n", - "3000 1.00029 \n", - "3060 1.06947 \n", - "3120 1.08483 \n", - "3180 0.569069 \n", - "3240 -0.715037 \n", - "3300 -0.987832 \n", - "3360 0.786597 \n", - "3420 0.430898 \n", - "3480 -1.06173 \n", - "3540 1.14725 \n", - "3600 -1.10472 \n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "solver = dae('ida', residual, \n", " compute_initcond='yp0',\n", @@ -335,32 +240,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\nts9sT2mFkbKuNWozu8V1FVXK8gxJR1S6U26xfUjbqus+I1o3W3a717Ea6z3GxU2bthtmWZ5fOxMR\nMcw5L0dGxDrbfyWp3/aqyjcYpK9rg78Zs442lrJcHpC0d0S8avsYSTdJmtPasrpa8rrZsaExDvcY\nf0bS3jXzeytL0J4z3LKsDJDNjIj1tveS9GyT11hX+fc52zcq60IgNDIp69rgNrMrj2GoHS7PiHi5\nZvpW2xfbnh4RL7Spxm4yonWzG7qnmvVr/kHSAbb3sb2TpJMl3dy+sgrjZkmnVaZPU/aNrY7tXWy/\ntTK9q6SPKjsYAZmUde1mSadKku25kl6s6RZEvR0uT9szbLsyfbiyE5UJjNEZ0brZsXsaw7G9UNKP\nJO2h7B7jKyLiGNuzJF0aEcdGxBbbX5F0m6SJki6LiJU5lt2pvivpWttfkLRG0klSdr92VZalsq6t\n/6p8RidJujIibs+n3M7TbF2z/eXK85dExC2259t+TNIrkk7PseSOlrI8JX1S0lm2t0h6VdKncyu4\nw9m+WtJRkvawvVbSBZImS6NbN7mMCAAgWTd0TwEA2oTQAAAkIzQAAMkIDQBAMkIDAJCM0AAAJCM0\nAADJCA0AQDJCA2gB239buQLrzrZ3tf0nrsSKbsAZ4UCL2P62pLdImiJpbUR8L+eSgDEjNIAWsT1Z\n2cX3XpP0geDDhi5A9xTQOntI2lXSVGV7G0DhsacBtIjtmyVdJeldkvaKiH/KuSRgzAp5aXSg09k+\nVdIbEXGN7QmS7rVdiohyzqUBY8KeBgAgGWMaAIBkhAYAIBmhAQBIRmgAAJIRGgCAZIQGACAZoQEA\nSEZoAACS/T+euSe0LgGHbgAAAABJRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "#plot of the oscilator\n", "solver = dae('ida', residual, \n", @@ -394,7 +281,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "# Planar Pendulum Example: Stepwise running\n", @@ -405,22 +295,14 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\nAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "solver = dae('ida', residual, \n", " compute_initcond='yp0',\n", @@ -461,19 +343,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plott length: 600 , last computation times: [58.60000000000056, 58.700000000000564, 58.800000000000566, 58.90000000000057, 59.00000000000057, 59.10000000000057, 59.20000000000057, 59.30000000000057, 59.400000000000574, 59.500000000000576, 59.60000000000058, 59.70000000000058, 59.80000000000058, 59.90000000000058, 60.0]\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "print ('plott length:', len(plott), ', last computation times:', plott[-15:]);" ] @@ -490,22 +367,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "solver = dae('ida', residual, \n", " compute_initcond='yp0',\n", @@ -549,19 +418,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plott length: 1825 , last computation times: [59.67949916586178, 59.70385725557751, 59.72821534529324, 59.752573435008976, 59.77693152472471, 59.80128961444044, 59.825647704156175, 59.85000579387191, 59.87436388358764, 59.898721973303374, 59.92308006301911, 59.94743815273484, 59.97179624245057, 59.99371852319473, 60.0]\n" - ] + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "print ('plott length:', len(plott), ', last computation times:', plott[-15:]);" ] @@ -569,7 +433,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "# Animation of the planar pendulum\n", @@ -579,10 +446,8 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "%run 'mpl_animation_html.ipynb'\n", @@ -593,9 +458,12 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -632,285 +500,14 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "
\n", - " \n", - "
\n", - " \n", - "
\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " Once \n", - " Loop \n", - " Reflect \n", - "
\n", - "
\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" + "collapsed": false, + "jupyter": { + "outputs_hidden": false } - ], + }, + "outputs": [], "source": [ "# First set up the figure, and the axis we want to animate\n", "fig = plt.figure()\n", @@ -939,36 +536,27 @@ "#one frame every 100 milliseconds\n", "animation.ArtistAnimation(fig, ims, interval=1000/frames_per_second, blit=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 } diff --git a/ipython_examples/Simple Oscillator.ipynb b/ipython_examples/Simple Oscillator.ipynb index d03b8968..cf065d5b 100644 --- a/ipython_examples/Simple Oscillator.ipynb +++ b/ipython_examples/Simple Oscillator.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -82,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -92,22 +92,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " t Solution Exact\n", - "------------------------------------\n", - " 0 1 1\n", - " 1 -0.370694 -0.370682\n", - " 2 -0.691508 -0.691484\n" - ] - } - ], + "outputs": [], "source": [ "print('\\n t Solution Exact')\n", "print('------------------------------------')\n", @@ -129,22 +116,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Error: Could not reach endpoint Error at time 24.5780834078\n", - "Computed Solutions:\n", - "\n", - " t Solution Exact\n", - "------------------------------------\n", - " 2 -0.691508 -0.691484\n" - ] - } - ], + "outputs": [], "source": [ "#Solve over the next hour by continuation\n", "times = np.linspace(0, 3600, 61)\n", @@ -169,81 +143,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Computed Solutions:\n", - "\n", - " t Solution Exact\n", - "------------------------------------\n", - " 2 -0.691508 -0.691484\n", - " 60 0.843074 0.843212\n", - " 120 0.372884 0.373054\n", - " 180 -0.235749 -0.235745\n", - " 240 -0.756553 -0.756932\n", - " 300 -0.996027 -0.996814\n", - " 360 -0.865262 -0.866242\n", - " 420 -0.412897 -0.413742\n", - " 480 0.192583 0.192521\n", - " 540 0.726263 0.727236\n", - " 600 0.989879 0.991682\n", - " 660 0.885441 0.887581\n", - " 720 0.452113 0.453622\n", - " 780 -0.149122 -0.148921\n", - " 840 -0.694753 -0.696119\n", - " 900 -0.981996 -0.984613\n", - " 960 -0.904317 -0.907187\n", - "1020 -0.490547 -0.492616\n", - "1080 0.105433 0.10503\n", - "1140 0.661996 0.663643\n", - "1200 0.972376 0.97562\n", - "1260 0.921229 0.925021\n", - "1320 0.527762 0.530648\n", - "1380 -0.0616772 -0.0609338\n", - "1440 -0.627855 -0.62987\n", - "1500 -0.960354 -0.964723\n", - "1560 -0.935939 -0.941048\n", - "1620 -0.563703 -0.567643\n", - "1680 0.0179025 0.0167187\n", - "1740 0.592593 0.594867\n", - "1800 0.946886 0.951941\n", - "1860 0.949087 0.955237\n", - "1920 0.59865 0.60353\n", - "1980 0.025868 0.0275291\n", - "2040 -0.556352 -0.558703\n", - "2100 -0.931643 -0.9373\n", - "2160 -0.960605 -0.96756\n", - "2220 -0.632579 -0.638239\n", - "2280 -0.0695761 -0.0717232\n", - "2340 0.51911 0.521447\n", - "2400 0.914706 0.920828\n", - "2460 0.97026 0.977994\n", - "2520 0.66523 0.6717\n", - "2580 0.113083 0.115777\n", - "2640 -0.48092 -0.483173\n", - "2700 -0.896022 -0.902558\n", - "2760 -0.978027 -0.986518\n", - "2820 -0.69649 -0.70385\n", - "2880 -0.156248 -0.159605\n", - "2940 0.441822 0.443956\n", - "3000 0.875509 0.882526\n", - "3060 0.983777 0.993115\n", - "3120 0.72638 0.734626\n", - "3180 0.199071 0.203121\n", - "3240 -0.401994 -0.403871\n", - "3300 -0.853534 -0.860769\n", - "3360 -0.987807 -0.997773\n", - "3420 -0.75483 -0.763966\n", - "3480 -0.241495 -0.246241\n", - "3540 0.361435 0.362997\n", - "3600 0.82981 0.837332\n" - ] - } - ], + "outputs": [], "source": [ "solver = ode('cvode', rhseqn, old_api=False, max_steps=5000)\n", "solution = solver.solve(times, solution.values.y[-1])\n", @@ -266,20 +168,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nZrX0PwskTldGLYBPAAAAAElFTkSuQmCC\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "#plot of the oscilator\n", "solver = ode('cvode', rhseqn, old_api=False)\n", @@ -300,22 +191,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " t Solution1 Solution2 Exact\n", - "-----------------------------------------------------\n", - " 0 1 1 1\n", - " 1 -0.37069371 -0.37068197 -0.37068197\n", - " 60 0.8430298 0.84321153 0.84321153\n" - ] - } - ], + "outputs": [], "source": [ "options1= {'rtol': 1e-6, 'atol': 1e-12, 'max_steps': 50000} # default rtol and atol\n", "options2= {'rtol': 1e-15, 'atol': 1e-25, 'max_steps': 50000}\n", @@ -334,7 +212,10 @@ { "cell_type": "markdown", "metadata": { - "collapsed": true + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } }, "source": [ "# Simple Oscillator Example: Stepwise running\n", @@ -345,20 +226,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "solver = ode('cvode', rhseqn, old_api=False)\n", "time = 0.\n", @@ -393,17 +263,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plott length: 600 , last computation times: [58.60000000000056, 58.700000000000564, 58.800000000000566, 58.90000000000057, 59.00000000000057, 59.10000000000057, 59.20000000000057, 59.30000000000057, 59.400000000000574, 59.500000000000576, 59.60000000000058, 59.70000000000058, 59.80000000000058, 59.90000000000058, 60.0]\n" - ] - } - ], + "outputs": [], "source": [ "print ('plott length:', len(plott), ', last computation times:', plott[-15:]);" ] @@ -420,20 +282,9 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAF5CAYAAABa9bp0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzsvXmUXld1J/o7VSoNVSWpNJVkW54A25gQsGWGEMABDCEk\njZuQBJ4IDYFOSLpJdyJ6NaxOJ4HwFuG9DDjk0SYkWS9AAOVBWBCHyQGaGZMQywYDxniSLVujNdcg\nVanqvD9O7Xy3Pt3hDHvf73xV+7dWrar6vnv3uffcc/b+7eGca6y1UCgUCoVCocgNA72+AIVCoVAo\nFIoyKElRKBQKhUKRJZSkKBQKhUKhyBJKUhQKhUKhUGQJJSkKhUKhUCiyhJIUhUKhUCgUWUJJikKh\nUCgUiiyhJEWhUCgUCkWWUJKiUCgUCoUiSyhJUSgUCoVCkSX6jqQYY55rjLnFGPOoMWbeGHNjw/E/\ntXBc8WfOGDPe1jUrFAqFQqEIR9+RFAAjAO4E8EYAvi8esgCuALBt4ecCa+1hmctTKBQKhULBgRW9\nvoBQWGs/B+BzAGCMMQGnHrHWnpK5KoVCoVAoFNzox0hKDAyAO40x+40x/2SM+cleX5BCoVAoFIp6\nLAeScgDArwP4BQAvB7APwJeNMdf09KoUCoVCoVDUwljrW9aRH4wx8wBeZq29JfC8LwN4yFr72orv\nNwF4MYC9AM4kXqZCoVAoFMsJqwFcBuBWa+3RFEF9V5PChH8B8Oya718M4MMtXYtCoVAoFEsRvwzg\nIykClitJuQYuDVSFvQDwoQ99CFdffXUrF7RUsGvXLtx00029voy+gvZZHLTfwqF9FgfttzDcfffd\nePWrXw0s2NIU9B1JMcaMAHgCXDEsADzOGPNUAMestfuMMe8EcCGlcowxvwXgQQDfhwtB/RqA5wN4\nUU0zZwDg6quvxo4dO2RuZIli/fr12meB0D6Lg/ZbOLTP4qD9Fo3kcom+IykAngbgS3B7n1gAf7rw\n+QcAvB5uH5SLC8evXDjmQgBTAL4L4AZr7VfbumCFQqFQKBTh6DuSYq39CmpWJVlrX9f1/x8D+GPp\n61IoFAqFQsGL5bAEWaFQKBQKRR9CSYqCFTt37uz1JfQdtM/ioP0WDu2zOGi/9Q59vU+KFIwxOwDc\nfvvtt2uxlEKhUCgUAdizZw+uu+46ALjOWrsnRZZGUhQKhUKhUGQJJSkKhUKhUCiyhJIUhUKhUCgU\nWUJJikKhUCgUiiyhJEWhUCgUCkWWUJKiUCgUCoUiSyhJUSgUCoVCkSWUpCgUCoVCocgSSlIUCoVC\noVBkCSUpCoVCoVAosoSSFIVCoVAoFFlCSYpCoVAoFIosoSRFoVAoFApFllCSolAoFAqFIksoSVEo\nFAqFQpEllKQoFAqFQqHIEkpSFAqFQqFQZAklKQqFQqFQKLKEkhSFQqFQKBRZQkmKQqFQKBSKLKEk\nRaFQKBQKRZZQkqJQKBQKhSJLKElRKBQKhUKRJZSkKBQKhUKhyBJKUhQKhUKhUGQJJSkKhUKhUCiy\nhJIUhUKhUCgUWUJJikKhUCgUiiyhJEWhUCgUCkWWUJKiUCgUCoUiSyhJUSgUCoVCkSWUpCgUCoVC\nocgSSlIUCoVCoVBkCSUpCoVCoVAosoSSFIVCoVAoFFlCSYpCoVAoFIosoSRFoVAoFApFllCSolAo\nFAqFIkv0HUkxxjzXGHOLMeZRY8y8MeZGj3OeZ4y53RhzxhjzI2PMa9u4VoVCoVAoFPHoO5ICYATA\nnQDeCMA2HWyMuQzApwB8EcBTAbwbwF8bY14kd4kKhUKhUChSsaLXFxAKa+3nAHwOAIwxxuOU/wTg\nAWvtmxf+v8cY8xwAuwB8XuYqFQqFQqFQpKIfIymh+AkAX+j67FYAz+rBtSgUCoVCofDEciAp2wAc\n6vrsEIB1xphVdSdOT8tc0JkzwNveBtx7r4x8APjc54APfUhO/n33Ab/zO8DkpIz8mRngrW8Fvv1t\nGfkA8IlPAH/5l3Lyjxxxz/n0aRn5584B73wn8M1vysgHgFtvBd7zHjn5hw4Bb387cOyYXBvvfS/w\n1a/Kyb/tNuB//S85+ceOuXH02GMy8q11z/jzgnHl//2/gXe9y7UlgVOngP/xP4BHHpGRDwB/8zdO\nr0rhe98D3vEOYG5ORv7p08Dv/i7w6KMy8gHgYx8DPvUpZqHW2r79ATAP4MaGY+4B8Jauz34WwByA\nlRXn7ABgr7jievvSl7500c9HPvIRm4r3vc9awNrrr08WVYqjR518wNpDh2TaeNGLnPw/+zMZ+R/4\ngJN/zTUy8k+d6vTRfffJtPGLv+jkv+MdMvL//u+d/Cc8QUb+5GSnj+66S6aN173Oyf/935eRf+ut\nTv6aNdbOz/PLn5vr9NEdd/DLt9baN77Ryf/v/11G/le/6uSvXu3uhxvz89aOjLg2vvQlfvnWWvvm\nNzv5r3udjPw77+w857NnZdrYvt3J/+QnZeT/wR84+a96Fa/cj3zkI/alL32pfcELXmoB9/PsZ19v\n4WpGd9hEO78cIikHAWzt+mwcwClr7UzdiZdcchNuueWWRT87d+5MvqBbb3W/v/lNYGoqWdx5+MpX\nOn9LeEfz88A3viEnvyj3O98BTp7kl1/soy90JwMZYC3w5S+7v+l5c+Of/sn9vu8+4MABfvnFKJZE\nHwHAZz7jfkt5qDSOpqeB++/nl79nT+fvT3+aXz7Qec5S44j66MwZ581z4wc/6ERcpe6BxufXviYj\nn8Yp4HQSNx5+uBMFIr3BDZpjX/wib0Rr586duOWWW/DzP38LAPfzmtfcxCZ/OZCU2wDc0PXZTy98\nXosf/UjkerBnD/Cc57hw/T338Mv/538Gtm8HLrkEuOsufvkPPeTI1dOfvlhJc2LPHuD5z3eT6Y47\n+OXfcQewYQPwlKcAd97JL/+BB1x4/vrrnXyJMPfttwPPe577+7vflZG/Zo3ccz582KV7nv1sd/3n\nzvG38e1vAz/1U+5vied8xx3AwADwzGfKGK9Tp1xa+DnPAb7/fUckuHH77Z0+kriH73/f/X7uc2XG\n0Zkz7tn+xE84Ijoxwd/Gd7/rnvHQkEwKmvr9uc+VkW+tew7PfrabcxIpnzvuAK65Bli9mteu9R1J\nMcaMGGOeaoy5ZuGjxy38f/HC9+80xnygcMpfAHi8Meb/NsZcZYz5zwB+EcC7mtrat49fKUxNAXv3\nAq94hfufJjAn7rsPeOITnQGWMF7kbd14o/PguWt3rAUefBB48Yvd/w8+yCsfcAT06qvdzw9+wC+f\nJukv/ZIzNBKRjgceAF7wAmDFCve3hPzHPQ644gqZZ0Bjf+dON8+knvP11wObNwN3380v/557gMsv\nB57xDBmHgOrWXvEKV6sg4dQ88IAzLlu3yoyje+8FNm50Rl4imvXggy66+8pXOt0h8Ry+9z1gxw7g\n8Y+XeQYPPgisWuUcs/vu45d/9KjTQz/7s+5/CQf8hz8EfuzHgCc/mbfesu9ICoCnAbgDwO1wOa8/\nBbAHwB8sfL8NwMV0sLV2L4CfA/BCuP1VdgH4j9ZarwD2vn1cl+2wd6/7/dSnAtu2yQzI++4DnvAE\n9yNlXNatc94d4CIrnDh82BGfq64CLrig02ecePhh4NJLndKR6KO9e53X9dzndv7nxKlTwPHj7hlf\ndpmM8t+71xngxz1OxnhRn7zwhe439zianHTk8Ior3LN++GFe+YAzWFdd5frpoYf4I2ZkTH76p91v\n7nFkrfxzvu++zjPYt88RCk7Q2H/JS9xv7nuw1sm84gqnL6SI1mWXufl86BB/NIj65IUvBAYHZUjK\nj37UmQsHD/LJ7TuSYq39irV2wFo72PXz+oXvX2etfUHJOddZa9dYa6+w1v6tb3tSJOXyy106hls+\n0PGAL7nEKWZuxbl3r5usl1/u/uc28tRHl13mfriNF+D6/ZJLgIsucoaMW3E++KCTf8kl7n/uVQfU\nJ5ddJmdcHnywY7z27+ePmO3fD2zZ4uQPDPAbYOqjyy93BlJiHD36qHvGl13m+od7Bc7DDwNjY8CV\nV7owOncfHTzooliS44icpksvdav2OA0Y4K551SpHIjZu5Cejx465CPgll8g5NTTXHv949z/3cyBi\nRY4fd7rn7Fk39mku7N/PJ7vvSErb4CYRDz/smOyFFwIXX8w/oSYn3VIzkj81xb+888ABN9C3b3ep\nBmmSwq2Y5+Ycabj4YkdSzp1z0RtO7N3rrn1szNV1cCuFYh9JeHfkYZPxAviNPI2joSE3XiUMMOAi\nlkTYuXHokEuTXHqp+5+7jw4dctdvjGuDu4+KTpNklODyy91YKrbJhYMH3TgaGJB5zvRML7nEtcNN\nsoBOJIWcGm598cADwKZNwPr17h6408+HFjb52LbN3ceh7k0/EqAkpQZjY/we8OHDznscHHRGkpsE\nHTnifo+PdwY8dxukFOgeuBXz3r1uMo2NyZCUQ4eA2dlOJAXgVwoHDjjZxjgyxy3/oYeAlSudgdy+\nnV/pHD3qCG5RcXKPo/37HTkB3HjiJopFxUmRFM6o4vx8h0TQOOL0IAE317YurE3cto1X+QOduXvp\npW4cHTrEu0+HtU7mBRfIEjnqIwmdSnPrwgtdO8eOuYgQF4opt/Fx9xk3EXrooQ5JlCBaRYfgwgt5\ni+CVpNRgfFyGpNBA3Lq1Qyo45ZNsmrjcyp88YGqHWz6RIMAN+AMHeI0LKTGKpACyxuWii/jH0cGD\nTiEMDLjx9NhjvMaFjOHWrZ3xyj1WiyRlyxaZcTQ8DIyOuvF05oyr5eHC0aOuz7dtc14qwN9HRQO8\nZYuMvli1ytWYjY874nX0KJ/848edwdq61bUxOso/14o6dXxcTqdu2SKjUycn3bjcvt05Hhs38pOI\nw4cXk11up4aud+tW10+cUJJSgw0b+HPMR450JtTmzY6Vc7JOMi7j404+wHsP1i4mERKK88iRzkDf\nssV5LZy7tlIfXXCB66fBQf5IB3nYgEwkpdhH4+PuuXA+52JEbmTEGXtuEtFNUiQNvATRKnqPK1Y4\n48KtL4iMAnIkZXzcRfyojzifc1EfAe4euPuo+Jw3b5bR2evXOwJBz4IzokXXS/NZImJW1BcS6Z6D\nB53DtGWLkpRWMTbGP+CLrJ8eJmfNCCmYzZudYVm9mvcejh51qRKarOPj/Marm6QAvPdAsjZudARl\n2zZe725y0lXnk+LculVG6RS9R4D3ORS9R2qDU/78/OKInMQ4KhJFug/ONookBXBzrt8iKd1kF5Ah\nKdLRIEkSVJxrdB+ckQ66XnIqt27lj6R0k5TDh3kjrwcPdsoYqK+4oCSlBhKRFKpJAWQiHYcPu9Dz\nihXOO9q0iTd8Swy8rUgK9RFnG4895gjo0FCnDc4+6lbM3PKBxeNIwrgcOeL6Z/169z93OuboURdB\nlIykFFNukpEUKQM8O+v6qVs+Z+qzLbIr1UdU81KMTp865VabcKGMyElEUkjXbdsmS1K2bXMEhdPu\nFB2C9eud/eGCkpQaSEdSJAxwUT61wR1JARZHOqTTPfQZFx57rNP3AD+Ro2ula9+0yeXmOT0XaQ+Y\n5BvTaUMyDTA+7l5/wGlcilGITZvcvXBHUtavd6u3AP65QNdajFrOzvLW1RTJ7uioi7xyP2eqeQH4\n+2hiwtUaFR0CgHc+F3Xq0JCLwEqSFO7I6+wscOLE4kgKwEuEimlJY5zt5IKSlBoQSeHyXObm3OTp\nTvdwR1IkSQqlpjZudL/Hx116g+sdRNa2E0kpkpSNG3lTbidOdOQCzkBa2/mcA8U+GhlxhpLbAy7m\nlrlJyvHj7jf1kcRcKEZSBgfdc+A2wKSYAf50T1mqBOBtoxhJoboU7nFENS+AXB9J6tTiXAP40zFH\njnTmMODmBM0PDnTXvNCc49R5RZICuCwEF5Sk1GBszIWkuV5wd/SoM1Y0ocbGXLERd9itSFK4owTH\njjmFU0wDAHyKZ2LCedMkd2jI9ROnYjt6VDaSQgqGvAla+cHVxuysa4P6yBj+dEy3YpYiKaTMuGtG\niOwW5wJ3vcKRI4vHEbf8KgPMHa0pPmfucXTsWMcoknxupww4P5IiSVK2bOHVF91O04YNbn5wOcfd\n9WU057iJEOm5YhscUJJSAzIyXAO+e7AMDLgHy610aMICMpGUsTHnmQL8irM7VUJ/91O658QJ1z+j\nox35AF8b5AF1KzbOSE1ZtIlTqXWTFO6akakp52AUlSUpfy6cOLFYPvc47Y7Icc+1uTnXRrdx4X7O\n3X104oQj2hzo1qlSJKVIdsfGZOfahg1uRSPXDs/dOpXsmuRcUJLSEqijuQY8GZeiUuD2LLoHvARJ\nKXpG1Edck7Y7nQTwk4hu1s+d7jl+3CkCCnFTW1zPoTtVArj2uJVOMa88NuYiilyvDzh+3K0+W7nS\n/c+d1qPx2H0PnMalu482b3apTy7jQmR3ZMT9z70XC9W2FO+Bm+x2kxQas1xjla6V2li71kVfufpo\netoRXkkiV0ZSAL42umteBgddJJxLPqWyy54zB5Sk1IBSGlzGhdJGJBfgz9GeOLFYPhl4rtDhsWOL\nByMpOC7F1q10qA2ulBtwPknZtMntw8K1i2S3YuaOpJSNI27jcvLk+cbLWr6ize4+Gh52KwK4x1Gb\nJIU70kHyieyuWOH6THocSUZSqL+45vOJE27s0Eo9Sn1y62zJcVSVKuEkcgMDjsAV2+ByzKanne4s\n9tGv/zqPbEBJSi3ooXJOKEDOuMzOugHT7d2dOcNX2NodSaGq/X4xLtaeb4BJQXBN2m6vYuVKl/rp\nJ+Ny8uRi+dxktHsc0YoA7rnWTbSko03FtrnlA+6ZSPYRd0Sum6TQmOK6h+5xCvBGXtsgu8ePl0en\nuZ4D9RGRXWqDO5pV7KMiIUqFkpQarFrlvBdOpbBqlVvmR+BUOlWRGoA3ZVWcUIODjqhwTVq6ByI/\nAK9SmJpyufhiH9H9cCk2SvcUIWGApUgKEblu+cW2U9FtvAAZA9ztxUtGUrgNsDRJaSMiJ01SetVH\nkg6BRCSlu4+kSQonlKTUgFaxcA74ticUt3fXzfqpDU7vcd26TmEut3xKV3SToOJ3qeiOpFB7XPJP\nnnRjs+itcPbR5KQjcmVRAi7FVkZSOO+he4UVwKuY5+bc8ywjKZzPue1ICpEUjtoja6tJCqdT0x1J\n4ZxrVZGU6Wm+PX2kSUpZHylJWUJYv553wHcPFmmSQsaY6x66a1IAfpLSNpHj7qOySArnODp50l3z\nQGH2ci5bbIvsSkdSVq5cHLUcG3O1RxzvyiqrVVgKUYKxMUdQJibS5U9Onr/CiuZaP/cRZ1Rxft7p\nhaL8lStdnQ0niei2O5yLBcqilpxQktIAbsXZhmdUHJDc3t2pU4ujEIA8SSH5HAa4LJIiQVKkIyll\nnhHXssU6kiIZSZGYa915eICnjTLFPDzsIoD9pC9Wr3YpaAKnF9+9zBxw6fORkf6JTlPRKW0nAPAS\n9okJp9ckIx1lfaSRlCUEblZeFkk5fZonvCodJbDWXWs3SeHMY1eRlLk555mloqyPSAFxRsy672Hd\nOl7F2T2OOBVnmdJZscL1k2QkpQ2yS99xyC/KBBwh4n7O0lGCMuMI8BiwKuPFXZ9Vlu7h7KOyqCXA\n00dl+ojakIykcMo/ftytrqIdc7mhJKUB0kpn3bqO8U9F2YAfHnYTjMMAT087stBdud1PxqWsj2jj\nNY4+mp8vr0nhTvdIGpc2FGdVSoxzrnU/A84wfZUB7rfIq+RcI53W7dS0Uecn6XBI6yNAPpJCkV2O\n6HRZ1JITSlIa0EYkhb7jkL9mTWeDLKDj3XFM2rJUCcBPUqr6iKMNuoduosXVRxMTjqi0ne6h+5Ei\nuwDfPczMuB9J41Vl4AHZKEE/kRTpcVQ119avl9cXkpGaNhyCtWt5ngFQfg9r17p6IY7i37Jxygkl\nKQ1oS3FyKP8ypQPwGZcqz6ifUhknT7qcePerxLn6qGxVCcmX9B45jUtZHp7a4JBfNY64V/eUPYNi\n+ymg6ywjWhzj6MwZZ0DKDDCXByw9jkhGGUnhmAu002nZc56ZcX2YirI+Ghnhi063QVLa0BdSRbOA\nkpRGtLG6B+CLpEiSlCrPiHNCdVe6A7x9VCYf4OujKg+be1mkdCSle/MnakPaw56a4nmvi3SU4MQJ\nR+K6yS6XAa4bR1z1WWXjiNLDnCSlm+xy9VHZnkckH+Cbz93yjXH3xLECSpqknDvnrlN6LpTpVC4o\nSWkAJ+uvyp8C8iSFQ36VB0wTisO7m5g433iRkuNSCt3XD8hHm9av7+w/koo20j1l44g7klJW2wTw\npd265a9a5Qr8uIiW5FyrMl7c+qJbH5EB5uojet1BEdJErg2dytVHJ08ufj8TgdshkE7rlelULihJ\naQBXgdHZs9V5eKC/IillJGV+nie8evr0+Z4XTWAuklJlgDlJSvc9cKYayu5h5Ur3w+UZleWYpdM9\nnLVHExPnPwOA9x7K5HMZ4KY+4jLy0mS0bHt0rtU9dbVTxe9TUEZ2AfcZp9PUHbVsQ2cDPM+5qo+4\noCSlAevX82xuROd3P8yREb69FaqMC1fKqipMT8o6dcDPzLhQf7f8wUHnkUmyfs7CWaC8MBdIf85l\nW9YTuIyLtPy64uXi9ylog6SUKWZuklKWKgFknZo2+kh69RDA00eTk+dHOQDeSIrkM6jSR9y1R2Vz\njQtKUhrANeBpsHQ/TM69FdoonF2xYvEungDfgK9KA9Bnkkph3TreKEG3YuPKk9PqIclIR6/SPTQ3\nUustaEm/JEmp8h65SEqVceGuzyoj7JxktEw+9VFqdLpKp3LWpExNOQepG1yRlCoiR/Kl+oibpGgk\npYeQJimAvOfCGTpcu7a8oBJIn7RV3iN9xqEUpAtnJybcMvCy1UPUfgraIHJ1IW7Jgkqu2qMzZxyR\nk76HqnQPR3q4KW2YOo7OnXP9JN1HVURudjY9PVylUznTPZOT5SSFK5JSN9esTSfsVX3EFf2mNpSk\n9BBcBriOpIyO8lTrVw0WzkhKledF36egynukz7iiBNKFs2XPmEtxttFH0qmSU6c6ac4iuEhKLx2C\n0VFHkFJfT3D6tHMGug0kRehS9QWdXzVWpfuoeA2xoPO7o5ZDQy7ayxVJKUv3cEVS6uYawKdTu9vg\nTKFruqfHaENxckUJqgY8ZySlzMBzsfK6SAqXUmiKpHCEV6u8R2o/VT4gn8qokk8bsaWgynhxFUi3\n1UeSBpieQXfUktKt0n3EGXntBqdONaZ8O3YOx+/cOTfWq9I90nMNyN/xm511i0I0ktJDcHkudUph\nZCR9wlpbT1I4lr9WKZ02JhTnssiqaNPcHI8HXPWMjel/kgLwkNEysjs05JYJS6YNpdM9XAa4Ls8/\nMiKrjzj7qM6p4SApZUQO4NGpU1MdWd3gTPdIz7XBwcUvkSy2IRWp4YSSlAa0FUlJVTozM47516Ua\nOOohJJWOtHGxtjp8y9VHVR62MTwe6lIgKVVEEeCJKraVEquLBnFFUsrA2Ue9SokVryEWTX2U+gyI\npEgWzk5OykdSqogcx3Ouq5HjgpKUBqxZ4x4wx4QaGDh/ZQwgr3S4lEJVuocrv9kUSUm9/pkZVy9Q\npnQ4iZyk4pQ2LnUROU7vri5KoAZ4afRRU7pHkshx9FFVzQvAG0mpqnkB+EhKGZSkLBFwbYFcx2il\nSQqXd1enODkm7enTnU3JusExoZo8I0AukgLwhumrFFtqH50969JevUj3AP0RJagjcm3NtdzJLlD9\nnDlrj3odSeGoYWsjklIGTpKi6Z4eg5OklEE6x8ylOOu2P+Ya8JIh7jrPiNO4SIfpV68+f2UMIJ9j\n7pd0j3TacGrKGadepjKkU2Jnzrj0cSzm5lw/9aqPOGtSqpYgc6ziqroHrnco1TlNHCmrunHEBSUp\nHuAiEb3KMbdhgLkGfN2EkoykcIagpcP0TZ5RinfXBkmpysNTuxzPoC4iRysSYlFHgtqIpHA6NXVR\nxZTnXJcGWL3aGeDcIyl1Tg3H1hR1ETmudyhpumeZgItEtFEsKKk4q4pOgf6IpNSRFK4QdBs1KXVK\n59y5NAPcBkmpG0fSUUtpA8xZwyY5F06fds9goMQCSPcRZwpdchz5ODUpfTQ97YhK1XPm2K9G0z3L\nBJrucajaIpralQ5NpnrAPiSl3yMpQNpzqBtHtEcHB0mpG0f90kdlz3lggGc+t1E4K9lHdZvF0ee5\n61TpSErT8t02HD8Onb1iRfkSZy4oSfGA9IQaHXXGd3Y2TT7J6gaHAaa3HFcZlzYmFB0Ti7p9D2ii\nSdekSEdS6BpS5AOyirNqq3FqVzKaRc+exkKsfEC2HkI6lSE9juocAqAdncoVSanaLA6QnWv9ku5Z\nu7Z8QQgXlKR4QFopcNRD1C1xXrnSbZSVIp8KxOrSPdI1KXRMLOj+qxRnqvfVtPuitPHiIKM+ipND\n+Usbr7pnAPD0kXTxr3R6WJLI9ZqkcEVSVq48/z1cQDuRFK4Ie1PhbEoNm/SW+ICSFC+04RnRMany\nqxht6oBvUjqcrLxKPh0Ti6Z7SH3OPgZeem8IQNYAj4ykGS/aUK+XxgtI6yOfSEqK/LqCSg75QL18\nejYc+kKyZqSpAJuDTNc5ZYBsJCV1rlEbdZGU+fm0NiYnq/uIC31LUowxbzTGPGiMmTbGfMsY8/Sa\nY19rjJk3xswt/J43xng/mn5QnHXyqY0U+U1RCI7QpE+6J+U51IVvqY3cPew6xczhAVOOuWxlDLWR\n0kf05ttekRROAyx1D/QW517WcwB59xHQfA9nz6Yto64j0xyF9m1FUprSeqk6VUlKCYwxrwTwpwDe\nCuBaAN8BcKsxZnPNaScBbCv8XOrbXhv5UzpGQj4gH0lpg/UD6ZGUNWvKVzQA6X0k7WED7ZHdqojc\n8LD8OOIIQUume+rSANQGh0NQF4VINcA+RC7ndA/twyKZQq+LEqxY4XSJZHFx6lwD2nnOVc+YC31J\nUgDsAvA+a+0HrbU/BPAbAKYAvL7mHGutPWKtPbzwc8S3sX4hKXWMNjWV0aR0hofTSUodK+cyLnUT\nKrWPfFceIXNEAAAgAElEQVQ0pO5jIhkl8CG70saL3j4bizbqLermWqq+8CFygNxzHhx0tW0cRKus\nRg7g66Om55zaRp2+SI0eS0dSaDGGdFRRSUoXjDFDAK4D8EX6zFprAXwBwLNqTh01xuw1xjxsjPmk\nMeZJvm32kwdchTYiKdPTLkyd0kYdCSpeB7d8ID3d49NH1nZSHjGQ9ozaGkd1UQK6jlg0GeDUVVy9\nHkdtRF45ImZ1UctUkuJT/wXIOjWpiwWkU6s+9WWARlIksBnAIIBDXZ8fgkvjlOEeuCjLjQB+Ge6+\nv2mMucinQVI6sQaYVn0s5XQPfZ6yTXRdeJXqSCSNi3QftWGAUz1gaePlU9tE1xGLNuqzJKOWTeme\nfnFqmogcB0mRJLtNEbPU6LH0M2gichpJaR8GQGkg3Vr7LWvth6y137XWfg3AywEcAfAGH8Gjo84D\njjXATWkAriKsJsUpHSUA4tuYnXVh/ir5xqQrBR+SknOYvmnVB7WdWlfT63QPkPYc6mpSqG2NpMg/\nZ8k+8kmVAPJOTT+TlDZSnxyoKP3KGo8BmAOwtevzcZwfXSmFtfacMeYOAE+oO27Xrl1Yv349Di1I\nffnLgV/5lZ3YuXNn0AU3DRauHPD27dXfj4wAhw/Hy/eNpMQO+Cb59J2kB5y7caFVH01kVHJJoXTh\nbGofEZGTJuy9JLttRQmkiZz0RmjF42IwOQlceGH196l95EsUrY3bLK0p2sSVQn/44d248cbdiz4/\nefJkvNAu9B1JsdbOGmNuB3ADgFsAwBhjFv7/cx8ZxpgBAE8G8Jm642666Sbs2LEDX/oS8IIXADff\nDDz+8eHX3DSh6DvJIi8OxTwwUL39carn0hTipu+kIympfTQ4WJ9jBtL7SDpMv2GDrHxAlsjVvQ8F\nkCdyqWRXOt3TtFcNtSFN5Ih0V9Wt1CGHSIp0umd42K1impmJ23beZ/VQ8bgYTE0BO3bsxDvesdhx\n37NnD6677rp4wQX0a7rnXQDeYIx5jTHmiQD+AsAwgPcDgDHmg8aYP6SDjTG/Z4x5kTHmcmPMtQA+\nDLcE+a99Gksd8DmQFA7FOTxcvzSVriMGvpGUnNM9TX2UaoCb9nkBeIxLk/w20j2x9+AzjtqKpMSu\n4pImcrOzzvhJ91FTpAaIT6H7kpTU+dzrmhS6jhg0jaOhIfeTe+Fs30VSAMBa+9GFPVHeDpf2uRPA\niwvLircDKO4isAHAX8IV1h4HcDuAZy0sX25EqlJoCrtRG7lHUprkA/kbl7Gx6u850j0+fZRKUiRT\nYj7e4+RkfAia7qFuaSqQdx9NTgIXXFD9/ehomgc8NeX6tqqP2hhHHCmrpmcAxO9Y2qRTh4ZcRFN6\nPj/6aLx8n7Qk4O5h48Zw+UQAe6kvONCXJAUArLU3A7i54rsXdP3/JgBvim2LSylI58l7mYdPDR36\npHtSPRefVRlTU/EhaJ9oFl1HDHyNi3S0KdUA1y1NXbPGGejYeoW2yG6TwwE4fREbpq+LyKW+DNOX\nyB3yqvCrbsNHX8SOVerboaHqY6QdP47I7qZN1d9zOX5SkVGftCEH+jXd0ypSQ5M+SmGpRFIk0z1t\n3EPKKq4m+WSApT3gnJ9zE1GkVVySc62tPkp5zk2KP0Vf5NBHqSTFJwIjvdScg6Q0EQi6jlj5lNKp\nQkokZWbGOXRKUjJAG/UWKUpnbs7tw9KkdGZn43fylI6k5FKTAqTdQ5381GXUuaR7ALk+ojakyW5q\nRE46YiZpgJcLSUnRqb7FxZL6iGOu1ZEgIO0efMYRB5SkeIAedOzDnJ52qz6aGG2KfJJRBWkDnFqE\n1VZKTNK4+CjO3A1wr4kcwNNHvU6tAvEGsokEAfKRFI7UqiRJ8RlHKXU1Z882L/eXdgg4otM+c02S\n7HJASYoHBgZcEVvqYKkrNExRCk27eALtGZfUmpQ65s8RSfEtVIuVn0OUIPb65+cd4c1BceYcbWoj\nkiJpgJdCJMU3JaaR3fpjNJKyhJCqOHutmDn26PAJQafcw6pVLuJUhRTjYm2zcWmjloDjOUstQaZ3\nCvVzuseXsKfuMSIZSfFN9+RKdqkNSbLbRKapjZRoFtA8F86eden2GORAUjSSsoTQBkmRLhYE8h7w\nkqzfp8iLo0BamqSsXl2/8kha6fRLtKlq+S4gP46oj1Jeo5GDUzMz415VEdtGryMpIyPpOtWHjErd\nw8qVzmnLVacqSckMyz2SIj3gc6jn6AeS0mul0w8kpW6JM+DuIdYD9vGwU2vY2nJqmlKrxWND4FN0\nunKle0Y5jyOSUSe/eGwI5udd5LJOvjHpBdJLIZLitU+KMeYpEbJ/YK2N5OH5Qdq4rFkjO6HayJO3\nEUlJnVA+u2CmEK0cSAoZ4LrUWZV8usYqcPRR3YZ61IZ0H9G1rFsXLr8oowwrVqQXkW+rep/7Atas\nid/HZGrKkYQVNdo/pY9oR1ufpeYpfbS1++1tXUjRqb77NtG1hMIntUrf50rkfAg7B3w3c7sT7g3D\nvntMzgO4EsADMReVIzi8O0n5QO+LQlO9eJ8JFWuA2/KApaNBPn0EpBngujZWr3YGRnJ57fAwcOxY\nvHzJPvJVzKnKPweyS9cSIx/o/T3kHEnx7aNUx6xpfPdDuidkx9lnAjjSeJQjMt+Lu5x80caEohxw\nnYdTJZ9kVCH3mhTfwly6lrVrw+T79NHQkCM/0s9Z0gAX+0iCpLQVglYD3Hv5wPLtI+kVkz4pN2pD\nMiLHke5puodU+JrDrwC4z1p7wudgY8xXAURmTPNEW0phelrGAFN4VzqScvCgnPyi5yLRRxwhaMla\nAt8VDcDyNS6hRC5GflFGFVLvodcROY4+6vVz5qjbkUr3tBVJkY5+N6UNOeBVOGutfb4vQVk4/met\ntQfiLys/tEVSYgf8wIAbMHWIXZLn+46GNmpSgDwNsM8eIynygXw84NwjKb4RuZh7CEn3SK/ukSzw\nznmuURvS8ute8kjy6dgY+UUZVWircDbmjd0+8jmgq3s80WYkJVZ+01tpY1nzmTNuEEtu1e27ugeI\nuwefQjhqI+YZ+Oz6S98vhVRGziSljT5qGkephfC5RFIkiZx0DRs9gxgD3PSSR6CdaFOKTvWNvM7P\nx70upS2SEhyoMcYYAL8I4PkAxtFFdKy1L+e5tLyQeyTFZ7DE3kMunlHO3l1bfTQ+Xn8Mh+Ks8x6p\njRj5IRG5lFqCHKJNKRG5pqWpwGID3OScdKMNfVSUUddG7HP2jVoCrj9D6yZyiVoODwMHInMSU1N+\nCzYAdw+hb+zOOZLyZwD+FsDlACYAnOz6WZKQNsApK0tyISlthCaL1xMqH2ietLEecFu1CtJErmmP\nEWojRj4tTfU1XlIhaI4oQRORa4PsSnrAORO5c+fcfUvqC5/I7tCQq8fIlcjl4hynIqbk5T8AeLm1\n9jPcF5Mzch4sPt4jtZHzhJJM90xNNe/WSm3k3EfSxsV3HKUYeJ/nPDfnSE1TnVU32nIIfMbRqVNx\n8oGwuRDjAW/YUH/MwIDrJ2mScvhwuHxKrfpGCaamgE2bwtrIyfGTjFqmOjW5RlJOYgntf+KLnElK\nThMqtgjLh2ilTqgmxQ+0Q1LOnXMGOKaNHMZRrOIM6aPi8aFtNMkfGEgjWr5zLba+jM5vkl88PrQN\nSTKaU2oVSKvza0JsVNE3tRrbR2fPOj2cwzhKRQxJeRuAtxpjhFdH54XYwRiShwfiB0suBthaN0Fi\n2lgu0abi8aFt+BjgFA+4DcXc6z6iNiTlx6YNQ1YPAfIGOLaPfJamSs+1lIiZT7qHriFG/vR0HpHd\nNhy/VMSQlI8C2ADgsDHmLmPMnuIP8/Vlg+Fh5/2GesCzs80vJCP5QH97wLED3pfIDQ25H+lURozi\nDzUuORpgn2JEkr+cSUobDoF06jMHItfvDgG1kat8Or9JfvH40DZyrUn5AIDrAHwIwCG47fKXPIqe\ny9CQ/3m+g2XVKlelH+sZ0bt56jA8DOzbFyefzm+ST8eH5IBnZprf9VFsI0cPeDkZl9i3y7alOCXH\nUS4RudwL7XPoo9TIq8+OzSmOX4hDELqKq61ISq4k5ecAvNha+3Xui8kZxQEfst2472BJ2e10aqp5\naSpdg/S+B8XjfeHbR9RGP9ekxBoX3xUNdA3L1bj0uwFeChG5pTKOmraUpzakI7sxReQ5zbVUxKR7\n9gGIqFvvb8Q+zBADnLtSCFlzHyNfWvlL95ExzSstYseR72ZxQDveXY7Ghd59JT2OfMluSrRpuUTk\npqbCC+1DNk4sHh+CNvSFr3w6PlR+8fwqtBGRS0UMSflvAP7IGHMZ76XkjTZISkqqQXpC+e6fAYQr\nBd+lqXSMtOeS8gyaQrJLhexKbylP1xOC3PooxgBLEznf1zdQG9J9FFNo35YBziH9LD0XKIKfc7on\nhqR8CG632fuNMaeNMceKP8zXlw2WkuKUlE/Hh8ovnt/URq6Fszn1kfRzjikilzbAbfWRj/FasyZu\ns7XJSfcm7qa6NzLAoWP1zBn3WzIiFzoXpCKvg4MuRSIdDZLWR3R8qPzi+U1t5BxJialJ+W32q+gD\npA4Wn22ZlaT4tSG57HKp9FEb9xBTRL5qlTMedYj1gEP76IT3K1M7iCGjIZutEQlqisjF7naa4zia\nmgortPdNrVIb0mk9aRJEx4fKB/zsjjTRSkUwSbHWfkDiQnLHUjAuIyMutDo312woYuTHekYh6R5p\npbNmTWeztVAD7Hv9dHwIQsfR/v1h8qmNUOMSWkTuI5+WmvfzXCv2UdPurjHyqY1c+8iHdKTMhTVr\n/Fa75Oz4bdniJ5+OD4HvrrzURqjOnptztiSbdI8xJkAVAcaYtXGXky9yJSm0x0iIgQyNRPhOWNo9\nMbc+ojakIx2+BngpecAS8qmNHPsoxMMuXhO3fGojxz5qg7CHjKNQfTc35/eSR6CdInU6PlS+z4Z6\nQNyWAiGF/KnwrUk5bowZD5D7qDHmcTEXlCvaSvfE5Jh9tj8m+cVr8oVviJt2O81VcaoBbm5DOgTd\nRh/lEKaXdgiojX4eR23MtRh9RM/MdxzFpEpCipeBfOdaTukeA+BXjTETnscHBMr7A0NDLkUS8zAp\nfN2E4eHw13KHKh0grlCtjQGfS91O8Zp84UvkqA01Ls1t9HMfpdTVSEYJcuojHUd+8ovXxC2f2lgK\nJOVhAL8WIPcggIhXqOWL2M3WpFl/DEmJaUMyBD056bfEOVa+teFh+hjl389h+tDN4orX5It+J3K0\nfHc5pXtidzuVjMj5RiGAeH0E+D9n2p/HJ7VCCCW7uTqW2ZAUa+1lwtfRF5AmKW0oneI5IW2Mjfkd\nm2Mfzcz4vT8JSPOAfQrhgPg+Ghjw23UyRn5ooR1dUwiknzMpcqmIXEgePtdURqi+oGXUoSuUcukj\naZ1aJFq5FZGH9NFjj4XLp3OlEbNPyrJFjga4LZIifQ9LoY+kPeDhYbkVDW2lDUP6KCaa5VssODzc\nWcUVIp/O9ZFfPCekjaUwF3zkU6G9dJRAcnPJlMjrctGpqVCSEoB+HyxtKM6Yavfl1kexXrxPhABw\nz2C5GuCQcUrnhMina2tC7GZrbUWbiCA0yadr8kXI0tSUQnvfuZCjvghdvtvvZQapUJISgH4nKTmv\nygjxsCkHHCIfkK8lyEXpxNxDyDhKKSJfTn0Uu9S8jT7yjcjROb4IXZra7wZ4KfSRRlKWEGI9YMnQ\nZBsGuI0BH+IZAWH95PvOmFj5wPIywG0Ukfd7H9Fx0vcgPU7pHF+EzDU6LrdxFJPuiRlHIZHR3PpI\nSUqmaGNCxUYJJD1gjRL4tZFbH4Xk+kOVTq6KMyQiR+f4Yql4wG3MtTbqsyTl07k+8ovncMun43JM\nifm+miAVMe/ugTFmDMAzAIyji+hYaz/IcF1ZYngYmPDdKWYBU1PA+vX+8gGnDNd67tlLg8snxxzz\nxkva0XYpKE7fKEFoiHi59REdt1zJrrTyl05lhBBROidEPhD2HHIsnA3Z24quyRe5kt2QpeYhacNU\nBJMUY8xLAXwYwAiA0wCKLyO3AJY0STl8OOycqSngggv8ji0uf/UlKSF7jADhA3521hV6SXtG27b5\ny6dzQuQDcvdAb5aVXrnS7yQlx7ShdB/FbDee0zOgc0LkF8/1aUP7qLkN6XsIXWoeIj8VMemePwXw\n/wJYa60ds9ZuKPxsZL6+rJDrgA8ZLKH30IZnFKp06BxfSOfJc1Q6xevylV8816eNHEmKZLpHuo9o\ns7hcIjU59hG1ERptsrb52Bj5ufZRjE4NaSMkKpqKGJJyEYA/t9YGdlv/I1elkBtJybGPADnln2Ox\nIJ0TIt93szhqIzQiNzsrH5FrI5Li20ZoOoYicjFhel+EGng6J0Q+XZsP2pgL1rolv74I2fU3poYt\nx5RY8bq45acihqTcCuBp3BfSD4gdLNKK01c+tZGj0pHuo9Wrw1JiIZGaHBVz8bpC5PvmmEPnQmwe\nPicDPD0dPo6k59r8fPh+OL7yV6xwpDUnfUFkV1pf+F5/zEq3paIvfIlcKmJIyqcB/LEx5m3GmF8w\nxtxY/OG+wCoYY95ojHnQGDNtjPmWMebpDcf/kjHm7oXjv2OMeUlom7nWEoQMltBVGbETKrfwahvR\nptBIzXLsI8m0Xsg9xGw3nlsfxUY6crqHUPkxZLd4XT4IiaRQGzn1EaUNc9IXKYhZ3fNXC79/v+Q7\nC2Aw/nL8YIx5JVxtzBsA/AuAXQBuNcZcaa097y0ExphnAfgIgLfAkaxXAfikMeZaa+0PfNtti9GG\nKOaQwUhtSE+ouTnn7fimDqQNcKjSCQ3T07EhqQxrXXjfl9i04QGHjqOQN3ankBTfc9owwKFRyyNH\n/I9PMcC+79Zqo48k04a5kV1qI+YefFZkxsiPSRsWr8sHWad7rLUDNT/iBGUBuwC8z1r7QWvtDwH8\nBoApAK+vOP63AHzWWvsua+091tq3AtgD4DdDGg31gGOWpgLyxiUkTB9Tb0HX5YuQe1i1yoVY+917\nBPJTnDn2UW73oH3kJz8kbZhbtCm0KDSW7Pr2URvRb0BWH6Wg7zZzM8YMAbgOwBfpM2utBfAFAM+q\nOO1ZC98XcWvN8aUgD9i3CCuU0caGb3OqSQndW2Fuzi19k84Bq3HhlR+qONsgu9JRxVD5sRG5XOot\nqI3QTQFD5UvXfxXP821DOvK63PRRCqJIijHmp4wx/2iMuc8Yc68x5hZjzHO5L64Cm+FSSoe6Pj8E\noGq3jW2Bx5cilESEDpalFCXwbSM0xE3HSvdRaMqNzvOVT9flg9CIHLXRz+OorXoLaQPc7x5w6D3k\nWM9RPM+3jdzm2tmzzqHzlU/n+covnufbRrYkxRjzarioxBSAPwfwHgDTAL5ojHkV7+WFXRoWbyzH\nfXzwwwwdLMsxShDqPVIbOSpOKQ+YNtRbjgbYt43QPUaojeU01+jYnAxwaBRiKRTOxkT86DwfhOqj\nNhyCFMQUzv5PAG+21t5U+Ozdxpg3Afg9uAJVSTwGYA7A1q7Px3F+tIRwMPB4AMCuXbuwvrCn/dGj\nALATU1M7vS40VOnQsbkpnZUrXTGmr3w6z1d+8TzfNnJSnFNT4UtTAX8SkWMfxRpgqc3WQlOrdGw/\np1ZzXd0TKp/eV+ajY5ZCtClGPp03Ouonv3heE1JXuu3evRu7d+9e9P3Jkyf9hTUghqQ8DsA/lnx+\nC4A/TLucZlhrZ40xtwO4YaFNGGPMwv9/XnHabSXfv2jh80rcdNNN2LFjx7/9/+1vA894Rn8b4DYn\nlK/84nm+bYTeg+/qh1j5ocaLzvOVXzzPt43Qe9i8OUz+9LSLYPiQs7YictJ9tGlTmPzpaf93opAh\nlYzInTsX1kcjI8Bj562XrEasvvB9X1kbUYKYSEobfZTbXCD5O3fuxM6dix33PXv24LrrrvMXWIOY\nmpR9cAa/GzcsfNcG3gXgDcaY1xhjngjgLwAMA3g/ABhjPmiMKRKmdwN4iTHmTcaYq4wxb4Mrvn1P\nSKNtDRbJJcgxleJLaULlIp/O85VfPM+3jdxC0CtW+L20rSi/n/tozZrOcnwfTE25urTQiFxOfZTb\nXKAxtxT0RT9HXlMQE0n5UwB/boy5BsA34eo6ngPgV+CW+orDWvtRY8xmAG+HS+PcCeDF1lralWA7\ngHOF428zxuwE8I6Fn3sB/PuQPVKA8AkV6hlRG21MKF/vLmY5Hl2XD9oqnJWuSclJMdOxx475H59y\nDz59G5Nyo/N8ENtH+/f7H5/SRz77hoTKHxpyRjg3kuKTkijKL16bj3xj/F+ER23kRlL6OfIaU8if\ngmCSYq19rzHmIID/BuAVCx/fDeCV1tp/4Ly4huu4GcDNFd+9oOSzjwP4eEqbsYMlt+VsgL9XmKtx\nCQ3fhso/d855wD6ef6599Mgj/sdLE63QZzAw4Op8ciO7sX3kk26MUfwhkde2SMr4eJj84rX5yB8e\n9t9jhNrwlU/1MdJOzdbuCskG+XSeD6Sd45kZl+bNlqQAgLX2EwA+wXwt2SM3Rjs355amxbJyCZJC\nRVihocnQe2gjSjA9LUNSQg1wjuHb0P1wYg1wbn0k7QG30Ue5RXaL18Ytn9rIjchJz7WQQn5Afq6l\noO82c+slYj1gKaUQ6z0Wr60JS8W4SEY6QmsVAPk+iqk9UgPc3IZk3U7MOAqJvMZEdpcCSQnpI3Ku\nllsf5UxSvCIpxphjAK601j5mjDmOmv1FrLUbuS4uN9A7UUJYeQyjPX7cXz6dEyK/eK5PG6Fvu4wZ\n8L7vsQiVT/nTUKVTvLYmSCsF6fDtUuijNshuTOFs8dqasBT6SHoche6FQ2200Ue+dX5KUsLgm+7Z\nBeB04e+gTdCWEkIfZo6hyeK5Pm2ELE0Fwrz4NnLMMRuh0bX5YGoqbGkqtRHq3UkZl9jN4gB5sptL\nmD70zbLFawnpoxwNMO12OujxZrY2DHAbTlPoPczPO13jU9AbOo5WrnSOrrTdOXHCXz6d0wa8SIq1\n9gOFv98vdjV9gDZIynJK9+SYKonpo4sv9pdPbYTIp1qfEPm+dUGxJIiuzQe5pnt893qJ3SyueG1N\nyNEDLqasfFbtxK4G9CWjofKpDel0D+Da8CEpoc85dCfy2HHku9It+5oUY8ycMWa85PNNxhjPtwv0\nL3IiKbG1CsVzfdqQvofc+ihH4xIj3/d9H0ulj2JSq0CHgDTJB/Ks28kl8hqzNHXlyrD3lfV7H9Fx\nOeqLXNM9MYWzVYH5VQBmEq6lL9DvgyV0Qkl7LikhbuuRdFzOSgfwU84xfUQ1RLmMo9iIHODXRkrU\nMsRAht5DaOFsyIZ6QFgfxUSb2ooStBVJacK5cy4tJJ3Wyy1tmALvJcjGmP+68KcF8KvGmInC14MA\nrgfwQ8ZryxLSEyq0ngOI8+5ClgjnaIBpJ8+mTbKklQ4dl2Mf0blNYfoYpUPGRXocHTnSfFyKfDrX\nR37xHB+EbrYWS7R8t2RP6SOf5xxrvELnQmj9V8wKKCmnhghrTF1NTjqbzmkDIfuk7Fr4bQD8BtxL\n/ggzAPYufL6k0e+MNtQDjh3wvvuYpBqXJpLSRiQlxriMjACHal9v2UGOBpiOz4nIxcw1OtdHfvEc\nX4QayJh7kDZedK6P/OI5IW1Ij6PQ+iyptF5bfbRlS5j8GCIXOlZj4U1SrLWXA4Ax5ksAXm6t9Vwo\nu7TQxoTy3e00xQOWvgff3U5TFWfTTp4xfURvfc7JAOdoXGJWcYUgVHHm2EdtkAjJdFJIDVvOJCWk\nj9asiatt8rmHmCJ1QH6uhT4D0pFtILgmxVr7/OVKUIA8jUvIHiPURkj+VHLJn3QtgbTinJ93ufgc\nFTOd6yO/eE5IGyH3IL10tI0+CvUeR0bkSYRGUuqhfeQnn97Y7SM/dC6nwHczt3cB+D1r7eTC35Ww\n1r6J5coyRZtRgvXr/eSH7DFCbYTkT6UnVMh7LIrXE6IUpHLAMRutkXxpxUzn+sinawpBbukeSeOS\nMhdyqiVYrgbYV/7kZJyuoGtrQkofTUw0H0dtxKY+z5xpPjfmGaTAN2BzLYChwt9VWPKbvLWlFHwN\nZMxg8b2HtpSOZC1BTI6Z2sipjzZsCJdP5/rIB+T6KNdoU05Eztp29gxqg6TkGDGbmvLbETY2LUnn\nNiFlHB0+7HdsbNSSzu1LkmKtfX7Z38sRuSmFmMHim9/MOQ9P5/rID90/g9rIwXhRGxddFC6fzvWR\nH5NjzqmPpqfjdv0F5NM9PvJjlu8W5UsZ4JDdTtsgcjEGmI73IYExkRR6XUq/Ezk6t2ketU1Skl8w\naIxZZ4x5mTHmiRwXlDtyIykxFda+9xBb5JVbHy2FaNNy7aOQDelC5YesdJuacruJ+mwNX4QvYU+J\nZlnrvyFdaB+FFNpL64uZGReVW65zIaeUVdYkxRjzUWPMby78vQbAvwL4KIC7jDG/wHx92WGpGBfJ\nfQ9GRmSNS2gfxRR5tRFtmplxxck+bcR6wL7POVfFDPhvSBdq4EMMsLRDkNpHORng0EJ+31VcS6GP\npInc7Kz7ybGPYhETSbkewNcW/v55uH1TxgD8VwC/y3Rd2WKpkJRcjEvs6+kBf6Ug2UcpBZWA3HMO\nNcAxRE6a7OY0F2Lrv3xXlqQ4BEA+ZDR0+W6ofDo+BCF9FBOFoGvyvYfBwbBdf0Pk56qPUhBDUtYD\noK26fgbAx621UwA+DeAKrgvLFcPDLrQ6P19/3NyciybkOFj63bujnTx9Pewco00hfSRNtGL7qI1o\nU/H8pjZy7KN+n2vUhrR8qdc3FI/PqY+kVmSm1LwUz69DrD6KRQxJ2QfgWcaYETiS8k8Ln28A4JEZ\n7W/4RglyZrS5KE4ictJh9Db6SHq301yNSy6Ks9/7aKnoi1xTJYB/G9KRlJQ+atrHpI0+6odIyp8B\n+DCARwDsB/Dlhc+vB3AXz2XlC9+HGWvgQyrF21qCLGVcYhUznSOdysiByMUu36U2cjAubdWk5NhH\noTUxQvcAACAASURBVOmemNVDQD7pnhzHUehS8xz7aGTEr0A652hTLII3trXW3myM+RcAFwP4vLWW\nEh8PYJnUpAByJIXOySVMH5s/pfOb5BePD20jl1QJIBdJaYvI5WhcciNyWjjbe/l0fKh8IB8iF+s0\n0fl14zDWsQzd6yVrkgIA1tp/BfCvZgHW4dPM15YlcjLA0oqTDHxM/pSurw5t9VHT+33KEELkYvdh\nofOb5BePD23D9x5C9xgpym/ao0M6BB27xwidk1PUUqqPaI+R2HuQNvA+7ytrg8ilpHt8Xqqa4jQB\nzXM1dq4NDDg9liNJidonxRjzGmPMXQCmAUwbY75rjPkPvJeWJ4gUNIWgc46khCidWBJE59dhqUQJ\nUpVOk/zi8SEIIVqx9zA/75ZSN8k3xu0zEiqfzm+SD+RZ2+S7HD81Itc0n1OIXBvjiM5vkl883her\nVrnxp/qiuY0lQVKMMW8C8F4AnwHwCgCvBPA5AH9hjNnFe3n5oa3B0kZo0qcIKzU0WYecJ5TvM0jx\nsIH+7yM630d+v0fkJPtoejpus7jVq/0McFup1Tb0Rcx+OD61QfPzaemYHMZRbLqH2siRpMSke/4L\ngP9krf1g4bN/MMZ8H8DbANzEcWG5YqkoTvKA67xbjvxpHdrwgFMUJy01r0vl5O4ZHTnSfBxHCLru\n3UKxfeTrAec+1+j8tWvr5cfMA9/9cNoiKaHvmCpek889xLy+gdrIIW04NdX84tgq+XR+HWLfVUZt\nNMmP3VojBTHpngsAfLPk828ufLeksVRICp1fh1gDv5SMi09aL0YhDA05r7nfI3JAcxux48gYv91I\n2+ij6em45+y7+ibFO/W5h5znmm/RZmof+Rr42HvIQWdPTTndErrYgdqQjNTEIoak3AeX5unGKwHc\nm3Y5+SMXkjI35yIhOZKUnLy7tlIZoQjtoxzDt75LO2PHEaDjyAc+NSNLJd0TO4580j1tzbVc+0ia\nyMUiJt3zVgD/nzHmegDfAGABPAfADSgnL0sKvi8lm5qKKxYE3ABoqhRPLToF/AZkiuLstXeXsqLB\n1wBLe3dLwQCnjCOfe8i9AJvOl5BPbeQwjjjShnVYCn3U7+OIdHrWkRRr7ccBPBPAYwBeBuDlC38/\nw1r7Cd7Lyw8DA/4h6OHh8GJBIGxCpYSge83KybiEvpDMVz6tqkjxXKTD9L1WnCk55ly8u5yNy1JK\n9zQV2rcRJcjVAA8P+70uJZbIkZ73Sa22oY/aJCmx+6TcDuDVzNfSN/B9mDkbr6KMKkxOApddFi6f\n2ug1kUtVOoDfPWzZEi4f8A/Tp0TkpKMQwNJP96TuMQL4PYec0z3WOjJb51Ckpnt86r9yjuwC7h7q\n+iD2HkKc45S5dvhw/TFZR1KMMQPGmLcYY75hjPm2Meb/MsZE+PH9j6VCUqQKHqkNn3uIiQT5ym+L\npEg/51QiV+cBt0V225gLsRE52kisCmfPdo6NkQ/0fi5IP2davrtcUxm53ENbfdRmTUpIuud3ALwD\nwASARwH8FoCbJS4qd0gPljY8o6KMujaWwoSSVDopHrDvPaTIJw+4CinjKGRVhjTZjdn1l+STjDr5\nQNrGhrmke6Q2Z6TluzHP2XelW1tkV5LIxb6+gdrodR9lHUkB8FoA/9la+2Jr7csAvBTAq4wxUbvW\n9jNyMMBtecDSxiW1j+qiBMvdM/KpPUoZR4ODLg3V7+OIZNTJLx4bAloOmoNTI0nkUuZayEq3fnb8\nKJ0lPRdS5PvupJ4rSbkEwGfpH2vtF+BW9lzIfVG5IweSklJL4OsB94NxqXsraIriDCkulg7T52qA\n6bxee3e595GvgVzOfdTGPfiktwcH3YZxMfKB/u+jfk/3rADQbRJmAURsG9PfaKPeoqlSXNoDtlae\npKSmSgA5727lSud15rC6J2fj4luQmDvZlTYuTX2UOhekxynJqEJqGiAXAzwyEl//Bfj1UT87BJOT\n8RG5WISs7jEA3m+MKWa4V8O9s+ffpoi19uVcF5cr2lSco6PV8ovHxrRRdw9nzzqiIm2AU4gcyah6\nK2hKaLKNEPRSMcDSEbmmELQ02aX2pSNmsfKlIzU+UcVUkhKyrUMM2hinQO/nWhsOQZupHiCMpHyg\n5LMPcV1IP2F4GDh4sP6Yqam491iQfJJRR1Jil6YCzYqtHzwjklEF6XtIfY9FW31U52Wn5pib7qGN\niFzu48g32rQUxlGu9+DzDCYmlgZJiZW/Zk1nb6mqF12mzOVYeJMUa+3rJC+kn5CD4qRCuJjQJLWR\nA0kZH4+XTzKqMDkZ/x4LasPHw+7nML204pyZcUqvHyJyVZiYcL+rHAafNqS9+F6Po35wappeGJp7\nJGVkBDhwoP6Y1HQP4PRa1VjvBUlZditzOJADSZmcjFea1EYvPWxqQ7qPUiZU0z3k7hn5Ks6Bgbhi\nQWrDp4/6fRwBshG5OsPgI9+nhi3FwyYZVWij3oLjOdelDlN0qs/rUtqobUpN95CMKqSQoFgoSYlA\nDopzYiKdpEgqHZ88uXR4NZWkNN0Dedj9bIBJfj9H5FLmgu9cGxiI2ywOaE41pBI5Oq/OAKeMI7r3\nXpLRc+fiX6havK6655CiL3x2hF0KhL0XNSlKUiKQQwhaOkrAYVwmJ5v3MZE0Lhx91KTUgPQ0QNOO\nsJIecIp8QJ7srlnjdoOt2xE25TkPDQErVviNIykix5FOApqJkPRzbiO1KunUpDhN1EYvo02zs47M\n5RydjkHfkRRjzAZjzIeNMSeNMceNMX9tjKntNmPMl40x84WfOWPMzbHXMDzcvOJA2gC3FUlJUQpN\nu53mHklpo4+A+r1eUjwXXw9Y0nhxeI9A/XyTngttyAfk6yGkSUob4yhnA+xzDymLHdrSR5ruScdH\nAFwN4AYAPwfgegDvazjHAvhLAFsBbANwAYA3x15A02CZn++PKEEbxkWqrsY3Ty7ZR1wecK9JRIp8\n6VViPmH6Njzg1LShZETOZ4mwNNFKTQNIkxTpdA/Q7LxKp1b7gcjFoK9IijHmiQBeDOA/Wmv/1Vr7\nTQD/BcD/YYzZ1nD6lLX2iLX28MLPROx1DA+7/Oi5c+XfT0+7KEI/Kx2O0CRQ3Qa9kEwyStAvkZSm\nNmLThoAfiUglQT4GOLYNGuMTNbOVo4g8h0iKZLqnjbnQBpGTTqFLE7l+jzZpTUozngXguLX2jsJn\ntD3/MxvO/WVjzBFjzF3GmD9MeYNz08NMVTorV7p16nWKOVVx+hiv2C2igeY+os+liVY/kxTaY6Sf\nDXBqH/mQlDZIRD+PI6Cd55xigEdHm4koHReDXKLTqSSl7o3dbTlN2e6Tkgm2AThc/MBaO2eMObbw\nXRU+DOAhAPsBPAXAHwG4EsAvxlwETZTJSWDduvO/TyUpxvhNWukJlVosSHLKwPE2TR/FuXlzvHyf\n1T3GyHl3qRE5aqPXaQBAjqScO+fqniRXcaUSxaYoQaq+yCHymuphN+m7tvpIWh+lkhTAtbF+/fnf\nt5XuabsmJQuSYox5J4C31Bxi4epQKkUsHFN+srV/Xfj3+8aYgwC+YIy53Fr7YNV5u3btwvqu0bBz\n505cdNFOANWTKpX107nS3qN0eBiQizZRG71e3TM8HP8eC18iJ/mcJybiN9Qj+U3PwJj45btNJIWr\nj3ptvIB0D7jqOdM+LDmne0ZHXQp9ZqY8ersUUmITE8DatfHyi0RLgqSsWuXmauhz3r17N3bv3r3o\ns5MnT8ZdRAmyICkA/gTA3zQc8wCAgwAWqVRjzCCADQAOBbT3z3DE5gkAKknKTTfdhB07dpz3+Z49\n7neV4uQwwL2OpHCy/ir5QN6K08cDTjWOQDORk+6j1HugJcJly09pHMVG5JpISltkd+vWNPkUpi/r\no4kJ93nOqdWREeBQjYZNTWWQ8Z6cLO+HVDI6NOTS11V9RGM4dRzV7QgrrS9SdSq9r6xpKXu3/J07\nd2Lnzp2LPtuzZw+uu+66uAvpQhYkxVp7FMDRpuOMMbcBGDPGXFuoS7kBjnD8c0CT18JFXho2GS5H\nG4qzjUiKdBQCkDfATTtISoagufqoSim0YYA5ogSAew5lBjg1DUDnNs211Huoc/w46r8A95zHxsrl\np1w/1bD12iG48MJ4+UWdWvbOs9TUatMLQzn6qC2npqqN1EgK4K6vSj5tqKeFszWw1v4QwK0A/soY\n83RjzLMB/D8AdltrDwKAMeZCY8zdxpinLfz/OGPM7xpjdhhjLjXG3Aj3ssSvWGu/F3MdviRFOkeb\nqnTqNsniWFJIcsrAFaaXJBGjo67eoa5QLUU+eY+9jBK04d2l9NGKFS5V1Mt0jzRhT41mNXnAbUWb\nUo0jAJw+Xf496bvYiBxQTyI4SMroaPX1A+npHl+dmrIasO4eUlfqxaKvSMoCXgXgh3Crej4F4KsA\nfr3w/RBcUSx15QyAF8KRm7sB/DGAjwG4MfYCeh1JmZnhCU0C1ZGIVMXctI8JF5GTzDEXC6TLkGrg\nV62qX8W1VEhKqlKrmwttpMTaSOulyKc2epk25CicBeqfM0cfNRG5VKejzmk6fVp2HJ0+7Y6peoOx\nD+ruIbUIPhZZpHtCYK09AeDVNd8/BGCw8P8jAJ7HeQ30kOpY/4oV8TlmwA2WI0fKv+PyHgE38MpW\nKKUal8HB+n1MOO5h7Vpg797y7zhCk0XvrixMn0qCmlZxtVUUypHKqKuHSFVqPiQl50hK00ZiHMs6\nfaIEORfat0FS6pyatiIp0mQ3JVID+EVSNN3TBxgcdJGCpgmVEpqUHixNxoVDcTZ5dwMD8VtEA34G\nXjIdkxqmpzbqyC4g5wFzLN+VTvcA7RC5KuNlLW9NShm4DHCviRxHukeapDTp1FSnaWKi+l1c0iTl\n9Ol0klIXSdF0T5+hSXH2g9IB6ouwJEkK9VEKkasz8FyeEVD/HKSjBIODaUTOp1hQchz1Q7qnLgpx\n9qzbHZkrIlcGDiInPRd6ne7hcggknZrRUbfcu+pdXKmRjqYUemo6CdBIypJCk+KUJClcSgeQrSWo\n81Db8rBzV5w+4yi1WFB6rxpAPgRd10erVrn0aix8olmpHnZRVlkb/eDUVBXap76rjOQb0986te45\nc0Tk6C3TknMtx5oUJSmR6CVJacO4cOXJJfuo15EUaQ+4rYJK6RC0tHHhkD87W/7Gbq4Cb6B55UoK\nmsZRao1cXcqK+ijFQDbVZ0mne7gKZ4uyipiedmROcj5LR1Lo89Q2QqEkJRI5kBTpfUxS72HdOtkQ\nNxXCzc+Xywd4lI6kcWl6zhwpt9lZV0RcJp+uIUU+UB0x48iTS/dRnXHhSIkNDbloT91cyJ3IUXF9\n2T3QZ/3wnOv6KJXI1ZFRjrkGNDt+kpEUruccCiUpkZCeUKOjnW2iu9FGLQFXEZa09wiU3wMHSVmz\npj4E3e/GhaOPaKdUScUp7RDUkVEOh4Da6FVUUbqP2iIpuc+1OrLLRVLqnjOXQ1A3johwtwklKZFo\nS3HWDXipnTwp9M1BUk6dKv+Oy8AD9R6w5BLhNsL0bRhgyYiZdCSFKyIH1BM56YJE6fosLoegVyRF\neiWd9DjiSIkBzXNNsriYYy7HQElKJNrIkwPVBnj16rRNe1ascNGUOqVTtn9KCKQjKW0oharnzPGu\njzr5AC9JKSOL0t4dR7Eg0P8OAbUhTUbbILtl44iTpEjeQy/ThpwOQZXjxxW1rIrgK0npM7QRmiRZ\nEvKB6kgHfSaZ7pEOr5465dIQqaHJKsXJtRxPehzVpXs4DXDZOKJiwdzTAHVRAq5ISpWHOj/fzoZ3\n/R5J4dKp09Nuf6Ay+RzXD9T3Ecc4qiIpXJEUoPw5KEnpM/SSpHCEJoHq0CGX0ullJOXUqfRIEFBt\nXNryHrmMS1UkZc2atIgcID+OaK6VbZLVRpg+5cV2xTbK5HO8oRhwfVz1nilOh6AXJIVjiTNQX8N2\n6lT69VO9hnQkpU5fSBMtJSl9hKUcSWmDpHCQiKZICgdJqXrO9NZcjnuoM8DSUQIOsis9jkZHnaEq\n2yRLOt1D+wUNJGrKKrLLFc1q0hep8leudD9Vxoteg5GCqj7i2p+jro9On+bTF5L1X1VzjQgqh84G\nqvuo7eXHgJKUaPSapLQRSeEywGVLhE+dAtavT5PfRiSl6jmTouC4h7m56j06uMZRleLkIruSilma\nsNctEZbuI850EiAfVazzsFM2HQSq5xpn8TJQ3UccUYI6MkpELwVNOluyjzSS0meoCkFzvA+F5AOy\n6Z42alKA88Or1rpIRKrirFuhxKV0qjwj6qPUe2giEanPeXDQyaiKdHAY4DbSPYDsXKirPZKUz+lh\nF+UVweEQUBuSxquKpHDWcwC9i6RwzbW6InjpSIqSlD7C6KgzttPTiz/nYv1r1rgQs6RnJM3Kq4o2\nKTSZqjgHBpwBqboHyZoULpLSRsqqyricPMlnvKTTPYBsVLGqj9rwsAHZuhoOhwCoj5hJkhRuh0B6\nrkmmSprmmkZSFP+GqgHP5RnV7dHRhnFZsybtfSgkHzi/Da56DmqjlzUpUqmMs2fdD8dzriKjXOOo\nSr50uociclxzQXKuNUXkUttoI5JS59RwGOCmucbVR5JktC6SwiF/3bryVzhoJEVxHqoYJxejJRm9\nUjpcBILkFcHlGQH1yl+6JmXt2vSCyqpxxKWYgfq0XhuRFCmSMj3t6nkkSQQnCaqSD8ilDc+dc9Fd\nrvlc9Zy5DPyZM+cvEeaaC20UztZFzLjSPcD5z4ErarlqlavR0kjKEgBNGJpAhBMn3O+xsfQ26jwL\nSaXDGeIGqkmKpAfMGb6VNvCAPEmRTgOU1WedPu1WxqQucW6LyEkXnZYtET550hFdqXoLuqd+qUkB\nzr8HrudMq7S65/PsrCNH0pEUrnQPUE1SuJxjJSlLAFUkhVNxSnt3dZEUSZLCme6RjqSMjbnr7TbA\nXPLpOValxPol3WPt+QXSnCFuQLaP2kj3AOUGeN269JUxq1a59Kx0arVX+mL16vSVMca4fujW2Vyr\nGQH5mpSqOj+u1CpQfg+0C62SlD5CGyRl/frzlY61vN5d2Q6M0kqHM5JSVe3OFQ0aG3NLqLsnLecz\nMKYTgSO0ke7hTGUA57fB9QyGhpwXXNVHkhEzrj6q0xcc8o3pEOoiuKOWvSIpHNcP1PeRZCTl5Eme\n6HpdJIVjiTNQfg9c6aQYKEmJBE2aMsVpDJ+B7JZPYXUuAw+UD0gOxU/vF6qKpEj10blzjnxxRVKA\n8ufMIX9gwD1LaZLS/Qw4i06rxtGJE8CGDenyAXkDXCaf2uCSD5Q/Z04DLE3kJEkKjRWpuQaUzzXu\nSEpZH504Ia+zuQhEWSRFSUofYuVKtwKmzDPiKKgEypUOt2dUlFlsg2MwElkri6SsWsXzyu8NG4Dj\nxxd/xql0qowLl/GiNiSNS1m6h2sZOFA9jk6c4PEeAXkiV/YMuPbzIflA+ySlnyIp1Efd87mfIilV\n6WGuSEpV6pNLZwNOTlWGgIsshkBJSgLWr5cL35J8aeMFyLLyMgPJaeA3bKhWzNIkhWvCVpGU4WGX\n6khFWSqDO1IDlEdSuEhKmXHhnAtjY+cbx6kpvtVDbZAUaX1BJKVogInIcTznXjkE3E7NzMz5+2dx\nRVKqin85o5ZlOpX+52ojBEpSElBFUjgVs3QaACg3YFwGuKxQjVN+mXFZKiSFSzFLk5S6dI90JGV0\nNH31EOCuc3p68f4T3PVlQPsG+NQp1z/Dw+nyN2xwpK2YCpiedkaZ4zmvWeMi1JKRFGkiV6Yvzp1z\nfcbRR1XR6ePHeVOrVSSFaz6HQElKAqoGfBvhW85ISjeJOH4c2LQpXT5QfQ+ckZSJicXFv5x9VFd7\n1C8kZf16t8RyZmaxfPouFVXjSDqSwj2OgMVtcI6jlSuri3+l04Ycq4cAYONG97tIIjiNFxX/SvdR\nmb4bHJSrq6FxxDUXypwOzrlWlkJXktKnqApBc04o8lSK8gGeNsqUzvw8LysvG/DcBh4oVwocSmf1\navfTz5GUsufM6T2uWuW84DLFJu0Bc841YHEbnHON2uiFU8M1TkknHDvW+Yw7DdAGYe+Wf/y4a5eD\nyJXV1VB7XPdQtqKRu0i9rI+Gh3lWD4VCSUoCytI9nIqZBnyxDc6VMTToikrn1ClHVMiwpaKMpEgo\nzjLjIkUiKOTdL8aL+qiMpHC2UZRvbTs1KZJktx9JiqTTRDqhqC/omUt68dJ9dOwYr4EHFj9n7ihE\nGUkhosUBqkkp1h5xzuVQKElJgHThbFWUgGv1kDEurXP0aOczUkCSJEWij4ptHD/uNrbiKv7tNi6U\nk++XSEoZSeFMZVAbRfnT0271kHRNiuQ4kiYpnMvAgfI+4nQIykgKtwFuI5Jy+rRzNAjHj/PpuzZI\nyoYNi58BtcH5DObmFte9KEnpU/QiBM3JmAE3Ocs8o36OpBw75q6fI3wLnK846X76xcOuiqSMjKS/\nRJKwcaNcrQLJ6V7aKdFHUmlD4PznTKuHOMnu2bOu/ojAvceIMbLPuXtlCb17iFunFiMRnOltKv6V\njMht2rRYZ1vLn6IHzidaSlL6EFXhVU7vEVg8WI4eBTZv5pEPnD/g24ikcBKtMg/46FG+66c2up8B\nwPccxsacwequPZImKVzyqQ1JD3v9emewpqY6nx07xlfgPTrqopPdZHfdOp7VQ8D544h0B/dc6L4H\nrj4aGHBtdDs1tGcUB7pX63FH/KocPy4DT8W/kjUp3dFv7qhlmb7grHkJhZKUBJABJu9ufp6/gAlY\nPKEee4yXpGzcWJ7u4WTlZ84s9u6OHuVTnJT6Kk4oiqRwoZuMUn9xroACFrfBWdtUtrSTOyLXTUYl\nIinA4j7inAtlK0uOHAG2bOGRD5TLB3jJLnA+oeYap8D5kVfysKWilhJkF1g8jjhJClB+DyMjPHse\nAefrbJp3knaHW1+EQElKAjZvdgyW2P6xY46ocCk2WjpYVP4SJKU7ksK1HA84n5VPT7sfbu+uLN3D\nhapICjdJoTbm53kjZsacTyIee4zXAEuTFHqeReXMPRe6PWDuPqoiKVxttOHUlEXMJMnuY4+531x9\nVLZCSVpfcBbmAp3oNznHEik34Pz5rCSlD0ETh5QNt9IZGHADRlIxd6d7qIiMyzPqHvDcBh4437hw\nhrhJfjdJWbnSeUdc8oFOGydPuloFbhJRfM4SZLf7GVC7HBgfd79pjk1OOrLLbYC7SYQkCeLWF90G\neH6efy50P2cJonjypLt2kg/wtdE9jgD+SEr3XDtypNMuBzZtcs4xFfBzr7CqShtquqcP0T3guZUO\ntXH4cOd/ifBtd7qH06voXhFAvznvodu4SNSkdBv4TZv4iRy1wZ0GoDa6DaSEh03e3aFDrs6DY6dT\noDPXaC5wGy/AjRmSC/Cne8bHXdSVUp9Hjrg9eLjILvXRoUPuN5FdyXTP4cP80SZrOytLuOfC6Kjr\nc+qjc+dcW5wGeMuWxSSIu4+6dSp3Hw0NuX4iu2CtuwdOohUCJSkJoIFHipN+cw7IrVs7E8paOQ+Y\nPBduktJtXNqKpHDfw/HjznsB+IlilQHmHEdbtiwmu9zjaPNmV/hL3t2hQ27scmFkxBkXyT7atq0z\n16gN7rkMdO6BSBAX2V250hlbugfuAm+gnSgB0Hm+jz3mUs8cLyMFXF8XHT+Jd9IUdTbAb+Cpj+j5\nHjrkUvScOmnr1k4fnT7t5jbnXAiBkpQE0KAoRlIGB3lzd92DZXaWP91D+zUA/GG9DRvcMtduxclt\n5KmPrOUnKd3GhZukrF7t6o+ojyQiKWUGmFM+9dHBg+43N0npNi4SkZRt2zrXD/BHm7Ztc7+pDe5I\nDeD6nORLzLXudA93lIDGDI1V7nFKbdA4or7iHKvdJIX7OZeRlC1b+FahAYvngkSGIARKUhKwYoWb\ntEWSsnkzz0ZrhPFxWc+ouyCR28APDCy+h8OHXb9xLn/dtg04cMD9ffy4C+FyKx1g8XPgVPzURlEx\nA/yeEcmfmnI/3FEIoNMGN0kBFpMUmnOcfVRUzDMzLjUj2UdSJKV7HEmuBuSOpHQTOQmSUhxHpDcu\nuIBP/tati9N63JGUbp0tMdeKZFdJSp+jmH+UUjrd3iOnYu4Orx48KDPgSXEeOOAUESeRu+CCzoTa\nv9/9vvBCPvllUQLu/GyRyB050olAcYHGEa0cAvorkgKcH0kZHuareQHcOJqYcD8SBn7zZhcRkoyk\nFCNm1FfcRG5y0kV1qXiZu96iGHmV6KPiXJMiKYBrY2bGpZQ49cXatW5bAcm5ppGUJQRpkjI+7hTm\n3JxMGuCii9zvRx91vw8c4DXwwGJWfuAAr0IA3IQ6edIpTAmS0l2Q+OijwPbtfPKBxUROiuzOzrpI\nE7XDvXpoaGixgeRWnMW6GgkPu+jFS9S8rFjh5BUjHZKRlEcfdfK56jmAxfqCngWnAabIa9EAS+jU\nYiRlwwaXcuVCMT0sMY6McfrnkUfc/22RFO755gslKYloI5IyP+8G+/79boByDsiNG90EfeQR5x1N\nTPCTiKLiPHiQXz7JO3iwQ1LI4HCgWJB45ox7FhIkhRTnvn0y8gF3Dw8/7P6+5BI++TQuDx5041WC\npBSNy8GD/NGsIkmRUszdYXQJ+TTXHnmEfxwRSdm/v9OOxHMg2fv2ARdfzCu/ONcknKbiXKNxxN1H\nF18sT1KOHHGp80cecdfPtRldKJSkJOKCCzqGcf9+/gFfXPnxyCNu8HAOliIrp9CnRCSlO93DCZJ3\n4IB7Bps383qPQOceKOLErfyLdTUPPQRceimv/GI65uGHXbiYu66GjItEXRDQCdNbK2O8iiSFDAD3\nXCAP9exZl3aTMJBHj7qomQRJof549FFg7173N/dYpT6anXXzmZNMA24cTUy4uiwJnU0rtg4d6sxp\n7rmwfbubA4AcSaHVpPv28T+DEPQVSTHG/I4x5hvGmEljzLHmM/7tvLcbY/YbY6aMMZ83xjyB/dnw\n5gAAEs1JREFU65ouvdQZFWtljEtRKUgoHaBDUqQU86WXuoFOrJxbPimZ/fvdD7d8wN3D3r1yJOWy\ny5yymZx0JIJ7HJFB37vXyb/kEr6lr4Tt290cIMXMTUYvucQZlxMnZEjK2JiLmh086O5jfJzvnTQE\nInL79jmdIUVGDx1yc40iH1wYHnb9RCRlwwbeInigM47273d9xG0gST+QY8atLyit9+ij7j4GB/mf\nA+ns06fdj0QKHXD9Q/qiV+grkgJgCMBHAbzX9wRjzFsA/CaAXwfwDACTAG41xqzkuKBLL3WV3Pfd\n52oiuJXO9u1u0D/wgBssEiTloovchLr/fpcT5r6HK690XtFdd7mI0BVX8MrfuNEt4b3vPhkSBLh7\n+NGPOkSOW+lQn/zgB85IciuFNWucUb/3XjmlQ310//3u/8sv55V/2WXu94MPypAUY9zY2bdPxuEA\nOgaYohB0T1wgeUSopfTFI4+458B9/YAbR/fe6/oJ4B+rj3uc+/3AA66PuA08tfHAA+45kA7nxPbt\njsTdd1+nPU7Q3HroISUpQbDW/oG19t0A7go47bcA/J/W2n+01n4PwGsAXAjgZRzXRIr48593v7kn\n7eCgk3n//cA99wBXXcUrH3AD/J57nGK49FLnTXKCDPBnPrP4fy4YA/zYjzkDf++9wBPY4mQdXHml\nUwj33++8x9FRXvl0zV/6kvstYSCvuEKepDz0EPD97zuPmzuSQnPtG99wERXucQR0iNYDD8gZ4H37\nXB8NDPCTiMc/3v2+/XYXqpcYR1dd5ebagw/yE1HA9dHkJPCtb7n/uckokYYf/MCN1yuv5JUPdEiK\n1Di6+GIXmf7mNzvtcWLrVreK6Ic/dH2kJEUIxpjLAWwD8EX6zFp7CsA/A3gWRxtPepL7vXu3UzpX\nX80hdTGuugr49redcXniE/nl79jhIhxf/rKMgb/4Ylcj8ulPu/8ljMuTngR85zuOSEgQuSuvdMsJ\nP/MZR4i4sXmziwZ96lPufymidc89wN13yxl4a909XHEFfzpp82b389GPuv9p7nHi6qtd/3z3u8CP\n/zi/fBqbH/uY6y9uh2DNGmdQPvEJ979EH117LXDnnW6uSZEUAPjkJ13UhtshGBx08+sf/sEVeUvo\ni6uuckT0rruAJz+ZXz7Zmb/7O5d+4y7MNcY9h89+1mUIJMaRL5Y0SYEjKBbAoa7PDy18l4zRUee9\nfP3r7qFy57AB4OlPB772Nff3Ndfwy9+xw/3+9rc7f3NiYMCRq9tucwpU4m2aT3qSMywzM8B11/HL\nJ3L4rW8BT30qv3yKBn3tay59xe09Aq6Pvvc9F4W49lp++aQ4b7sNeMYz+OUb48bn17/utsmXMJBP\nfaojcseOAU95Cr/8Jz/ZefHf+IbMMwCApz0N+MpXHAGScJquucYVRz/4oMxcu/xyd+233Saj7wA3\nPr/6VTemJEjE057mxtDdd8uMo8svd5GOr3/dPQNuhwBwduerX3V/S+g8X/ScpBhj3mmMma/5mTPG\ncAfkDBx5YcHP/dzi39x40Ys6f0t4dxdf7Lx4AHjhC/nlA8BP/7T7fcMNMvKf//zO3xJE65JLOkWJ\ndC/cILkvepGM0imOo+c8h1/+5s0dhf+85/HLB4Cf+Rn3+4Yb+PP8APDiF3f+lriHtWs7hvclL+GX\nD3TG0TOfKeM0FQmoRB+tXAlcf737u/g8OEFz4eqrZZymZz+787fEcx4Y6DxnqT4i+RdfzJ+6DYHA\nNA/GnwD4m4ZjHoiUfRCOkGzF4mjKOIA7mk7etWsX1neVru/cuRM7d+5c9Nmb3+yWc/7ar0VeZQN+\n8ieBP/kT4Cd+gnenVoIxwN//vYtEvOAF/PIB4C1vccWzv/3bMvKvvRZ473tdeJh7+THhk590tUf/\n7t/JyN+1yy2LfOMbZeQ/8YnAzTe7PuLcqbWI97/fjaVf+iUZ+W94gytUf93rZORfeKFLlczN8a9a\nIfzd37mfV75SRv7rX++WIf/8z8vIHx8H/vZvHZmQKDoFgPe8B/jgB4Ff/VUZ+Tt3unTVjTfKyF+/\nHvj4x904koiKAsC73+2iNL/xGzLyX/Yy18azGgojdu/ejd27dy/67CS9DI4Bxlq2gEJrMMa8FsBN\n1trGt8wYY/YD+GNr7U0L/6+DIyyvsdZ+rOKcHQBuv/3227FDwi1XKBQKhWKJYs+ePbjO5QKvs9bu\nSZHV83RPCIwxFxtjngrgUgCDxpinLvyMFI75oTHm3xdO+zMAv2uMeakx5scBfBDAIwD+odWLVygU\nCoVCEYQc0j0heDvcEmICMbTnA1go8cEVAP4tUGut/SNjzDCA9wEYA/A1AC+x1s7IX65CoVAoFIpY\n9BVJsda+DkBtNtpaO1jy2dsAvE3mqhQKhUKhUEigr9I9CoVCoVAolg+UpCgUCoVCocgSSlIUCoVC\noVBkCSUpCoVCoVAosoSSFIVCoVAoFFlCSYpCoVAoFIosoSRFoVAoFApFllCSolAoFAqFIksoSVEo\nFAqFQpEllKQoFAqFQqHIEkpSFAqFQqFQZAklKQqFQqFQKLKEkhSFQqFQKBRZQkmKQqFQKBSKLKEk\nRaFQKBQKRZZQkqJQKBQKhSJLKElRKBQKhUKRJZSkKBQKhUKhyBJKUhQKhUKhUGQJJSkKhUKhUCiy\nhJIUhUKhUCgUWUJJikKhUCgUiiyhJEWhUCgUCkWWUJKiUCgUCoUiSyhJUSgUCoVCkSWUpCgUCoVC\nocgSSlIUCoVCoVBkCSUpCoVCoVAosoSSFIVCoVAoFFlCSYpCoVAoFIosoSRFoVAoFApFllCSolAo\nFAqFIksoSVEoFAqFQpEllKQoFAqFQqHIEkpSFAqFQqFQZAklKQqFQqFQKLKEkhSFQqFQKBRZQkmK\nQqFQKBSKLKEkRaFQKBQKRZZQkqJQKBQKhSJLKElRKBQKhUKRJfqKpBhjfscY8w1jzKQx5pjnOX9j\njJnv+vmM9LUuV+zevbvXl9B30D6Lg/ZbOLTP4qD91jv0FUkBMATgowDeG3jeZwFsBbBt4Wcn83Up\nFqCTORzaZ3HQfguH9lkctN96hxW9voAQWGv/AACMMa8NPPWstfaIwCUpFAqFQqEQQr9FUmLxPGPM\nIWPMD40xNxtjNvb6ghQKhUKhUNSjryIpkfgsgI8DeBDA4wG8E8BnjDHPstbanl6ZQqFQKBSKSvSc\npBhj3gngLTWHWABXW2t/FCPfWvvRwr/fN8bcBeB+AM8D8KWK01YDwN133x3T5LLGyZMnsWfPnl5f\nRl9B+ywO2m/h0D6Lg/ZbGAq2c3WqLNPrYIIxZhOATQ2HPWCtPVc457UAbrLWRqVtjDGHAfxPa+1f\nVXz/KgAfjpGtUCgUCoUCAPDL1tqPpAjoeSTFWnsUwNG22jPGbIcjRQdqDrsVwP/f3v3HWl3XcRx/\nvrRAhZAVAelkQohZCgZKa6mEliYszdzIyiE0m5Y159oylona2vph5C9cf2Sl+aOB6dA/XEa0nAiR\nUDZDNAVEQzCEAQIqXN798fmc+b2Hcy73eH98v9f7emyf7Zzv93PO/dz3zjnf9/fz+X4/n68C64E3\neqFZZmZm7xaHAceSjqVdUnpPSiskHQO8Hzgf+A5wRt71fETsynXWAFdHxCJJg4C5pGtSNgFjgZ8A\ng4DxEbG3l/8FMzMz66TSe1JadAMws/C8Nkg4FXgsPz4OODI/bgPG59cMBTaSMrtrnaCYmZlVW5/q\nSTEzM7P+o7/Mk2JmZmZ9jJMUMzMzqyQnKQ1IukLSOkl7JC2XdGrZbaoKSadLekjSf/Nijec1qHOD\npI2Sdkv6k6SxZbS1KiTNkbRC0o488/GDksbV1Rkoab6kLZJ2Srpf0vCy2lwFki6X9JSk7bk8Ielz\nhf2O2UHkz95+SfMK2xy3OpLmNliIdnVhv2PWgKSjJP0ux2V3/r5OrKvTpeOBk5Q6kr4E/Jx0V9DH\ngaeAP0oaVmrDqmMQ8E/gCtJEe+1Iuhr4FnAZMBnYRYrfgN5sZMWcDtwKfAL4DGmhzEclHV6ocxMw\nHbiQdNfaUaS70vqzl0gTPU7KZQmwSNIJeb9j1oF8cvV10m9YkePW2NO0X4j2tMI+x6yOpKHAUuBN\n4BzgBNJdt9sKdbp+PIgIl0IBlgM3F54LeBn4btltq1oB9gPn1W3bCFxVeD4E2APMKLu9VSnAsBy7\n0woxehO4oFDn+FxnctntrVIhzak02zE7aJwGA88CZ5Jm1p6XtztujeM1F1jVZJ9j1jguPwb+epA6\nXT4euCelQNJ7SWdsf65tixTZxcAny2pXXyFpNOkMpBi/HcDfcPyKhpJ6obbm55NI0wEU4/YssAHH\nDQBJh0i6CDgCWIZjdjDzgYcjYknd9lNw3Jo5Lg9jvyDp7jwvF/iz1szngSclLcjD2KskXVrb2V3H\nAycp7Q0DDgU2123fTAq2dWwk6eDr+DUhSaSu48cjojbmPRJ4K3+Bi/p93CSdKGkn6Uz2dtLZ7Boc\ns6ZyMncyMKfB7hE4bo0sB2aRhi0uB0YDj+UJQf1Za2wM8A1Sj93ZwC+BWyRdnPd3y/Ggr03mVhbR\n4PoL6zTH7223Ax+l/Xh3M44brAEmkHqfLgTuknRGB/X7dczysh83AZ+N1ias7Ndxi4ji9O1PS1oB\nvAjMoPnSKP06ZqROjhUR8YP8/ClJHyMlLnd38LqW4uaelPa2kGapHVG3fTgHZoN2oE2kD6Dj14Ck\n24BpwKcjYmNh1yZggKQhdS/p93GLiH0RsTYiVkXE90kXgV6JY9bMJOCDwEpJeyXtBaYAV0p6ixSb\ngY5bxyJiO/AcaSkVf9YaewV4pm7bM8Co/LhbjgdOUgrymcdK4Kzattw9fxbwRFnt6isiYh3pg1mM\n3xDSXS39On45QTkfmBoRG+p2rwT20T5u40hf9mW91si+4RBgII5ZM4uBk0jDPRNyeZJ0Zlt7vBfH\nrUOSBgMfJl346c9aY0tJFxAXHU/qgeq244GHew40D7hT0kpgBXAV6WK935bZqKrIY7RjSRkywBhJ\nE4CtEfESqav5GknPk1aR/iHp7qhFJTS3EiTdDnwZOA/YJal2ZrE9It6IiB2S7gDmSdoG7ARuAZZG\nxIpyWl0+ST8CHiHdivw+0srkU4CzHbPGIi20urq4TdIu4LWIeCY/d9zqSPoZ8DDpAHs0cD0pMfm9\nP2tN/QJYKmkOsICUfFxKuu29puvHg7JvY6piAb6ZA7qHlCmfUnabqlJIB4n9pGGxYvl1oc51pDOQ\n3aQFHceW3e6SY9YoXm3AzEKdgaS5VLaQfgQXAsPLbnvJcfsVsDZ/DzcBjwJnOmYtx3EJ+RZkx61p\njO7LB889pLt27gVGO2YHjds04F/5t/7fwNca1OnS8cALDJqZmVkl+ZoUMzMzqyQnKWZmZlZJTlLM\nzMyskpykmJmZWSU5STEzM7NKcpJiZmZmleQkxczMzCrJSYqZmZlVkpMUMzMzqyQnKWbWKyRNkdTW\nYDXZ3vjb+3PZ2sn6UwqveaCn22dmjTlJMbMuywfztsKBvVjaJF1LWjX1QxGxo6RmXgKM62TdpcBI\n0sJpZlYSr4JsZt1hZOHxRaRVZMfx9mrZr0fEPuDV3m5YwfaI2NKZirW2StoDDOjZZplZM+5JMbMu\ni4hXawXYnjbF/wrbdxeGUIYASLpE0jZJ0yWtkbRL0gJJh+d96yRtlXSzpFqyg6QBkm6U9LKk1yUt\nkzSl1TZLGi9piaQdkrZL+rukid0XFTPrKvekmFlvql92/Qjg28AMYAjwYC7bgHOBMcADwOPAwvya\n+cBH8mteAS4AHpF0UkS80EJb7gFWAZcB+4GTgb2t/0tm1lOcpJhZmd4DXB4R6wEk3Q9cDAyPiD3A\nGkl/AaYCCyWNAmYBx0TEpvwe8ySdC8wGrmnhb48CfhoR/8nPW0lwzKwXOEkxszLtriUo2WZgfU5Q\nituG58cnAocCzxWHgEjXjXTqepOCecAdkmYCi4GFEbG2xfcwsx7kJMXMylQ/vBJNttWunxsM7AMm\nkoZoil5v5Q9HxPWS7gGmA9OA6yRdFBGLWnkfM+s5vnDWzPqSf5B6UkZExNq60vKdQxHxfETcHBHn\nkK6Fmd3dDTazd85Jipn1Jh28SnP5+pF7gbskXSDpWEmTJX0vX5fSuUZIh0m6Nd9xNErSp4BTgdVd\naZ+ZdS8P95hZb6q/u+edmEW6QPZG4GjgNWAZ8HAL79EGfAC4ExhBup7lD8B13dA+M+smiuiO3wwz\ns+qStB/4QkQ81OLrfgMcGRFf7JmWmVlHPNxjZv3FfZI2dKaipNMk7QS+0sNtMrMOuCfFzN71JI3J\nD9si4sVO1B9IGkqCNKV/mdP5m/VbTlLMzMyskjzcY2ZmZpXkJMXMzMwqyUmKmZmZVZKTFDMzM6sk\nJylmZmZWSU5SzMzMrJKcpJiZmVklOUkxMzOzSvo/cuXpmtlclR4AAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "solver = ode('cvode', rhseqn, old_api=False, one_step_compute=True)\n", "time = 0.\n", @@ -470,48 +321,33 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "plott length: 1328 , last computation times: [59.2297953049153, 59.28543421477497, 59.34107312463465, 59.39671203449432, 59.452350944353995, 59.50798985421367, 59.56362876407334, 59.61926767393302, 59.67490658379269, 59.730545493652365, 59.78618440351204, 59.84182331337171, 59.897462223231386, 59.95310113309106, 60.0]\n" - ] - } - ], + "outputs": [], "source": [ "print ('plott length:', len(plott), ', last computation times:', plott[-15:]);" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.15+" + "pygments_lexer": "ipython3", + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 4 } diff --git a/ipython_examples/mpl_animation_html.ipynb b/ipython_examples/mpl_animation_html.ipynb index 7e64c8d5..38bffa45 100644 --- a/ipython_examples/mpl_animation_html.ipynb +++ b/ipython_examples/mpl_animation_html.ipynb @@ -11,10 +11,8 @@ }, { "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "import os\n", @@ -39,10 +37,8 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, + "execution_count": null, + "metadata": {}, "outputs": [], "source": [ "def circle(ax, x, y, r, color='r'):\n", @@ -62,9 +58,12 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -371,9 +370,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -468,23 +470,23 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.12.4" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 4 } diff --git a/notebook-requirements.txt b/notebook-requirements.txt new file mode 100644 index 00000000..e8569e75 --- /dev/null +++ b/notebook-requirements.txt @@ -0,0 +1,5 @@ +cython +matplotlib +pandas +ggplot +ipython[notebook] diff --git a/packages/scikits-odes-core/.gitattributes b/packages/scikits-odes-core/.gitattributes new file mode 100644 index 00000000..f2615d28 --- /dev/null +++ b/packages/scikits-odes-core/.gitattributes @@ -0,0 +1 @@ +src/scikits_odes_core/_version.py export-subst diff --git a/packages/scikits-odes-core/LICENSE.txt b/packages/scikits-odes-core/LICENSE.txt new file mode 120000 index 00000000..1ef648f6 --- /dev/null +++ b/packages/scikits-odes-core/LICENSE.txt @@ -0,0 +1 @@ +../../LICENSE.txt \ No newline at end of file diff --git a/packages/scikits-odes-core/MANIFEST.in b/packages/scikits-odes-core/MANIFEST.in new file mode 100644 index 00000000..c7637429 --- /dev/null +++ b/packages/scikits-odes-core/MANIFEST.in @@ -0,0 +1,5 @@ +include tox.ini +prune **/__pycache__ +prune **/*.pyc +prune **/*.swp +prune **/*.swo diff --git a/packages/scikits-odes-core/README.md b/packages/scikits-odes-core/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/scikits-odes-core/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/scikits-odes-core/pyproject.toml b/packages/scikits-odes-core/pyproject.toml new file mode 100644 index 00000000..4898f884 --- /dev/null +++ b/packages/scikits-odes-core/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools"] + +[project] +name = 'scikits-odes-core' +dynamic = ["version"] +description = 'Core support module for scikits.odes' +readme = "README.md" +authors = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +maintainers = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +license = {file = 'LICENSE.txt'} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Topic :: Scientific/Engineering', + 'Programming Language :: Python :: 3', + "Programming Language :: Python :: 3 :: Only", + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', +] + +[project.urls] +Homepage = "http://cage.ugent.be/~bm/progs.html" +Documentation = "https://scikits-odes.readthedocs.io/en/stable/" +Repository = "https://github.com/bmcage/odes" +Issues = "https://github.com/bmcage/odes/issues" +Paper = "https://doi.org/10.21105/joss.00165" +DOI = "https://doi.org/10.5281/zenodo.5511691" diff --git a/packages/scikits-odes-core/setup.cfg b/packages/scikits-odes-core/setup.cfg new file mode 100644 index 00000000..016fbbeb --- /dev/null +++ b/packages/scikits-odes-core/setup.cfg @@ -0,0 +1,7 @@ +[versioneer] +VCS = git +style = pep440 +versionfile_source = src/scikits_odes_core/_version.py +versionfile_build = scikits_odes_core/_version.py +tag_prefix = v +#parentdir_prefix = diff --git a/packages/scikits-odes-core/setup.py b/packages/scikits-odes-core/setup.py new file mode 100644 index 00000000..30331558 --- /dev/null +++ b/packages/scikits-odes-core/setup.py @@ -0,0 +1,10 @@ +import setuptools + +import versioneer + +setuptools.setup( + version = versioneer.get_version(), + packages = setuptools.find_packages('src'), + package_dir = {'': 'src'}, + cmdclass=versioneer.get_cmdclass(), +) diff --git a/packages/scikits-odes-core/src/scikits_odes_core/__init__.py b/packages/scikits-odes-core/src/scikits_odes_core/__init__.py new file mode 100644 index 00000000..f9e3b85e --- /dev/null +++ b/packages/scikits-odes-core/src/scikits_odes_core/__init__.py @@ -0,0 +1,342 @@ +from . import _version +__version__ = _version.get_versions()['version'] + + +class DaeBase: + """ + The interface which DAE solvers must implement. + + Parameters + ---------- + Rfn : + residual function + options : mapping + Additional options for initialization, solver dependent + """ + + integrator_classes = [] + + def __init__(self, Rfn, **options): + raise NotImplementedError('all DAE solvers must implement this') + + def set_options(self, **options): + """ + Set specific options for the solver. + + Calling set_options a second time, normally resets the solver. + """ + raise NotImplementedError('all DAE solvers must implement this') + + def solve(self, tspan, y0, yp0): + """ + Runs the solver. + + Parameters + ---------- + tspan : list/array + A list of times at which the computed value will be returned. + Must contain the start time as first entry. + y0 : list/array + List of initial values + yp0 : list/array + List of initial values of derivatives + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnumXXX) + ``values`` Named tuple with entries array t and array y and array ydot. y will correspond to y_retn value and ydot to yp_retn! + ``errors`` Named tuple with entries t and y and ydot of error + ``roots`` Named tuple with entries array t and array y and array ydot + ``tstop`` Named tuple with entries array t and array y and array ydot + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + ========== ========================================== + Field Meaning + ========== ========================================== + ``flag`` indicating return status of the solver + ``t`` numpy array of times at which the computations were successful + ``y`` numpy array of values corresponding to times t (values of y[i, :] ~ t[i]) + ``yp`` numpy array of derivatives corresponding to times t (values of yp[i, :] ~ t[i]) + ``t_err`` float or None - if recoverable error occurred (for example reached maximum number of allowed iterations), this is the time at which it happened + ``y_err`` numpy array of values corresponding to time t_err + ``yp_err`` numpy array of derivatives corresponding to time t_err + ========== ========================================== + + """ + raise NotImplementedError('all DAE solvers must implement this') + + def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): + """ + Initializes the solver and allocates memory. + + Parameters + ---------- + t0 : number + initial time + y0 : list/array + initial condition for y + yp0 : list/array + initial condition for yp + y_ic0 : numpy array + (optional) returns the calculated consistent initial condition for y + yp_ic0 : numpy array + (optional) returns the calculated consistent initial condition for y + derivated. + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnumXXX) + ``values`` Named tuple with entries t and y and ydot. y will correspond to y_retn value and ydot to yp_retn! + ``errors`` Named tuple with entries t and y and ydot + ``roots`` Named tuple with entries t and y and ydot + ``tstop`` Named tuple with entries t and y and ydot + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` status of the computation (successful or error occurred) + ``t_out`` time, where the solver stopped (when no error occurred, t_out == t) + =========== ========================================== + + """ + raise NotImplementedError('all DAE solvers must implement this') + + def step(self, t, y_retn=None, yp_retn=None): + """ + Method for calling successive next step of the IDA solver to allow + more precise control over the IDA solver. The 'init_step' method has to + be called before the 'step' method. + + A step is done towards time t, and output at t returned. This time can + be higher or lower than the previous time. If option + 'one_step_compute'==True, and the solver supports it, only one internal + solver step is done in the direction of t starting at the current step. + + If old_api=True, the old behavior is used: if t>0.0 then integration is + performed until this time and results at this time are returned in + y_retn; else if if t<0.0 only one internal step is performed towards + time abs(t) and results after this one time step are returned. + + Parameters + ---------- + t : number + y_retn : numpy array (ndim = 1) or None. + (Needs to be preallocated) If not None, will be filled with y at + time t. If None y_retn is not used. + yp_retn : numpy array (ndim = 1) or None. + (Needs to be preallocated) If not None, will be filled with + derivatives of y at time t. If None yp_retn is not used. + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnumXXX) + ``values`` Named tuple with entries t and y and ydot. y will correspond to y_retn value and ydot to yp_retn! + ``errors`` Named tuple with entries t and y and ydot + ``roots`` Named tuple with entries t and y and ydot + ``tstop`` Named tuple with entries t and y and ydot + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` status of the computation (successful or error occurred) + ``t_out`` time, where the solver stopped (when no error occurred, t_out == t) + =========== ========================================== + + """ + raise NotImplementedError('all DAE solvers must implement this') + + +class OdeBase: + """ + The interface which ODE solvers must implement. + + Parameters + ---------- + Rfn : function + A function which computes the required derivatives. The signature + should be ``func(t, y, y_dot, *args, **kwargs)``. Note that *args and + **kwargs handling are solver dependent. + + options : mapping + Additional options for initialization, solver dependent + """ + + integrator_classes = [] + + def __init__(self, Rfn, **options): + raise NotImplementedError('all ODE solvers must implement this') + + def set_options(self, **options): + """ + Set specific options for the solver. + + Calling set_options a second time, normally resets the solver. + """ + raise NotImplementedError('all ODE solvers must implement this') + + def solve(self, tspan, y0): + """ + Runs the solver. + + Parameters + ---------- + tspan : array (or similar) + a list of times at which the computed value will be returned. Must + contain the start time as first entry. + + y0 : array (or similar) + a list of initial values + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnum) + ``values`` Named tuple with entries t and y + ``errors`` Named tuple with entries t and y + ``roots`` Named tuple with entries t and y + ``tstop`` Named tuple with entries t and y + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + ========== ========================================== + Field Meaning + ========== ========================================== + ``flag`` indicating return status of the solver + ``t`` numpy array of times at which the computations were successful + ``y`` numpy array of values corresponding to times t (values of y[i, :] ~ t[i]) + ``t_err`` float or None - if recoverable error occurred (for example reached maximum number of allowed iterations), this is the time at which it happened + ``y_err`` numpy array of values corresponding to time t_err + ========== ========================================== + """ + raise NotImplementedError('all ODE solvers must implement this') + + def init_step(self, t0, y0): + """ + Initializes the solver and allocates memory. + + Parameters + ---------- + t0 : number + initial time + y0 : array + initial condition for y (can be list or numpy array) + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnum) + ``values`` Named tuple with entries t and y + ``errors`` Named tuple with entries t and y + ``roots`` Named tuple with entries t and y + ``tstop`` Named tuple with entries t and y + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + ========== ========================================== + Field Meaning + ========== ========================================== + ``flag`` boolean status of the computation (successful or error occurred) + ``t_out`` initial time + ========== ========================================== + """ + raise NotImplementedError('all ODE solvers must implement this') + + def step(self, t, y_retn=None): + """ + Method for calling successive next step of the ODE solver to allow + more precise control over the solver. The 'init_step' method has to + be called before the 'step' method. + + A step is done towards time t, and output at t returned. This time can + be higher or lower than the previous time. If option + 'one_step_compute'==True, and the solver supports it, only one internal + solver step is done in the direction of t starting at the current step. + + If old_api=True, the old behavior is used: if t>0.0 then integration is + performed until this time and results at this time are returned in + y_retn if t<0.0 only one internal step is performed towards time abs(t) + and results after this one time step are returned + + Parameters + ---------- + t : number + + y_retn : numpy vector (ndim = 1) + in which the computed value will be stored (needs to be + preallocated). If None y_retn is not used. + + Returns + ------- + old_api is False : namedtuple + namedtuple with the following attributes + + =========== ========================================== + Field Meaning + =========== ========================================== + ``flag`` An integer flag (StatusEnum) + ``values`` Named tuple with entries t and y + ``errors`` Named tuple with entries t and y + ``roots`` Named tuple with entries t and y + ``tstop`` Named tuple with entries t and y + ``message`` String with message in case of an error + =========== ========================================== + + old_api is True : tuple + tuple with the following elements in order + + ========== ========================================== + Field Meaning + ========== ========================================== + ``flag`` status of the computation (successful or error occurred) + ``t_out`` time, where the solver stopped (when no error occurred, t_out == t) + ========== ========================================== + """ + raise NotImplementedError('all ODE solvers must implement this') diff --git a/packages/scikits-odes-core/src/scikits_odes_core/_version.py b/packages/scikits-odes-core/src/scikits_odes_core/_version.py new file mode 100644 index 00000000..3dbadf78 --- /dev/null +++ b/packages/scikits-odes-core/src/scikits_odes_core/_version.py @@ -0,0 +1,683 @@ + +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + git_date = "$Format:%ci$" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "v" + cfg.parentdir_prefix = "None" + cfg.versionfile_source = "src/scikits_odes_core/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} diff --git a/packages/scikits-odes-core/tox.ini b/packages/scikits-odes-core/tox.ini new file mode 100644 index 00000000..22d8dba8 --- /dev/null +++ b/packages/scikits-odes-core/tox.ini @@ -0,0 +1,33 @@ +[tox] +envlist = py37,py38,py39,py310,py311,py312,check-manifest,checkreadme +setenv = LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 + +[testenv] +passenv= + PIP_VERBOSE + PYTHONFAULTHANDLER +deps = + pytest +commands = + pytest {posargs} +changedir = + {toxworkdir} + +[testenv:check-manifest] +deps= + check-manifest +setenv = + CHECK_MANIFEST=true +commands= + check-manifest +changedir = + {toxinidir} + +[testenv:checkreadme] +deps= + readme_renderer + setuptools +commands= + python setup.py check -s -r +changedir = + {toxinidir} diff --git a/packages/scikits-odes-core/versioneer.py b/packages/scikits-odes-core/versioneer.py new file mode 100644 index 00000000..1e3753e6 --- /dev/null +++ b/packages/scikits-odes-core/versioneer.py @@ -0,0 +1,2277 @@ + +# Version: 0.29 + +"""The Versioneer - like a rocketeer, but for versions. + +The Versioneer +============== + +* like a rocketeer, but for versions! +* https://github.com/python-versioneer/python-versioneer +* Brian Warner +* License: Public Domain (Unlicense) +* Compatible with: Python 3.7, 3.8, 3.9, 3.10, 3.11 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url] + +This is a tool for managing a recorded version number in setuptools-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. + + +## Quick Install + +Versioneer provides two installation modes. The "classic" vendored mode installs +a copy of versioneer into your repository. The experimental build-time dependency mode +is intended to allow you to skip this step and simplify the process of upgrading. + +### Vendored mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) + * Note that you will need to add `tomli; python_version < "3.11"` to your + build-time dependencies if you use `pyproject.toml` +* run `versioneer install --vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +### Build-time dependency mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) +* add `versioneer` (with `[toml]` extra, if configuring in `pyproject.toml`) + to the `requires` key of the `build-system` table in `pyproject.toml`: + ```toml + [build-system] + requires = ["setuptools", "versioneer[toml]"] + build-backend = "setuptools.build_meta" + ``` +* run `versioneer install --no-vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +## Version Identifiers + +Source trees come from a variety of places: + +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI + +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: + +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step + +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes). + +The version identifier is used for multiple purposes: + +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball + +## Theory of Operation + +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. + +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. + +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. + +## Installation + +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. + +## Version-String Flavors + +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. + +Both functions return a dictionary with different flavors of version +information: + +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. + +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". + +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. + +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None + +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". + +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. + +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions + +## Styles + +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. + +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". + +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. + +## Debugging + +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). + +## Known Limitations + +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/python-versioneer/python-versioneer/issues). + +### Subprojects + +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: + +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other languages) in subdirectories. + +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). + +`pip install --editable .` should work correctly. `setup.py install` might +work too. + +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. + +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. + +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. + +### Editable installs with setuptools <= 18.5 + +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. + +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. + +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. + +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. + + +## Updating Versioneer + +To upgrade your project to a new release of Versioneer, do the following: + +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg` and `pyproject.toml`, if necessary, + to include any new configuration settings indicated by the release notes. + See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install --[no-]vendor` in your source tree, to replace + `SRC/_version.py` +* commit any changed files + +## Future Directions + +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. + +## Similar projects + +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer +* [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools + plugin + +## License + +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the "Unlicense", as described in +https://unlicense.org/. + +[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer + +""" +# pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring +# pylint:disable=missing-class-docstring,too-many-branches,too-many-statements +# pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error +# pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with +# pylint:disable=attribute-defined-outside-init,too-many-arguments + +import configparser +import errno +import json +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import NoReturn +import functools + +have_tomllib = True +if sys.version_info >= (3, 11): + import tomllib +else: + try: + import tomli as tomllib + except ImportError: + have_tomllib = False + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + versionfile_source: str + versionfile_build: Optional[str] + parentdir_prefix: Optional[str] + verbose: Optional[bool] + + +def get_root() -> str: + """Get the project root directory. + + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + my_path = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(my_path)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir and "VERSIONEER_PEP518" not in globals(): + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py)) + except NameError: + pass + return root + + +def get_config_from_root(root: str) -> VersioneerConfig: + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise OSError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + root_pth = Path(root) + pyproject_toml = root_pth / "pyproject.toml" + setup_cfg = root_pth / "setup.cfg" + section: Union[Dict[str, Any], configparser.SectionProxy, None] = None + if pyproject_toml.exists() and have_tomllib: + try: + with open(pyproject_toml, 'rb') as fobj: + pp = tomllib.load(fobj) + section = pp['tool']['versioneer'] + except (tomllib.TOMLDecodeError, KeyError) as e: + print(f"Failed to load config from {pyproject_toml}: {e}") + print("Try to load it from setup.cfg") + if not section: + parser = configparser.ConfigParser() + with open(setup_cfg) as cfg_file: + parser.read_file(cfg_file) + parser.get("versioneer", "VCS") # raise error if missing + + section = parser["versioneer"] + + # `cast`` really shouldn't be used, but its simplest for the + # common VersioneerConfig users at the moment. We verify against + # `None` values elsewhere where it matters + + cfg = VersioneerConfig() + cfg.VCS = section['VCS'] + cfg.style = section.get("style", "") + cfg.versionfile_source = cast(str, section.get("versionfile_source")) + cfg.versionfile_build = section.get("versionfile_build") + cfg.tag_prefix = cast(str, section.get("tag_prefix")) + if cfg.tag_prefix in ("''", '""', None): + cfg.tag_prefix = "" + cfg.parentdir_prefix = section.get("parentdir_prefix") + if isinstance(section, configparser.SectionProxy): + # Make sure configparser translates to bool + cfg.verbose = section.getboolean("verbose") + else: + cfg.verbose = section.get("verbose") + + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + HANDLERS.setdefault(vcs, {})[method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +LONG_VERSION_PY['git'] = r''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%%d.dev%%d" %% (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%%d" %% (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%%d" %% pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(versionfile_source: str, ipy: Optional[str]) -> None: + """Git-specific installation logic for Versioneer. + + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [versionfile_source] + if ipy: + files.append(ipy) + if "VERSIONEER_PEP518" not in globals(): + try: + my_path = __file__ + if my_path.endswith((".pyc", ".pyo")): + my_path = os.path.splitext(my_path)[0] + ".py" + versioneer_file = os.path.relpath(my_path) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + with open(".gitattributes", "r") as fobj: + for line in fobj: + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + break + except OSError: + pass + if not present: + with open(".gitattributes", "a+") as fobj: + fobj.write(f"{versionfile_source} export-subst\n") + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.29) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +%s +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename: str) -> Dict[str, Any]: + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except OSError: + raise NotThisMethod("unable to read _version.py") + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename: str, versions: Dict[str, Any]) -> None: + """Write the given version number to the given _version.py file.""" + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set %s to '%s'" % (filename, versions["version"])) + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose: bool = False) -> Dict[str, Any]: + """Get the project version from whatever source is available. + + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or bool(cfg.verbose) # `bool()` used to avoid `None` + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print("got version from file %s %s" % (versionfile_abs, ver)) + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} + + +def get_version() -> str: + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(cmdclass: Optional[Dict[str, Any]] = None): + """Get the custom setuptools subclasses used by Versioneer. + + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/python-versioneer/python-versioneer/issues/52 + + cmds = {} if cmdclass is None else cmdclass.copy() + + # we add "version" to setuptools + from setuptools import Command + + class cmd_version(Command): + description = "report generated version string" + user_options: List[Tuple[str, str, str]] = [] + boolean_options: List[str] = [] + + def initialize_options(self) -> None: + pass + + def finalize_options(self) -> None: + pass + + def run(self) -> None: + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version + + # we override "build_py" in setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # pip install -e . and setuptool/editable_wheel will invoke build_py + # but the build_py command is not expected to copy any files. + + # we override different "build_py" commands for both environments + if 'build_py' in cmds: + _build_py: Any = cmds['build_py'] + else: + from setuptools.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + if getattr(self, "editable_mode", False): + # During editable installs `.py` and data files are + # not copied to build_lib + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py + + if 'build_ext' in cmds: + _build_ext: Any = cmds['build_ext'] + else: + from setuptools.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if not cfg.versionfile_build: + return + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + if not os.path.exists(target_versionfile): + print(f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py.") + return + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe # type: ignore + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if 'py2exe' in sys.modules: # py2exe enabled? + try: + from py2exe.setuptools_buildexe import py2exe as _py2exe # type: ignore + except ImportError: + from py2exe.distutils_buildexe import py2exe as _py2exe # type: ignore + + class cmd_py2exe(_py2exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["py2exe"] = cmd_py2exe + + # sdist farms its file list building out to egg_info + if 'egg_info' in cmds: + _egg_info: Any = cmds['egg_info'] + else: + from setuptools.command.egg_info import egg_info as _egg_info + + class cmd_egg_info(_egg_info): + def find_sources(self) -> None: + # egg_info.find_sources builds the manifest list and writes it + # in one shot + super().find_sources() + + # Modify the filelist and normalize it + root = get_root() + cfg = get_config_from_root(root) + self.filelist.append('versioneer.py') + if cfg.versionfile_source: + # There are rare cases where versionfile_source might not be + # included by default, so we must be explicit + self.filelist.append(cfg.versionfile_source) + self.filelist.sort() + self.filelist.remove_duplicates() + + # The write method is hidden in the manifest_maker instance that + # generated the filelist and was thrown away + # We will instead replicate their final normalization (to unicode, + # and POSIX-style paths) + from setuptools import unicode_utils + normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') + for f in self.filelist.files] + + manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') + with open(manifest_filename, 'w') as fobj: + fobj.write('\n'.join(normalized)) + + cmds['egg_info'] = cmd_egg_info + + # we override different "sdist" commands for both environments + if 'sdist' in cmds: + _sdist: Any = cmds['sdist'] + else: + from setuptools.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self) -> None: + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir: str, files: List[str]) -> None: + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- + +You will also need to edit your setup.py to use the results: + + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) + +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = + +""" + +OLD_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + +INIT_PY_SNIPPET = """ +from . import {0} +__version__ = {0}.get_versions()['version'] +""" + + +def do_setup() -> int: + """Do main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (OSError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (OSError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + maybe_ipy: Optional[str] = ipy + if os.path.exists(ipy): + try: + with open(ipy, "r") as f: + old = f.read() + except OSError: + old = "" + module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] + snippet = INIT_PY_SNIPPET.format(module) + if OLD_SNIPPET in old: + print(" replacing boilerplate in %s" % ipy) + with open(ipy, "w") as f: + f.write(old.replace(OLD_SNIPPET, snippet)) + elif snippet not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(snippet) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + maybe_ipy = None + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(cfg.versionfile_source, maybe_ipy) + return 0 + + +def scan_setup_py() -> int: + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py", "r") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +def setup_command() -> NoReturn: + """Set up Versioneer and exit with appropriate error code.""" + errors = do_setup() + errors += scan_setup_py() + sys.exit(1 if errors else 0) + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + setup_command() diff --git a/packages/scikits-odes-daepack/LICENSE.txt b/packages/scikits-odes-daepack/LICENSE.txt new file mode 120000 index 00000000..1ef648f6 --- /dev/null +++ b/packages/scikits-odes-daepack/LICENSE.txt @@ -0,0 +1 @@ +../../LICENSE.txt \ No newline at end of file diff --git a/packages/scikits-odes-daepack/README.md b/packages/scikits-odes-daepack/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/scikits-odes-daepack/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/scikits-odes-daepack/meson.build b/packages/scikits-odes-daepack/meson.build new file mode 100644 index 00000000..cb1224dc --- /dev/null +++ b/packages/scikits-odes-daepack/meson.build @@ -0,0 +1,99 @@ +project('scikits-odes-daepack', + ['c', 'fortran'], + version : '0.1', + meson_version: '>= 1.1.0', + default_options : [ + 'warning_level=1', + 'buildtype=release' + ]) + +py = import('python').find_installation(pure: false) +py_dep = py.dependency() + +incdir_numpy = run_command(py, + ['-c', 'import numpy; print(numpy.get_include())'], + check : true +).stdout().strip() + +incdir_f2py = run_command(py, + ['-c', 'import numpy.f2py; print(numpy.f2py.get_include())'], + check : true +).stdout().strip() + +fortranobject_c = incdir_f2py / 'fortranobject.c' + +py_pkg_name = 'scikits_odes_daepack' +py_pkg_dir = 'src' / py_pkg_name +daepack_dir = py_pkg_dir / 'daepack' + +inc_np_all = include_directories(incdir_numpy, incdir_f2py) + +ddaspk_source = custom_target('ddaspkmodule.c', + input : [py_pkg_dir / 'ddaspk.pyf'], + output : ['ddaspkmodule.c', 'ddaspk-f2pywrappers.f'], + command : [py, '-m', 'numpy.f2py', '@INPUT@'], +) + +lsodi_source = custom_target('lsodimodule.c', + input : [py_pkg_dir / 'lsodi.pyf'], + output : ['lsodimodule.c', 'lsodi-f2pywrappers.f'], + command : [py, '-m', 'numpy.f2py', '@INPUT@'], +) + +daepack_dep = declare_dependency( + sources : [ + daepack_dir / 'ainvg.f', + daepack_dir / 'cfode.f', + daepack_dir / 'daux.f', + daepack_dir / 'ddaspk.f', + daepack_dir / 'dlinpk.f', + daepack_dir / 'ewset.f', + daepack_dir / 'intdy.f', + daepack_dir / 'lsodi.f', + daepack_dir / 'prepji.f', + daepack_dir / 'solsy.f', + daepack_dir / 'stodi.f', + daepack_dir / 'vnorm.f', + daepack_dir / 'xerrwv.f', + ]) + +py.extension_module('ddaspk', + [ + ddaspk_source, + fortranobject_c, + ], + include_directories: [ + inc_np_all, + ], + dependencies : [ + py_dep, + daepack_dep, + ], + install : true, + subdir : py_pkg_name, +) + +py.extension_module('lsodi', + [ + lsodi_source, + fortranobject_c, + ], + include_directories: [ + inc_np_all, + ], + dependencies : [ + py_dep, + daepack_dep, + ], + install : true, + subdir : py_pkg_name, +) + +py.install_sources( + [ + py_pkg_dir / '__init__.py', + py_pkg_dir / 'ddaspkint.py', + py_pkg_dir / 'lsodiint.py', + ], + subdir : py_pkg_name, +) diff --git a/packages/scikits-odes-daepack/pyproject.toml b/packages/scikits-odes-daepack/pyproject.toml new file mode 100644 index 00000000..e461e55c --- /dev/null +++ b/packages/scikits-odes-daepack/pyproject.toml @@ -0,0 +1,45 @@ +[build-system] +build-backend = 'mesonpy' +requires = ['meson-python', 'numpy'] + +[project] +name = 'scikits-odes-daepack' +version = "0.1" +description = 'Wrapper around daepack' +readme = "README.md" +authors = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +maintainers = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +license = {file = 'LICENSE.txt'} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Topic :: Scientific/Engineering', + 'Programming Language :: Python :: 3', + "Programming Language :: Python :: 3 :: Only", + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', +] +dependencies = ["numpy", "scikits-odes-core"] + +[project.urls] +Homepage = "http://cage.ugent.be/~bm/progs.html" +Documentation = "https://scikits-odes.readthedocs.io/en/stable/" +Repository = "https://github.com/bmcage/odes" +Issues = "https://github.com/bmcage/odes/issues" +Paper = "https://doi.org/10.21105/joss.00165" +DOI = "https://doi.org/10.5281/zenodo.5511691" + +[tool.meson-python.args] +setup = [ + '-Dpython.install_env=auto', # This should mean that venvs are autodetected +] diff --git a/scikits/odes/tests/__init__.py b/packages/scikits-odes-daepack/src/scikits_odes_daepack/__init__.py similarity index 100% rename from scikits/odes/tests/__init__.py rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/__init__.py diff --git a/scikits/odes/daepack/ainvg.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ainvg.f similarity index 100% rename from scikits/odes/daepack/ainvg.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ainvg.f diff --git a/scikits/odes/daepack/cfode.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/cfode.f similarity index 100% rename from scikits/odes/daepack/cfode.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/cfode.f diff --git a/scikits/odes/daepack/daux.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/daux.f similarity index 100% rename from scikits/odes/daepack/daux.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/daux.f diff --git a/scikits/odes/daepack/ddaspk.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ddaspk.f similarity index 100% rename from scikits/odes/daepack/ddaspk.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ddaspk.f diff --git a/scikits/odes/daepack/dlinpk.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/dlinpk.f similarity index 100% rename from scikits/odes/daepack/dlinpk.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/dlinpk.f diff --git a/scikits/odes/daepack/ewset.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ewset.f similarity index 100% rename from scikits/odes/daepack/ewset.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/ewset.f diff --git a/scikits/odes/daepack/intdy.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/intdy.f similarity index 100% rename from scikits/odes/daepack/intdy.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/intdy.f diff --git a/scikits/odes/daepack/lsodi.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/lsodi.f similarity index 100% rename from scikits/odes/daepack/lsodi.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/lsodi.f diff --git a/scikits/odes/daepack/prepji.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/prepji.f similarity index 100% rename from scikits/odes/daepack/prepji.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/prepji.f diff --git a/scikits/odes/daepack/solsy.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/solsy.f similarity index 100% rename from scikits/odes/daepack/solsy.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/solsy.f diff --git a/scikits/odes/daepack/stodi.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/stodi.f similarity index 100% rename from scikits/odes/daepack/stodi.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/stodi.f diff --git a/scikits/odes/daepack/vnorm.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/vnorm.f similarity index 100% rename from scikits/odes/daepack/vnorm.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/vnorm.f diff --git a/scikits/odes/daepack/xerrwv.f b/packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/xerrwv.f similarity index 100% rename from scikits/odes/daepack/xerrwv.f rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/daepack/xerrwv.f diff --git a/scikits/odes/ddaspk.pyf b/packages/scikits-odes-daepack/src/scikits_odes_daepack/ddaspk.pyf similarity index 100% rename from scikits/odes/ddaspk.pyf rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/ddaspk.pyf diff --git a/scikits/odes/ddaspkint.py b/packages/scikits-odes-daepack/src/scikits_odes_daepack/ddaspkint.py similarity index 97% rename from scikits/odes/ddaspkint.py rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/ddaspkint.py index 308d54f6..dbaf56bd 100644 --- a/scikits/odes/ddaspkint.py +++ b/packages/scikits-odes-daepack/src/scikits_odes_daepack/ddaspkint.py @@ -109,26 +109,22 @@ 'algebraic_vars_idx' array. """ -from __future__ import print_function - __all__ = ['ddaspk'] -__version__ = "$Id$" __docformat__ = "restructuredtext en" -from numpy import asarray, array, zeros, sin, int32, isscalar, empty from copy import copy -from .dae import DaeBase -import re, sys +import re +import sys + +from numpy import asarray, array, zeros, sin, int32, isscalar, empty +from scikits_odes_core import DaeBase + +from .ddaspk import ddaspk as _runner + class ddaspk(DaeBase): - try: - from .ddaspk import ddaspk as _runner - except ImportError: - print(sys.exc_info()[1]) - _runner = None - # _runner = getattr(_ddaspk,'ddaspk',None) name = 'ddaspk' - + _runner = _runner messages = { 1: 'A step was successfully taken in the ' 'intermediate-output mode. The code has not ' 'yet reached TOUT.', @@ -212,7 +208,7 @@ def set_options(self, **options): for (key, value) in options.items(): self.options[key.lower()] = value self.initialized = False - + def _init_data(self): self.rtol = self.options['rtol'] self.atol = self.options['atol'] @@ -255,7 +251,7 @@ def _init_data(self): self.excl_algvar_err = self.options['exclude_algvar_from_error'] self.success = 1 - + def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): """ See dae.DaeBase """ @@ -264,7 +260,7 @@ def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): self.yp0 = yp0 self.t = t0 self._reset(len(y0), self.options['jacfn'] is not None) - + if self.compute_initcond: if self.first_step <= 0.: first_step = 1e-18 @@ -385,15 +381,15 @@ def _jacFn(self, t, y, yp, cj): def solve(self, tspan, y0, yp0, hook_fn = None): """ See dae.DaeBase """ - + t_retn = empty([len(tspan), ], float) y_retn = empty([len(tspan), len(y0)], float) yp_retn = empty([len(tspan), len(y0)], float) - + y_ic0_retn = empty(len(y0), float) yp_ic0_retn = empty(len(y0), float) tinit = self.init_step(tspan[0], y0, yp0, y_ic0_retn, yp_ic0_retn) - + t_retn[0] = tinit y_retn[0,:] = y0[:] yp_retn[0, :] = yp0[:] @@ -445,8 +441,8 @@ def step(self, t, y_retn, yp_retn = None): y_retn[:] = self.y[:] if yp_retn is not None: yp_retn[:] = self.yp[:] - + return self.flag, self.t -if ddaspk._runner: - DaeBase.integrator_classes.append(ddaspk) + +DaeBase.integrator_classes.append(ddaspk) diff --git a/scikits/odes/lsodi.pyf b/packages/scikits-odes-daepack/src/scikits_odes_daepack/lsodi.pyf similarity index 100% rename from scikits/odes/lsodi.pyf rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/lsodi.pyf diff --git a/scikits/odes/lsodiint.py b/packages/scikits-odes-daepack/src/scikits_odes_daepack/lsodiint.py similarity index 96% rename from scikits/odes/lsodiint.py rename to packages/scikits-odes-daepack/src/scikits_odes_daepack/lsodiint.py index 013e439a..4a6a624e 100644 --- a/scikits/odes/lsodiint.py +++ b/packages/scikits-odes-daepack/src/scikits_odes_daepack/lsodiint.py @@ -71,29 +71,24 @@ def adda(t, y, ml, mu, p, nrowp): Source: http://www.netlib.org/ode/lsodi.f """ - -from __future__ import print_function - __all__ = ['lsodi'] -__version__ = "$Id$" __docformat__ = "restructuredtext en" -from numpy import asarray, array, zeros, sin, int32, isscalar, empty from copy import copy -from .dae import DaeBase -import re, sys +import re +import sys -class lsodi(DaeBase): - try: - from .lsodi import lsodi as _runner - from .lsodi import intdy as _intdy - except ImportError: - print(sys.exc_info()[1]) - _runner = None - _intdy = None +from numpy import asarray, array, zeros, sin, int32, isscalar, empty +from scikits_odes_core import DaeBase + +from .lsodi import lsodi as _runner +from .lsodi import intdy as _intdy - name = 'lsodi' +class lsodi(DaeBase): + name = 'lsodi' + _runner = _runner + _intdy = _intdy messages = {2 : 'lsodi was successful.', -1 : 'excess work done on this call (check all inputs).', -2 : 'excess accuracy requested (tolerances too small).', @@ -171,7 +166,7 @@ def _init_data(self): else: raise ValueError('Unknown init cond calculation method %s' %( self.options['compute_initcond'])) - + if self.options['adda_func'] is None: raise ValueError('adda_func is required for lsodi algorithm!') @@ -186,7 +181,7 @@ def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): self.yp0 = yp0 self.t = t0 self._reset(len(y0), self.jac is not None) - + if self.compute_initcond: if self.first_step <= 0.: first_step = 1e-18 @@ -288,11 +283,11 @@ def _jacFn(self, t, y, yp, cj): def solve(self, tspan, y0, yp0, hook_fn = None): """ See dae.DaeBase """ - + t_retn = empty([len(tspan), ], float) y_retn = empty([len(tspan), len(y0)], float) yp_retn = empty([len(tspan), len(y0)], float) - + y_ic0_retn = empty(len(y0), float) yp_ic0_retn = empty(len(y0), float) tinit = self.init_step(tspan[0], y0, yp0, y_ic0_retn, yp_ic0_retn) @@ -335,7 +330,7 @@ def __run(self, *args): if istate in [-1,-4,-5] : print('lsodi: present residual is', y1prime_tmp) self.success = 0 - + if self.success: yh = self.rwork[20:] order = 1 @@ -376,5 +371,4 @@ def step(self, t, y_retn, yp_retn = None): yp_retn[:] = self.yp[:] return self.call_args[4], self.t -if lsodi._runner: - DaeBase.integrator_classes.append(lsodi) +DaeBase.integrator_classes.append(lsodi) diff --git a/packages/scikits-odes-daepack/tox.ini b/packages/scikits-odes-daepack/tox.ini new file mode 100644 index 00000000..5e6118cd --- /dev/null +++ b/packages/scikits-odes-daepack/tox.ini @@ -0,0 +1,12 @@ +[tox] +envlist = py37,py38,py39,py310,py311,py312 +setenv = LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 + +[testenv] +passenv= + PIP_VERBOSE + PYTHONFAULTHANDLER +deps = + pytest +commands = + pytest {posargs} diff --git a/packages/scikits-odes-sundials/.gitattributes b/packages/scikits-odes-sundials/.gitattributes new file mode 100644 index 00000000..9ce4a7ea --- /dev/null +++ b/packages/scikits-odes-sundials/.gitattributes @@ -0,0 +1 @@ +src/scikits_odes_sundials/_version.py export-subst diff --git a/packages/scikits-odes-sundials/LICENSE.txt b/packages/scikits-odes-sundials/LICENSE.txt new file mode 120000 index 00000000..1ef648f6 --- /dev/null +++ b/packages/scikits-odes-sundials/LICENSE.txt @@ -0,0 +1 @@ +../../LICENSE.txt \ No newline at end of file diff --git a/packages/scikits-odes-sundials/MANIFEST.in b/packages/scikits-odes-sundials/MANIFEST.in new file mode 100644 index 00000000..7699e6dc --- /dev/null +++ b/packages/scikits-odes-sundials/MANIFEST.in @@ -0,0 +1,8 @@ +recursive-include src *.pyx *.pxd +include tox.ini +include setup_build.py +include local-requirements.txt +prune **/__pycache__ +prune **/*.pyc +prune **/*.swp +prune **/*.swo diff --git a/packages/scikits-odes-sundials/README.md b/packages/scikits-odes-sundials/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/scikits-odes-sundials/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/scikits-odes-sundials/local-requirements.txt b/packages/scikits-odes-sundials/local-requirements.txt new file mode 100644 index 00000000..718a2e71 --- /dev/null +++ b/packages/scikits-odes-sundials/local-requirements.txt @@ -0,0 +1 @@ +../scikits-odes-core/ diff --git a/packages/scikits-odes-sundials/pyproject.toml b/packages/scikits-odes-sundials/pyproject.toml new file mode 100644 index 00000000..d1d83dc4 --- /dev/null +++ b/packages/scikits-odes-sundials/pyproject.toml @@ -0,0 +1,39 @@ +[build-system] +requires = ["setuptools", "numpy", "cython<3", "pkgconfig"] + +[project] +name = 'scikits-odes-sundials' +dynamic = ["version"] +description = 'Sundials wrapper module for scikits.odes' +readme = "README.md" +authors = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +maintainers = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +license = {file = 'LICENSE.txt'} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Topic :: Scientific/Engineering', + 'Programming Language :: Python :: 3', + "Programming Language :: Python :: 3 :: Only", + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', +] +dependencies = ["numpy", "scikits-odes-core"] + +[project.urls] +Homepage = "http://cage.ugent.be/~bm/progs.html" +Documentation = "https://scikits-odes.readthedocs.io/en/stable/" +Repository = "https://github.com/bmcage/odes" +Issues = "https://github.com/bmcage/odes/issues" +Paper = "https://doi.org/10.21105/joss.00165" +DOI = "https://doi.org/10.5281/zenodo.5511691" diff --git a/packages/scikits-odes-sundials/setup.cfg b/packages/scikits-odes-sundials/setup.cfg new file mode 100644 index 00000000..f6039a88 --- /dev/null +++ b/packages/scikits-odes-sundials/setup.cfg @@ -0,0 +1,7 @@ +[versioneer] +VCS = git +style = pep440 +versionfile_source = src/scikits_odes_sundials/_version.py +versionfile_build = scikits_odes_sundials/_version.py +tag_prefix = v +#parentdir_prefix = diff --git a/packages/scikits-odes-sundials/setup.py b/packages/scikits-odes-sundials/setup.py new file mode 100644 index 00000000..c386df7b --- /dev/null +++ b/packages/scikits-odes-sundials/setup.py @@ -0,0 +1,19 @@ +import setuptools + +import versioneer + +from setup_build import build_ext + +cmdclass = {} +cmdclass["build_ext"] = build_ext + +setuptools.setup( + version = versioneer.get_version(), + packages = setuptools.find_packages('src'), + package_dir = {'': 'src'}, + cmdclass=versioneer.get_cmdclass(cmdclass), + # To trick build into running build_ext + ext_modules = [ + setuptools.Extension('scikits_odes_sundials.x',['x.c']) + ], +) diff --git a/setup_build.py b/packages/scikits-odes-sundials/setup_build.py similarity index 88% rename from setup_build.py rename to packages/scikits-odes-sundials/setup_build.py index 0ece2adf..3eba78e0 100644 --- a/setup_build.py +++ b/packages/scikits-odes-sundials/setup_build.py @@ -1,13 +1,12 @@ - import io import os from os.path import join -from distutils.log import info import sys +import textwrap -from numpy.distutils.command.build_ext import build_ext as _build_ext -from numpy.distutils.system_info import get_info -from numpy.distutils.extension import Extension +from distutils.log import info +from setuptools import Extension +from distutils.command.build_ext import build_ext as _build_ext PKGCONFIG_CVODE = 'sundials-cvode-serial' PKGCONFIG_IDA = 'sundials-ida-serial' @@ -26,22 +25,42 @@ def write_pxi(filename, definitions): return filename +def check_macro_true(cmd, symbol, headers=None, include_dirs=None): + """ + Copied from numpy.distutils.command.config:config.check_macro_true, checks + if macro is true + """ + cmd._check_compiler() + body = textwrap.dedent(""" + int main(void) + { + #if %s + #else + #error false or undefined macro + #endif + ; + return 0; + }""") % (symbol,) + + return cmd.try_compile(body, headers, include_dirs) + + def check_macro_def(cmd, symbol, headers=None, include_dirs=None): """ Based on numpy.distutils.command.config:config.check_macro_true, checks if macro is defined or not """ cmd._check_compiler() - body = """ -int main(void) -{ -#ifdef %s -#else -#error undefined macro -#endif - ; - return 0; -}""" % (symbol,) + body = textwrap.dedent(""" + int main(void) + { + #ifdef %s + #else + #error undefined macro + #endif + ; + return 0; + }""") % (symbol,) return cmd.try_compile(body, headers, include_dirs) @@ -55,24 +74,27 @@ def get_sundials_config_pxi(include_dirs, dist): something... """ SUNDIALS_CONFIG_H = "sundials/sundials_config.h" - BASE_PATH = join('scikits', 'odes', 'sundials') + BASE_PATH = 'src/scikits_odes_sundials' config_cmd = dist.get_command_obj("config") # Get float type - if config_cmd.check_macro_true( + if check_macro_true( + config_cmd, "SUNDIALS_DOUBLE_PRECISION", headers=[SUNDIALS_CONFIG_H], include_dirs=include_dirs ): SUNDIALS_FLOAT_TYPE = '"double"' info("Found sundials built with double precision.") - elif config_cmd.check_macro_true( + elif check_macro_true( + config_cmd, "SUNDIALS_SINGLE_PRECISION", headers=[SUNDIALS_CONFIG_H], include_dirs=include_dirs ): SUNDIALS_FLOAT_TYPE = '"single"' info("Found sundials built with single precision.") - elif config_cmd.check_macro_true( + elif check_macro_true( + config_cmd, "SUNDIALS_EXTENDED_PRECISION", headers=[SUNDIALS_CONFIG_H], include_dirs=include_dirs ): @@ -84,13 +106,15 @@ def get_sundials_config_pxi(include_dirs, dist): info("Failed to find sundials precision, falling back to double...") # Get index (int) type - if config_cmd.check_macro_true( + if check_macro_true( + config_cmd, "SUNDIALS_INT32_T", headers=[SUNDIALS_CONFIG_H], include_dirs=include_dirs ): SUNDIALS_INDEX_SIZE = '"int32"' info("Found sundials built with int32.") - elif config_cmd.check_macro_true( + elif check_macro_true( + config_cmd, "SUNDIALS_INT64_T", headers=[SUNDIALS_CONFIG_H], include_dirs=include_dirs ): @@ -130,8 +154,9 @@ class build_ext(_build_ext): Cython building, and C compilation. """ def _get_cython_ext(self): - base_path = join('scikits', 'odes', 'sundials') - base_module = "scikits.odes.sundials" + import numpy + base_path = 'src/scikits_odes_sundials' + base_module = "scikits_odes_sundials" SUNDIALS_LIBRARIES = [] CVODE_LIBRARIES = [] @@ -145,7 +170,8 @@ def _get_cython_ext(self): CVODES_LIBRARY_DIRS = [] IDAS_LIBRARY_DIRS = [] - SUNDIALS_INCLUDE_DIRS = [] + # numpy is required for all the extensions + SUNDIALS_INCLUDE_DIRS = [numpy.get_include()] CVODE_INCLUDE_DIRS = [] IDA_INCLUDE_DIRS = [] CVODES_INCLUDE_DIRS = [] @@ -260,19 +286,6 @@ def _get_cython_ext(self): if not CVODES_LIBRARIES: CVODES_LIBRARIES.append('sundials_cvodes') - if has_lapack: - lapack_opt = get_info('lapack_opt', notfound_action=2) - - if lapack_opt: - SUNDIALS_INCLUDE_DIRS.extend(lapack_opt.get('include_dirs',[])) - SUNDIALS_LIBRARY_DIRS.extend(lapack_opt.get('library_dirs',[])) - SUNDIALS_LIBRARIES.extend(lapack_opt.get('libraries',[])) - info('Found LAPACK paths via lapack_opt ...') - else: - info('LAPACK was not found, but SUNDIALS compiled against ' - 'lapack, check your numpy installation' - ) - CVODE_LIBRARIES.extend(SUNDIALS_LIBRARIES) IDA_LIBRARIES.extend(SUNDIALS_LIBRARIES) CVODES_LIBRARIES.extend(SUNDIALS_LIBRARIES) @@ -328,9 +341,11 @@ def _get_cython_ext(self): def run(self): """ Distutils calls this method to run the command """ from Cython.Build import cythonize - self.extensions.extend(cythonize( - self._get_cython_ext(), - compiler_directives= {'language_level' : sys.version_info[0]}) - ) + self.extensions = cythonize( + self._get_cython_ext(), + compiler_directives={ + 'language_level': 3, + }, + ) _build_ext.run(self) # actually do the build diff --git a/scikits/odes/sundials/__init__.py b/packages/scikits-odes-sundials/src/scikits_odes_sundials/__init__.py similarity index 95% rename from scikits/odes/sundials/__init__.py rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/__init__.py index afadc0ae..11022d2c 100644 --- a/scikits/odes/sundials/__init__.py +++ b/packages/scikits-odes-sundials/src/scikits_odes_sundials/__init__.py @@ -1,8 +1,11 @@ -# -# odes - Extra ode integrators -# +""" +SUNDIALS wrapper +""" import inspect +from . import _version +__version__ = _version.get_versions()['version'] + class CVODESolveException(Exception): """Base class for exceptions raised by ``CVODE.validate_flags``.""" diff --git a/packages/scikits-odes-sundials/src/scikits_odes_sundials/_version.py b/packages/scikits-odes-sundials/src/scikits_odes_sundials/_version.py new file mode 100644 index 00000000..a88b57c0 --- /dev/null +++ b/packages/scikits-odes-sundials/src/scikits_odes_sundials/_version.py @@ -0,0 +1,683 @@ + +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + git_date = "$Format:%ci$" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "v" + cfg.parentdir_prefix = "None" + cfg.versionfile_source = "src/scikits_odes_sundials/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} diff --git a/scikits/odes/sundials/c_cvode.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_cvode.pxd similarity index 100% rename from scikits/odes/sundials/c_cvode.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_cvode.pxd diff --git a/scikits/odes/sundials/c_cvodes.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_cvodes.pxd similarity index 100% rename from scikits/odes/sundials/c_cvodes.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_cvodes.pxd diff --git a/scikits/odes/sundials/c_ida.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_ida.pxd similarity index 100% rename from scikits/odes/sundials/c_ida.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_ida.pxd diff --git a/scikits/odes/sundials/c_idas.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_idas.pxd similarity index 100% rename from scikits/odes/sundials/c_idas.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_idas.pxd diff --git a/scikits/odes/sundials/c_nvector_serial.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_nvector_serial.pxd similarity index 100% rename from scikits/odes/sundials/c_nvector_serial.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_nvector_serial.pxd diff --git a/scikits/odes/sundials/c_sundials.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sundials.pxd similarity index 100% rename from scikits/odes/sundials/c_sundials.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sundials.pxd diff --git a/scikits/odes/sundials/c_sunlinsol.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunlinsol.pxd similarity index 100% rename from scikits/odes/sundials/c_sunlinsol.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunlinsol.pxd diff --git a/scikits/odes/sundials/c_sunmatrix.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunmatrix.pxd similarity index 100% rename from scikits/odes/sundials/c_sunmatrix.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunmatrix.pxd diff --git a/scikits/odes/sundials/c_sunnonlinsol.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunnonlinsol.pxd similarity index 100% rename from scikits/odes/sundials/c_sunnonlinsol.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/c_sunnonlinsol.pxd diff --git a/scikits/odes/sundials/common_defs.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/common_defs.pxd similarity index 100% rename from scikits/odes/sundials/common_defs.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/common_defs.pxd diff --git a/scikits/odes/sundials/common_defs.pyx b/packages/scikits-odes-sundials/src/scikits_odes_sundials/common_defs.pyx similarity index 100% rename from scikits/odes/sundials/common_defs.pyx rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/common_defs.pyx diff --git a/scikits/odes/sundials/cvode.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/cvode.pxd similarity index 100% rename from scikits/odes/sundials/cvode.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/cvode.pxd diff --git a/scikits/odes/sundials/cvode.pyx b/packages/scikits-odes-sundials/src/scikits_odes_sundials/cvode.pyx similarity index 100% rename from scikits/odes/sundials/cvode.pyx rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/cvode.pyx diff --git a/scikits/odes/sundials/cvodes.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/cvodes.pxd similarity index 100% rename from scikits/odes/sundials/cvodes.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/cvodes.pxd diff --git a/scikits/odes/sundials/cvodes.pyx b/packages/scikits-odes-sundials/src/scikits_odes_sundials/cvodes.pyx similarity index 100% rename from scikits/odes/sundials/cvodes.pyx rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/cvodes.pyx diff --git a/scikits/odes/sundials/ida.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/ida.pxd similarity index 100% rename from scikits/odes/sundials/ida.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/ida.pxd diff --git a/scikits/odes/sundials/ida.pyx b/packages/scikits-odes-sundials/src/scikits_odes_sundials/ida.pyx similarity index 100% rename from scikits/odes/sundials/ida.pyx rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/ida.pyx diff --git a/scikits/odes/sundials/idas.pxd b/packages/scikits-odes-sundials/src/scikits_odes_sundials/idas.pxd similarity index 100% rename from scikits/odes/sundials/idas.pxd rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/idas.pxd diff --git a/scikits/odes/sundials/idas.pyx b/packages/scikits-odes-sundials/src/scikits_odes_sundials/idas.pyx similarity index 100% rename from scikits/odes/sundials/idas.pyx rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/idas.pyx diff --git a/scikits/odes/info.py b/packages/scikits-odes-sundials/src/scikits_odes_sundials/tests/__init__.py similarity index 100% rename from scikits/odes/info.py rename to packages/scikits-odes-sundials/src/scikits_odes_sundials/tests/__init__.py diff --git a/packages/scikits-odes-sundials/src/scikits_odes_sundials/tests/test_helpers.py b/packages/scikits-odes-sundials/src/scikits_odes_sundials/tests/test_helpers.py new file mode 100644 index 00000000..dfe14d14 --- /dev/null +++ b/packages/scikits-odes-sundials/src/scikits_odes_sundials/tests/test_helpers.py @@ -0,0 +1,36 @@ +from scikits_odes_sundials import _get_num_args + + +class TestGetNumArgs: + """ + Check the correct number for `_get_num_args` + """ + def test_functions(self): + def _func(a, b, c): + pass + assert _get_num_args(_func) == 3 + + def _func(a, b, c=None): + pass + # kwd args should not make a difference + assert _get_num_args(_func) == 3 + + def test_methods(self): + class C: + @ classmethod + def class_method(cls, a, b): + pass + + @ staticmethod + def static_method(a, b): + pass + + def method(self, a, b): + pass + + # self should not be counted + assert _get_num_args(C.method) == 2 + # static methods should also work + assert _get_num_args(C.static_method) == 2 + # class methods should also work + assert _get_num_args(C.class_method) == 2 diff --git a/packages/scikits-odes-sundials/tox.ini b/packages/scikits-odes-sundials/tox.ini new file mode 100644 index 00000000..598c288c --- /dev/null +++ b/packages/scikits-odes-sundials/tox.ini @@ -0,0 +1,42 @@ +[tox] +envlist = py37,py38,py39,py310,py311,py312,check-manifest,checkreadme +setenv = LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 + +[testenv] +passenv= + SUNDIALS_DIR + SUNDIALS_LIBDIR + SUNDIALS_INCLUDEDIR + LD_LIBRARY_PATH + LIBRARY_PATH + CPATH + PIP_VERBOSE + PYTHONFAULTHANDLER +deps = + pytest + -r local-requirements.txt +commands = + pytest --pyargs scikits_odes_sundials {posargs} +changedir = + {toxworkdir} + +[testenv:check-manifest] +deps= + check-manifest + -r local-requirements.txt +setenv = + CHECK_MANIFEST=true +commands= + check-manifest +changedir = + {toxinidir} + +[testenv:checkreadme] +deps= + -r local-requirements.txt + readme_renderer + setuptools +commands= + python setup.py check -s -r +changedir = + {toxinidir} diff --git a/packages/scikits-odes-sundials/versioneer.py b/packages/scikits-odes-sundials/versioneer.py new file mode 100644 index 00000000..1e3753e6 --- /dev/null +++ b/packages/scikits-odes-sundials/versioneer.py @@ -0,0 +1,2277 @@ + +# Version: 0.29 + +"""The Versioneer - like a rocketeer, but for versions. + +The Versioneer +============== + +* like a rocketeer, but for versions! +* https://github.com/python-versioneer/python-versioneer +* Brian Warner +* License: Public Domain (Unlicense) +* Compatible with: Python 3.7, 3.8, 3.9, 3.10, 3.11 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url] + +This is a tool for managing a recorded version number in setuptools-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. + + +## Quick Install + +Versioneer provides two installation modes. The "classic" vendored mode installs +a copy of versioneer into your repository. The experimental build-time dependency mode +is intended to allow you to skip this step and simplify the process of upgrading. + +### Vendored mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) + * Note that you will need to add `tomli; python_version < "3.11"` to your + build-time dependencies if you use `pyproject.toml` +* run `versioneer install --vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +### Build-time dependency mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) +* add `versioneer` (with `[toml]` extra, if configuring in `pyproject.toml`) + to the `requires` key of the `build-system` table in `pyproject.toml`: + ```toml + [build-system] + requires = ["setuptools", "versioneer[toml]"] + build-backend = "setuptools.build_meta" + ``` +* run `versioneer install --no-vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +## Version Identifiers + +Source trees come from a variety of places: + +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI + +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: + +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step + +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes). + +The version identifier is used for multiple purposes: + +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball + +## Theory of Operation + +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. + +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. + +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. + +## Installation + +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. + +## Version-String Flavors + +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. + +Both functions return a dictionary with different flavors of version +information: + +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. + +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". + +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. + +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None + +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". + +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. + +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions + +## Styles + +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. + +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". + +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. + +## Debugging + +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). + +## Known Limitations + +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/python-versioneer/python-versioneer/issues). + +### Subprojects + +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: + +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other languages) in subdirectories. + +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). + +`pip install --editable .` should work correctly. `setup.py install` might +work too. + +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. + +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. + +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. + +### Editable installs with setuptools <= 18.5 + +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. + +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. + +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. + +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. + + +## Updating Versioneer + +To upgrade your project to a new release of Versioneer, do the following: + +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg` and `pyproject.toml`, if necessary, + to include any new configuration settings indicated by the release notes. + See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install --[no-]vendor` in your source tree, to replace + `SRC/_version.py` +* commit any changed files + +## Future Directions + +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. + +## Similar projects + +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer +* [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools + plugin + +## License + +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the "Unlicense", as described in +https://unlicense.org/. + +[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer + +""" +# pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring +# pylint:disable=missing-class-docstring,too-many-branches,too-many-statements +# pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error +# pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with +# pylint:disable=attribute-defined-outside-init,too-many-arguments + +import configparser +import errno +import json +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import NoReturn +import functools + +have_tomllib = True +if sys.version_info >= (3, 11): + import tomllib +else: + try: + import tomli as tomllib + except ImportError: + have_tomllib = False + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + versionfile_source: str + versionfile_build: Optional[str] + parentdir_prefix: Optional[str] + verbose: Optional[bool] + + +def get_root() -> str: + """Get the project root directory. + + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + my_path = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(my_path)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir and "VERSIONEER_PEP518" not in globals(): + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py)) + except NameError: + pass + return root + + +def get_config_from_root(root: str) -> VersioneerConfig: + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise OSError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + root_pth = Path(root) + pyproject_toml = root_pth / "pyproject.toml" + setup_cfg = root_pth / "setup.cfg" + section: Union[Dict[str, Any], configparser.SectionProxy, None] = None + if pyproject_toml.exists() and have_tomllib: + try: + with open(pyproject_toml, 'rb') as fobj: + pp = tomllib.load(fobj) + section = pp['tool']['versioneer'] + except (tomllib.TOMLDecodeError, KeyError) as e: + print(f"Failed to load config from {pyproject_toml}: {e}") + print("Try to load it from setup.cfg") + if not section: + parser = configparser.ConfigParser() + with open(setup_cfg) as cfg_file: + parser.read_file(cfg_file) + parser.get("versioneer", "VCS") # raise error if missing + + section = parser["versioneer"] + + # `cast`` really shouldn't be used, but its simplest for the + # common VersioneerConfig users at the moment. We verify against + # `None` values elsewhere where it matters + + cfg = VersioneerConfig() + cfg.VCS = section['VCS'] + cfg.style = section.get("style", "") + cfg.versionfile_source = cast(str, section.get("versionfile_source")) + cfg.versionfile_build = section.get("versionfile_build") + cfg.tag_prefix = cast(str, section.get("tag_prefix")) + if cfg.tag_prefix in ("''", '""', None): + cfg.tag_prefix = "" + cfg.parentdir_prefix = section.get("parentdir_prefix") + if isinstance(section, configparser.SectionProxy): + # Make sure configparser translates to bool + cfg.verbose = section.getboolean("verbose") + else: + cfg.verbose = section.get("verbose") + + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + HANDLERS.setdefault(vcs, {})[method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +LONG_VERSION_PY['git'] = r''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%%d.dev%%d" %% (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%%d" %% (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%%d" %% pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(versionfile_source: str, ipy: Optional[str]) -> None: + """Git-specific installation logic for Versioneer. + + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [versionfile_source] + if ipy: + files.append(ipy) + if "VERSIONEER_PEP518" not in globals(): + try: + my_path = __file__ + if my_path.endswith((".pyc", ".pyo")): + my_path = os.path.splitext(my_path)[0] + ".py" + versioneer_file = os.path.relpath(my_path) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + with open(".gitattributes", "r") as fobj: + for line in fobj: + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + break + except OSError: + pass + if not present: + with open(".gitattributes", "a+") as fobj: + fobj.write(f"{versionfile_source} export-subst\n") + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.29) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +%s +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename: str) -> Dict[str, Any]: + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except OSError: + raise NotThisMethod("unable to read _version.py") + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename: str, versions: Dict[str, Any]) -> None: + """Write the given version number to the given _version.py file.""" + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set %s to '%s'" % (filename, versions["version"])) + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose: bool = False) -> Dict[str, Any]: + """Get the project version from whatever source is available. + + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or bool(cfg.verbose) # `bool()` used to avoid `None` + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print("got version from file %s %s" % (versionfile_abs, ver)) + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} + + +def get_version() -> str: + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(cmdclass: Optional[Dict[str, Any]] = None): + """Get the custom setuptools subclasses used by Versioneer. + + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/python-versioneer/python-versioneer/issues/52 + + cmds = {} if cmdclass is None else cmdclass.copy() + + # we add "version" to setuptools + from setuptools import Command + + class cmd_version(Command): + description = "report generated version string" + user_options: List[Tuple[str, str, str]] = [] + boolean_options: List[str] = [] + + def initialize_options(self) -> None: + pass + + def finalize_options(self) -> None: + pass + + def run(self) -> None: + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version + + # we override "build_py" in setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # pip install -e . and setuptool/editable_wheel will invoke build_py + # but the build_py command is not expected to copy any files. + + # we override different "build_py" commands for both environments + if 'build_py' in cmds: + _build_py: Any = cmds['build_py'] + else: + from setuptools.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + if getattr(self, "editable_mode", False): + # During editable installs `.py` and data files are + # not copied to build_lib + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py + + if 'build_ext' in cmds: + _build_ext: Any = cmds['build_ext'] + else: + from setuptools.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if not cfg.versionfile_build: + return + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + if not os.path.exists(target_versionfile): + print(f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py.") + return + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe # type: ignore + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if 'py2exe' in sys.modules: # py2exe enabled? + try: + from py2exe.setuptools_buildexe import py2exe as _py2exe # type: ignore + except ImportError: + from py2exe.distutils_buildexe import py2exe as _py2exe # type: ignore + + class cmd_py2exe(_py2exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["py2exe"] = cmd_py2exe + + # sdist farms its file list building out to egg_info + if 'egg_info' in cmds: + _egg_info: Any = cmds['egg_info'] + else: + from setuptools.command.egg_info import egg_info as _egg_info + + class cmd_egg_info(_egg_info): + def find_sources(self) -> None: + # egg_info.find_sources builds the manifest list and writes it + # in one shot + super().find_sources() + + # Modify the filelist and normalize it + root = get_root() + cfg = get_config_from_root(root) + self.filelist.append('versioneer.py') + if cfg.versionfile_source: + # There are rare cases where versionfile_source might not be + # included by default, so we must be explicit + self.filelist.append(cfg.versionfile_source) + self.filelist.sort() + self.filelist.remove_duplicates() + + # The write method is hidden in the manifest_maker instance that + # generated the filelist and was thrown away + # We will instead replicate their final normalization (to unicode, + # and POSIX-style paths) + from setuptools import unicode_utils + normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') + for f in self.filelist.files] + + manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') + with open(manifest_filename, 'w') as fobj: + fobj.write('\n'.join(normalized)) + + cmds['egg_info'] = cmd_egg_info + + # we override different "sdist" commands for both environments + if 'sdist' in cmds: + _sdist: Any = cmds['sdist'] + else: + from setuptools.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self) -> None: + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir: str, files: List[str]) -> None: + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- + +You will also need to edit your setup.py to use the results: + + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) + +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = + +""" + +OLD_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + +INIT_PY_SNIPPET = """ +from . import {0} +__version__ = {0}.get_versions()['version'] +""" + + +def do_setup() -> int: + """Do main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (OSError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (OSError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + maybe_ipy: Optional[str] = ipy + if os.path.exists(ipy): + try: + with open(ipy, "r") as f: + old = f.read() + except OSError: + old = "" + module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] + snippet = INIT_PY_SNIPPET.format(module) + if OLD_SNIPPET in old: + print(" replacing boilerplate in %s" % ipy) + with open(ipy, "w") as f: + f.write(old.replace(OLD_SNIPPET, snippet)) + elif snippet not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(snippet) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + maybe_ipy = None + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(cfg.versionfile_source, maybe_ipy) + return 0 + + +def scan_setup_py() -> int: + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py", "r") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +def setup_command() -> NoReturn: + """Set up Versioneer and exit with appropriate error code.""" + errors = do_setup() + errors += scan_setup_py() + sys.exit(1 if errors else 0) + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + setup_command() diff --git a/packages/scikits-odes/.gitattributes b/packages/scikits-odes/.gitattributes new file mode 100644 index 00000000..d7127d59 --- /dev/null +++ b/packages/scikits-odes/.gitattributes @@ -0,0 +1 @@ +src/scikits_odes/_version.py export-subst diff --git a/packages/scikits-odes/LICENSE.txt b/packages/scikits-odes/LICENSE.txt new file mode 120000 index 00000000..1ef648f6 --- /dev/null +++ b/packages/scikits-odes/LICENSE.txt @@ -0,0 +1 @@ +../../LICENSE.txt \ No newline at end of file diff --git a/packages/scikits-odes/MANIFEST.in b/packages/scikits-odes/MANIFEST.in new file mode 100644 index 00000000..c20b035b --- /dev/null +++ b/packages/scikits-odes/MANIFEST.in @@ -0,0 +1,6 @@ +prune **/__pycache__ +prune **/*.pyc +prune **/*.swp +prune **/*.swo +include tox.ini +include local-requirements.txt diff --git a/packages/scikits-odes/README.md b/packages/scikits-odes/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/scikits-odes/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/packages/scikits-odes/local-requirements.txt b/packages/scikits-odes/local-requirements.txt new file mode 100644 index 00000000..1cfad808 --- /dev/null +++ b/packages/scikits-odes/local-requirements.txt @@ -0,0 +1,4 @@ +# this is to link to the other packages in the repository +../scikits-odes-core/ +../scikits-odes-daepack/ +../scikits-odes-sundials/ diff --git a/packages/scikits-odes/pyproject.toml b/packages/scikits-odes/pyproject.toml new file mode 100644 index 00000000..db92c4a5 --- /dev/null +++ b/packages/scikits-odes/pyproject.toml @@ -0,0 +1,44 @@ +[build-system] +requires = ["setuptools"] + +[project] +name = 'scikits-odes' +dynamic = ["version"] +description = 'A python module for ordinary differential equation and differential algebraic equation solvers' +readme = "README.md" +authors = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +maintainers = [ + {name = 'B. Malengier', email = 'benny.malengier@gmail.org'}, +] +license = {file = 'LICENSE.txt'} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Topic :: Scientific/Engineering', + 'Programming Language :: Python :: 3', + "Programming Language :: Python :: 3 :: Only", + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', +] +dependencies = [ + "scipy", + "scikits-odes-core", + "scikits-odes-daepack", + "scikits-odes-sundials", +] + +[project.urls] +Homepage = "http://cage.ugent.be/~bm/progs.html" +Documentation = "https://scikits-odes.readthedocs.io/en/stable/" +Repository = "https://github.com/bmcage/odes" +Issues = "https://github.com/bmcage/odes/issues" +Paper = "https://doi.org/10.21105/joss.00165" +DOI = "https://doi.org/10.5281/zenodo.5511691" diff --git a/packages/scikits-odes/setup.cfg b/packages/scikits-odes/setup.cfg new file mode 100644 index 00000000..e81a48ff --- /dev/null +++ b/packages/scikits-odes/setup.cfg @@ -0,0 +1,7 @@ +[versioneer] +VCS = git +style = pep440 +versionfile_source = src/scikits_odes/_version.py +versionfile_build = scikits_odes/_version.py +tag_prefix = v +#parentdir_prefix = diff --git a/packages/scikits-odes/setup.py b/packages/scikits-odes/setup.py new file mode 100644 index 00000000..04a3cf47 --- /dev/null +++ b/packages/scikits-odes/setup.py @@ -0,0 +1,10 @@ +import setuptools + +import versioneer + +setuptools.setup( + version = versioneer.get_version(), + packages = setuptools.find_namespace_packages('src'), + package_dir = {'': 'src'}, + cmdclass=versioneer.get_cmdclass(), +) diff --git a/scikits/odes/__init__.py b/packages/scikits-odes/src/scikits/odes/__init__.py similarity index 65% rename from scikits/odes/__init__.py rename to packages/scikits-odes/src/scikits/odes/__init__.py index 2ec57215..105e4d96 100644 --- a/scikits/odes/__init__.py +++ b/packages/scikits-odes/src/scikits/odes/__init__.py @@ -14,14 +14,6 @@ .. _SUNDIALS: https://computation.llnl.gov/casc/sundials/main.html """ -from .dae import * -from .ode import * - -__all__ = ['test'] + [s for s in dir() if not s.startswith('_')] - -try: - from numpy.testing import Tester - test = Tester().test -except: - #testing could not be loaded, old numpy version - pass +# Compat with older versions +from scikits_odes import * +from scikits_odes import __version__ diff --git a/packages/scikits-odes/src/scikits/odes/dae.py b/packages/scikits-odes/src/scikits/odes/dae.py new file mode 100644 index 00000000..f0844a3e --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/dae.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes.dae import * diff --git a/packages/scikits-odes/src/scikits/odes/ddaspk.py b/packages/scikits-odes/src/scikits/odes/ddaspk.py new file mode 100644 index 00000000..238f2b62 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/ddaspk.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_daepack.ddaspk import * diff --git a/packages/scikits-odes/src/scikits/odes/ddaspkint.py b/packages/scikits-odes/src/scikits/odes/ddaspkint.py new file mode 100644 index 00000000..d17f377e --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/ddaspkint.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_daepack.ddaspkint import * diff --git a/packages/scikits-odes/src/scikits/odes/dopri5.py b/packages/scikits-odes/src/scikits/odes/dopri5.py new file mode 100644 index 00000000..f33b0c1d --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/dopri5.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes.dopri5 import * diff --git a/packages/scikits-odes/src/scikits/odes/lsodi.py b/packages/scikits-odes/src/scikits/odes/lsodi.py new file mode 100644 index 00000000..0036a481 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/lsodi.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_daepack.lsodi import * diff --git a/packages/scikits-odes/src/scikits/odes/lsodiint.py b/packages/scikits-odes/src/scikits/odes/lsodiint.py new file mode 100644 index 00000000..a7417124 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/lsodiint.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_daepack.lsodiint import * diff --git a/packages/scikits-odes/src/scikits/odes/ode.py b/packages/scikits-odes/src/scikits/odes/ode.py new file mode 100644 index 00000000..97e0d87e --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/ode.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes.odes import * diff --git a/packages/scikits-odes/src/scikits/odes/odeint.py b/packages/scikits-odes/src/scikits/odes/odeint.py new file mode 100644 index 00000000..8d213015 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/odeint.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes.odeint import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/__init__.py b/packages/scikits-odes/src/scikits/odes/sundials/__init__.py new file mode 100644 index 00000000..7187e2a9 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/__init__.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/common_defs.py b/packages/scikits-odes/src/scikits/odes/sundials/common_defs.py new file mode 100644 index 00000000..8943a8f1 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/common_defs.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials.common_defs import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/cvode.py b/packages/scikits-odes/src/scikits/odes/sundials/cvode.py new file mode 100644 index 00000000..b1cb9db6 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/cvode.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials.cvode import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/cvodes.py b/packages/scikits-odes/src/scikits/odes/sundials/cvodes.py new file mode 100644 index 00000000..31a905e0 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/cvodes.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials.cvodes import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/ida.py b/packages/scikits-odes/src/scikits/odes/sundials/ida.py new file mode 100644 index 00000000..28ac9093 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/ida.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials.ida import * diff --git a/packages/scikits-odes/src/scikits/odes/sundials/idas.py b/packages/scikits-odes/src/scikits/odes/sundials/idas.py new file mode 100644 index 00000000..d4775f93 --- /dev/null +++ b/packages/scikits-odes/src/scikits/odes/sundials/idas.py @@ -0,0 +1,2 @@ +# Compat with older versions +from scikits_odes_sundials.idas import * diff --git a/packages/scikits-odes/src/scikits/odes/tests/__init__.py b/packages/scikits-odes/src/scikits/odes/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scikits/odes/tests/test_dae.py b/packages/scikits-odes/src/scikits/odes/tests/test_dae.py similarity index 91% rename from scikits/odes/tests/test_dae.py rename to packages/scikits-odes/src/scikits/odes/tests/test_dae.py index 7598f438..f429c89f 100644 --- a/scikits/odes/tests/test_dae.py +++ b/packages/scikits-odes/src/scikits/odes/tests/test_dae.py @@ -1,56 +1,18 @@ # Authors: B. Malengier, russel (scipy trac) -from __future__ import print_function - """ Tests for differential algebraic equation solvers. """ -import numpy import platform -import scipy.sparse as sparse - -from numpy import (arange, zeros, array, dot, sqrt, cos, sin, allclose, - empty) +from numpy import zeros, array, dot, sqrt, cos, sin, allclose, empty from numpy.testing import TestCase +import scipy.sparse as sparse from scipy.integrate import ode as Iode -from scikits.odes import ode,dae -from scikits.odes.sundials import _get_num_args -from scikits.odes.sundials.common_defs import DTYPE +from scikits_odes_sundials import _get_num_args -class TestGetNumArgs(TestCase): - """ - Check the correct number for `_get_num_args` - """ - def test_functions(self): - def _func(a, b, c): - pass - assert _get_num_args(_func) == 3 - - def _func(a, b, c=None): - pass - # kwd args should not make a difference - assert _get_num_args(_func) == 3 - - def test_methods(self): - class C: - @ classmethod - def class_method(cls, a, b): - pass - - @ staticmethod - def static_method(a, b): - pass - - def method(self, a, b): - pass - - # self should not be counted - assert _get_num_args(C.method) == 2 - # static methods should also work - assert _get_num_args(C.static_method) == 2 - # class methods should also work - assert _get_num_args(C.class_method) == 2 +from scikits.odes import ode,dae +from scikits.odes.sundials.common_defs import DTYPE class TestDae(TestCase): diff --git a/scikits/odes/tests/test_dop.py b/packages/scikits-odes/src/scikits/odes/tests/test_dop.py similarity index 100% rename from scikits/odes/tests/test_dop.py rename to packages/scikits-odes/src/scikits/odes/tests/test_dop.py diff --git a/scikits/odes/tests/test_get_info.py b/packages/scikits-odes/src/scikits/odes/tests/test_get_info.py similarity index 100% rename from scikits/odes/tests/test_get_info.py rename to packages/scikits-odes/src/scikits/odes/tests/test_get_info.py diff --git a/scikits/odes/tests/test_odeint.py b/packages/scikits-odes/src/scikits/odes/tests/test_odeint.py similarity index 100% rename from scikits/odes/tests/test_odeint.py rename to packages/scikits-odes/src/scikits/odes/tests/test_odeint.py diff --git a/scikits/odes/tests/test_on_funcs.py b/packages/scikits-odes/src/scikits/odes/tests/test_on_funcs.py similarity index 100% rename from scikits/odes/tests/test_on_funcs.py rename to packages/scikits-odes/src/scikits/odes/tests/test_on_funcs.py diff --git a/scikits/odes/tests/test_on_funcs_ida.py b/packages/scikits-odes/src/scikits/odes/tests/test_on_funcs_ida.py similarity index 100% rename from scikits/odes/tests/test_on_funcs_ida.py rename to packages/scikits-odes/src/scikits/odes/tests/test_on_funcs_ida.py diff --git a/scikits/odes/tests/test_user_return_vals_cvode.py b/packages/scikits-odes/src/scikits/odes/tests/test_user_return_vals_cvode.py similarity index 100% rename from scikits/odes/tests/test_user_return_vals_cvode.py rename to packages/scikits-odes/src/scikits/odes/tests/test_user_return_vals_cvode.py diff --git a/scikits/odes/tests/test_user_return_vals_ida.py b/packages/scikits-odes/src/scikits/odes/tests/test_user_return_vals_ida.py similarity index 100% rename from scikits/odes/tests/test_user_return_vals_ida.py rename to packages/scikits-odes/src/scikits/odes/tests/test_user_return_vals_ida.py diff --git a/packages/scikits-odes/src/scikits_odes/__init__.py b/packages/scikits-odes/src/scikits_odes/__init__.py new file mode 100644 index 00000000..eeb575bc --- /dev/null +++ b/packages/scikits-odes/src/scikits_odes/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +""" +scikits-odes is a scikit offering a cython wrapper around some extra ode/dae +solvers, so they can mature outside of scipy. + +It offers wrappers around the following solvers from `SUNDIALS`_ + * CVODE + * IDA + +It additionally offers wrappers around + * `ddaspk ` (included) + * `lsodi ` (included) + +.. _SUNDIALS: https://computation.llnl.gov/casc/sundials/main.html +""" + +from .dae import dae +from .ode import ode +from . import _version +__version__ = _version.get_versions()['version'] diff --git a/packages/scikits-odes/src/scikits_odes/_version.py b/packages/scikits-odes/src/scikits_odes/_version.py new file mode 100644 index 00000000..6569ec5e --- /dev/null +++ b/packages/scikits-odes/src/scikits_odes/_version.py @@ -0,0 +1,683 @@ + +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + git_date = "$Format:%ci$" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "v" + cfg.parentdir_prefix = "None" + cfg.versionfile_source = "src/scikits_odes/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} diff --git a/scikits/odes/dae.py b/packages/scikits-odes/src/scikits_odes/dae.py similarity index 56% rename from scikits/odes/dae.py rename to packages/scikits-odes/src/scikits_odes/dae.py index 50791429..e4288d91 100644 --- a/scikits/odes/dae.py +++ b/packages/scikits-odes/src/scikits_odes/dae.py @@ -21,184 +21,13 @@ G(t,y,y') = 0 """ - -from __future__ import print_function - __all__ = ['dae'] -__version__ = "$Id$" __docformat__ = "restructuredtext en" +import re +import sys -from numpy import asarray, array, zeros, sin, int32, isscalar, empty -from copy import copy -import re, sys - -class DaeBase(object): - """ - The interface which DAE solvers must implement. - - Parameters - ---------- - Rfn : - residual function - options : mapping - Additional options for initialization, solver dependent - """ - - integrator_classes = [] - - def __init__(self, Rfn, **options): - raise NotImplementedError('all DAE solvers must implement this') - - def set_options(self, **options): - """ - Set specific options for the solver. - - Calling set_options a second time, normally resets the solver. - """ - raise NotImplementedError('all DAE solvers must implement this') - - def solve(self, tspan, y0, yp0): - """ - Runs the solver. - - Parameters - ---------- - tspan : list/array - A list of times at which the computed value will be returned. Must contain the start time as first entry. - y0 : list/array - List of initial values - yp0 : list/array - List of initial values of derivatives - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnumXXX) - ``values`` Named tuple with entries array t and array y and array ydot. y will correspond to y_retn value and ydot to yp_retn! - ``errors`` Named tuple with entries t and y and ydot of error - ``roots`` Named tuple with entries array t and array y and array ydot - ``tstop`` Named tuple with entries array t and array y and array ydot - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - ========== ========================================== - Field Meaning - ========== ========================================== - ``flag`` indicating return status of the solver - ``t`` numpy array of times at which the computations were successful - ``y`` numpy array of values corresponding to times t (values of y[i, :] ~ t[i]) - ``yp`` numpy array of derivatives corresponding to times t (values of yp[i, :] ~ t[i]) - ``t_err`` float or None - if recoverable error occured (for example reached maximum number of allowed iterations), this is the time at which it happened - ``y_err`` numpy array of values corresponding to time t_err - ``yp_err`` numpy array of derivatives corresponding to time t_err - ========== ========================================== - - """ - raise NotImplementedError('all DAE solvers must implement this') - - def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): - """ - Initializes the solver and allocates memory. - - Parameters - ---------- - t0 : number - initial time - y0 : list/array - initial condition for y - yp0 : list/array - initial condition for yp - y_ic0 : numpy array - (optional) returns the calculated consistent initial condition for y - yp_ic0 : numpy array - (optional) returns the calculated consistent initial condition for y derivated. - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnumXXX) - ``values`` Named tuple with entries t and y and ydot. y will correspond to y_retn value and ydot to yp_retn! - ``errors`` Named tuple with entries t and y and ydot - ``roots`` Named tuple with entries t and y and ydot - ``tstop`` Named tuple with entries t and y and ydot - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` status of the computation (successful or error occured) - ``t_out`` time, where the solver stopped (when no error occured, t_out == t) - =========== ========================================== - - """ - raise NotImplementedError('all DAE solvers must implement this') +from scikits_odes_core import DaeBase - def step(self, t, y_retn=None, yp_retn=None): - """ - Method for calling successive next step of the IDA solver to allow - more precise control over the IDA solver. The 'init_step' method has to - be called before the 'step' method. - - A step is done towards time t, and output at t returned. This time can be higher or lower than the previous time. If option 'one_step_compute'==True, and the solver supports it, only one internal solver step is done in the direction of t starting at the current step. - - If old_api=True, the old behavior is used: if t>0.0 then integration is - performed until this time and results at this time are returned in - y_retn; else if if t<0.0 only one internal step is perfomed towards time - abs(t) and results after this one time step are returned. - - Parameters - ---------- - t : number - y_retn : numpy array (ndim = 1) or None. - (Needs to be preallocated) If not None, will be filled with y at time t. If None y_retn is not used. - yp_retn : numpy array (ndim = 1) or None. - (Needs to be preallocated) If not None, will be filled with derivatives of y at time t. If None yp_retn is not used. - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnumXXX) - ``values`` Named tuple with entries t and y and ydot. y will correspond to y_retn value and ydot to yp_retn! - ``errors`` Named tuple with entries t and y and ydot - ``roots`` Named tuple with entries t and y and ydot - ``tstop`` Named tuple with entries t and y and ydot - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` status of the computation (successful or error occured) - ``t_out`` time, where the solver stopped (when no error occured, t_out == t) - =========== ========================================== - - """ - raise NotImplementedError('all DAE solvers must implement this') #------------------------------------------------------------------------------ # User interface @@ -208,7 +37,10 @@ class dae(object): """ A generic interface class to differential algebraic equations. - Define equation res = G(t,y,y') which can eg be G = f(y,t) - A y' when solving A y' = f(y,t), and where (optional) jac is the jacobian matrix of the nonlinear system see fortran source code), so d res/dy + scaling * d res/dy' or d res/dy depending on the backend. + Define equation res = G(t,y,y') which can eg be G = f(y,t) - A y' when + solving A y' = f(y,t), and where (optional) jac is the jacobian matrix of + the nonlinear system see fortran source code), so d res/dy + scaling * d + res/dy' or d res/dy depending on the backend. Parameters ---------- @@ -226,8 +58,10 @@ class dae(object): x : independent variable, eg the time, float y : array of n unknowns in x yprime : dy/dx array of n unknowns in x, dimension = dim(y) - return_residual: array that must be updated with the value of the residuals, so G(t,y,y'). The dimension is equal to dim(y) - return value: integer, 0 for success. It is not guaranteed that a solver takes this status into account + return_residual: array that must be updated with the value of the + residuals, so G(t,y,y'). The dimension is equal to dim(y) + return value: integer, 0 for success. It is not guaranteed that a solver + takes this status into account Some solvers will allow userdata to be passed to eqsres, or optional formats that are more performant. @@ -240,7 +74,8 @@ class dae(object): See Also -------- - odeint : an ODE integrator with a simpler interface based on lsoda from ODEPACK + odeint : an ODE integrator with a simpler interface based on lsoda from + ODEPACK ode : class around vode ODE integrator @@ -248,8 +83,10 @@ class dae(object): ----- Possible future solvers - ddaskr: Not included, starting hints: http://osdir.com/ml/python.f2py.user/2005-07/msg00014.html - Modified Extended Backward Differentiation Formulae (MEBDF): Not included. Fortran codes: http://www.ma.ic.ac.uk/~jcash/IVP_software/readme.html + ddaskr: Not included, starting hints: + http://osdir.com/ml/python.f2py.user/2005-07/msg00014.html + Modified Extended Backward Differentiation Formulae (MEBDF): Not included. + Fortran codes: http://www.ma.ic.ac.uk/~jcash/IVP_software/readme.html Examples -------- @@ -300,7 +137,8 @@ def solve(self, tspan, y0, yp0): Parameters ---------- tspan : list/array - A list of times at which the computed value will be returned. Must contain the start time as first entry. + A list of times at which the computed value will be returned. Must + contain the start time as first entry. y0 : list/array list array of initial values yp0 : list/array @@ -332,7 +170,7 @@ def solve(self, tspan, y0, yp0): ``t`` numpy array of times at which the computations were successful ``y`` numpy array of values corresponding to times t (values of y[i, :] ~ t[i]) ``yp`` numpy array of derivatives corresponding to times t (values of yp[i, :] ~ t[i]) - ``t_err`` float or None - if recoverable error occured (for example reached maximum number of allowed iterations), this is the time at which it happened + ``t_err`` float or None - if recoverable error occurred (for example reached maximum number of allowed iterations), this is the time at which it happened ``y_err`` numpy array of values corresponding to time t_err ``yp_err`` numpy array of derivatives corresponding to time t_err ========== ========================================== @@ -357,7 +195,8 @@ def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): y_ic0 : numpy array (optional) returns the calculated consistent initial condition for y yp_ic0 : numpy array - (optional) returns the calculated consistent initial condition for y derivated. + (optional) returns the calculated consistent initial condition for y + derivated. Returns ------- @@ -381,8 +220,8 @@ def init_step(self, t0, y0, yp0, y_ic0_retn = None, yp_ic0_retn = None): =========== ========================================== Field Meaning =========== ========================================== - ``flag`` status of the computation (successful or error occured) - ``t_out`` time, where the solver stopped (when no error occured, t_out == t) + ``flag`` status of the computation (successful or error occurred) + ``t_out`` time, where the solver stopped (when no error occurred, t_out == t) =========== ========================================== """ @@ -394,20 +233,25 @@ def step(self, t, y_retn=None, yp_retn=None): more precise control over the IDA solver. The 'init_step' method has to be called before the 'step' method. - A step is done towards time t, and output at t returned. This time can be higher or lower than the previous time. If option 'one_step_compute'==True, and the solver supports it, only one internal solver step is done in the direction of t starting at the current step. + A step is done towards time t, and output at t returned. This time can + be higher or lower than the previous time. If option + 'one_step_compute'==True, and the solver supports it, only one internal + solver step is done in the direction of t starting at the current step. If old_api=True, the old behavior is used: if t>0.0 then integration is performed until this time and results at this time are returned in - y_retn; else if if t<0.0 only one internal step is perfomed towards time + y_retn; else if if t<0.0 only one internal step is performed towards time abs(t) and results after this one time step are returned. Parameters ---------- t : number y_retn : numpy array (ndim = 1) or None. - (Needs to be preallocated) If not None, will be filled with y at time t. If None y_retn is not used. + (Needs to be preallocated) If not None, will be filled with y at + time t. If None y_retn is not used. yp_retn : numpy array (ndim = 1) or None. - (Needs to be preallocated) If not None, will be filled with derivatives of y at time t. If None yp_retn is not used. + (Needs to be preallocated) If not None, will be filled with + derivatives of y at time t. If None yp_retn is not used. Returns ------- @@ -431,8 +275,8 @@ def step(self, t, y_retn=None, yp_retn=None): =========== ========================================== Field Meaning =========== ========================================== - ``flag`` status of the computation (successful or error occured) - ``t_out`` time, where the solver stopped (when no error occured, t_out == t) + ``flag`` status of the computation (successful or error occurred) + ``t_out`` time, where the solver stopped (when no error occurred, t_out == t) =========== ========================================== """ @@ -453,7 +297,7 @@ def find_dae_integrator(name): if not dae.LOADED: ## ida try: - from .sundials import ida + from scikits_odes_sundials import ida DaeBase.integrator_classes.append(ida.IDA) except ValueError as msg: print('Could not load IDA solver', msg) @@ -462,7 +306,7 @@ def find_dae_integrator(name): ## idas try: - from .sundials import idas + from scikits_odes_sundials import idas DaeBase.integrator_classes.append(idas.IDAS) except ValueError as msg: print('Could not load IDAS solver', msg) @@ -471,13 +315,13 @@ def find_dae_integrator(name): ## ddaspk try: - from .ddaspkint import ddaspk + from scikits_odes_daepack.ddaspkint import ddaspk except ImportError: print(sys.exc_info()[1]) ## lsodi try: - from .lsodiint import lsodi + from scikits_odes_daepack.lsodiint import lsodi except ImportError: print(sys.exc_info()[1]) diff --git a/scikits/odes/dopri5.py b/packages/scikits-odes/src/scikits_odes/dopri5.py similarity index 96% rename from scikits/odes/dopri5.py rename to packages/scikits-odes/src/scikits_odes/dopri5.py index e5bd3344..3ecc4ba3 100644 --- a/scikits/odes/dopri5.py +++ b/packages/scikits-odes/src/scikits_odes/dopri5.py @@ -40,21 +40,15 @@ Options and references the same as “dopri5”. """ - -from __future__ import print_function - -import sys from collections import namedtuple -try: - from enum import IntEnum -except ImportError: - from enum34 import IntEnum +from enum import IntEnum from warnings import warn +import sys import numpy as np +from scipy.integrate import ode as _runner -from .ode import OdeBase - +from scikits_odes_core import OdeBase SolverReturn = namedtuple( "SolverReturn", [ @@ -65,6 +59,7 @@ SolverVariables = namedtuple("SolverVariables", ["t", "y"]) + class StatusEnumDOP(IntEnum): SUCCESS = 1 SOLOUT = 2 @@ -100,14 +95,8 @@ class DOPSolveFailed(DOPSolveException): ) class dopri5(OdeBase): - try: - from scipy.integrate import ode as _runner - except ImportError: - print(sys.exc_info()[1]) - _runner = None - name = 'dopri5' - + _runner = _runner default_values = { 'rtol': 1e-6, 'atol': 1e-12, @@ -355,6 +344,7 @@ def validate_flags(self, soln): warn(WARNING_STR.format(soln.flag, *soln.err_values)) return soln + class dop853(dopri5): name = 'dop853' default_values = { @@ -371,8 +361,5 @@ class dop853(dopri5): } -if dopri5._runner: - OdeBase.integrator_classes.append(dopri5) - -if dop853._runner: - OdeBase.integrator_classes.append(dop853) +OdeBase.integrator_classes.append(dopri5) +OdeBase.integrator_classes.append(dop853) diff --git a/scikits/odes/ode.py b/packages/scikits-odes/src/scikits_odes/ode.py similarity index 62% rename from scikits/odes/ode.py rename to packages/scikits-odes/src/scikits_odes/ode.py index b1d73dae..a6b53379 100644 --- a/scikits/odes/ode.py +++ b/packages/scikits-odes/src/scikits_odes/ode.py @@ -17,170 +17,14 @@ :math:`\mathrm{len}(y_0)`. """ - -from __future__ import print_function - __all__ = ['ode'] -__version__ = "$Id$" __docformat__ = "restructuredtext en" -import re, sys - -from numpy import isscalar, array, asarray - -class OdeBase(object): - """ - The interface which ODE solvers must implement. - - Parameters - ---------- - Rfn : function - A function which computes the required derivatives. The signature should be ``func(t, y, y_dot, *args, **kwargs)``. Note that *args and **kwargs handling are solver dependent. - - options : mapping - Additional options for initialization, solver dependent - """ - - integrator_classes = [] - - def __init__(self, Rfn, **options): - raise NotImplementedError('all ODE solvers must implement this') - - def set_options(self, **options): - """ - Set specific options for the solver. - - Calling set_options a second time, normally resets the solver. - """ - raise NotImplementedError('all ODE solvers must implement this') +import re +import sys - def solve(self, tspan, y0): - """ - Runs the solver. - - Parameters - ---------- - tspan : array (or similar) - a list of times at which the computed value will be returned. Must - contain the start time as first entry. - - y0 : array (or similar) - a list of initial values - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnum) - ``values`` Named tuple with entries t and y - ``errors`` Named tuple with entries t and y - ``roots`` Named tuple with entries t and y - ``tstop`` Named tuple with entries t and y - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - ========== ========================================== - Field Meaning - ========== ========================================== - ``flag`` indicating return status of the solver - ``t`` numpy array of times at which the computations were successful - ``y`` numpy array of values corresponding to times t (values of y[i, :] ~ t[i]) - ``t_err`` float or None - if recoverable error occured (for example reached maximum number of allowed iterations), this is the time at which it happened - ``y_err`` numpy array of values corresponding to time t_err - ========== ========================================== - """ - raise NotImplementedError('all ODE solvers must implement this') - - def init_step(self, t0, y0): - """ - Initializes the solver and allocates memory. - - Parameters - ---------- - t0 : number - initial time - y0 : array - initial condition for y (can be list or numpy array) - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnum) - ``values`` Named tuple with entries t and y - ``errors`` Named tuple with entries t and y - ``roots`` Named tuple with entries t and y - ``tstop`` Named tuple with entries t and y - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - ========== ========================================== - Field Meaning - ========== ========================================== - ``flag`` boolean status of the computation (successful or error occured) - ``t_out`` inititial time - ========== ========================================== - """ - raise NotImplementedError('all ODE solvers must implement this') - - def step(self, t, y_retn=None): - """ - Method for calling successive next step of the ODE solver to allow - more precise control over the solver. The 'init_step' method has to - be called before the 'step' method. - - A step is done towards time t, and output at t returned. This time can be higher or lower than the previous time. If option 'one_step_compute'==True, and the solver supports it, only one internal solver step is done in the direction of t starting at the current step. - - If old_api=True, the old behavior is used: if t>0.0 then integration is performed until this time and results at this time are returned in y_retn if t<0.0 only one internal step is perfomed towards time abs(t) and results after this one time step are returned - - Parameters - ---------- - t : number - - y_retn : numpy vector (ndim = 1) - in which the computed value will be stored (needs to be preallocated). If None y_retn is not used. - - Returns - ------- - old_api is False : namedtuple - namedtuple with the following attributes - - =========== ========================================== - Field Meaning - =========== ========================================== - ``flag`` An integer flag (StatusEnum) - ``values`` Named tuple with entries t and y - ``errors`` Named tuple with entries t and y - ``roots`` Named tuple with entries t and y - ``tstop`` Named tuple with entries t and y - ``message`` String with message in case of an error - =========== ========================================== - - old_api is True : tuple - tuple with the following elements in order - - ========== ========================================== - Field Meaning - ========== ========================================== - ``flag`` status of the computation (successful or error occured) - ``t_out`` time, where the solver stopped (when no error occured, t_out == t) - ========== ========================================== - """ - raise NotImplementedError('all ODE solvers must implement this') +from scikits_odes_core import OdeBase #------------------------------------------------------------------------------ # User interface @@ -380,16 +224,23 @@ def step(self, t, y_retn=None): more precise control over the solver. The 'init_step' method has to be called before the 'step' method. - A step is done towards time t, and output at t returned. This time can be higher or lower than the previous time. If option 'one_step_compute'==True, and the solver supports it, only one internal solver step is done in the direction of t starting at the current step. + A step is done towards time t, and output at t returned. This time can + be higher or lower than the previous time. If option + 'one_step_compute'==True, and the solver supports it, only one internal + solver step is done in the direction of t starting at the current step. - If old_api=True, the old behavior is used: if t>0.0 then integration is performed until this time and results at this time are returned in y_retn if t<0.0 only one internal step is perfomed towards time abs(t) and results after this one time step are returned + If old_api=True, the old behavior is used: if t>0.0 then integration is + performed until this time and results at this time are returned in + y_retn if t<0.0 only one internal step is perfomed towards time abs(t) + and results after this one time step are returned Parameters ---------- t : number y_retn : numpy vector (ndim = 1) - in which the computed value will be stored (needs to be preallocated). If None y_retn is not used. + in which the computed value will be stored (needs to be + preallocated). If None y_retn is not used. Returns ------- @@ -463,7 +314,7 @@ def find_ode_integrator(name): if not ode.LOADED: ## cvode try: - from .sundials import cvode + from scikits_odes_sundials import cvode OdeBase.integrator_classes.append(cvode.CVODE) except ValueError as msg: print('Could not load CVODE solver', msg) @@ -471,7 +322,7 @@ def find_ode_integrator(name): print(sys.exc_info()[1]) ## cvodes try: - from .sundials import cvodes + from scikits_odes_sundials import cvodes OdeBase.integrator_classes.append(cvodes.CVODES) except ValueError as msg: print('Could not load CVODES solver', msg) diff --git a/scikits/odes/odeint.py b/packages/scikits-odes/src/scikits_odes/odeint.py similarity index 99% rename from scikits/odes/odeint.py rename to packages/scikits-odes/src/scikits_odes/odeint.py index 1af64138..8ce9dda3 100644 --- a/scikits/odes/odeint.py +++ b/packages/scikits-odes/src/scikits_odes/odeint.py @@ -4,12 +4,10 @@ @author: benny """ - -from __future__ import print_function - from copy import copy from .ode import ode + def odeint(rhsfun, tout, y0, method='bdf', **options): """ Integrate a system of ordinary differential equations. diff --git a/packages/scikits-odes/tox.ini b/packages/scikits-odes/tox.ini new file mode 100644 index 00000000..761f0b09 --- /dev/null +++ b/packages/scikits-odes/tox.ini @@ -0,0 +1,42 @@ +[tox] +envlist = py37,py38,py39,py310,py311,py312,check-manifest,checkreadme +setenv = LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 + +[testenv] +passenv= + SUNDIALS_DIR + SUNDIALS_LIBDIR + SUNDIALS_INCLUDEDIR + LD_LIBRARY_PATH + LIBRARY_PATH + CPATH + PIP_VERBOSE + PYTHONFAULTHANDLER +deps = + pytest + -r local-requirements.txt +commands = + pytest --pyargs scikits.odes {posargs} +changedir = + {toxworkdir} + +[testenv:check-manifest] +deps= + check-manifest + -r local-requirements.txt +setenv = + CHECK_MANIFEST=true +commands= + check-manifest +changedir = + {toxinidir} + +[testenv:checkreadme] +deps= + readme_renderer + setuptools + -r local-requirements.txt +commands= + python setup.py check -s -r +changedir = + {toxinidir} diff --git a/packages/scikits-odes/versioneer.py b/packages/scikits-odes/versioneer.py new file mode 100644 index 00000000..1e3753e6 --- /dev/null +++ b/packages/scikits-odes/versioneer.py @@ -0,0 +1,2277 @@ + +# Version: 0.29 + +"""The Versioneer - like a rocketeer, but for versions. + +The Versioneer +============== + +* like a rocketeer, but for versions! +* https://github.com/python-versioneer/python-versioneer +* Brian Warner +* License: Public Domain (Unlicense) +* Compatible with: Python 3.7, 3.8, 3.9, 3.10, 3.11 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url] + +This is a tool for managing a recorded version number in setuptools-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. + + +## Quick Install + +Versioneer provides two installation modes. The "classic" vendored mode installs +a copy of versioneer into your repository. The experimental build-time dependency mode +is intended to allow you to skip this step and simplify the process of upgrading. + +### Vendored mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) + * Note that you will need to add `tomli; python_version < "3.11"` to your + build-time dependencies if you use `pyproject.toml` +* run `versioneer install --vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +### Build-time dependency mode + +* `pip install versioneer` to somewhere in your $PATH + * A [conda-forge recipe](https://github.com/conda-forge/versioneer-feedstock) is + available, so you can also use `conda install -c conda-forge versioneer` +* add a `[tool.versioneer]` section to your `pyproject.toml` or a + `[versioneer]` section to your `setup.cfg` (see [Install](INSTALL.md)) +* add `versioneer` (with `[toml]` extra, if configuring in `pyproject.toml`) + to the `requires` key of the `build-system` table in `pyproject.toml`: + ```toml + [build-system] + requires = ["setuptools", "versioneer[toml]"] + build-backend = "setuptools.build_meta" + ``` +* run `versioneer install --no-vendor` in your source tree, commit the results +* verify version information with `python setup.py version` + +## Version Identifiers + +Source trees come from a variety of places: + +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI + +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: + +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step + +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes). + +The version identifier is used for multiple purposes: + +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball + +## Theory of Operation + +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. + +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. + +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. + +## Installation + +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. + +## Version-String Flavors + +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. + +Both functions return a dictionary with different flavors of version +information: + +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. + +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". + +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. + +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None + +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". + +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. + +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions + +## Styles + +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. + +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". + +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. + +## Debugging + +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). + +## Known Limitations + +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/python-versioneer/python-versioneer/issues). + +### Subprojects + +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: + +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other languages) in subdirectories. + +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). + +`pip install --editable .` should work correctly. `setup.py install` might +work too. + +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. + +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. + +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. + +### Editable installs with setuptools <= 18.5 + +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. + +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. + +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. + +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. + + +## Updating Versioneer + +To upgrade your project to a new release of Versioneer, do the following: + +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg` and `pyproject.toml`, if necessary, + to include any new configuration settings indicated by the release notes. + See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install --[no-]vendor` in your source tree, to replace + `SRC/_version.py` +* commit any changed files + +## Future Directions + +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. + +## Similar projects + +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer +* [versioningit](https://github.com/jwodder/versioningit) - a PEP 518-based setuptools + plugin + +## License + +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the "Unlicense", as described in +https://unlicense.org/. + +[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer + +""" +# pylint:disable=invalid-name,import-outside-toplevel,missing-function-docstring +# pylint:disable=missing-class-docstring,too-many-branches,too-many-statements +# pylint:disable=raise-missing-from,too-many-lines,too-many-locals,import-error +# pylint:disable=too-few-public-methods,redefined-outer-name,consider-using-with +# pylint:disable=attribute-defined-outside-init,too-many-arguments + +import configparser +import errno +import json +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import NoReturn +import functools + +have_tomllib = True +if sys.version_info >= (3, 11): + import tomllib +else: + try: + import tomli as tomllib + except ImportError: + have_tomllib = False + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + versionfile_source: str + versionfile_build: Optional[str] + parentdir_prefix: Optional[str] + verbose: Optional[bool] + + +def get_root() -> str: + """Get the project root directory. + + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + pyproject_toml = os.path.join(root, "pyproject.toml") + versioneer_py = os.path.join(root, "versioneer.py") + if not ( + os.path.exists(setup_py) + or os.path.exists(pyproject_toml) + or os.path.exists(versioneer_py) + ): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + my_path = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(my_path)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir and "VERSIONEER_PEP518" not in globals(): + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py)) + except NameError: + pass + return root + + +def get_config_from_root(root: str) -> VersioneerConfig: + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise OSError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + root_pth = Path(root) + pyproject_toml = root_pth / "pyproject.toml" + setup_cfg = root_pth / "setup.cfg" + section: Union[Dict[str, Any], configparser.SectionProxy, None] = None + if pyproject_toml.exists() and have_tomllib: + try: + with open(pyproject_toml, 'rb') as fobj: + pp = tomllib.load(fobj) + section = pp['tool']['versioneer'] + except (tomllib.TOMLDecodeError, KeyError) as e: + print(f"Failed to load config from {pyproject_toml}: {e}") + print("Try to load it from setup.cfg") + if not section: + parser = configparser.ConfigParser() + with open(setup_cfg) as cfg_file: + parser.read_file(cfg_file) + parser.get("versioneer", "VCS") # raise error if missing + + section = parser["versioneer"] + + # `cast`` really shouldn't be used, but its simplest for the + # common VersioneerConfig users at the moment. We verify against + # `None` values elsewhere where it matters + + cfg = VersioneerConfig() + cfg.VCS = section['VCS'] + cfg.style = section.get("style", "") + cfg.versionfile_source = cast(str, section.get("versionfile_source")) + cfg.versionfile_build = section.get("versionfile_build") + cfg.tag_prefix = cast(str, section.get("tag_prefix")) + if cfg.tag_prefix in ("''", '""', None): + cfg.tag_prefix = "" + cfg.parentdir_prefix = section.get("parentdir_prefix") + if isinstance(section, configparser.SectionProxy): + # Make sure configparser translates to bool + cfg.verbose = section.getboolean("verbose") + else: + cfg.verbose = section.get("verbose") + + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + HANDLERS.setdefault(vcs, {})[method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, process.returncode + return stdout, process.returncode + + +LONG_VERSION_PY['git'] = r''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. +# Generated by versioneer-0.29 +# https://github.com/python-versioneer/python-versioneer + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys +from typing import Any, Callable, Dict, List, Optional, Tuple +import functools + + +def get_keywords() -> Dict[str, str]: + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + VCS: str + style: str + tag_prefix: str + parentdir_prefix: str + versionfile_source: str + verbose: bool + + +def get_config() -> VersioneerConfig: + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY: Dict[str, str] = {} +HANDLERS: Dict[str, Dict[str, Callable]] = {} + + +def register_vcs_handler(vcs: str, method: str) -> Callable: # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f: Callable) -> Callable: + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command( + commands: List[str], + args: List[str], + cwd: Optional[str] = None, + verbose: bool = False, + hide_stderr: bool = False, + env: Optional[Dict[str, str]] = None, +) -> Tuple[Optional[str], Optional[int]]: + """Call the given command(s).""" + assert isinstance(commands, list) + process = None + + popen_kwargs: Dict[str, Any] = {} + if sys.platform == "win32": + # This hides the console window if pythonw.exe is used + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + popen_kwargs["startupinfo"] = startupinfo + + for command in commands: + try: + dispcmd = str([command] + args) + # remember shell=False, so use git.cmd on windows, not just git + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) + break + except OSError as e: + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = process.communicate()[0].strip().decode() + if process.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, process.returncode + return stdout, process.returncode + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%%d.dev%%d" %% (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%%d" %% (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%%d" %% pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions() -> Dict[str, Any]: + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for _ in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs: str) -> Dict[str, str]: + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords: Dict[str, str] = {} + try: + with open(versionfile_abs, "r") as fobj: + for line in fobj: + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords( + keywords: Dict[str, str], + tag_prefix: str, + verbose: bool, +) -> Dict[str, Any]: + """Get version information from git keywords.""" + if "refnames" not in keywords: + raise NotThisMethod("Short version file found") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + # Filter out refs that exactly match prefix or that don't start + # with a number once the prefix is stripped (mostly a concern + # when prefix is '') + if not re.match(r'\d', r): + continue + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs( + tag_prefix: str, + root: str, + verbose: bool, + runner: Callable = run_command +) -> Dict[str, Any]: + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + # GIT_DIR can interfere with correct operation of Versioneer. + # It may be intended to be passed to the Versioneer-versioned project, + # but that should not change where we get our version from. + env = os.environ.copy() + env.pop("GIT_DIR", None) + runner = functools.partial(runner, env=env) + + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=not verbose) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces: Dict[str, Any] = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) + # --abbrev-ref was added in git-1.6.3 + if rc != 0 or branch_name is None: + raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") + branch_name = branch_name.strip() + + if branch_name == "HEAD": + # If we aren't exactly on a branch, pick a branch which represents + # the current commit. If all else fails, we are on a branchless + # commit. + branches, rc = runner(GITS, ["branch", "--contains"], cwd=root) + # --contains was added in git-1.5.4 + if rc != 0 or branches is None: + raise NotThisMethod("'git branch --contains' returned error") + branches = branches.split("\n") + + # Remove the first line if we're running detached + if "(" in branches[0]: + branches.pop(0) + + # Strip off the leading "* " from the list of branches. + branches = [branch[2:] for branch in branches] + if "master" in branches: + branch_name = "master" + elif not branches: + branch_name = None + else: + # Pick the first branch that is returned. Good or bad. + branch_name = branches[0] + + pieces["branch"] = branch_name + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparsable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + out, rc = runner(GITS, ["rev-list", "HEAD", "--left-right"], cwd=root) + pieces["distance"] = len(out.split()) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(versionfile_source: str, ipy: Optional[str]) -> None: + """Git-specific installation logic for Versioneer. + + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [versionfile_source] + if ipy: + files.append(ipy) + if "VERSIONEER_PEP518" not in globals(): + try: + my_path = __file__ + if my_path.endswith((".pyc", ".pyo")): + my_path = os.path.splitext(my_path)[0] + ".py" + versioneer_file = os.path.relpath(my_path) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + with open(".gitattributes", "r") as fobj: + for line in fobj: + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + break + except OSError: + pass + if not present: + with open(".gitattributes", "a+") as fobj: + fobj.write(f"{versionfile_source} export-subst\n") + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir( + parentdir_prefix: str, + root: str, + verbose: bool, +) -> Dict[str, Any]: + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for _ in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.29) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +%s +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename: str) -> Dict[str, Any]: + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except OSError: + raise NotThisMethod("unable to read _version.py") + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename: str, versions: Dict[str, Any]) -> None: + """Write the given version number to the given _version.py file.""" + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set %s to '%s'" % (filename, versions["version"])) + + +def plus_or_dot(pieces: Dict[str, Any]) -> str: + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces: Dict[str, Any]) -> str: + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_branch(pieces: Dict[str, Any]) -> str: + """TAG[[.dev0]+DISTANCE.gHEX[.dirty]] . + + The ".dev0" means not master branch. Note that .dev0 sorts backwards + (a feature branch will appear "older" than the master branch). + + Exceptions: + 1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0" + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def pep440_split_post(ver: str) -> Tuple[str, Optional[int]]: + """Split pep440 version string at the post-release segment. + + Returns the release segments before the post-release and the + post-release version number (or -1 if no post-release segment is present). + """ + vc = str.split(ver, ".post") + return vc[0], int(vc[1] or 0) if len(vc) == 2 else None + + +def render_pep440_pre(pieces: Dict[str, Any]) -> str: + """TAG[.postN.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + if pieces["distance"]: + # update the post release segment + tag_version, post_version = pep440_split_post(pieces["closest-tag"]) + rendered = tag_version + if post_version is not None: + rendered += ".post%d.dev%d" % (post_version + 1, pieces["distance"]) + else: + rendered += ".post0.dev%d" % (pieces["distance"]) + else: + # no commits, use the tag as the version + rendered = pieces["closest-tag"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_post_branch(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] . + + The ".dev0" means not master branch. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["branch"] != "master": + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_old(pieces: Dict[str, Any]) -> str: + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces: Dict[str, Any]) -> str: + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces: Dict[str, Any]) -> str: + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces: Dict[str, Any], style: str) -> Dict[str, Any]: + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-branch": + rendered = render_pep440_branch(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-post-branch": + rendered = render_pep440_post_branch(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose: bool = False) -> Dict[str, Any]: + """Get the project version from whatever source is available. + + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or bool(cfg.verbose) # `bool()` used to avoid `None` + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print("got version from file %s %s" % (versionfile_abs, ver)) + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} + + +def get_version() -> str: + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(cmdclass: Optional[Dict[str, Any]] = None): + """Get the custom setuptools subclasses used by Versioneer. + + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/python-versioneer/python-versioneer/issues/52 + + cmds = {} if cmdclass is None else cmdclass.copy() + + # we add "version" to setuptools + from setuptools import Command + + class cmd_version(Command): + description = "report generated version string" + user_options: List[Tuple[str, str, str]] = [] + boolean_options: List[str] = [] + + def initialize_options(self) -> None: + pass + + def finalize_options(self) -> None: + pass + + def run(self) -> None: + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version + + # we override "build_py" in setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # pip install -e . and setuptool/editable_wheel will invoke build_py + # but the build_py command is not expected to copy any files. + + # we override different "build_py" commands for both environments + if 'build_py' in cmds: + _build_py: Any = cmds['build_py'] + else: + from setuptools.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + if getattr(self, "editable_mode", False): + # During editable installs `.py` and data files are + # not copied to build_lib + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py + + if 'build_ext' in cmds: + _build_ext: Any = cmds['build_ext'] + else: + from setuptools.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if not cfg.versionfile_build: + return + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + if not os.path.exists(target_versionfile): + print(f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py.") + return + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe # type: ignore + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if 'py2exe' in sys.modules: # py2exe enabled? + try: + from py2exe.setuptools_buildexe import py2exe as _py2exe # type: ignore + except ImportError: + from py2exe.distutils_buildexe import py2exe as _py2exe # type: ignore + + class cmd_py2exe(_py2exe): + def run(self) -> None: + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["py2exe"] = cmd_py2exe + + # sdist farms its file list building out to egg_info + if 'egg_info' in cmds: + _egg_info: Any = cmds['egg_info'] + else: + from setuptools.command.egg_info import egg_info as _egg_info + + class cmd_egg_info(_egg_info): + def find_sources(self) -> None: + # egg_info.find_sources builds the manifest list and writes it + # in one shot + super().find_sources() + + # Modify the filelist and normalize it + root = get_root() + cfg = get_config_from_root(root) + self.filelist.append('versioneer.py') + if cfg.versionfile_source: + # There are rare cases where versionfile_source might not be + # included by default, so we must be explicit + self.filelist.append(cfg.versionfile_source) + self.filelist.sort() + self.filelist.remove_duplicates() + + # The write method is hidden in the manifest_maker instance that + # generated the filelist and was thrown away + # We will instead replicate their final normalization (to unicode, + # and POSIX-style paths) + from setuptools import unicode_utils + normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') + for f in self.filelist.files] + + manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') + with open(manifest_filename, 'w') as fobj: + fobj.write('\n'.join(normalized)) + + cmds['egg_info'] = cmd_egg_info + + # we override different "sdist" commands for both environments + if 'sdist' in cmds: + _sdist: Any = cmds['sdist'] + else: + from setuptools.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self) -> None: + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir: str, files: List[str]) -> None: + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- + +You will also need to edit your setup.py to use the results: + + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) + +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = + +""" + +OLD_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + +INIT_PY_SNIPPET = """ +from . import {0} +__version__ = {0}.get_versions()['version'] +""" + + +def do_setup() -> int: + """Do main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (OSError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (OSError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + maybe_ipy: Optional[str] = ipy + if os.path.exists(ipy): + try: + with open(ipy, "r") as f: + old = f.read() + except OSError: + old = "" + module = os.path.splitext(os.path.basename(cfg.versionfile_source))[0] + snippet = INIT_PY_SNIPPET.format(module) + if OLD_SNIPPET in old: + print(" replacing boilerplate in %s" % ipy) + with open(ipy, "w") as f: + f.write(old.replace(OLD_SNIPPET, snippet)) + elif snippet not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(snippet) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + maybe_ipy = None + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(cfg.versionfile_source, maybe_ipy) + return 0 + + +def scan_setup_py() -> int: + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py", "r") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +def setup_command() -> NoReturn: + """Set up Versioneer and exit with appropriate error code.""" + errors = do_setup() + errors += scan_setup_py() + sys.exit(1 if errors else 0) + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + setup_command() diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index e5a68b78..00000000 --- a/pyproject.toml +++ /dev/null @@ -1,2 +0,0 @@ -[build-system] -requires = ["setuptools<=64.0.0", "wheel", "numpy", "cython<3.0.0a8"] diff --git a/scikits/__init__.py b/scikits/__init__.py deleted file mode 100644 index 8d17c21c..00000000 --- a/scikits/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__import__('pkg_resources').declare_namespace(__name__) - diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 0b31a16e..00000000 --- a/setup.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[metadata] -license_file = LICENSE.txt -description-file = README.md - -[check-manifest] -ignore = - .travis.yml - *.c diff --git a/setup.py b/setup.py deleted file mode 100644 index 1c963457..00000000 --- a/setup.py +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/env python -""" -Odes is a scikit toolkit for scipy to add some extra ode solvers. -At present it provides dae solvers you can use, extending the capabilities -offered in scipy.integrade.ode. - -LICENSE: the license of odes is the same as scipy, new BSD. -""" - -import os -import sys - -from setuptools import find_packages - -if '' not in sys.path: - sys.path.insert(0, '') - -from common import * - -additional_kwargs = {} - -if "bdist_wheel" in sys.argv or "install" in sys.argv: - from os.path import join - from glob import glob - from numpy.distutils.core import setup, Extension - from setup_build import build_ext - - # add cython build logic - additional_kwargs["cmdclass"] = {'build_ext': build_ext} - - # f2py requires build_src to be called - base_path = join('scikits', 'odes') - daepack_paths = glob(join(base_path, 'daepack', '*.f')) - additional_kwargs['ext_modules'] = [ - Extension('scikits.odes.ddaspk', - sources=[join(base_path, 'ddaspk.pyf')] + daepack_paths, - ), Extension('scikits.odes.lsodi', - sources=[join(base_path, 'lsodi.pyf')] + daepack_paths, - ), - ] - -else: - from setuptools import setup - -setup( - name = DISTNAME, - version = VERSION, - maintainer = MAINTAINER, - maintainer_email = MAINTAINER_EMAIL, - description = DESCRIPTION, - long_description = LONG_DESCRIPTION, - url = URL, - license = LICENSE, -# setup_requires = BUILD_REQUIRES, - install_requires = INSTALL_REQUIRES, - packages = find_packages(), - namespace_packages = ['scikits'], - zip_safe = False, - package_data = { - # If any package contains *.pxd files, include them: - '': ['*.pxd'], - }, - classifiers = CLASSIFIERS, - **additional_kwargs -) diff --git a/tox.ini b/tox.ini index 19bd0ca5..3b411766 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39,py310,py311,py312,check-manifest,checkreadme,docs +envlist = {py37,py38,py39,py310,py311,py312}-{test,notebooks},docs setenv = LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 #skipsdist=True @@ -15,45 +15,25 @@ passenv= PIP_VERBOSE PYTHONFAULTHANDLER deps = - numpy - scipy - cython - nose pytest - wheel + packages/scikits-odes + packages/scikits-odes-core + packages/scikits-odes-daepack + packages/scikits-odes-sundials + notebooks: nbval + notebooks: -r notebook-requirements.txt commands = env - py.test --pyargs scikits.odes {posargs} -changedir = - {toxworkdir} - -[testenv:check-manifest] -deps= - check-manifest - numpy - cython -setenv = - CHECK_MANIFEST=true -commands= - check-manifest -changedir = - {toxinidir} - -[testenv:checkreadme] -deps= - readme_renderer - numpy - cython -commands= - python setup.py check -s -r -changedir = - {toxinidir} + test: pytest --pyargs scikits.odes --pyargs scikits_odes --pyargs scikits_odes_core --pyargs scikits_odes_daepack --pyargs scikits_odes_sundials {posargs} + notebooks: pytest --nbval ipython_examples/ [testenv:doctr] passenv=* deps= - numpy - cython + packages/scikits-odes + packages/scikits-odes-core + packages/scikits-odes-daepack + packages/scikits-odes-sundials doctr jinja2 -rapidocs/requirements.txt @@ -65,6 +45,11 @@ changedir = [testenv:docs] changedir=docs -deps=-rdocs/requirements.txt +deps= + packages/scikits-odes + packages/scikits-odes-core + packages/scikits-odes-daepack + packages/scikits-odes-sundials + -rdocs/requirements.txt commands= sphinx-build -W -b html -d {envtmpdir}/doctrees . {envtmpdir}/html