diff --git a/.readthedocs.yml b/.readthedocs.yml index 12a5727..2a458c6 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -11,7 +11,7 @@ build: image: latest python: - version: 3.7 + version: 3.9 install: - requirements: docs/rtd-pip-requirements.txt - method: pip diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 95908f8..d95d439 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,35 +6,53 @@ trigger: - master -pool: - vmImage: 'ubuntu-latest' -strategy: - matrix: - Python36: - python.version: '3.6' - Python37: - python.version: '3.7' - -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - displayName: 'Python $(python.version)' - -- script: | - python -m pip install --upgrade pip - pip install -e ".[test]" - displayName: 'Install dependencies' - -- script: | - python -m pip freeze - displayName: 'Package listing' - -- script: | - python -m pip install pytest pytest-azurepipelines - pytest --cov=./ - coverage xml - codecov -t "$CODECOV" - displayName: 'pytest' - env: - CODECOV: $(codecov) +variables: + PYTHONUNBUFFERED: '1' + +jobs: +- template: azure-templates.yml + parameters: + name: Linux + os: linux + +- template: azure-templates.yml + parameters: + name: MacOS + os: macos + +- template: azure-templates.yml + parameters: + name: Windows + os: windows + +- job: 'PEP8' + pool: + vmImage: 'Ubuntu-18.04' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.x' + architecture: 'x64' + + - script: | + python -m pip install --upgrade flake8 + flake8 + displayName: 'Run check' + + +- job: 'Publish' + dependsOn: 'Linux' + pool: + vmImage: 'Ubuntu-18.04' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.x' + architecture: 'x64' + + - script: | + python -m pip install astropy + python setup.py sdist + displayName: 'Build sdist' diff --git a/azure-templates.yml b/azure-templates.yml new file mode 100644 index 0000000..768fa2f --- /dev/null +++ b/azure-templates.yml @@ -0,0 +1,68 @@ +jobs: +- job: ${{ format(parameters.name) }} + pool: + ${{ if eq(parameters.os, 'windows') }}: + vmImage: windows-2019 + ${{ if eq(parameters.os, 'macos') }}: + vmImage: macOS-10.15 + ${{ if eq(parameters.os, 'linux') }}: + vmImage: ubuntu-18.04 + + strategy: + matrix: + Python38: + python.version: '3.8' + Python39: + python.version: '3.9' + Python310: + python.version: '3.10' + maxParallel: 4 + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + architecture: 'x64' + + - bash: | + export PIP_INSTALL='pip install --upgrade' + echo "##vso[task.setvariable variable=PIP_INSTALL]$PIP_INSTALL" + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + displayName: Pip on Linux/Darwin + + - powershell: | + Set-Variable -Name PIP_INSTALL -Value 'python -m pip install --upgrade' + Write-Host "##vso[task.setvariable variable=PIP_INSTALL]$PIP_INSTALL" + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: Pip on Windows + + - script: | + $(PIP_INSTALL) -e .[test] + displayName: build package + + - script: | + python -m pip freeze + displayName: freeze output + + - script: | + pytest --cov=./ -v --junitxml=junit/test-results.xml + displayName: run test + + - bash: | + codecov -t $codecov_token + env: + codecov_token: $(CODECOV_TOKEN) + condition: ne( variables['Agent.OS'], 'Windows_NT' ) + displayName: codecov upload on Linux/Darwin + + - powershell: | + codecov -t "$(CODECOV_TOKEN)" + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: codecov upload on Windows + + - task: PublishTestResults@2 + condition: succeededOrFailed() + inputs: + testResultsFiles: '**/test-*.xml' + testRunTitle: 'Python $(python.version)-${{ format(parameters.name) }}' + diff --git a/docs/exts/numfig.py b/docs/exts/numfig.py deleted file mode 100644 index 3134382..0000000 --- a/docs/exts/numfig.py +++ /dev/null @@ -1,107 +0,0 @@ -from docutils.nodes import figure, caption, Text, reference, raw, SkipNode, Element -from sphinx.roles import XRefRole - - -# Element classes - -class page_ref(reference): - pass - -class num_ref(reference): - pass - - -# Visit/depart functions - -def skip_page_ref(self, node): - raise SkipNode - -def latex_visit_page_ref(self, node): - self.body.append("\\pageref{%s:%s}" % (node['refdoc'], node['reftarget'])) - raise SkipNode - -def latex_visit_num_ref(self, node): - fields = node['reftarget'].split('#') - if len(fields) > 1: - label, target = fields - ref_link = '%s:%s' % (node['refdoc'], target) - latex = "\\hyperref[%s]{%s \\ref*{%s}}" % (ref_link, label, ref_link) - self.body.append(latex) - else: - self.body.append('\\ref{%s:%s}' % (node['refdoc'], fields[0])) - - raise SkipNode - - -def doctree_read(app, doctree): - # first generate figure numbers for each figure - env = app.builder.env - figid_docname_map = getattr(env, 'figid_docname_map', {}) - - for figure_info in doctree.traverse(figure): - for id in figure_info['ids']: - figid_docname_map[id] = env.docname - - env.figid_docname_map = figid_docname_map - - -def doctree_resolved(app, doctree, docname): - i = 1 - figids = {} - for figure_info in doctree.traverse(figure): - if app.builder.name != 'latex' and app.config.number_figures: - for cap in figure_info.traverse(caption): - cap[0] = Text("%s %d: %s" % (app.config.figure_caption_prefix, i, cap[0])) - - for id in figure_info['ids']: - figids[id] = i - - i += 1 - - - # replace numfig nodes with links - if app.builder.name != 'latex': - for ref_info in doctree.traverse(num_ref): - if '#' in ref_info['reftarget']: - label, target = ref_info['reftarget'].split('#') - labelfmt = label + " %d" - else: - labelfmt = '%d' - target = ref_info['reftarget'] - - if target not in figids: - continue - - if app.builder.name == 'html': - target_doc = app.builder.env.figid_docname_map[target] - link = "%s#%s" % (app.builder.get_relative_uri(docname, target_doc), - target) - html = '%s' % (link, labelfmt %(figids[target])) - ref_info.replace_self(raw(html, html, format='html')) - else: - ref_info.replace_self(Text(labelfmt % (figids[target]))) - - -def clean_env(app): - app.builder.env.i=1 - app.builder.env.figid_docname_map = {} - -def setup(app): - app.add_config_value('number_figures', True, True) - app.add_config_value('figure_caption_prefix', "Figure", True) - - app.add_node(page_ref, - text=(skip_page_ref, None), - html=(skip_page_ref, None), - latex=(latex_visit_page_ref, None)) - - app.add_role('page', XRefRole(nodeclass=page_ref)) - - app.add_node(num_ref, - latex=(latex_visit_num_ref, None)) - - app.add_role('num', XRefRole(nodeclass=num_ref)) - - app.connect("builder-inited", clean_env) - app.connect('doctree-read', doctree_read) - app.connect('doctree-resolved', doctree_resolved) diff --git a/docs/source/conf.py b/docs/source/conf.py index 4dd0d6c..97abfa5 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -62,13 +62,6 @@ def check_sphinx_version(expected_version): 'astropy': ('http://docs.astropy.org/en/stable/', None), } -if sys.version_info[0] == 2: - intersphinx_mapping['python'] = ('http://docs.python.org/2/', None) - # intersphinx_mapping['pythonloc'] = ( - # 'http://docs.python.org/', - # os.path.abspath(os.path.join(os.path.dirname(__file__), - # 'local/python2_local_links.inv'))) - # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. @@ -76,7 +69,6 @@ def check_sphinx_version(expected_version): # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - # 'numfig', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', diff --git a/wiimatch/lsq_optimizer.py b/wiimatch/lsq_optimizer.py index 9b79871..542e0e5 100644 --- a/wiimatch/lsq_optimizer.py +++ b/wiimatch/lsq_optimizer.py @@ -273,11 +273,11 @@ def build_lsq_eqs(images, masks, sigmas, degree, center=None, def pinv_solve(matrix, free_term, nimages, tol=None): - """ + r""" Solves a system of linear equations .. math:: - a \ cdot c = b. + a \cdot c = b. using Moore-Penrose pseudoinverse. diff --git a/wiimatch/tests/test_match.py b/wiimatch/tests/test_match.py index 28319fc..084fccc 100644 --- a/wiimatch/tests/test_match.py +++ b/wiimatch/tests/test_match.py @@ -1,7 +1,7 @@ """ -A module containing unit tests for the `wcsutil` module. +A module containing unit tests for the ``wcsutil`` module. -Licensed under a 3-clause BSD style license - see LICENSE.rst +:License: :doc:`../LICENSE` """ import pytest diff --git a/wiimatch/tests/test_utils.py b/wiimatch/tests/test_utils.py index 9c7d08e..b0c332e 100644 --- a/wiimatch/tests/test_utils.py +++ b/wiimatch/tests/test_utils.py @@ -1,10 +1,9 @@ """ -A module containing unit tests for the `wcsutil` module. +A module containing unit tests for the ``wcsutil`` module. -Licensed under a 3-clause BSD style license - see LICENSE.rst +:License: :doc:`../LICENSE` """ -import pytest import numpy as np from wiimatch import utils @@ -27,6 +26,6 @@ def test_utils_coordinates_no_center(): center = tuple(i // 2 for i in image_shape) for orig, cc, i in zip(center, c[0], ind): - assert(i - orig, cc) + assert np.allclose(i - orig, cc) assert np.allclose(c[1], center, rtol=1.e-8, atol=1.e-12)