diff --git a/.codecov.yml b/.codecov.yml index 03afe9c3..04dd6510 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -20,7 +20,7 @@ coverage: target: auto if_no_uploads: error if_not_found: success - if_ci_failed: failure + if_ci_failed: error paths: '!*/tests/.*' tests: diff --git a/.codespell/ignore_lines.txt b/.codespell/ignore_lines.txt new file mode 100644 index 00000000..07fa7c8c --- /dev/null +++ b/.codespell/ignore_lines.txt @@ -0,0 +1,2 @@ +;; Please include filenames and explanations for each ignored line. +;; See https://docs.openverse.org/meta/codespell.html for docs. diff --git a/.codespell/ignore_words.txt b/.codespell/ignore_words.txt new file mode 100644 index 00000000..9757d7c0 --- /dev/null +++ b/.codespell/ignore_words.txt @@ -0,0 +1,11 @@ +;; Please include explanations for each ignored word (lowercase). +;; See https://docs.openverse.org/meta/codespell.html for docs. + +;; abbreviation for "materials" often used in a journal title +mater + +;; alternative use of socioeconomic +socio-economic + +;; Frobenius norm used in np.linalg.norm +fro diff --git a/.coveragerc b/.coveragerc index f6252ad3..0ed6eac5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,32 +1,13 @@ -# Configuration of the coverage.py tool for reporting test coverage. - +[run] +source = + diffpy.utils [report] -# RE patterns for lines to be excluded from consideration. -exclude_lines = - ## Have to re-enable the standard pragma - pragma: no cover - ## Don't complain if tests don't hit defensive assertion code: - raise AssertionError - raise NotImplementedError - ^[ ]*assert False - - ## Don't complain if non-runnable code isn't run: - ^[ ]*@unittest.skip\b - ^[ ]{4}unittest.main() - if __name__ == .__main__.: omit = */python?.?/* */site-packages/nose/* # ignore _version.py and versioneer.py .*version.* *_version.py - # ignore wx directory - */wx/* - -[run] -source = - src/diffpy/utils/ -omit = - ## exclude debug.py from codecov report - */tests/debug.py +exclude_lines = + if __name__ == '__main__': diff --git a/.flake8 b/.flake8 index 49384350..2d2cb168 100644 --- a/.flake8 +++ b/.flake8 @@ -4,9 +4,8 @@ exclude = __pycache__, build, dist, - versioneer.py, - doc/manual/source/conf.py + doc/source/conf.py max-line-length = 115 -# Ignore some style 'errors' produced while formatting by 'black' (see link below) +# Ignore some style 'errors' produced while formatting by 'black' # https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings extend-ignore = E203 diff --git a/.gitarchive.cfg b/.gitarchive.cfg deleted file mode 100644 index 95e1448c..00000000 --- a/.gitarchive.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[DEFAULT] -commit = $Format:%H$ -date = $Format:%ci$ -timestamp = $Format:%ct$ -refnames = $Format:%D$ diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 13fc0b54..00000000 --- a/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -/.gitattributes export-ignore -/.gitignore export-ignore -/.travis.yml export-ignore -/conda-recipe/ export-ignore -/devutils export-ignore -/doc export-ignore -.gitarchive.cfg export-subst -*.bat text eol=crlf diff --git a/.github/ISSUE_TEMPLATE/bug_feature.md b/.github/ISSUE_TEMPLATE/bug_feature.md new file mode 100644 index 00000000..b3454deb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_feature.md @@ -0,0 +1,16 @@ +--- +name: Bug Report or Feature Request +about: Report a bug or suggest a new feature! +title: "" +labels: "" +assignees: "" +--- + +### Problem + + + +### Proposed solution diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md new file mode 100644 index 00000000..a87a44a8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -0,0 +1,22 @@ +--- +name: Release +about: Checklist and communication channel for PyPI and GitHub release +title: "Ready for PyPI/GitHub release" +labels: "release" +assignees: "" +--- + +### Release checklist for GitHub contributors + +- [ ] All PRs/issues attached to the release are merged. +- [ ] All the badges on the README are passing. +- [ ] License information is verified as correct. If you are unsure, please comment below. +- [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are + missing), tutorials, and other human written text is up-to-date with any changes in the code. +- [ ] Installation instructions in the README, documentation and on the website (e.g., diffpy.org) are updated and + tested +- [ ] Successfully run any tutorial examples or do functional testing in some other way. +- [ ] Grammar and writing quality have been checked (no typos). + +Please mention @sbillinge when you are ready for release. Include any additional comments necessary, such as +version information and details about the pre-release. diff --git a/.github/workflows/build-wheel-release-upload.yml b/.github/workflows/build-wheel-release-upload.yml new file mode 100644 index 00000000..9ea21782 --- /dev/null +++ b/.github/workflows/build-wheel-release-upload.yml @@ -0,0 +1,16 @@ +name: Release (GitHub/PyPI) + +on: + workflow_dispatch: + push: + tags: + - '*' # Trigger on all tags initially, but tag and release privilege are verified in _build-wheel-release-upload.yml + +jobs: + release: + uses: Billingegroup/release-scripts/.github/workflows/_build-wheel-release-upload.yml@v0 + with: + project: diffpy.utils + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} diff --git a/.github/workflows/check-news-item.yml b/.github/workflows/check-news-item.yml new file mode 100644 index 00000000..be549960 --- /dev/null +++ b/.github/workflows/check-news-item.yml @@ -0,0 +1,12 @@ +name: Check for News + +on: + pull_request_target: + branches: + - main + +jobs: + check-news-item: + uses: Billingegroup/release-scripts/.github/workflows/_check-news-item.yml@v0 + with: + project: diffpy.utils diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index a4661f5c..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Build Documentation - -on: - push: - branches: - - main - release: - -jobs: - test: - runs-on: ubuntu-latest - defaults: - run: - shell: bash -l {0} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: conda-incubator/setup-miniconda@v2 - with: - activate-environment: build - auto-update-conda: true - - - name: install requirements - run: >- - conda install -n build -c conda-forge - --file requirements/build.txt - --file requirements/run.txt - --file requirements/docs.txt - --quiet --yes - - - name: install the package - run: python -m pip install . --no-deps - - - name: build documents - run: make -C doc html - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./doc/build/html diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index c39ace43..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: CI - -on: - push: - branches: - - main - - CI - pull_request: - workflow_dispatch: - -jobs: - miniconda: - name: Miniconda ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: ["ubuntu-latest"] - steps: - - name: check out diffpy.utils - uses: actions/checkout@v3 - with: - repository: diffpy/diffpy.utils - path: . - fetch-depth: 0 # avoid shallow clone with no tags - - - name: initialize miniconda - # this uses a marketplace action that sets up miniconda in a way that makes - # it easier to use. I tried setting it up without this and it was a pain - uses: conda-incubator/setup-miniconda@v2 - with: - activate-environment: test - # environment.yml file is needed by this action. Because I don't want - # maintain this but rather maintain the requirements files it just has - # basic things in it like conda and pip - environment-file: ./environment.yml - python-version: 3 - auto-activate-base: false - - - name: install diffpy.utils requirements - shell: bash -l {0} - run: | - conda config --set always_yes yes --set changeps1 no - conda config --add channels conda-forge - conda activate test - conda install --file requirements/run.txt - conda install --file requirements/test.txt - pip install . - - - name: Validate diffpy.utils - shell: bash -l {0} - run: | - conda activate test - coverage run run_tests.py - coverage report -m - codecov diff --git a/.github/workflows/matrix-and-codecov-on-merge-to-main.yml b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml new file mode 100644 index 00000000..99a3c623 --- /dev/null +++ b/.github/workflows/matrix-and-codecov-on-merge-to-main.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: + - main + release: + types: + - prereleased + - published + workflow_dispatch: + +jobs: + CI: + uses: Billingegroup/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0 + with: + project: diffpy.utils + c_extension: false + headless: false + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/publish-docs-on-release.yml b/.github/workflows/publish-docs-on-release.yml new file mode 100644 index 00000000..56667dfa --- /dev/null +++ b/.github/workflows/publish-docs-on-release.yml @@ -0,0 +1,14 @@ +name: Build and Deploy Docs + +on: + release: + types: + - published + workflow_dispatch: + +jobs: + publish-docs-on-release: + uses: Billingegroup/release-scripts/.github/workflows/_publish-docs-on-release.yml@v0 + with: + project: diffpy.utils + c_extension: false diff --git a/.github/workflows/tests-on-pr.yml b/.github/workflows/tests-on-pr.yml new file mode 100644 index 00000000..dd0a102e --- /dev/null +++ b/.github/workflows/tests-on-pr.yml @@ -0,0 +1,16 @@ +name: Tests on PR + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +jobs: + tests-on-pr: + uses: Billingegroup/release-scripts/.github/workflows/_tests-on-pr.yml@v0 + with: + project: diffpy.utils + c_extension: false + headless: false diff --git a/.gitignore b/.gitignore index f49476b4..a25212ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,49 +1,99 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] +*$py.class # C extensions *.so -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -temp -develop-eggs +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +venv/ +*.egg-info/ .installed.cfg -lib -lib64 -tags +*.egg +bin/ +temp/ +tags/ errors.err +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + # Installer logs pip-log.txt +pip-delete-this-directory.txt MANIFEST # Unit test / coverage reports +htmlcov/ +.tox/ .coverage -.tox +.coverage.* +.cache nosetests.xml +coverage.xml +*,cover +.hypothesis/ # Translations *.mo +*.pot # Mr Developer .mr.developer.cfg .project .pydevproject +# Django stuff: +*.log + +# Sphinx documentation +docs/build/ +docs/source/generated/ + +# pytest +.pytest_cache/ + +# PyBuilder +target/ + +# Editor files +# mac +.DS_Store +*~ + +# vim +*.swp +*.swo + +# pycharm +.idea/ + +# VSCode +.vscode/ + +# Ipython Notebook +.ipynb_checkpoints + # version information setup.cfg /src/diffpy/*/version.cfg # Rever rever/ - -# PyCharm -.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4588061..aee43d0e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,10 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - exclude: '\.(rst|txt)$' + - id: check-case-conflict + - id: check-merge-conflict + - id: check-toml + - id: check-added-large-files - repo: https://github.com/psf/black rev: 24.4.2 hooks: @@ -41,3 +44,9 @@ repos: name: Prevent Commit to Main Branch args: ["--branch", "main"] stages: [pre-commit] + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: + - tomli diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 00000000..d115a8aa --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,10 @@ +Authors +======= + +Billinge Group and community contributors. + +Contributors +------------ + +For a list of contributors, visit +https://github.com/diffpy/diffpy.utils/graphs/contributors diff --git a/AUTHORS.txt b/AUTHORS.txt deleted file mode 100644 index 92b450db..00000000 --- a/AUTHORS.txt +++ /dev/null @@ -1,5 +0,0 @@ -Pavol Juhas -Andrew yang -Timur Davis -Christopher L. Farrow -Simon J.L. Billinge diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a0750dae..3032bdd3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,51 @@ Release Notes .. current developments +3.5.0 +===== + +**Added:** + +* Support for Python 3.13 + +**Removed:** + +* Support for Python 3.10 + + +3.4.3 +===== + +**Added:** + +* Diffraction_objects mentioned in the README + +**Fixed:** + +* Recut to group's package standard, fix installation, add GitHub release workflow +* setuptools-git-versioning from <2.0 to >= 2.0 in pyproject.toml +* Two Pytest warnings due to numpy and pytest mocker in test_dump function +* Add pip dependencies under pip.txt and conda dependencies under conda.txt + + +3.4.2 +===== + +**Added:** + +* link docs in the README + +**Changed:** + +* removed need to install requirements separately when pip installing. + +**Fixed:** + +* Updated package structure to new group standard + + + + 3.4.0 ===== @@ -72,7 +117,7 @@ v3.2.3 **Added:** -* Compatability with Python 3.12.0rc3, 3.11. +* Compatibility with Python 3.12.0rc3, 3.11. * CI Coverage. * New tests for loadData function. * loadData function now toggleable. Can return either (a) data read from data blocks or (b) header information stored diff --git a/CODE_OF_CONDUCT.rst b/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..ff9c3561 --- /dev/null +++ b/CODE_OF_CONDUCT.rst @@ -0,0 +1,133 @@ +===================================== + Contributor Covenant Code of Conduct +===================================== + +Our Pledge +---------- + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +Our Standards +------------- + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Enforcement Responsibilities +---------------------------- + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +Scope +----- + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +Enforcement +----------- + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +sb2896@columbia.edu. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +Enforcement Guidelines +---------------------- + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +1. Correction +**************** + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +2. Warning +************* + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +3. Temporary Ban +****************** + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +4. Permanent Ban +****************** + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +Attribution +----------- + +This Code of Conduct is adapted from the `Contributor Covenant `_. + +Community Impact Guidelines were inspired by `Mozilla's code of conduct enforcement ladder `_. + +For answers to common questions about this code of conduct, see the `FAQ `_. `Translations are available `_ diff --git a/LICENSE.rst b/LICENSE.rst new file mode 100644 index 00000000..d042ca2c --- /dev/null +++ b/LICENSE.rst @@ -0,0 +1,141 @@ +OPEN SOURCE LICENSE AGREEMENT +============================= + +Copyright (c) 1989, 1991 Free Software Foundation, Inc. + +Copyright (c) 2006, The Regents of the University of California through Lawrence Berkeley National Laboratory + +Copyright (c) 2006-2007, Board of Trustees of Michigan State University + +Copyright (c) 2008-2012, The Trustees of Columbia University in the City of New York + +Copyright (c) 2009-2011, University of Tennessee + +Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") + +Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National Laboratory + +Copyright (c) 2019-2024, The Trustees of Columbia University in the City of New York. +All rights reserved. + +The "DiffPy-CMI" is distributed subject to the following license conditions: + +.. code-block:: text + + SOFTWARE LICENSE AGREEMENT + + Software: DiffPy-CMI + + + (1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either + source code, or binary form and accompanying documentation). + + Part of the software was derived from the DANSE, ObjCryst++ (with permission), + PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of + which the original Copyrights are contained in each individual file. + + Each licensee is addressed as "you" or "Licensee." + + + (2) The copyright holders shown above and their third-party Licensors hereby + grant licensee a royalty-free nonexclusive license, subject to the limitations + stated herein and U.S. Government license rights. + + + (3) You may modify and make a copy or copies of the software for use within + your organization, if you meet the following conditions: + + (a) Copies in source code must include the copyright notice and this + software license agreement. + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy. + + + (4) You may modify a copy or copies of the Software or any portion of it, thus + forming a work based on the Software, and distribute copies of such work + outside your organization, if you meet all of the following conditions: + + (a) Copies in source code must include the copyright notice and this + Software License Agreement; + + (b) Copies in binary form must include the copyright notice and this + Software License Agreement in the documentation and/or other materials + provided with the copy; + + (c) Modified copies and works based on the Software must carry prominent + notices stating that you changed specified portions of the Software. + + (d) Neither the name of Brookhaven Science Associates or Brookhaven + National Laboratory nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + written permission. + + + (5) Portions of the Software resulted from work developed under a U.S. + Government contract and are subject to the following license: + The Government is granted for itself and others acting on its behalf a + paid-up, nonexclusive, irrevocable worldwide license in this computer software + to reproduce, prepare derivative works, and perform publicly and display + publicly. + + + (6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT + WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY + LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND + THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL + LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF + THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE + PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION + UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. + + + (7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR + THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF + ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, + CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING + BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, + WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING + NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS + BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. + + +Brookhaven National Laboratory Notice +===================================== + +Acknowledgment of sponsorship +----------------------------- + +This software was produced by the Brookhaven National Laboratory, under +Contract DE-AC02-98CH10886 with the Department of Energy. + + +Government disclaimer of liability +---------------------------------- + +Neither the United States nor the United States Department of Energy, nor +any of their employees, makes any warranty, express or implied, or assumes +any legal liability or responsibility for the accuracy, completeness, or +usefulness of any data, apparatus, product, or process disclosed, or +represents that its use would not infringe privately owned rights. + + +Brookhaven disclaimer of liability +---------------------------------- + +Brookhaven National Laboratory makes no representations or warranties, +express or implied, nor assumes any liability for the use of this software. + + +Maintenance of notice +--------------------- + +In the interest of clarity regarding the origin and status of this +software, Brookhaven National Laboratory requests that any recipient of it +maintain this notice affixed to any distribution by the recipient that +contains a copy or derivative of this software. + +END OF LICENSE diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index f6d92af7..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,137 +0,0 @@ -OPEN SOURCE LICENSE AGREEMENT -============================= - -Copyright (c) 2009-2011, University of Tennessee -Copyright (c) 1989, 1991 Free Software Foundation, Inc. -Copyright (c) 2006, The Regents of the University of California through - Lawrence Berkeley National Laboratory -Copyright (c) 2014, Australian Synchrotron Research Program Inc., ("ASRP") -Copyright (c) 2006-2007, Board of Trustees of Michigan State University -Copyright (c) 2008-2012, The Trustees of Columbia University in the City - of New York - -Copyright (c) 2014-2019, Brookhaven Science Associates, Brookhaven National - Laboratory - - -The "DiffPy-CMI" is distributed subject to the following license conditions: - - -SOFTWARE LICENSE AGREEMENT - - Software: DiffPy-CMI - - -(1) The "Software", below, refers to the aforementioned DiffPy-CMI (in either -source code, or binary form and accompanying documentation). - -Part of the software was derived from the DANSE, ObjCryst++ (with permission), -PyCifRW, Python periodictable, CCTBX, and SasView open source projects, of -which the original Copyrights are contained in each individual file. - -Each licensee is addressed as "you" or "Licensee." - - -(2) The copyright holders shown above and their third-party Licensors hereby -grant licensee a royalty-free nonexclusive license, subject to the limitations -stated herein and U.S. Government license rights. - - -(3) You may modify and make a copy or copies of the software for use within -your organization, if you meet the following conditions: - - (a) Copies in source code must include the copyright notice and this - software license agreement. - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy. - - -(4) You may modify a copy or copies of the Software or any portion of it, thus -forming a work based on the Software, and distribute copies of such work -outside your organization, if you meet all of the following conditions: - - (a) Copies in source code must include the copyright notice and this - Software License Agreement; - - (b) Copies in binary form must include the copyright notice and this - Software License Agreement in the documentation and/or other materials - provided with the copy; - - (c) Modified copies and works based on the Software must carry prominent - notices stating that you changed specified portions of the Software. - - (d) Neither the name of Brookhaven Science Associates or Brookhaven - National Laboratory nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - written permission. - - -(5) Portions of the Software resulted from work developed under a U.S. -Government contract and are subject to the following license: -The Government is granted for itself and others acting on its behalf a -paid-up, nonexclusive, irrevocable worldwide license in this computer software -to reproduce, prepare derivative works, and perform publicly and display -publicly. - - -(6) WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" WITHOUT -WARRANTY OF ANY KIND. THE COPYRIGHT HOLDERS, THEIR THIRD PARTY -LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND -THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING -BUT NOT LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL -LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF -THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF THE SOFTWARE WOULD NOT INFRINGE -PRIVATELY OWNED RIGHTS, (4) DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION -UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL BE CORRECTED. - - -(7) LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT HOLDERS, THEIR -THIRD PARTY LICENSORS, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF -ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, INCIDENTAL, -CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF ANY KIND OR NATURE, INCLUDING -BUT NOT LIMITED TO LOSS OF PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, -WHETHER SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING -NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, EVEN IF ANY OF SAID PARTIES HAS -BEEN WARNED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGES. - - -Brookhaven National Laboratory Notice -===================================== - -Acknowledgment of sponsorship ------------------------------ - -This software was produced by the Brookhaven National Laboratory, under -Contract DE-AC02-98CH10886 with the Department of Energy. - - -Government disclaimer of liability ----------------------------------- - -Neither the United States nor the United States Department of Energy, nor -any of their employees, makes any warranty, express or implied, or assumes -any legal liability or responsibility for the accuracy, completeness, or -usefulness of any data, apparatus, product, or process disclosed, or -represents that its use would not infringe privately owned rights. - - -Brookhaven disclaimer of liability ----------------------------------- - -Brookhaven National Laboratory makes no representations or warranties, -express or implied, nor assumes any liability for the use of this software. - - -Maintenance of notice ---------------------- - -In the interest of clarity regarding the origin and status of this -software, Brookhaven National Laboratory requests that any recipient of it -maintain this notice affixed to any distribution by the recipient that -contains a copy or derivative of this software. - - -END OF LICENSE diff --git a/MANIFEST.in b/MANIFEST.in index 1e928c83..f1a78eec 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,15 +1,12 @@ -recursive-include src * -include AUTHORS.txt LICENSE*.txt README.rst -recursive-exclude src *.py[co] -global-exclude .gitattributes .gitignore .gitarchive.cfg -global-exclude .DS_Store +graft src +graft tests +graft requirements -# Avoid user content in setup.cfg to make distribution reproducible. -exclude setup.cfg +include AUTHORS.rst LICENSE*.rst README.rst -# Exclude git-tracked files spuriously added by setuptools_scm -exclude .coveragerc -exclude .travis* -prune conda-recipe -prune devutils -prune doc +# Exclude all bytecode files and __pycache__ directories +global-exclude *.py[cod] # Exclude all .pyc, .pyo, and .pyd files. +global-exclude .DS_Store # Exclude Mac filesystem artifacts. +global-exclude __pycache__ # Exclude Python cache directories. +global-exclude .git* # Exclude git files and directories. +global-exclude .idea # Exclude PyCharm project settings. diff --git a/README.rst b/README.rst index b7b1ec35..48967571 100644 --- a/README.rst +++ b/README.rst @@ -1,26 +1,73 @@ -.. image:: https://github.com/diffpy/diffpy.utils/actions/workflows/main.yml/badge.svg - :target: https://github.com/diffpy/diffpy.utils/actions/workflows/main.yml +|Icon| |title|_ +=============== -.. image:: https://codecov.io/gh/diffpy/diffpy.utils/branch/main/graph/badge.svg - :target: https://codecov.io/gh/diffpy/diffpy.utils +.. |title| replace:: diffpy.utils +.. _title: https://diffpy.github.io/diffpy.utils +.. |Icon| image:: https://avatars.githubusercontent.com/diffpy + :target: https://diffpy.github.io/diffpy.utils + :height: 100px -diffpy.utils +|PyPi| |Forge| |PythonVersion| |PR| + +|CI| |Codecov| |Black| |Tracking| + +.. |Black| image:: https://img.shields.io/badge/code_style-black-black + :target: https://github.com/psf/black + +.. |CI| image:: https://github.com/diffpy/diffpy.utils/actions/workflows/matrix-and-codecov-on-merge-to-main.yml/badge.svg + :target: https://github.com/diffpy/diffpy.utils/actions/workflows/matrix-and-codecov-on-merge-to-main.yml + +.. |Codecov| image:: https://codecov.io/gh/diffpy/diffpy.utils/branch/main/graph/badge.svg + :target: https://codecov.io/gh/diffpy/diffpy.utils + +.. |Forge| image:: https://img.shields.io/conda/vn/conda-forge/diffpy.utils + :target: https://anaconda.org/conda-forge/diffpy.utils + +.. |PR| image:: https://img.shields.io/badge/PR-Welcome-29ab47ff + +.. |PyPi| image:: https://img.shields.io/pypi/v/diffpy.utils + :target: https://pypi.org/project/diffpy.utils/ + +.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/diffpy.utils + :target: https://pypi.org/project/diffpy.utils/ + +.. |Tracking| image:: https://img.shields.io/badge/issue_tracking-github-blue + :target: https://github.com/diffpy/diffpy.utils/issues + +diffpy.utils Package ======================================================================== General purpose shared utilities for the diffpy libraries. The diffpy.utils package provides functions for extracting array data from -variously formatted text files and wx GUI utilities used by the PDFgui -program. The package also includes an interpolation function based on the +variously formatted text files, an interpolation function based on the Whittaker-Shannon formula that can be used to resample a PDF or other profile -function over a new grid. +function over a new grid, `Diffraction_objects` for conveniently manipulating +diffraction data, and some wx GUI utilities used by the PDFgui +program. -For more information about the diffpy.utils library, see the users manual at -http://diffpy.github.io/diffpy.utils. +Citation +-------- -INSTALLATION ------------------------------------------------------------------------- +If you use this program for a scientific research that leads +to publication, we ask that you acknowledge use of the program +by citing the following paper in your publication: + + P. Juhás, C. L. Farrow, X. Yang, K. R. Knox and S. J. L. Billinge, + `Complex modeling: a strategy and software program for combining + multiple information sources to solve ill posed structure and + nanostructure inverse problems + `__, + *Acta Crystallogr. A* **71**, 562-568 (2015). + +Documentation +------------- + +Documentation may be found at, https://diffpy.github.io/diffpy.utils + +Installation +------------ The preferred method is to use `Miniconda Python `_ @@ -28,66 +75,68 @@ and install from the "conda-forge" channel of Conda packages. To add "conda-forge" to the conda channels, run the following in a terminal. :: - conda config --add channels conda-forge + conda config --add channels conda-forge We want to install our packages in a suitable conda environment. -The following creates and activates a new environment named ``diffpy-utils`` :: +The following creates and activates a new environment named ``diffpy.utils_env`` :: - conda create -n diffpy-utils python=3 - conda activate diffpy-utils + conda create -n diffpy.utils_env diffpy.utils + conda activate diffpy.utils_env -Then, to fully install ``diffpy.utils`` in our active environment, run :: +To confirm that the installation was successful, type :: - conda install diffpy.utils + python -c "import diffpy.utils; print(diffpy.utils.__version__)" -Another option is to use ``pip`` to download and install the latest release from -`Python Package Index `_. -To install using ``pip`` into your ``diffpy-utils`` environment, we will also have to install dependencies :: +The output should print the latest version displayed on the badges above. - pip install numpy - pip install diffpy.utils - -For those planning to use functions in the ``diffpy.utils.wx`` module, you will also need to install ``wxPython``. -Both of the following lines will install this package. :: +If the above does not work, you can use ``pip`` to download and install the latest release from +`Python Package Index `_. +To install using ``pip`` into your ``diffpy.utils_env`` environment, type :: - conda install wxPython - pip install wxPython + pip install diffpy.utils If you prefer to install from sources, after installing the dependencies, obtain the source archive from `GitHub `_. Once installed, ``cd`` into your ``diffpy.utils`` directory and run the following :: - pip install . + pip install . -To check the installation integrity, if the following passes all checks, you are good! :: +Getting Started +--------------- - pip install pytest - python -m diffpy.utils.tests.run +You may consult our `online documentation `_ for tutorials and API references. +Support and Contribute +---------------------- -DEVELOPMENT ------------------------------------------------------------------------- +`Diffpy user group `_ is the discussion forum for general questions and discussions about the use of diffpy.utils. Please join the diffpy.utils users community by joining the Google group. The diffpy.utils project welcomes your expertise and enthusiasm! -diffpy.utils is an open-source software developed as a part of the -DiffPy-CMI complex modeling initiative at the Brookhaven National -Laboratory. The diffpy.utils sources are hosted at -https://github.com/diffpy/diffpy.utils. +If you see a bug or want to request a feature, please `report it as an issue `_ and/or `submit a fix as a PR `_. You can also post it to the `Diffpy user group `_. -Feel free to fork the project and contribute. To install diffpy.utils +Feel free to fork the project and contribute. To install diffpy.utils in a development mode, with its sources being directly used by Python rather than copied to a package directory, use the following in the root directory :: - pip install -e . + pip install -e . + +To ensure code quality and to prevent accidental commits into the default branch, please set up the use of our pre-commit +hooks. + +1. Install pre-commit in your working environment by running ``conda install pre-commit``. -Note that this is only supported for `setuptools` version 62.0 and above. +2. Initialize pre-commit (one time only) ``pre-commit install``. +Thereafter your code will be linted by black and isort and checked against flake8 before you can commit. +If it fails by black or isort, just rerun and it should pass (black and isort will modify the files so should +pass after they are modified). If the flake8 test fails please see the error messages and fix them manually before +trying to commit again. -CONTACTS ------------------------------------------------------------------------- +Improvements and fixes are always appreciated. -For more information on diffpy.utils please visit the project web-page +Before contributing, please read our `Code of Conduct `_. -http://www.diffpy.org/ +Contact +------- -or email Prof. Simon Billinge at sb2896@columbia.edu. +For more information on diffpy.utils please visit the project `web-page `_ or email Prof. Simon Billinge at sb2896@columbia.edu. diff --git a/devutils/makesdist b/devutils/makesdist deleted file mode 100755 index 8b0a2179..00000000 --- a/devutils/makesdist +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -"""Create source distribution tar.gz archive, where each file belongs -to a root user and modification time is set to the git commit time. -""" - -import glob -import gzip -import os -import subprocess -import sys -import tarfile - -from setup import FALLBACK_VERSION, versiondata - -BASEDIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -sys.path.insert(0, BASEDIR) - - -timestamp = versiondata.getint("DEFAULT", "timestamp") - -vfb = versiondata.get("DEFAULT", "version").split(".post")[0] + ".post0" -emsg = "Invalid FALLBACK_VERSION. Expected %r got %r." -assert vfb == FALLBACK_VERSION, emsg % (vfb, FALLBACK_VERSION) - - -def inform(s): - sys.stdout.write(s) - sys.stdout.flush() - return - - -inform('Run "setup.py sdist --formats=tar" ') -cmd_sdist = [sys.executable] + "setup.py sdist --formats=tar".split() -ec = subprocess.call(cmd_sdist, cwd=BASEDIR, stdout=open(os.devnull, "w")) -if ec: - sys.exit(ec) -inform("[done]\n") - -tarname = max(glob.glob(BASEDIR + "/dist/*.tar"), key=os.path.getmtime) - -tfin = tarfile.open(tarname) -fpout = gzip.GzipFile(tarname + ".gz", "w", mtime=0) -tfout = tarfile.open(fileobj=fpout, mode="w") - - -def fixtarinfo(tinfo): - tinfo.uid = tinfo.gid = 0 - tinfo.uname = tinfo.gname = "root" - tinfo.mtime = timestamp - tinfo.mode &= ~0o022 - return tinfo - - -inform("Filter %s --> %s.gz " % (2 * (os.path.basename(tarname),))) -for ti in tfin: - tfout.addfile(fixtarinfo(ti), tfin.extractfile(ti)) - -tfin.close() -os.remove(tarname) -inform("[done]\n") diff --git a/doc/Makefile b/doc/Makefile index 00a6ed10..623232f0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -6,6 +6,7 @@ SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build +BASENAME = $(subst .,,$(subst $() $(),,diffpy.utils)) # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) @@ -85,17 +86,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/diffpyutils.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/$(BASENAME).qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/diffpyutils.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/$(BASENAME).qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/diffpyutils" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/diffpyutils" + @echo "# mkdir -p $$HOME/.local/share/devhelp/$(BASENAME)" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/$(BASENAME)" @echo "# devhelp" epub: diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 00000000..2be83069 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=PackagingScientificPython + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder new file mode 100644 index 00000000..e69de29b diff --git a/doc/source/api/diffpy.utils.parsers.rst b/doc/source/api/diffpy.utils.parsers.rst index 82c70ed7..0709cf3a 100644 --- a/doc/source/api/diffpy.utils.parsers.rst +++ b/doc/source/api/diffpy.utils.parsers.rst @@ -1,4 +1,4 @@ -.. _Parsers Documentation: +:tocdepth: -1 diffpy.utils.parsers package ============================ @@ -8,28 +8,37 @@ diffpy.utils.parsers package :undoc-members: :show-inheritance: -For a sample data extraction workflow, see :ref:`parsers example`. +Submodules +---------- + +diffpy.utils.parsers.resample module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.utils.parsers.resample + :members: + :undoc-members: + :show-inheritance: diffpy.utils.parsers.loaddata module ------------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. automodule:: diffpy.utils.parsers.loaddata :members: :undoc-members: :show-inheritance: -diffpy.utils.parsers.serialization module ------------------------------------------ +diffpy.utils.parsers.custom_exceptions module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.utils.parsers.serialization +.. automodule:: diffpy.utils.parsers.custom_exceptions :members: :undoc-members: :show-inheritance: -diffpy.utils.parsers.resample module ------------------------------------- +diffpy.utils.parsers.serialization module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. automodule:: diffpy.utils.parsers.resample +.. automodule:: diffpy.utils.parsers.serialization :members: :undoc-members: :show-inheritance: diff --git a/doc/source/api/diffpy.utils.rst b/doc/source/api/diffpy.utils.rst index f9a9c099..cf69f596 100644 --- a/doc/source/api/diffpy.utils.rst +++ b/doc/source/api/diffpy.utils.rst @@ -12,15 +12,17 @@ Subpackages ----------- .. toctree:: + :titlesonly: diffpy.utils.parsers diffpy.utils.wx + diffpy.utils.scattering_objects Submodules ---------- diffpy.utils.tools module -------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^ .. automodule:: diffpy.utils.tools :members: diff --git a/doc/source/api/diffpy.utils.scattering_objects.rst b/doc/source/api/diffpy.utils.scattering_objects.rst new file mode 100644 index 00000000..fe511bf5 --- /dev/null +++ b/doc/source/api/diffpy.utils.scattering_objects.rst @@ -0,0 +1,28 @@ +:tocdepth: -1 + +diffpy.utils.scattering_objects package +======================================= + +.. automodule:: diffpy.utils.scattering_objects + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +diffpy.utils.scattering_objects.user_config module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.utils.scattering_objects.user_config + :members: + :undoc-members: + :show-inheritance: + +diffpy.utils.scattering_objects.diffraction_objects module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. automodule:: diffpy.utils.scattering_objects.diffraction_objects + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/api/diffpy.utils.wx.rst b/doc/source/api/diffpy.utils.wx.rst index fb747f58..76c89035 100644 --- a/doc/source/api/diffpy.utils.wx.rst +++ b/doc/source/api/diffpy.utils.wx.rst @@ -1,4 +1,4 @@ -.. _wx Python Utilities Documentation +:tocdepth: -1 diffpy.utils.wx package ======================= @@ -8,8 +8,11 @@ diffpy.utils.wx package :undoc-members: :show-inheritance: +Submodules +---------- + diffpy.utils.wx.gridutils module --------------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. automodule:: diffpy.utils.wx.gridutils :members: diff --git a/doc/source/conf.py b/doc/source/conf.py index e85a33da..721f940e 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -13,20 +13,20 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import os import sys import time from importlib.metadata import version +from pathlib import Path # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) -sys.path.insert(0, os.path.abspath("../..")) -sys.path.insert(0, os.path.abspath("../../src")) +# documentation root, use Path().resolve() to make it absolute, like shown here. +# sys.path.insert(0, str(Path(".").resolve())) +sys.path.insert(0, str(Path("../..").resolve())) +sys.path.insert(0, str(Path("../../src").resolve())) # abbreviations -ab_authors = "Pavol Juhás, Timur Davis, Christopher L. Farrow, Simon J.L. Billinge group" +ab_authors = "Pavol Juhás, Christopher L. Farrow, Billinge Group members and community contributors" # -- General configuration ------------------------------------------------ @@ -38,8 +38,11 @@ # ones. extensions = [ "sphinx.ext.autodoc", - "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.todo", "sphinx.ext.viewcode", + "sphinx.ext.intersphinx", + "sphinx_rtd_theme", "m2r", ] @@ -59,7 +62,7 @@ # General information about the project. project = "diffpy.utils" -copyright = "%Y, Brookhaven National Laboratory" +copyright = "%Y, The Trustees of Columbia University in the City of New York" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -199,7 +202,8 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = "diffpyutilsdoc" +basename = "diffpy.utils".replace(" ", "").replace(".", "") +htmlhelp_basename = basename + "doc" # -- Options for LaTeX output --------------------------------------------- diff --git a/doc/source/examples/toolsexample.rst b/doc/source/examples/toolsexample.rst index d4d00cce..b3f615fd 100644 --- a/doc/source/examples/toolsexample.rst +++ b/doc/source/examples/toolsexample.rst @@ -56,4 +56,4 @@ Using the tools module, we can efficiently get them in terms of a dictionary. updated_dict = get_package_info("my_package", metadata=existing_dict)) note that `"diffpy.utils"` is automatically included in the package info since the `get_user_info` function is - part of diffpy.utils. + part of diffpy.utils. diff --git a/doc/source/index.rst b/doc/source/index.rst index 0cd373a6..f9f9fe80 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -1,8 +1,10 @@ -#################################################### -diffpy.utils documentation -#################################################### +####### +|title| +####### -diffpy.utils - general purpose shared utilities for the diffpy libraries. +.. |title| replace:: diffpy.utils documentation + +diffpy.utils - Shared utilities for diffpy packages. | Software version |release|. | Last updated |today|. @@ -28,22 +30,22 @@ Authors diffpy.utils is developed by members of the Billinge Group at Columbia University and at Brookhaven National Laboratory including -Pavol Juhás, Timur Davis, Christopher L. Farrow, Simon J.L. Billinge. +Pavol Juhás, Christopher L. Farrow, the Billinge Group +and its community contributors. For a detailed list of contributors see https://github.com/diffpy/diffpy.utils/graphs/contributors. -====================================== +============ Installation -====================================== +============ See the `README `_ file included with the distribution. -====================================== +================= Table of contents -====================================== - +================= .. toctree:: :titlesonly: @@ -53,9 +55,9 @@ Table of contents Examples Package API -====================================== +======= Indices -====================================== +======= * :ref:`genindex` * :ref:`search` diff --git a/doc/source/utilities/toolsutility.rst b/doc/source/utilities/toolsutility.rst index 973056e5..01685a93 100644 --- a/doc/source/utilities/toolsutility.rst +++ b/doc/source/utilities/toolsutility.rst @@ -17,7 +17,7 @@ The ``diffpy.utils.tools`` module provides tool functions for use with diffpy ap ``{"package_info": {"package1": "version_number1", "package2": "version_number2"}`` if the function is called more than once. - Users can use these functions to track and manage versions of packages that can later be stored, for example, in an output - file header. + Users can use these functions to track and manage versions of packages that can later be stored, for example, in an output + file header. For a more in-depth tutorial for how to use these tools, click :ref:`here `. diff --git a/news/codespell.rst b/news/codespell.rst new file mode 100644 index 00000000..8c5ba6d2 --- /dev/null +++ b/news/codespell.rst @@ -0,0 +1,23 @@ +**Added:** + +* Spelling check via Codespell in pre-commit + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/news/dump.rst b/news/dump.rst new file mode 100644 index 00000000..7f99d586 --- /dev/null +++ b/news/dump.rst @@ -0,0 +1,23 @@ +**Added:** + +* functionality in dump to allow writing data on dspace + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/pyproject.toml b/pyproject.toml index 5d54b46f..4f9238ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,41 +1,40 @@ [build-system] -requires = ["setuptools>=62.0", "setuptools-git-versioning<2"] +requires = ["setuptools>=62.0", "setuptools-git-versioning>=2.0"] build-backend = "setuptools.build_meta" [project] name = "diffpy.utils" -dynamic=['version'] +dynamic=['version', 'dependencies'] authors = [ { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, ] maintainers = [ { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, ] -description = "Shared utilities for diffpy packages." +description = "Shared utilities for diffpy packages" keywords = ["text data parsers", "wx grid", "diffraction objects"] readme = "README.rst" -requires-python = ">=3.9" +requires-python = ">=3.11, <3.14" classifiers = [ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', + 'License :: Free To Use But Restricted', 'Operating System :: MacOS :: MacOS X', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', 'Operating System :: Unix', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Scientific/Engineering :: Physics', + 'Topic :: Scientific/Engineering :: Chemistry', ] [project.urls] Homepage = "https://github.com/diffpy/diffpy.utils/" -Issues = "https://github.com/diffpy/diffpy.utils/issues" +Issues = "https://github.com/diffpy/diffpy.utils/issues/" [tool.setuptools-git-versioning] enabled = true @@ -45,10 +44,18 @@ dirty_template = "{tag}" [tool.setuptools.packages.find] where = ["src"] # list of folders that contain the packages (["."] by default) -include = ["diffpy*"] # package names should match these glob patterns (["*"] by default) -exclude = ["diffpy.utils.tests*"] # exclude packages matching these glob patterns (empty by default) +include = ["*"] # package names should match these glob patterns (["*"] by default) +exclude = [] # exclude packages matching these glob patterns (empty by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[tool.setuptools.dynamic] +dependencies = {file = ["requirements/pip.txt"]} + +[tool.codespell] +exclude-file = ".codespell/ignore_lines.txt" +ignore-words = ".codespell/ignore_words.txt" +skip = "*.cif,*.dat" + [tool.black] line-length = 115 include = '\.pyi?$' diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 21473ae6..00000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -testpaths= src/diffpy/utils/tests -python_files = test_*.py diff --git a/requirements/build.txt b/requirements/build.txt index f72d870d..e69de29b 100644 --- a/requirements/build.txt +++ b/requirements/build.txt @@ -1,2 +0,0 @@ -python -setuptools diff --git a/requirements/run.txt b/requirements/conda.txt similarity index 100% rename from requirements/run.txt rename to requirements/conda.txt diff --git a/requirements/pip.txt b/requirements/pip.txt new file mode 100644 index 00000000..24ce15ab --- /dev/null +++ b/requirements/pip.txt @@ -0,0 +1 @@ +numpy diff --git a/requirements/test.txt b/requirements/test.txt index 72644779..9966e09d 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -4,4 +4,5 @@ codecov coverage pytest-env pytest-mock +pytest-cov freezegun diff --git a/rever.xsh b/rever.xsh deleted file mode 100644 index f1a87228..00000000 --- a/rever.xsh +++ /dev/null @@ -1,18 +0,0 @@ -$PROJECT = 'diffpy.utils' -$ACTIVITIES = [ - 'changelog', # Create a CHANGELOG.rst using news directory - 'tag', # Creates a tag for the new version number - 'push_tag', # Pushes the tag up to the $TAG_REMOTE - 'ghrelease', # Creates a Github release entry for the new tag - 'pypi', # Sends the package to pypi - ] -$CHANGELOG_FILENAME = 'CHANGELOG.rst' -$CHANGELOG_TEMPLATE = 'TEMPLATE.rst' -$CHANGELOG_IGNORE = ['TEMPLATE.rst'] -$PUSH_TAG_REMOTE = 'git@github.com:diffpy/diffpy.utils.git' # Repo to push tags to -$GITHUB_ORG = 'diffpy' # Github org for Github releases and conda-forge -$GITHUB_REPO = 'diffpy.utils' # Github repo for Github releases and conda-forge -$GHRELEASE_PREPEND = """See [CHANGELOG.rst](CHANGELOG.rst) for detailed release notes. - -The release is also available at [PyPI](https://pypi.org/project/diffpy.utils/) and [Conda](https://anaconda.org/conda-forge/diffpy.utils). -""" # release message diff --git a/run_tests.py b/run_tests.py deleted file mode 100644 index 9ab1aabb..00000000 --- a/run_tests.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python - -import sys - -import pytest - -if __name__ == "__main__": - # show output results from every test function - args = ["-v"] - # show the message output for skipped and expected failure tests - if len(sys.argv) > 1: - args.extend(sys.argv[1:]) - print("pytest arguments: {}".format(args)) - # # compute coverage stats for xpdAcq - # call pytest and exit with the return code from pytest - exit_res = pytest.main(args) - sys.exit(exit_res) diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index f37a7759..11a4204c 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -5,11 +5,15 @@ # Simon J. L. Billinge # (c) 2010 The Trustees of Columbia University # in the City of New York. All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.utils/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## @@ -23,5 +27,4 @@ __path__ = extend_path(__path__, __name__) - # End of file diff --git a/src/diffpy/utils/__init__.py b/src/diffpy/utils/__init__.py index 3abeab37..41a4fa54 100644 --- a/src/diffpy/utils/__init__.py +++ b/src/diffpy/utils/__init__.py @@ -1,20 +1,19 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.utils by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2010 The Trustees of Columbia University -# in the City of New York. All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Chris Farrow, Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.utils/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## -"""Smaller shared functions for use by other diffpy packages. -""" +"""Shared utilities for diffpy packages""" # package version from diffpy.utils.version import __version__ diff --git a/src/diffpy/utils/parsers/loaddata.py b/src/diffpy/utils/parsers/loaddata.py index 4bb0d792..18375d90 100644 --- a/src/diffpy/utils/parsers/loaddata.py +++ b/src/diffpy/utils/parsers/loaddata.py @@ -30,7 +30,7 @@ def loadData(filename, minrows=10, headers=False, hdel="=", hignore=None, **kwar Minimum number of rows in the first data block. All rows must have the same number of floating point values. headers: bool - when False (defualt), the function returns a numpy array of the data in the data block. + when False (default), the function returns a numpy array of the data in the data block. When True, the function instead returns a dictionary of parameters and their corresponding values parsed from header (information prior the data block). See hdel and hignore for options to help with parsing header information. diff --git a/src/diffpy/utils/parsers/resample.py b/src/diffpy/utils/parsers/resample.py index f81fc2a2..e88c4f0b 100644 --- a/src/diffpy/utils/parsers/resample.py +++ b/src/diffpy/utils/parsers/resample.py @@ -113,7 +113,7 @@ def resample(r, s, dr): # spad = numpy.concatenate([s,spad]) # rnew = numpy.arange(0, rpad[-1], dr) # snew = numpy.zeros_like(rnew) - # Accomodate for the fact that r[0] might not be 0 + # Accommodate for the fact that r[0] might not be 0 # u = (rnew-r[0]) / dr0 # for n in range(len(spad)): # snew += spad[n] * numpy.sinc(u - n) diff --git a/src/diffpy/utils/parsers/serialization.py b/src/diffpy/utils/parsers/serialization.py index a0bec92c..46d4b8ff 100644 --- a/src/diffpy/utils/parsers/serialization.py +++ b/src/diffpy/utils/parsers/serialization.py @@ -56,7 +56,7 @@ def serialize_data( include a path element in the database entry (default True). If 'path' is not included in hddata, extract path from filename. serial_file - Serial language file to dump dictionary into. If None (defualt), no dumping will occur. + Serial language file to dump dictionary into. If None (default), no dumping will occur. Returns ------- diff --git a/src/diffpy/utils/scattering_objects/diffraction_objects.py b/src/diffpy/utils/scattering_objects/diffraction_objects.py index bd5b16db..94d2831a 100644 --- a/src/diffpy/utils/scattering_objects/diffraction_objects.py +++ b/src/diffpy/utils/scattering_objects/diffraction_objects.py @@ -445,6 +445,8 @@ def dump(self, filepath, xtype=None): data_to_save = np.column_stack((self.on_q[0], self.on_q[1])) elif xtype == "tth": data_to_save = np.column_stack((self.on_tth[0], self.on_tth[1])) + elif xtype == "d": + data_to_save = np.column_stack((self.on_d[0], self.on_d[1])) else: print(f"WARNING: cannot handle the xtype '{xtype}'") self.metadata.update(get_package_info("diffpy.utils", metadata=self.metadata)) diff --git a/src/diffpy/utils/tests/__init__.py b/src/diffpy/utils/tests/__init__.py deleted file mode 100644 index 42a123f3..00000000 --- a/src/diffpy/utils/tests/__init__.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.utils by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2011 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Unit tests for diffpy.utils. -""" - -import unittest - - -def testsuite(pattern=""): - """Create a unit tests suite for diffpy.utils package. - - Parameters - ---------- - pattern : str, optional - Regular expression pattern for selecting test cases. - Select all tests when empty. Ignore the pattern when - any of unit test modules fails to import. - - Returns - ------- - suite : `unittest.TestSuite` - The TestSuite object containing the matching tests. - """ - import re - from importlib.resources import as_file, files - from itertools import chain - from os.path import dirname - - loader = unittest.defaultTestLoader - ref = files(__package__) - with as_file(ref) as thisdir: - depth = __name__.count(".") + 1 - topdir = thisdir - for i in range(depth): - topdir = dirname(topdir) - suite_all = loader.discover(str(thisdir), top_level_dir=topdir) - # always filter the suite by pattern to test-cover the selection code. - suite = unittest.TestSuite() - rx = re.compile(pattern) - tsuites = list(chain.from_iterable(suite_all)) - tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover - return suite_all - tcases = chain.from_iterable(tsuites) - for tc in tcases: - tcwords = tc.id().split(".") - shortname = ".".join(tcwords[-3:]) - if rx.search(shortname): - suite.addTest(tc) - # verify all tests are found for an empty pattern. - assert pattern or suite_all.countTestCases() == suite.countTestCases() - return suite - - -def test(): - """Execute all unit tests for the diffpy.utils package. - - Returns - ------- - result : `unittest.TestResult` - """ - suite = testsuite() - runner = unittest.TextTestRunner() - result = runner.run(suite) - return result - - -# End of file diff --git a/src/diffpy/utils/tests/debug.py b/src/diffpy/utils/tests/debug.py deleted file mode 100644 index fed20421..00000000 --- a/src/diffpy/utils/tests/debug.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.utils Complex Modeling Initiative -# (c) 2016 Brookhaven Science Associates, -# Brookhaven National Laboratory. -# All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE.txt for license information. -# -############################################################################## - -""" -Convenience module for debugging the unit tests using - -python -m diffpy.utils.tests.debug - -Exceptions raised by failed tests or other errors are not caught. -""" - - -if __name__ == "__main__": - import sys - - from diffpy.utils.tests import testsuite - - pattern = sys.argv[1] if len(sys.argv) > 1 else "" - suite = testsuite(pattern) - suite.debug() - - -# End of file diff --git a/src/diffpy/utils/tests/run.py b/src/diffpy/utils/tests/run.py deleted file mode 100644 index 241caf11..00000000 --- a/src/diffpy/utils/tests/run.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.utils by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2012 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Convenience module for executing all unit tests with - -python -m diffpy.utils.tests.run -""" - -if __name__ == "__main__": - import sys - - # show warnings by default - if not sys.warnoptions: - import os - import warnings - - warnings.simplefilter("default") - # also affect subprocesses - os.environ["PYTHONWARNINGS"] = "default" - from diffpy.utils.tests import test - - # produce zero exit code for a successful test - sys.exit(not test().wasSuccessful()) - -# End of file diff --git a/src/diffpy/utils/tests/testhelpers.py b/src/diffpy/utils/tests/testhelpers.py deleted file mode 100644 index aaa2a519..00000000 --- a/src/diffpy/utils/tests/testhelpers.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -############################################################################## -# -# diffpy.utils by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2011 The Trustees of Columbia University -# in the City of New York. All rights reserved. -# -# File coded by: Pavol Juhas -# -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. -# -############################################################################## - -"""Helper routines for running other unit tests. -""" - -# helper functions - - -def datafile(filename): - from importlib.resources import as_file, files - - ref = files(__package__) / ("testdata/" + filename) - with as_file(ref) as rv: - return rv - - -# End of file diff --git a/src/diffpy/utils/version.py b/src/diffpy/utils/version.py index 2566d69f..6eec4d9f 100644 --- a/src/diffpy/utils/version.py +++ b/src/diffpy/utils/version.py @@ -1,15 +1,15 @@ #!/usr/bin/env python ############################################################################## # -# diffpy.utils by DANSE Diffraction group -# Simon J. L. Billinge -# (c) 2011 The Trustees of Columbia University -# in the City of New York. All rights reserved. +# (c) 2024 The Trustees of Columbia University in the City of New York. +# All rights reserved. # -# File coded by: Pavol Juhas +# File coded by: Billinge Group members and community contributors. # -# See AUTHORS.txt for a list of people who contributed. -# See LICENSE_DANSE.txt for license information. +# See GitHub contributions for a more detailed list of contributors. +# https://github.com/diffpy/diffpy.utils/graphs/contributors +# +# See LICENSE.rst for license information. # ############################################################################## @@ -24,3 +24,5 @@ __version__ = version("diffpy.utils") # End of file + +# Expect to run PR \ No newline at end of file diff --git a/src/diffpy/utils/tests/conftest.py b/tests/conftest.py similarity index 73% rename from src/diffpy/utils/tests/conftest.py rename to tests/conftest.py index e3b63139..5471acc1 100644 --- a/src/diffpy/utils/tests/conftest.py +++ b/tests/conftest.py @@ -17,3 +17,13 @@ def user_filesystem(tmp_path): json.dump(home_config_data, f) yield tmp_path + + +@pytest.fixture +def datafile(): + """Fixture to dynamically load any test file.""" + + def _load(filename): + return "tests/testdata/" + filename + + return _load diff --git a/src/diffpy/utils/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py similarity index 93% rename from src/diffpy/utils/tests/test_diffraction_objects.py rename to tests/test_diffraction_objects.py index fa613a53..a155b95e 100644 --- a/src/diffpy/utils/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -232,7 +232,7 @@ def test_diffraction_objects_equality(inputs1, inputs2, expected): def test_dump(tmp_path, mocker): - x, y = np.linspace(0, 10, 11), np.linspace(0, 10, 11) + x, y = np.linspace(0, 5, 6), np.linspace(0, 5, 6) directory = Path(tmp_path) file = directory / "testfile" test = Diffraction_object() @@ -242,8 +242,12 @@ def test_dump(tmp_path, mocker): test.insert_scattering_quantity( x, y, "q", metadata={"thing1": 1, "thing2": "thing2", "package_info": {"package2": "3.4.5"}} ) - with mocker.patch("importlib.metadata.version", return_value="3.3.0"), freeze_time("2012-01-14"): + + mocker.patch("importlib.metadata.version", return_value="3.3.0") + + with freeze_time("2012-01-14"): test.dump(file, "q") + with open(file, "r") as f: actual = f.read() expected = ( @@ -256,10 +260,6 @@ def test_dump(tmp_path, mocker): "3.000000000000000000e+00 3.000000000000000000e+00\n" "4.000000000000000000e+00 4.000000000000000000e+00\n" "5.000000000000000000e+00 5.000000000000000000e+00\n" - "6.000000000000000000e+00 6.000000000000000000e+00\n" - "7.000000000000000000e+00 7.000000000000000000e+00\n" - "8.000000000000000000e+00 8.000000000000000000e+00\n" - "9.000000000000000000e+00 9.000000000000000000e+00\n" - "1.000000000000000000e+01 1.000000000000000000e+01\n" ) + assert actual == expected diff --git a/src/diffpy/utils/tests/test_loaddata.py b/tests/test_loaddata.py similarity index 89% rename from src/diffpy/utils/tests/test_loaddata.py rename to tests/test_loaddata.py index 9399e71d..2ca2fa07 100644 --- a/src/diffpy/utils/tests/test_loaddata.py +++ b/tests/test_loaddata.py @@ -6,18 +6,20 @@ import unittest import numpy +import pytest from diffpy.utils.parsers import loadData -from diffpy.utils.tests.testhelpers import datafile - -loaddata01 = datafile("loaddata01.txt") -loaddatawithheaders = datafile("loaddatawithheaders.txt") ############################################################################## class TestLoadData(unittest.TestCase): + @pytest.fixture(autouse=True) + def prepare_fixture(self, datafile): + self.datafile = datafile + def test_loadData_default(self): """check loadData() with default options""" + loaddata01 = self.datafile("loaddata01.txt") d2c = numpy.array([[3, 31], [4, 32], [5, 33]]) self.assertRaises(IOError, loadData, "doesnotexist") # the default minrows=10 makes it read from the third line @@ -35,6 +37,7 @@ def test_loadData_default(self): def test_loadData_1column(self): """check loading of one-column data.""" + loaddata01 = self.datafile("loaddata01.txt") d1c = numpy.arange(1, 6) d = loadData(loaddata01, usecols=[0], minrows=1) self.assertTrue(numpy.array_equal(d1c, d)) @@ -46,6 +49,7 @@ def test_loadData_1column(self): def test_loadData_headers(self): """check loadData() with headers options enabled""" + loaddatawithheaders = self.datafile("loaddatawithheaders.txt") hignore = ["# ", "// ", "["] # ignore lines beginning with these strings delimiter = ": " # what our data should be separated by hdata = loadData(loaddatawithheaders, headers=True, hdel=delimiter, hignore=hignore) diff --git a/src/diffpy/utils/tests/test_resample.py b/tests/test_resample.py similarity index 100% rename from src/diffpy/utils/tests/test_resample.py rename to tests/test_resample.py diff --git a/src/diffpy/utils/tests/test_serialization.py b/tests/test_serialization.py similarity index 91% rename from src/diffpy/utils/tests/test_serialization.py rename to tests/test_serialization.py index bbe6be24..51921e01 100644 --- a/src/diffpy/utils/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -5,21 +5,15 @@ from diffpy.utils.parsers import deserialize_data, loadData, serialize_data from diffpy.utils.parsers.custom_exceptions import ImproperSizeError, UnsupportedTypeError -from diffpy.utils.tests.testhelpers import datafile tests_dir = os.path.dirname(os.path.abspath(locals().get("__file__", "file.py"))) -targetjson = datafile("targetjson.json") -schemaname = datafile("strumining.json") -wrongtype = datafile("wrong.type") -loadfile = datafile("loadfile.txt") -warningfile = datafile("generatewarnings.txt") -nodt = datafile("loaddatawithheaders.txt") - -def test_load_multiple(tmp_path): - # generate json and apply schema +def test_load_multiple(tmp_path, datafile): + # Load test data + targetjson = datafile("targetjson.json") generatedjson = tmp_path / "generated_serialization.json" + tlm_list = os.listdir(os.path.join(tests_dir, "testdata", "dbload")) tlm_list.sort() generated_data = None @@ -50,7 +44,12 @@ def test_load_multiple(tmp_path): assert target_data == deserialize_data(generatedjson, filetype=".json") -def test_exceptions(): +def test_exceptions(datafile): + # Load test data + wrongtype = datafile("wrong.type") + loadfile = datafile("loadfile.txt") + warningfile = datafile("generatewarnings.txt") + nodt = datafile("loaddatawithheaders.txt") hdata = loadData(loadfile, headers=True) data_table = loadData(loadfile) diff --git a/src/diffpy/utils/tests/test_tools.py b/tests/test_tools.py similarity index 100% rename from src/diffpy/utils/tests/test_tools.py rename to tests/test_tools.py diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 00000000..421a96e4 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,10 @@ +"""Unit tests for __version__.py +""" + +import diffpy.utils + + +def test_package_version(): + """Ensure the package version is defined and not set to the initial placeholder.""" + assert hasattr(diffpy.utils, "__version__") + assert diffpy.utils.__version__ != "0.0.0" diff --git a/src/diffpy/utils/tests/testdata/dbload/e1.gr b/tests/testdata/dbload/e1.gr similarity index 100% rename from src/diffpy/utils/tests/testdata/dbload/e1.gr rename to tests/testdata/dbload/e1.gr diff --git a/src/diffpy/utils/tests/testdata/dbload/e2.gr b/tests/testdata/dbload/e2.gr similarity index 100% rename from src/diffpy/utils/tests/testdata/dbload/e2.gr rename to tests/testdata/dbload/e2.gr diff --git a/src/diffpy/utils/tests/testdata/dbload/e3.gr b/tests/testdata/dbload/e3.gr similarity index 100% rename from src/diffpy/utils/tests/testdata/dbload/e3.gr rename to tests/testdata/dbload/e3.gr diff --git a/src/diffpy/utils/tests/testdata/generated_db.json b/tests/testdata/generated_db.json similarity index 100% rename from src/diffpy/utils/tests/testdata/generated_db.json rename to tests/testdata/generated_db.json diff --git a/src/diffpy/utils/tests/testdata/generatewarnings.txt b/tests/testdata/generatewarnings.txt similarity index 100% rename from src/diffpy/utils/tests/testdata/generatewarnings.txt rename to tests/testdata/generatewarnings.txt diff --git a/src/diffpy/utils/tests/testdata/loaddata01.txt b/tests/testdata/loaddata01.txt similarity index 100% rename from src/diffpy/utils/tests/testdata/loaddata01.txt rename to tests/testdata/loaddata01.txt diff --git a/src/diffpy/utils/tests/testdata/loaddatawithheaders.txt b/tests/testdata/loaddatawithheaders.txt similarity index 100% rename from src/diffpy/utils/tests/testdata/loaddatawithheaders.txt rename to tests/testdata/loaddatawithheaders.txt diff --git a/src/diffpy/utils/tests/testdata/loadfile.txt b/tests/testdata/loadfile.txt similarity index 100% rename from src/diffpy/utils/tests/testdata/loadfile.txt rename to tests/testdata/loadfile.txt diff --git a/src/diffpy/utils/tests/testdata/strumining.json b/tests/testdata/strumining.json similarity index 100% rename from src/diffpy/utils/tests/testdata/strumining.json rename to tests/testdata/strumining.json diff --git a/src/diffpy/utils/tests/testdata/targetjson.json b/tests/testdata/targetjson.json similarity index 100% rename from src/diffpy/utils/tests/testdata/targetjson.json rename to tests/testdata/targetjson.json diff --git a/src/diffpy/utils/tests/testdata/wrong.type b/tests/testdata/wrong.type similarity index 100% rename from src/diffpy/utils/tests/testdata/wrong.type rename to tests/testdata/wrong.type