diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index d6e5b4a..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -odvc/_version.py export-subst diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..f4a3336 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,36 @@ +name: Tests + +on: + pull_request: + push: + branches: [main] + +jobs: + run: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + os: [windows-latest, ubuntu-latest, macos-latest] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + + - name: Setup Micromamba + uses: mamba-org/provision-with-micromamba@main + with: + environment-file: false + + - name: Python ${{ matrix.python-version }} + shell: bash -l {0} + run: | + micromamba create --name TEST python=${{ matrix.python-version }} --file requirements.txt --file requirements-dev.txt --channel conda-forge + micromamba activate TEST + python -m pip install -e . --no-deps --force-reinstall + + - name: Tests + shell: bash -l {0} + run: | + micromamba activate TEST + python -m pytest -rxs tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..3c1f25b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,91 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.2.0 + hooks: + - id: trailing-whitespace + - id: check-ast + - id: debug-statements + - id: end-of-file-fixer + - id: check-docstring-first + - id: check-added-large-files + exclude_types: [yaml] + - id: requirements-txt-fixer + - id: file-contents-sorter + files: requirements-dev.txt + +- repo: https://github.com/PyCQA/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + exclude: docs/source/conf.py + args: [--max-line-length=105] + +- repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort + additional_dependencies: [toml] + args: ["--profile", "black", "--filter-files"] + +- repo: https://github.com/psf/black + rev: 22.3.0 + hooks: + - id: black + language_version: python3 + +- repo: https://github.com/keewis/blackdoc + rev: v0.3.4 + hooks: + - id: blackdoc + +- repo: https://github.com/econchick/interrogate + rev: 1.5.0 + hooks: + - id: interrogate + exclude: ^(docs|setup.py|tests) + args: [--config=pyproject.toml] + +- repo: https://github.com/codespell-project/codespell + rev: v2.1.0 + hooks: + - id: codespell + exclude: > + (?x)^( + .*\.yaml + )$ + args: + - --quiet-level=2 + +- repo: https://github.com/asottile/pyupgrade + rev: v2.32.1 + hooks: + - id: pyupgrade + args: + - --py36-plus + +- repo: https://github.com/asottile/add-trailing-comma + rev: v2.2.3 + hooks: + - id: add-trailing-comma + +- repo: https://github.com/deathbeds/prenotebook + rev: f5bdb72a400f1a56fe88109936c83aa12cc349fa + hooks: + - id: prenotebook + +- repo: https://github.com/pycqa/pydocstyle + rev: 6.1.1 + hooks: + - id: pydocstyle + exclude: ^(docs|setup.py) + +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit.com hooks + + for more information, see https://pre-commit.ci + autofix_prs: false + autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' + autoupdate_schedule: monthly + skip: [] + submodules: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7c8b86d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: minimal - -sudo: false - -matrix: - fast_finish: true - include: - - name: python-3.6 - env: TEST_TARGET=default PY=3.6 - - name: python-3.7 - env: TEST_TARGET=default PY=3.7 - - name: coding_standards - env: PY=3.7 - - name: docs - env: PY=3.7 - -before_install: - # Install miniconda and create TEST env. - - | - wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - conda config --set always_yes yes --set changeps1 no --set show_channel_urls true - conda update conda --quiet - conda config --add channels conda-forge --force - conda config --set channel_priority strict - conda config --set safety_checks disabled - conda create --name TEST python=$PY --file requirements.txt --file requirements-dev.txt - source activate TEST - -install: - - python setup.py sdist && version=$(python setup.py --version) && pushd dist && pip install --no-deps --force-reinstall odvc-${version}.tar.gz && popd - -script: - - if [[ $TEST_TARGET == 'default' ]]; then - cp -r tests/ /tmp ; - pushd /tmp && pytest -n 2 -rxs tests && popd ; - fi - - - if [[ $TRAVIS_JOB_NAME == 'coding_standards' ]]; then - pytest --flake8 -m flake8 ; - fi diff --git a/README.rst b/README.md similarity index 77% rename from README.rst rename to README.md index ab66179..d7a21ee 100644 --- a/README.rst +++ b/README.md @@ -1,8 +1,4 @@ -odvc ------- - -.. image:: https://travis-ci.org/ioos/odvc.svg?branch=master - :target: https://travis-ci.org/ioos/odvc +# odvc Ocean Dimensionless Vertical Coordinates diff --git a/notebooks/ocean_s_coordinate.ipynb b/notebooks/ocean_s_coordinate.ipynb index 85ed7ec..c251751 100644 --- a/notebooks/ocean_s_coordinate.ipynb +++ b/notebooks/ocean_s_coordinate.ipynb @@ -2,53 +2,22 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "url = (\"http://geoport.whoi.edu/thredds/dodsC/examples/bora_feb.nc\")" + "url = \"http://geoport.whoi.edu/thredds/dodsC/examples/bora_feb.nc\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[\n", - " float64 s_rho(s_rho)\n", - " long_name: S-coordinate at RHO-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " standard_name: ocean_s_coordinate\n", - " formula_terms: s: s_rho eta: zeta depth: h a: theta_s b: theta_b depth_c: hc\n", - " field: s_rho, scalar\n", - " unlimited dimensions: \n", - " current shape = (20,)\n", - " filling off, \n", - " float64 s_w(s_w)\n", - " long_name: S-coordinate at W-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " standard_name: ocean_s_coordinate\n", - " formula_terms: s: s_w eta: zeta depth: h a: theta_s b: theta_b depth_c: hc\n", - " field: s_w, scalar\n", - " unlimited dimensions: \n", - " current shape = (21,)\n", - " filling off]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from netCDF4 import Dataset\n", "\n", @@ -64,27 +33,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', u's_rho'),\n", - " (u'eta', u'zeta'),\n", - " (u'depth', u'h'),\n", - " (u'a', u'theta_s'),\n", - " (u'b', u'theta_b'),\n", - " (u'depth_c', u'hc')])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms\n", "\n", @@ -95,27 +48,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', (u's_rho',)),\n", - " (u'eta', (u'ocean_time', u'eta_rho', u'xi_rho')),\n", - " (u'depth', (u'eta_rho', u'xi_rho')),\n", - " (u'a', ()),\n", - " (u'b', ()),\n", - " (u'depth_c', ())])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms_dims\n", "\n", @@ -127,22 +64,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(8, 20, 60, 160)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import z_shape\n", "\n", @@ -153,27 +79,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "{u'a': array(4.0),\n", - " u'b': array(0.9),\n", - " u'depth': dask.array,\n", - " u'depth_c': array(4.0),\n", - " u'eta': dask.array,\n", - " u's': dask.array}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import prepare_arrays\n", "\n", @@ -185,70 +95,50 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(u'a', ()),\n", - " (u's', (1, 20, 1, 1)),\n", - " (u'eta', (8, 1, 60, 160)),\n", - " (u'depth_c', ()),\n", - " (u'b', ()),\n", - " (u'depth', (1, 1, 60, 160))]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "[(var, arr.shape) for var, arr in arrays.items()]" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(8, 20, 60, 160)\n" - ] - } - ], + "outputs": [], "source": [ "from odvc import ocean_s_coordinate\n", "\n", "\n", - "z = ocean_s_coordinate(arrays['s'],\n", - " arrays['eta'],\n", - " arrays['depth'],\n", - " arrays['a'],\n", - " arrays['b'],\n", - " arrays['depth_c'])\n", + "z = ocean_s_coordinate(\n", + " arrays[\"s\"],\n", + " arrays[\"eta\"],\n", + " arrays[\"depth\"],\n", + " arrays[\"a\"],\n", + " arrays[\"b\"],\n", + " arrays[\"depth_c\"],\n", + ")\n", "\n", "print(z.shape)" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ - "salt = nc.get_variables_by_attributes(long_name='averaged salinity')[0]\n", - "temp = nc.get_variables_by_attributes(long_name='averaged potential temperature')[0]\n", + "salt = nc.get_variables_by_attributes(long_name=\"averaged salinity\")[0]\n", + "temp = nc.get_variables_by_attributes(\n", + " long_name=\"averaged potential temperature\"\n", + ")[0]\n", "\n", "s = salt[-1, :, 45, 137]\n", "t = temp[-1, :, 45, 137]\n", @@ -257,22 +147,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\nw4Zuj9mxY4dy1113KYqiKA0NDcprr72mKIqi3HXXXcquXbsURVGUJ598Uvnhhx8sdRp9dq7n39jY\n2Hn+a9euVf7+979bsPpz15fz72rFihXK2rVrFUWxzeuvKP37OxgsfwM//fSTct999ymKoihbt25V\n7r33XkVRbOdvQFoWfTB37lxmzZoFQFFREV5eXmg0GmpqalAUhcbGRvT67iuCbt26lbi4OH7/+9/T\n0NDAI488AkBqaioTJkwAYPr06WzdupW5c+da9oTOUn+ef0pKCnl5eaxfv56IiAgee+wx3NxOvSmR\ntejL+R936NAhsrKyePLJJwHbvP7Qv7+Dw4cPk5uba/d/A87OztTX16MoCvX19Z0/t5W/AQmLPtLp\ndCxZsoQffviB119/HW9vb2699VbefvttPD09mThxYrfjq6qqKC4uZtWqVRQWFnLPPffw7bffonRZ\nmsvV1ZX6+npLn0qf9Nf5jxkzhuuuu44RI0bwzjvv8MYbb/Doo4+qdFa9d7bnf9yqVau4995fNkmy\n1esP/fc7SExM5Le//a3d/w2MGzeOtrY25s2bR01NDatWrQJs6G9AtTaNnSgvL1dmzpypzJ49W8nO\nzlYURVHWrFmjrFixottxK1eu7NbUvvzyy5XKykpl+vTpnd/74YcflKefftoyhfeTcz3/urq6zu9l\nZWUpCxcutEjd/aW3568oilJbW6tceuml3b5n69dfUc79dzBY/gbefvtt5eWXX1YURVGKi4uViy66\nSGltbbWZvwEZDdUH//3vfzs/FTg7O6PVamltbe1sOgcGBlJXV9ftMePHj2fLli0AlJaW0tLSgre3\nNwkJCezatQuAzZs3k5SUZMEz6Zv+PP/bb7+dgwcPArB9+3ZGjbL+pbP7cv4Au3fvZvLk7vt02+L1\nh/79HQyWv4Hm5ubOn3t6emIwGDAajTbzNyBLlPdBS0sLS5YsoaKigvb2du68806cnZ159dVXcXJy\nwtHRkT/96U+EhITw6KOP8sADDxAcHMxLL73Ezp07MZlMLF68mPPPP5+8vDyeeOIJDAYDw4cP55ln\nnrHOkRBd9Of5p6ens2LFChwcHAgMDOTpp5+2+vvVfT3/999/H71ez80339z5XLZ4/aF/fweD5W/A\n1dWVpUuXUl1dTXt7OwsXLuTSSy+1mb8BCQshhBA9kttQQggheiRhIYQQokcSFkIIIXokYSGEEKJH\n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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "\n", diff --git a/notebooks/ocean_s_coordinate_g1.ipynb b/notebooks/ocean_s_coordinate_g1.ipynb index 4293d20..fc5ec39 100644 --- a/notebooks/ocean_s_coordinate_g1.ipynb +++ b/notebooks/ocean_s_coordinate_g1.ipynb @@ -2,66 +2,25 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "url = (\"http://omgsrv1.meas.ncsu.edu:8080/thredds/dodsC/fmrc/sabgom/\"\n", - " \"SABGOM_Forecast_Model_Run_Collection_best.ncd\")" + "url = (\n", + " \"http://omgsrv1.meas.ncsu.edu:8080/thredds/dodsC/fmrc/sabgom/\"\n", + " \"SABGOM_Forecast_Model_Run_Collection_best.ncd\"\n", + ")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[\n", - " float64 s_rho(s_rho)\n", - " units: \n", - " long_name: S-coordinate at RHO-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " positive: up\n", - " standard_name: ocean_s_coordinate_g1\n", - " formula_terms: s: s_rho C: Cs_r eta: zeta depth: h depth_c: hc\n", - " field: s_rho, scalar\n", - " _CoordinateTransformType: Vertical\n", - " _CoordinateAxisType: GeoZ\n", - " _CoordinateZisPositive: up\n", - " _CoordinateAxes: s_rho\n", - " unlimited dimensions: \n", - " current shape = (36,)\n", - " filling off, \n", - " float64 s_w(s_w)\n", - " units: \n", - " long_name: S-coordinate at W-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " positive: up\n", - " standard_name: ocean_s_coordinate_g1\n", - " formula_terms: s: s_w C: Cs_w eta: zeta depth: h depth_c: hc\n", - " field: s_w, scalar\n", - " _CoordinateTransformType: Vertical\n", - " _CoordinateAxisType: GeoZ\n", - " _CoordinateZisPositive: up\n", - " _CoordinateAxes: s_w\n", - " unlimited dimensions: \n", - " current shape = (37,)\n", - " filling off]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from netCDF4 import Dataset\n", "\n", @@ -77,26 +36,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', u's_rho'),\n", - " (u'C', u'Cs_r'),\n", - " (u'eta', u'zeta'),\n", - " (u'depth', u'h'),\n", - " (u'depth_c', u'hc')])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms\n", "\n", @@ -107,26 +51,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', (u's_rho',)),\n", - " (u'C', (u's_rho',)),\n", - " (u'eta', (u'time', u'eta_rho', u'xi_rho')),\n", - " (u'depth', (u'eta_rho', u'xi_rho')),\n", - " (u'depth_c', ())])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms_dims\n", "\n", @@ -138,22 +67,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(496, 36, 320, 440)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import z_shape\n", "\n", @@ -164,26 +82,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "{u'C': dask.array,\n", - " u'depth': dask.array,\n", - " u'depth_c': array(5.0),\n", - " u'eta': dask.array,\n", - " u's': dask.array}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import prepare_arrays\n", "\n", @@ -195,67 +98,44 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(u'depth', (1, 1, 320, 440)),\n", - " (u's', (1, 36, 1, 1)),\n", - " (u'eta', (496, 1, 320, 440)),\n", - " (u'C', (1, 36, 1, 1)),\n", - " (u'depth_c', ())]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "[(var, arr.shape) for var, arr in arrays.items()]" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(496, 36, 320, 440)\n" - ] - } - ], + "outputs": [], "source": [ "from odvc import ocean_s_coordinate_g1\n", "\n", - "z = ocean_s_coordinate_g1(arrays['s'],\n", - " arrays['C'],\n", - " arrays['eta'],\n", - " arrays['depth'],\n", - " arrays['depth_c'])\n", + "z = ocean_s_coordinate_g1(\n", + " arrays[\"s\"], arrays[\"C\"], arrays[\"eta\"], arrays[\"depth\"], arrays[\"depth_c\"]\n", + ")\n", "\n", "print(z.shape)" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "salt = nc.get_variables_by_attributes(standard_name='sea_water_salinity')[0]\n", - "temp = nc.get_variables_by_attributes(standard_name='sea_water_potential_temperature')[0]\n", + "salt = nc.get_variables_by_attributes(standard_name=\"sea_water_salinity\")[0]\n", + "temp = nc.get_variables_by_attributes(\n", + " standard_name=\"sea_water_potential_temperature\"\n", + ")[0]\n", "\n", "s = salt[-1, :, 5, 364]\n", "t = temp[-1, :, 5, 364]\n", @@ -264,22 +144,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\nAKERGgCA0P4f5EqNmsoMg/8AAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "\n", diff --git a/notebooks/ocean_s_coordinate_g2.ipynb b/notebooks/ocean_s_coordinate_g2.ipynb index 145aea4..f295bc0 100644 --- a/notebooks/ocean_s_coordinate_g2.ipynb +++ b/notebooks/ocean_s_coordinate_g2.ipynb @@ -2,56 +2,25 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "url = (\"http://dm2.caricoos.org/thredds/dodsC/content/roms/\"\n", - " \"20150930/r1/ocean_his_0121.nc\")" + "url = (\n", + " \"http://dm2.caricoos.org/thredds/dodsC/content/roms/\"\n", + " \"20150930/r1/ocean_his_0121.nc\"\n", + ")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[\n", - " float64 s_rho(s_rho)\n", - " long_name: S-coordinate at RHO-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " positive: up\n", - " standard_name: ocean_s_coordinate_g2\n", - " formula_terms: s: s_rho C: Cs_r eta: zeta depth: h depth_c: hc\n", - " field: s_rho, scalar\n", - " unlimited dimensions: \n", - " current shape = (32,)\n", - " filling off, \n", - " float64 s_w(s_w)\n", - " long_name: S-coordinate at W-points\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " positive: up\n", - " standard_name: ocean_s_coordinate_g2\n", - " formula_terms: s: s_w C: Cs_w eta: zeta depth: h depth_c: hc\n", - " field: s_w, scalar\n", - " unlimited dimensions: \n", - " current shape = (33,)\n", - " filling off]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from netCDF4 import Dataset\n", "\n", @@ -67,26 +36,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', u's_rho'),\n", - " (u'C', u'Cs_r'),\n", - " (u'eta', u'zeta'),\n", - " (u'depth', u'h'),\n", - " (u'depth_c', u'hc')])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms\n", "\n", @@ -97,26 +51,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u's', (u's_rho',)),\n", - " (u'C', (u's_rho',)),\n", - " (u'eta', (u'ocean_time', u'eta_rho', u'xi_rho')),\n", - " (u'depth', (u'eta_rho', u'xi_rho')),\n", - " (u'depth_c', ())])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms_dims\n", "\n", @@ -128,22 +67,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(1, 32, 164, 400)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import z_shape\n", "\n", @@ -154,26 +82,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "{u'C': dask.array,\n", - " u'depth': dask.array,\n", - " u'depth_c': array(1.0),\n", - " u'eta': dask.array,\n", - " u's': dask.array}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import prepare_arrays\n", "\n", @@ -185,67 +98,42 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(u'depth', (1, 1, 164, 400)),\n", - " (u's', (1, 32, 1, 1)),\n", - " (u'eta', (1, 1, 164, 400)),\n", - " (u'C', (1, 32, 1, 1)),\n", - " (u'depth_c', ())]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "[(var, arr.shape) for var, arr in arrays.items()]" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(1, 32, 164, 400)\n" - ] - } - ], + "outputs": [], "source": [ "from odvc import ocean_s_coordinate_g1\n", "\n", - "z = ocean_s_coordinate_g1(arrays['s'],\n", - " arrays['C'],\n", - " arrays['eta'],\n", - " arrays['depth'],\n", - " arrays['depth_c'])\n", + "z = ocean_s_coordinate_g1(\n", + " arrays[\"s\"], arrays[\"C\"], arrays[\"eta\"], arrays[\"depth\"], arrays[\"depth_c\"]\n", + ")\n", "\n", "print(z.shape)" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "salt = nc.get_variables_by_attributes(long_name='salinity')[0]\n", - "temp = nc.get_variables_by_attributes(long_name='potential temperature')[0]\n", + "salt = nc.get_variables_by_attributes(long_name=\"salinity\")[0]\n", + "temp = nc.get_variables_by_attributes(long_name=\"potential temperature\")[0]\n", "\n", "s = salt[-1, :, 162, 128]\n", "t = temp[-1, :, 162, 128]\n", @@ -254,22 +142,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "\n", diff --git a/notebooks/ocean_sigma_coordinate-FVCOM.ipynb b/notebooks/ocean_sigma_coordinate-FVCOM.ipynb index fee4c68..f08dbdb 100644 --- a/notebooks/ocean_sigma_coordinate-FVCOM.ipynb +++ b/notebooks/ocean_sigma_coordinate-FVCOM.ipynb @@ -2,44 +2,25 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "url = (\"http://www.smast.umassd.edu:8080/thredds/dodsC/FVCOM/NECOFS/\"\n", - " \"Forecasts/NECOFS_GOM3_FORECAST.nc\")" + "url = (\n", + " \"http://www.smast.umassd.edu:8080/thredds/dodsC/FVCOM/NECOFS/\"\n", + " \"Forecasts/NECOFS_GOM3_FORECAST.nc\"\n", + ")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[\n", - " float32 siglay(siglay, node)\n", - " long_name: Sigma Layers\n", - " standard_name: ocean_sigma_coordinate\n", - " positive: up\n", - " valid_min: -1.0\n", - " valid_max: 0.0\n", - " formula_terms: sigma: siglay eta: zeta depth: h\n", - " unlimited dimensions: \n", - " current shape = (40, 53087)\n", - " filling off]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from netCDF4 import Dataset\n", "\n", @@ -55,22 +36,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u'sigma', u'siglay'), (u'eta', u'zeta'), (u'depth', u'h')])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms\n", "\n", @@ -81,24 +51,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u'sigma', (u'siglay', u'node')),\n", - " (u'eta', (u'time', u'node')),\n", - " (u'depth', (u'node',))])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms_dims\n", "\n", @@ -110,22 +67,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(145, 40, 53087)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import z_shape\n", "\n", @@ -136,24 +82,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "{u'depth': dask.array,\n", - " u'eta': dask.array,\n", - " u'sigma': dask.array}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import prepare_arrays\n", "\n", @@ -164,39 +97,31 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(145, 40, 53087)\n" - ] - } - ], + "outputs": [], "source": [ "from odvc import ocean_sigma_coordinate\n", "\n", "\n", - "z = ocean_sigma_coordinate(arrays['sigma'],\n", - " arrays['eta'],\n", - " arrays['depth'])\n", + "z = ocean_sigma_coordinate(arrays[\"sigma\"], arrays[\"eta\"], arrays[\"depth\"])\n", "print(z.shape)" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "salt = nc.get_variables_by_attributes(standard_name='sea_water_salinity')[0]\n", - "temp = nc.get_variables_by_attributes(standard_name='sea_water_potential_temperature')[0]\n", + "salt = nc.get_variables_by_attributes(standard_name=\"sea_water_salinity\")[0]\n", + "temp = nc.get_variables_by_attributes(\n", + " standard_name=\"sea_water_potential_temperature\"\n", + ")[0]\n", "\n", "s = salt[-1, :, 175]\n", "t = temp[-1, :, 175]\n", @@ -205,22 +130,11 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\n+93vVK4osHbt2sXLL7/MsmXLOHHiBHPnzkWr1dKvXz8WLFiAphOtZm58LXJycnjggQfIyMgAYObM\nmVx99dUqV+h/DoeDp59+moKCAux2Ow8++CB9+vTplK+L5q5FSkoK999/Pz179gRaf12EfGB8++23\nOBwOli9fzq5du3jhhRd47bXX1C5LFTabDYBly5apXIk6/v73v/PJJ58QGelZsbxo0SLmzJlDVlYW\nCxYsYNWqVVx++eUqVxkYZ16LvXv3cvfdd3P33XerXFlgrVy5koSEBF566SWqqqq44YYbGDRoUKd8\nXTR3LR566CHuuecen18XId8ltX37diZMmABAZmYm2dnZKleknv3792O1Wrn33nu588472bVrl9ol\nBVRGRgZ/+ctfvHs35eTkkJXlWeU9ceJE1q9fr2Z5AXXmtcjOzmbNmjXMnj2b+fPnY7FYVK4wMKZN\nm8YjjzwCeHoj9Hp9p31dNHct9u7de16vi5APDLPZ7O2CAdDpdLjdbhUrUo/RaOTee+/lzTffZOHC\nhTzxxBOd6lr85Cc/Qac7vcFe4yVGJpOJmpoaNcpSxZnXIjMzk6eeeop3332X9PR0/vKXv6hYXeCY\nTCYiIyMxm808+uijPPbYY01+JzrT6+LMa/H4448zfPjw83pdhHxgREVFNUlFt9uNtoVdSDu6nj17\ncv3113tvx8XFUVJSonJV6mn8OrBYLMTEdN69kq644goGDx4MwOWXX86+fftUrihwCgsLufPOO7nx\nxhu59tprO/XrovG1uOaaa877dRHy76wjRoxg7dq1AOzcuZMBAwaoXJF6VqxYwQsvvABAcXExZrOZ\nxMRElatSz6BBg9i8eTMAa9euZdSoUSpXpJ777ruP3bt3A7BhwwaGDh2qckWBUVpayj333MOTTz7J\nzTffDHTe10Vz1+J8XxchP+h9xRVXsG7dOm699VbAM9DZWU2fPp158+Yxa9YswHMtOmNrq2HGy9y5\nc3nmmWdwOBz06dOHadOmqVxZ4DVci4ULF7Jw4UL0ej1JSUk899xzKlcWGK+//jo1NTUsWbKEJUuW\nADB//nyef/75Tve6aO5aPP300yxatMjn14XsJSWEEMInne/jpxBCiDaRwBBCCOGToB3DkBXcQggR\nXIK2hdF4BfcTTzzhnf0jhBBCHUHbwjjfFdyFhYW4XK5AlCaEEB2GTqejW7duPt03aAOjpRXczU0T\n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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "\n", diff --git a/notebooks/ocean_sigma_coordinate-NYHOPS.ipynb b/notebooks/ocean_sigma_coordinate-NYHOPS.ipynb index a5f2e67..5802b2b 100644 --- a/notebooks/ocean_sigma_coordinate-NYHOPS.ipynb +++ b/notebooks/ocean_sigma_coordinate-NYHOPS.ipynb @@ -2,44 +2,25 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "url = (\"http://colossus.dl.stevens-tech.edu:8080/thredds/dodsC/\"\n", - " \"latest/Bight_gcmplt.nc\")" + "url = (\n", + " \"http://colossus.dl.stevens-tech.edu:8080/thredds/dodsC/\"\n", + " \"latest/Bight_gcmplt.nc\"\n", + ")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[\n", - " float32 sigma(sigma)\n", - " long_name: stretched vertical coordinate levels\n", - " units: 1\n", - " positive: up\n", - " standard_name: ocean_sigma_coordinate\n", - " formula_terms: sigma: sigma eta: elev depth: depth\n", - " axis: Z\n", - " unlimited dimensions: \n", - " current shape = (11,)\n", - " filling off]" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from netCDF4 import Dataset\n", "\n", @@ -55,22 +36,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u'sigma', u'sigma'), (u'eta', u'elev'), (u'depth', u'depth')])" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms\n", "\n", @@ -81,24 +51,11 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "OrderedDict([(u'sigma', (u'sigma',)),\n", - " (u'eta', (u'time', u'ypos', u'xpos')),\n", - " (u'depth', (u'ypos', u'xpos'))])" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import get_formula_terms_dims\n", "\n", @@ -110,22 +67,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "(288, 11, 22, 124)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import z_shape\n", "\n", @@ -136,24 +82,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "{u'depth': dask.array,\n", - " u'eta': dask.array,\n", - " u'sigma': dask.array}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from odvc import prepare_arrays\n", "\n", @@ -165,63 +98,40 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(u'depth', (1, 1, 22, 124)),\n", - " (u'eta', (288, 1, 22, 124)),\n", - " (u'sigma', (1, 11, 1, 1))]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "[(var, arr.shape) for var, arr in arrays.items()]" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(288, 11, 22, 124)\n" - ] - } - ], + "outputs": [], "source": [ - " from odvc import ocean_sigma_coordinate\n", + "from odvc import ocean_sigma_coordinate\n", "\n", - "z = ocean_sigma_coordinate(arrays['sigma'],\n", - " arrays['eta'],\n", - " arrays['depth'])\n", + "z = ocean_sigma_coordinate(arrays[\"sigma\"], arrays[\"eta\"], arrays[\"depth\"])\n", "\n", "print(z.shape)" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "salt = nc.get_variables_by_attributes(standard_name='sea_water_salinity')[0]\n", - "temp = nc.get_variables_by_attributes(standard_name='sea_water_temperature')[0]\n", + "salt = nc.get_variables_by_attributes(standard_name=\"sea_water_salinity\")[0]\n", + "temp = nc.get_variables_by_attributes(standard_name=\"sea_water_temperature\")[0]\n", "\n", "s = salt[-1, :, 0, 0]\n", "t = temp[-1, :, 0, 0]\n", @@ -230,22 +140,11 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "collapsed": false }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "%matplotlib inline\n", "\n", diff --git a/odvc/__init__.py b/odvc/__init__.py index 0d6019f..90f4ddb 100644 --- a/odvc/__init__.py +++ b/odvc/__init__.py @@ -1,8 +1,8 @@ -# -*- coding: utf-8 -*- +try: + from ._version import __version__ +except ImportError: + __version__ = "unknown" -from __future__ import absolute_import, division, print_function - -from ._version import get_versions from .formulas import ( ocean_double_sigma_coordinate, ocean_s_coordinate, @@ -12,9 +12,6 @@ ocean_sigma_z_coordinate, ) -__version__ = get_versions()["version"] -del get_versions - __all__ = [ "ocean_double_sigma_coordinate", "ocean_sigma_z_coordinate", diff --git a/odvc/_version.py b/odvc/_version.py deleted file mode 100644 index ffb5432..0000000 --- a/odvc/_version.py +++ /dev/null @@ -1,566 +0,0 @@ -# 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.18 (https://github.com/warner/python-versioneer) - -"""Git implementation of _version.py.""" - -import errno -import os -import re -import subprocess -import sys - - -def get_keywords(): - """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.""" - - -def get_config(): - """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 = "" - cfg.versionfile_source = "odvc/_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 = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - - def decorate(f): - """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, args, cwd=None, verbose=False, hide_stderr=False, env=None -): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) - break - except EnvironmentError: - e = sys.exc_info()[1] - 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 = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """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 i 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, - } - else: - 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): - """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 = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - 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) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # 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 = set([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 = set([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 = set([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) :] - 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, root, verbose, run_command=run_command): - """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"] - - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) - 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 = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - 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 = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # 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: - # unparseable. 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 - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """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_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """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_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 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): - """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): - """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, style): - """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-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(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(): - """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 i 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/odvc/formulas.py b/odvc/formulas.py index 849baec..1854cdf 100644 --- a/odvc/formulas.py +++ b/odvc/formulas.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, print_function - import numpy as np diff --git a/odvc/utils.py b/odvc/utils.py index d87c51c..66a73cd 100644 --- a/odvc/utils.py +++ b/odvc/utils.py @@ -1,7 +1,3 @@ -# -*- coding: utf-8 -*- - -from __future__ import absolute_import, division, print_function - from collections import OrderedDict import dask diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a50133b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[build-system] +requires = ["setuptools>=41.2", "setuptools_scm", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.interrogate] +ignore-init-method = true +ignore-init-module = false +ignore-magic = false +ignore-semiprivate = false +ignore-private = false +ignore-module = false +fail-under = 85 +exclude = ["setup.py", "docs", "tests"] +verbose = 1 +quiet = false +color = true diff --git a/setup.cfg b/setup.cfg index 7d39353..5498fc4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,22 +1,52 @@ -# 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. +[metadata] +name = odvc +description = Ocean Dimensionless Vertical Coordinates +author = Filipe Fernandes +author_email = ocefpaf@gmail.com +url = https://github.com/pyoceans/odvc +long_description_content_type = text/markdown +long_description = file: README.md +license = BSD-3-Clause +license_files = LICENSE.txt +keywords = CF-conventions dimensionless coordinate vertical coordinate +project_urls = + Documentation = https://ioos.github.io/odvc + Bug Tracker = https://github.com/ioos/odvc/issues + Source Code = https://github.com/ioos/odvc +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Science/Research + Operating System :: OS Independent + License :: OSI Approved :: BSD License + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 + Topic :: Scientific/Engineering -[versioneer] -VCS = git -style = pep440 -versionfile_source = odvc/_version.py -versionfile_build = odvc/_version.py -tag_prefix = v -parentdir_prefix = +[options] +zip_safe = True +include_package_data = True +install_requires = + dask >=1 + netcdf4 + numpy +python_requires = >=3.7 +packages = find: -[tool:pytest] -flake8-max-line-length = 105 -flake8-ignore = - docs/* ALL - versioneer.py ALL - odvc/_version.py ALL +[sdist] +formats = gztar -[metadata] -description-file = README.rst -license_file = LICENSE.txt +[check-manifest] +ignore = + *.yml + .coveragerc + Makefile + docs + docs/* + notebooks + notebooks/* + tests + tests/* diff --git a/setup.py b/setup.py index ae4c056..15290dd 100644 --- a/setup.py +++ b/setup.py @@ -1,59 +1,12 @@ -from __future__ import absolute_import, division, print_function - -import os - from setuptools import setup -import versioneer - -rootpath = os.path.abspath(os.path.dirname(__file__)) - - -def read(*parts): - return open(os.path.join(rootpath, *parts), "r").read() - - -long_description = "{}\n{}".format(read("README.rst"), read("CHANGES.txt")) -LICENSE = read("LICENSE.txt") - - -with open("requirements.txt") as f: - require = f.readlines() -install_requires = [r.strip() for r in require] - setup( + # The package metadata is specified in setup.cfg but GitHub's downstream dependency graph + # does not work unless we put the name this here too. name="odvc", - python_requires=">=3.6", - version=versioneer.get_version(), - license=LICENSE, - long_description=long_description, - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Intended Audience :: Science/Research", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "License :: OSI Approved :: BSD", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Topic :: Scientific/Engineering", - "Topic :: Education", - ], - description="Ocean Dimensionless Vertical Coordinates", - author="Filipe Fernandes", - author_email="ocefpaf@gmail.com", - maintainer="Filipe Fernandes", - maintainer_email="ocefpaf@gmail.com", - url="https://github.com/pyoceans/odvc", - download_url="http://pypi.python.org/pypi/odvc", - platforms="any", - keywords=[ - "CF-conventions", - "dimensionless coordinate", - "vertical coordinate", - ], - install_requires=install_requires, - tests_require=["pytest"], - packages=["odvc"], - cmdclass=versioneer.get_cmdclass(), + use_scm_version={ + "write_to": "odvc/_version.py", + "write_to_template": '__version__ = "{version}"', + "tag_regex": r"^(?Pv)?(?P[^\+]+)(?P.*)?$", + }, ) diff --git a/tests/test_ocean_s_coordinate_g1.py b/tests/test_ocean_s_coordinate_g1.py index 77cc4a7..76819c4 100644 --- a/tests/test_ocean_s_coordinate_g1.py +++ b/tests/test_ocean_s_coordinate_g1.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import os import unittest @@ -90,6 +88,6 @@ def test_z_values(self): -15.50607592, -8.88076055, -3.15458049, - ] + ], ) np.testing.assert_allclose(self.sliced.compute(), z_comp) diff --git a/tests/test_utils.py b/tests/test_utils.py index 1de9088..c520b27 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import os import unittest @@ -35,9 +33,7 @@ def setUp(self): self.formula_terms = get_formula_terms(self.formula_terms_variable) self.dims = get_formula_terms_dims(self.nc, self.formula_terms) self.new_shape = z_shape(self.nc, self.dims) - self.arrays = prepare_arrays( - self.nc, self.formula_terms, self.new_shape - ) + self.arrays = prepare_arrays(self.nc, self.formula_terms, self.new_shape) def tearDown(self): self.nc.close() @@ -52,10 +48,7 @@ def test_no_formula_terms_variables(self): def test_formula_terms_variables(self): assert len(self.formula_terms_variables) == 1 assert hasattr(self.formula_terms_variable, "formula_terms") - assert ( - self.formula_terms_variable.standard_name - == "ocean_s_coordinate_g1" - ) + assert self.formula_terms_variable.standard_name == "ocean_s_coordinate_g1" def test_formula_terms_isstr(self): for k, v in self.formula_terms.items(): diff --git a/versioneer.py b/versioneer.py deleted file mode 100644 index 1be4fa4..0000000 --- a/versioneer.py +++ /dev/null @@ -1,1904 +0,0 @@ -# Version: 0.18 - -"""The Versioneer - like a rocketeer, but for versions. - -The Versioneer -============== - -* like a rocketeer, but for versions! -* https://github.com/warner/python-versioneer -* Brian Warner -* License: Public Domain -* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy -* [![Latest Version] -(https://pypip.in/version/versioneer/badge.svg?style=flat) -](https://pypi.python.org/pypi/versioneer/) -* [![Build Status] -(https://travis-ci.org/warner/python-versioneer.png?branch=master) -](https://travis-ci.org/warner/python-versioneer) - -This is a tool for managing a recorded version number in distutils-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 - -* `pip install versioneer` to somewhere to your $PATH -* add a `[versioneer]` section to your setup.cfg (see below) -* run `versioneer install` in your source tree, commit the results - -## 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/warner/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 langauges) 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/warner/python-versioneer/issues/38) is tracking -this issue. The discussion in -[PR #61](https://github.com/warner/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/warner/python-versioneer/issues/83) describes -this one, but upgrading to a newer version of setuptools should probably -resolve it. - -### Unicode version strings - -While Versioneer works (and is continually tested) with both Python 2 and -Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. -Newer releases probably generate unicode version strings on py2. It's not -clear that this is wrong, but it may be surprising for applications when then -write these strings to a network connection or include them in bytes-oriented -APIs like cryptographic checksums. - -[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates -this question. - - -## 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`, if necessary, to include any new configuration settings - indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. -* re-run `versioneer install` 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. - - -## 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 Creative Commons "Public Domain -Dedication" license (CC0-1.0), as described in -https://creativecommons.org/publicdomain/zero/1.0/ . - -""" - -from __future__ import print_function - -import errno -import json -import os -import re -import subprocess -import sys - -try: - import configparser -except ImportError: - import ConfigParser as configparser - - -class VersioneerConfig: - """Container for Versioneer configuration parameters.""" - - -def get_root(): - """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") - versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) 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") - versioneer_py = os.path.join(root, "versioneer.py") - if not (os.path.exists(setup_py) 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. - me = os.path.realpath(os.path.abspath(__file__)) - me_dir = os.path.normcase(os.path.splitext(me)[0]) - vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) - if me_dir != vsr_dir: - print( - "Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(me), versioneer_py) - ) - except NameError: - pass - return root - - -def get_config_from_root(root): - """Read the project setup.cfg file to determine Versioneer config.""" - # This might raise EnvironmentError (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 . - setup_cfg = os.path.join(root, "setup.cfg") - parser = configparser.SafeConfigParser() - with open(setup_cfg, "r") as f: - parser.readfp(f) - VCS = parser.get("versioneer", "VCS") # mandatory - - def get(parser, name): - if parser.has_option("versioneer", name): - return parser.get("versioneer", name) - return None - - cfg = VersioneerConfig() - cfg.VCS = VCS - cfg.style = get(parser, "style") or "" - cfg.versionfile_source = get(parser, "versionfile_source") - cfg.versionfile_build = get(parser, "versionfile_build") - cfg.tag_prefix = get(parser, "tag_prefix") - if cfg.tag_prefix in ("''", '""'): - cfg.tag_prefix = "" - cfg.parentdir_prefix = get(parser, "parentdir_prefix") - cfg.verbose = get(parser, "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 = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - - def decorate(f): - """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, args, cwd=None, verbose=False, hide_stderr=False, env=None -): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen( - [c] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - ) - break - except EnvironmentError: - e = sys.exc_info()[1] - 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 = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %s (error)" % dispcmd) - print("stdout was %s" % stdout) - return None, p.returncode - return stdout, p.returncode - - -LONG_VERSION_PY[ - "git" -] = ''' -# 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.18 (https://github.com/warner/python-versioneer) - -"""Git implementation of _version.py.""" - -import errno -import os -import re -import subprocess -import sys - - -def get_keywords(): - """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.""" - - -def get_config(): - """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 = {} -HANDLERS = {} - - -def register_vcs_handler(vcs, method): # decorator - """Decorator to mark a method as the handler for a particular VCS.""" - def decorate(f): - """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, args, cwd=None, verbose=False, hide_stderr=False, - env=None): - """Call the given command(s).""" - assert isinstance(commands, list) - p = None - for c in commands: - try: - dispcmd = str([c] + args) - # remember shell=False, so use git.cmd on windows, not just git - p = subprocess.Popen([c] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None)) - break - except EnvironmentError: - e = sys.exc_info()[1] - 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 = p.communicate()[0].strip() - if sys.version_info[0] >= 3: - stdout = stdout.decode() - if p.returncode != 0: - if verbose: - print("unable to run %%s (error)" %% dispcmd) - print("stdout was %%s" %% stdout) - return None, p.returncode - return stdout, p.returncode - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """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 i 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} - else: - 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): - """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 = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - 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) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # 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 = set([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 = set([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 = set([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):] - 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, root, verbose, run_command=run_command): - """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"] - - out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=True) - 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 = run_command(GITS, ["describe", "--tags", "--dirty", - "--always", "--long", - "--match", "%%s*" %% tag_prefix], - 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 = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # 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: - # unparseable. 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 - count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], - cwd=root) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], - cwd=root)[0].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def plus_or_dot(pieces): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """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_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%%d" %% pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%%d" %% pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """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_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 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): - """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): - """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, style): - """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-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(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(): - """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 i 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): - """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 = {} - try: - f = open(versionfile_abs, "r") - for line in f.readlines(): - 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) - f.close() - except EnvironmentError: - pass - return keywords - - -@register_vcs_handler("git", "keywords") -def git_versions_from_keywords(keywords, tag_prefix, verbose): - """Get version information from git keywords.""" - if not keywords: - raise NotThisMethod("no keywords at all, weird") - date = keywords.get("date") - if date is not None: - # 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 = set([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 = set([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 = set([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) :] - 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, root, verbose, run_command=run_command): - """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"] - - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) - 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 = run_command( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - "%s*" % tag_prefix, - ], - 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 = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) - if full_out is None: - raise NotThisMethod("'git rev-parse' failed") - full_out = full_out.strip() - - pieces = {} - pieces["long"] = full_out - pieces["short"] = full_out[:7] # maybe improved later - pieces["error"] = None - - # 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: - # unparseable. 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 - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) - pieces["distance"] = int(count_out) # total number of commits - - # commit date: see ISO-8601 comment in git_versions_from_keywords() - date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ - 0 - ].strip() - pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) - - return pieces - - -def do_vcs_install(manifest_in, versionfile_source, ipy): - """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 = [manifest_in, versionfile_source] - if ipy: - files.append(ipy) - try: - me = __file__ - if me.endswith(".pyc") or me.endswith(".pyo"): - me = os.path.splitext(me)[0] + ".py" - versioneer_file = os.path.relpath(me) - except NameError: - versioneer_file = "versioneer.py" - files.append(versioneer_file) - present = False - try: - f = open(".gitattributes", "r") - for line in f.readlines(): - if line.strip().startswith(versionfile_source): - if "export-subst" in line.strip().split()[1:]: - present = True - f.close() - except EnvironmentError: - pass - if not present: - f = open(".gitattributes", "a+") - f.write("%s export-subst\n" % versionfile_source) - f.close() - files.append(".gitattributes") - run_command(GITS, ["add", "--"] + files) - - -def versions_from_parentdir(parentdir_prefix, root, verbose): - """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 i 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, - } - else: - 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.18) 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): - """Try to determine the version from _version.py if present.""" - try: - with open(filename) as f: - contents = f.read() - except EnvironmentError: - 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, versions): - """Write the given version number to the given _version.py file.""" - os.unlink(filename) - 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): - """Return a + if we don't already have one, else return a .""" - if "+" in pieces.get("closest-tag", ""): - return "." - return "+" - - -def render_pep440(pieces): - """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_pre(pieces): - """TAG[.post.devDISTANCE] -- No -dirty. - - Exceptions: - 1: no tags. 0.post.devDISTANCE - """ - if pieces["closest-tag"]: - rendered = pieces["closest-tag"] - if pieces["distance"]: - rendered += ".post.dev%d" % pieces["distance"] - else: - # exception #1 - rendered = "0.post.dev%d" % pieces["distance"] - return rendered - - -def render_pep440_post(pieces): - """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_old(pieces): - """TAG[.postDISTANCE[.dev0]] . - - The ".dev0" means dirty. - - Eexceptions: - 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): - """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): - """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, style): - """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-pre": - rendered = render_pep440_pre(pieces) - elif style == "pep440-post": - rendered = render_pep440_post(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=False): - """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 cfg.verbose - 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(): - """Get the short version string for this project.""" - return get_versions()["version"] - - -def get_cmdclass(): - """Get the custom setuptools/distutils subclasses used by Versioneer.""" - 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/warner/python-versioneer/issues/52 - - cmds = {} - - # we add "version" to both distutils and setuptools - from distutils.core import Command - - class cmd_version(Command): - description = "report generated version string" - user_options = [] - boolean_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - 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 both distutils and 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 -> ? - - # we override different "build_py" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.build_py import build_py as _build_py - else: - from distutils.command.build_py import build_py as _build_py - - class cmd_build_py(_build_py): - def run(self): - root = get_root() - cfg = get_config_from_root(root) - versions = get_versions() - _build_py.run(self) - # 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 "cx_Freeze" in sys.modules: # cx_freeze enabled? - from cx_Freeze.dist import build_exe as _build_exe - - # 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): - 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.distutils_buildexe import py2exe as _py2exe # py3 - except ImportError: - from py2exe.build_exe import py2exe as _py2exe # py2 - - class cmd_py2exe(_py2exe): - def run(self): - 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 - - # we override different "sdist" commands for both environments - if "setuptools" in sys.modules: - from setuptools.command.sdist import sdist as _sdist - else: - from distutils.command.sdist import sdist as _sdist - - class cmd_sdist(_sdist): - def run(self): - 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, files): - 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 = - -""" - -INIT_PY_SNIPPET = """ -from ._version import get_versions -__version__ = get_versions()['version'] -del get_versions -""" - - -def do_setup(): - """Main VCS-independent setup function for installing Versioneer.""" - root = get_root() - try: - cfg = get_config_from_root(root) - except ( - EnvironmentError, - configparser.NoSectionError, - configparser.NoOptionError, - ) as e: - if isinstance(e, (EnvironmentError, 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") - if os.path.exists(ipy): - try: - with open(ipy, "r") as f: - old = f.read() - except EnvironmentError: - old = "" - if INIT_PY_SNIPPET not in old: - print(" appending to %s" % ipy) - with open(ipy, "a") as f: - f.write(INIT_PY_SNIPPET) - else: - print(" %s unmodified" % ipy) - else: - print(" %s doesn't exist, ok" % ipy) - ipy = None - - # Make sure both the top-level "versioneer.py" and versionfile_source - # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so - # they'll be copied into source distributions. Pip won't be able to - # install the package without this. - manifest_in = os.path.join(root, "MANIFEST.in") - simple_includes = set() - try: - with open(manifest_in, "r") as f: - for line in f: - if line.startswith("include "): - for include in line.split()[1:]: - simple_includes.add(include) - except EnvironmentError: - pass - # That doesn't cover everything MANIFEST.in can do - # (http://docs.python.org/2/distutils/sourcedist.html#commands), so - # it might give some false negatives. Appending redundant 'include' - # lines is safe, though. - if "versioneer.py" not in simple_includes: - print(" appending 'versioneer.py' to MANIFEST.in") - with open(manifest_in, "a") as f: - f.write("include versioneer.py\n") - else: - print(" 'versioneer.py' already in MANIFEST.in") - if cfg.versionfile_source not in simple_includes: - print( - " appending versionfile_source ('%s') to MANIFEST.in" - % cfg.versionfile_source - ) - with open(manifest_in, "a") as f: - f.write("include %s\n" % cfg.versionfile_source) - else: - print(" versionfile_source already in MANIFEST.in") - - # Make VCS-specific changes. For git, this means creating/changing - # .gitattributes to mark _version.py for export-subst keyword - # substitution. - do_vcs_install(manifest_in, cfg.versionfile_source, ipy) - return 0 - - -def scan_setup_py(): - """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 - - -if __name__ == "__main__": - cmd = sys.argv[1] - if cmd == "setup": - errors = do_setup() - errors += scan_setup_py() - if errors: - sys.exit(1)