From b46248561a8e934b0d4ba231d78204fcf4739abb Mon Sep 17 00:00:00 2001 From: Toon Verstraelen Date: Fri, 3 May 2024 07:53:50 +0200 Subject: [PATCH 1/4] Fix Python 3.12 compatibility --- .gitignore | 3 +++ iodata/formats/extxyz.py | 3 +-- iodata/formats/qchemlog.py | 3 +-- iodata/test/test_utils.py | 11 ++++++++++- iodata/utils.py | 26 +++++++++++++++++++++++++- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 3da101502..fb57579a7 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,9 @@ celerybeat-schedule # dotenv .env +# direnv +.envrc + # virtualenv .venv venv/ diff --git a/iodata/formats/extxyz.py b/iodata/formats/extxyz.py index 7f6b24232..1db534aeb 100644 --- a/iodata/formats/extxyz.py +++ b/iodata/formats/extxyz.py @@ -27,7 +27,6 @@ """ -from distutils.util import strtobool import shlex from typing import Iterator @@ -35,7 +34,7 @@ from ..docstrings import document_load_one, document_load_many from ..periodic import sym2num, num2sym -from ..utils import angstrom, amu, LineIterator +from ..utils import angstrom, amu, LineIterator, strtobool from .xyz import load_one as load_one_xyz diff --git a/iodata/formats/qchemlog.py b/iodata/formats/qchemlog.py index 55d09d513..58af4cdb7 100644 --- a/iodata/formats/qchemlog.py +++ b/iodata/formats/qchemlog.py @@ -22,14 +22,13 @@ """ from typing import Tuple -from distutils.util import strtobool import numpy as np from ..docstrings import document_load_one from ..orbitals import MolecularOrbitals from ..periodic import sym2num -from ..utils import LineIterator, angstrom, kcalmol, calmol, kjmol +from ..utils import LineIterator, angstrom, kcalmol, calmol, kjmol, strtobool __all__ = [] diff --git a/iodata/test/test_utils.py b/iodata/test/test_utils.py index 42b582b51..d3b55536a 100644 --- a/iodata/test/test_utils.py +++ b/iodata/test/test_utils.py @@ -18,9 +18,18 @@ # -- """Unit tests for iodata.utils.""" +import pytest -from ..utils import amu +from ..utils import amu, strtobool def test_amu(): assert abs(amu * 1.008 - 1837.47) < 1e-1 + + +def test_strtobool(): + assert strtobool("T") is True + assert strtobool("false") is False + assert strtobool("y") is True + with pytest.raises(ValueError): + strtobool("whatever") diff --git a/iodata/utils.py b/iodata/utils.py index facb8e53a..6035d9528 100644 --- a/iodata/utils.py +++ b/iodata/utils.py @@ -31,7 +31,7 @@ __all__ = ['LineIterator', 'Cube', 'set_four_index_element', 'volume', - 'derive_naturals', 'check_dm'] + 'derive_naturals', 'check_dm', 'strtobool'] # The unit conversion factors below can be used as follows: @@ -263,3 +263,27 @@ def check_dm(dm: np.ndarray, overlap: np.ndarray, eps: float = 1e-4, occ_max: fl if occupations.max() > occ_max + eps: raise ValueError('The density matrix has eigenvalues considerably larger than ' 'max. error=%e' % (occupations.max() - 1)) + + +STRTOBOOL = { + 'y': True, + 'yes': True, + 't': True, + 'true': True, + 'on': True, + '1': True, + 'n': False, + 'no': False, + 'f': False, + 'false': False, + 'off': False, + '0': False +} + + +def strtobool(value: str) -> bool: + """Interpret string as a boolean.""" + result = STRTOBOOL.get(value.lower()) + if result is None: + raise ValueError(f"'{value}' cannot be converted to boolean") + return result From 1d434cf8c5fc1be8dae3fd72b9902d57828bc93a Mon Sep 17 00:00:00 2001 From: Toon Verstraelen Date: Fri, 3 May 2024 19:19:19 +0200 Subject: [PATCH 2/4] Modernize project structure --- .cardboardlint.yml | 22 -- .github/workflows/ci.yml | 102 ------- .github/workflows/pytest.yml | 20 ++ .pycodestylerc | 3 - .pydocstylerc | 2 - .pylintrc | 502 ----------------------------------- .roberto.yaml | 24 -- .yamllint | 7 - environment.yml | 9 - pyproject.toml | 50 ++++ setup.py | 79 ------ 11 files changed, 70 insertions(+), 750 deletions(-) delete mode 100644 .cardboardlint.yml delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pytest.yml delete mode 100644 .pycodestylerc delete mode 100644 .pydocstylerc delete mode 100644 .pylintrc delete mode 100644 .roberto.yaml delete mode 100644 .yamllint delete mode 100644 environment.yml create mode 100644 pyproject.toml delete mode 100755 setup.py diff --git a/.cardboardlint.yml b/.cardboardlint.yml deleted file mode 100644 index 1dd42a944..000000000 --- a/.cardboardlint.yml +++ /dev/null @@ -1,22 +0,0 @@ -linters: - - import: - packages: ['iodata'] - - namespace: - filefilter: ['- */__init__.py', '- */test_*.py', '- *setup.py', '- tools/*', - '- doc/*.py', '+ *.py', '+ *.pyx'] - - pylint: - - pycodestyle: - config: .pycodestylerc - - autopep8: - config: .pycodestylerc - line-range: [79, 100] - - pydocstyle: - - whitespace: - filefilter: ['- iodata/test/data/*', '- *Makefile', '+ *'] - - header: - extra: [] - shebang: '#!/usr/bin/env python3' - - yamllint: - filefilter: ['- *conda.recipe/meta.yaml', '+ *.yml', '+ *.yaml'] - - rst-lint: - filefilter: ['+ README.rst'] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 72d79aadb..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: CI -on: - push: - tags: - - '[1-9]+.[0-9]+.[0-9]+*' - branches: - - master - pull_request: - branches: - - master - -jobs: - # These are quick tests using Python's venv on different Python versions. - test-venv: - timeout-minutes: 30 - if: "! startsWith(github.ref, 'refs/tags')" - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - python-version: 3.7 - - os: ubuntu-latest - python-version: 3.8 - - os: ubuntu-latest - python-version: 3.9 - - os: macos-latest - python-version: 3.7 - - runs-on: ${{ matrix.os }} - env: - # Tell Roberto to upload coverage results - ROBERTO_UPLOAD_COVERAGE: 1 - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - name: Fetch base branch (usually master) - run: | - if [[ -n "${GITHUB_HEAD_REF}" ]]; then - git fetch origin ${GITHUB_BASE_REF} --depth=2 - fi - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - architecture: x64 - - name: Install Pip and Roberto - run: | - python -m pip install --upgrade pip - python -m pip install roberto>=2.0.0 - - name: Test with Roberto - run: | - if [[ -n "${GITHUB_HEAD_REF}" ]]; then - ROBERTO_GIT_MERGE_BRANCH=${GITHUB_SHA} \ - ROBERTO_GIT_BRANCH=${GITHUB_BASE_REF} \ - python -m roberto - else - ROBERTO_TESTENV_USE=venv \ - python -m roberto robot - fi - - - test-conda: - # This is a slow test in a Conda environment, including deployment of - # tagged releases. - timeout-minutes: 30 - if: (github.ref == 'refs/heads/master') || startsWith(github.ref, 'refs/tags') - strategy: - fail-fast: false - - runs-on: ubuntu-latest - env: - ROBERTO_UPLOAD_COVERAGE: 1 - ROBERTO_PACKAGE_MANAGER: conda - ROBERTO_TESTENV_USE: conda - ROBERTO_DEPLOY_NOARCH: 1 - TWINE_USERNAME: theochem - TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} - steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/miniconda3 - !~/miniconda3/conda-bld - !~/miniconda3/locks - !~/miniconda3/pkgs - !~/miniconda3/var - !~/miniconda3/envs/*/conda-bld - !~/miniconda3/envs/*/locks - !~/miniconda3/envs/*/pkgs - !~/miniconda3/envs/*/var - key: ${{ runner.os }}-conda-4 - - name: Install Roberto - run: | - python -m pip install roberto>=2.0.0 - - name: Test and deploy with Roberto - run: | - python -m roberto robot diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 000000000..dc03526e2 --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,20 @@ +name: pytest +on: + push: + branches: + - main + tags-ignore: + - '**' + pull_request: +jobs: + tests: + runs-on: "ubuntu-latest" + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Install development version + run: pip install -e .[dev] + - name: Run pytest + run: pytest -vv diff --git a/.pycodestylerc b/.pycodestylerc deleted file mode 100644 index b4686f6ff..000000000 --- a/.pycodestylerc +++ /dev/null @@ -1,3 +0,0 @@ -[pycodestyle] -max-line-length=100 -ignore=E741,W503 diff --git a/.pydocstylerc b/.pydocstylerc deleted file mode 100644 index 6133249c5..000000000 --- a/.pydocstylerc +++ /dev/null @@ -1,2 +0,0 @@ -[pydocstyle] -add_ignore=D100,D101,D102,D103,D104,D105 diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index f73a67630..000000000 --- a/.pylintrc +++ /dev/null @@ -1,502 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist=numpy, iodata.overlap_accel - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Specify a configuration file. -#rcfile= - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable= - print-statement, - parameter-unpacking, - unpacking-in-except, - old-raise-syntax, - backtick, - long-suffix, - old-ne-operator, - old-octal-literal, - import-star-module-level, - raw-checker-failed, - bad-inline-option, - locally-disabled, - locally-enabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - apply-builtin, - basestring-builtin, - buffer-builtin, - cmp-builtin, - coerce-builtin, - execfile-builtin, - file-builtin, - long-builtin, - raw_input-builtin, - reduce-builtin, - standarderror-builtin, - unicode-builtin, - xrange-builtin, - coerce-method, - delslice-method, - getslice-method, - setslice-method, - no-absolute-import, - old-division, - dict-iter-method, - dict-view-method, - next-method-called, - metaclass-assignment, - indexing-exception, - raising-string, - reload-builtin, - oct-method, - hex-method, - nonzero-method, - cmp-method, - input-builtin, - round-builtin, - intern-builtin, - unichr-builtin, - map-builtin-not-iterating, - zip-builtin-not-iterating, - range-builtin-not-iterating, - filter-builtin-not-iterating, - using-cmp-argument, - eq-without-hash, - div-method, - idiv-method, - rdiv-method, - exception-message-attribute, - invalid-str-codec, - sys-max-int, - bad-python3-import, - deprecated-string-function, - deprecated-str-translate-call, - too-many-arguments, - too-many-locals, - too-few-public-methods, - fixme, - invalid-name, - duplicate-code, - unsubscriptable-object, - no-member, - too-many-lines, - unspecified-encoding, - bad-option-value - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable= - - -[REPORTS] - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio).You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local,numpy - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules=numpy - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=100 - -# Maximum number of lines in a module -max-module-lines=1000 - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[BASIC] - -# Naming hint for argument names -argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct argument names -argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Naming hint for attribute names -attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct attribute names -attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming hint for function names -function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct function names -function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,_,f - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for method names -method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct method names -method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=((^_)|(^test_)) - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Naming hint for variable names -variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - -# Regular expression matching correct variable names -variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$ - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of statements in function / method body -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[IMPORTS] - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception diff --git a/.roberto.yaml b/.roberto.yaml deleted file mode 100644 index d35bcb71a..000000000 --- a/.roberto.yaml +++ /dev/null @@ -1,24 +0,0 @@ -absolute: true # Force absolute comparison for cardboardlint -project: - name: iodata - requirements: [ - [sympy, sympy], - # pylint 2.11.* seems to have bugs which break the CI. - ["pylint <2.11.0", "pylint<2.11.0"] - ] - packages: - - dist_name: qc-iodata - tools: - - write-py-version - - cardboardlint-static - - build-py-inplace - - cardboardlint-dynamic - - pytest - - upload-codecov - - build-sphinx-doc - - upload-docs-gh - - build-py-source - - build-conda - - deploy-pypi - - deploy-conda - - deploy-github diff --git a/.yamllint b/.yamllint deleted file mode 100644 index fe8f4d16e..000000000 --- a/.yamllint +++ /dev/null @@ -1,7 +0,0 @@ -extends: default - -rules: - document-start: disable - line-length: - max: 100 - truthy: disable diff --git a/environment.yml b/environment.yml deleted file mode 100644 index d4cf29bf6..000000000 --- a/environment.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: rtd-iodata -dependencies: - - python=3.7 - - numpy - - scipy - - attrs >=20.1.0 - - pip: - - sphinx-autodoc-typehints - - sphinxcontrib-napoleon diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..45e12f818 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,50 @@ +[build-system] +requires = ["setuptools>=65.0", "setuptools_scm[toml]>=7.1.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "qc-iodata" +authors = [ + { name="HORTON-ChemTools Dev Team", email="horton.chemtools@gmail.com" }, +] +description = "Python Input and Output Library for Quantum Chemistry" +readme = "README.rst" +license = {file = "LICENSE"} +requires-python = ">=3.9" +classifiers = [ + "Environment :: Console", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Scientific/Engineering :: Chemistry", + "Intended Audience :: Science/Research", +] +dependencies = [ + "numpy>=1.0", + "scipy", + "attrs>=20.1.0", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = ["pytest", "pytest-xdist"] + +[project.urls] +Documentation = "https://iodata.readthedocs.io/en/latest/" +Issues = "https://github.com/theochem/iodata/issues/" +Source = "https://github.com/theochem/iodata/" + +[project.scripts] +iodata-convert = "iodata.__main__:main" + +[tool.pytest.ini_options] +addopts = "-n auto" + +[tool.setuptools] +packages = ["iodata"] + +[tool.setuptools_scm] +write_to = "iodata/_version.py" +version_scheme = "post-release" +local_scheme = "no-local-version" diff --git a/setup.py b/setup.py deleted file mode 100755 index 74d00e34e..000000000 --- a/setup.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# IODATA is an input and output module for quantum chemistry. -# Copyright (C) 2011-2019 The IODATA Development Team -# -# This file is part of IODATA. -# -# IODATA is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 -# of the License, or (at your option) any later version. -# -# IODATA is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see -# -- -"""Installation script for IOData. - -Directly calling this script is only needed by IOData developers in special -circumstances. End users are recommended to install IOData with pip or conda. -Developers are recommended to use Roberto. -""" - - -import os - -from setuptools import setup - - -def get_version_info(): - """Read __version__ and DEV_CLASSIFIER from version.py, using exec, not import.""" - fn_version = os.path.join("iodata", "_version.py") - if os.path.isfile(fn_version): - myglobals = {} - with open(fn_version, "r") as f: - exec(f.read(), myglobals) # pylint: disable=exec-used - return myglobals["__version__"], myglobals["DEV_CLASSIFIER"] - return "0.0.0.post0", "Development Status :: 2 - Pre-Alpha" - - -def get_readme(): - """Load README.rst for display on PyPI.""" - with open('README.rst', encoding="utf-8") as fhandle: - return fhandle.read() - - -VERSION, DEV_CLASSIFIER = get_version_info() - -setup( - name='qc-iodata', - version=VERSION, - description='Python Input and Output Library for Quantum Chemistry.', - long_description=get_readme(), - author='HORTON-ChemTools Dev Team', - author_email='horton.chemtools@gmail.com', - url='https://github.com/theochem/iodata', - package_dir={'iodata': 'iodata'}, - packages=['iodata', 'iodata.formats', 'iodata.inputs', 'iodata.test', 'iodata.test.data'], - include_package_data=True, - entry_points={ - 'console_scripts': ['iodata-convert = iodata.__main__:main'] - }, - classifiers=[ - DEV_CLASSIFIER, - 'Environment :: Console', - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3', - 'Topic :: Scientific/Engineering :: Physics', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Intended Audience :: Science/Research', - ], - setup_requires=['numpy>=1.0'], - install_requires=['numpy>=1.0', 'scipy', 'attrs>=20.1.0', - 'importlib_resources; python_version < "3.8"'], -) From 9862efc9add3d96291771cf3bc95046d9428d2df Mon Sep 17 00:00:00 2001 From: Toon Verstraelen Date: Fri, 3 May 2024 19:32:05 +0200 Subject: [PATCH 3/4] Add basic pre-commit --- .editorconfig | 18 ++++++++++++++++++ .github/workflows/pytest.yml | 19 +++++++++++++------ .pre-commit-config.yaml | 31 +++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 .editorconfig create mode 100644 .pre-commit-config.yaml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..df64623b1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig is awesome: https://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 4 +max_line_length = 100 + +[Makefile] +indent_style = tab + +[{*.json,*.yml,*.yaml}] +indent_style = space +indent_size = 2 diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index dc03526e2..f171e5a14 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -2,19 +2,26 @@ name: pytest on: push: branches: - - main + # Run tests for change on the main branch ... + - main tags-ignore: - - '**' + # ... but not for tags (avoids duplicate work). + - '**' pull_request: + # Run tests on pull requests jobs: tests: - runs-on: "ubuntu-latest" + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.12"] steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 with: - python-version: 3.x + python-version: ${{ matrix.python-version }} - name: Install development version run: pip install -e .[dev] - - name: Run pytest + - name: Run Pytest run: pytest -vv diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..12e2786ec --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +exclude: 'iodata/test/data/.*' +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-added-large-files + - id: check-ast + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-json + - id: check-merge-conflict + - id: check-symlinks + - id: check-toml + - id: check-vcs-permalinks + - id: debug-statements + - id: detect-private-key + - id: destroyed-symlinks + - id: end-of-file-fixer + - id: fix-byte-order-marker + - id: mixed-line-ending + - id: pretty-format-json + args: ["--autofix", "--no-sort-keys"] + - id: trailing-whitespace +- repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.5.5 + hooks: + - id: remove-crlf +- repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.28.1 + hooks: + - id: check-github-workflows From 819b63cdc07a39db9c30f4d33591a12564c584f3 Mon Sep 17 00:00:00 2001 From: Toon Verstraelen Date: Fri, 3 May 2024 19:40:42 +0200 Subject: [PATCH 4/4] Try workflow for mac and windows --- .github/workflows/pytest.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index f171e5a14..c33ba83b8 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -11,10 +11,11 @@ on: # Run tests on pull requests jobs: tests: - runs-on: ubuntu-latest strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.9", "3.12"] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }}