diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b7fb3631..6dca6f1e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -58,3 +58,10 @@ repos: - id: prettier additional_dependencies: - "prettier@^3.2.4" + # docformatter - formats docstrings using PEP 257 + - repo: https://github.com/s-weigand/docformatter + rev: 5757c5190d95e5449f102ace83df92e7d3b06c6c + hooks: + - id: docformatter + additional_dependencies: [tomli] + args: [--in-place, --config, ./pyproject.toml] diff --git a/news/docformatter.rst b/news/docformatter.rst new file mode 100644 index 00000000..56368125 --- /dev/null +++ b/news/docformatter.rst @@ -0,0 +1,23 @@ +**Added:** + +* docforamtter in pre-commit for automatic formatting of docstrings to PEP 257 + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/__init__.py b/src/diffpy/__init__.py index 11a4204c..00208e23 100644 --- a/src/diffpy/__init__.py +++ b/src/diffpy/__init__.py @@ -16,7 +16,6 @@ # See LICENSE.rst for license information. # ############################################################################## - """diffpy - tools for structure analysis by diffraction. Blank namespace package. diff --git a/src/diffpy/utils/__init__.py b/src/diffpy/utils/__init__.py index c9909a8a..12f4a49d 100644 --- a/src/diffpy/utils/__init__.py +++ b/src/diffpy/utils/__init__.py @@ -12,8 +12,7 @@ # See LICENSE.rst for license information. # ############################################################################## - -"""Shared utilities for diffpy packages""" +"""Shared utilities for diffpy packages.""" # package version from diffpy.utils.version import __version__ diff --git a/src/diffpy/utils/parsers/__init__.py b/src/diffpy/utils/parsers/__init__.py index bab9943c..a0278e27 100644 --- a/src/diffpy/utils/parsers/__init__.py +++ b/src/diffpy/utils/parsers/__init__.py @@ -12,6 +12,4 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Various utilities related to data parsing and manipulation. -""" +"""Various utilities related to data parsing and manipulation.""" diff --git a/src/diffpy/utils/parsers/serialization.py b/src/diffpy/utils/parsers/serialization.py index 46d4b8ff..20b34b31 100644 --- a/src/diffpy/utils/parsers/serialization.py +++ b/src/diffpy/utils/parsers/serialization.py @@ -33,8 +33,8 @@ def serialize_data( show_path=True, serial_file=None, ): - """Serialize file data into a dictionary. Can also save dictionary into a serial language file. Dictionary is - formatted as {filename: data}. + """Serialize file data into a dictionary. Can also save dictionary into a + serial language file. Dictionary is formatted as {filename: data}. Requires hdata and data_table (can be generated by loadData). diff --git a/src/diffpy/utils/resampler.py b/src/diffpy/utils/resampler.py index 21fabf56..115087a2 100644 --- a/src/diffpy/utils/resampler.py +++ b/src/diffpy/utils/resampler.py @@ -12,7 +12,6 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - """Various utilities related to data parsing and manipulation.""" import warnings @@ -80,7 +79,8 @@ def wsinterp(x, xp, fp, left=None, right=None): def nsinterp(xp, fp, qmin=0, qmax=25, left=None, right=None): - """One-dimensional Whittaker-Shannon interpolation onto the Nyquist-Shannon grid. + """One-dimensional Whittaker-Shannon interpolation onto the Nyquist-Shannon + grid. Takes a band-limited function fp and original grid xp and resamples fp on the NS grid. Uses the minimum number of points N required by the Nyquist sampling theorem. diff --git a/src/diffpy/utils/tools.py b/src/diffpy/utils/tools.py index a6c30ed3..f2f4e136 100644 --- a/src/diffpy/utils/tools.py +++ b/src/diffpy/utils/tools.py @@ -4,9 +4,28 @@ from pathlib import Path -def _stringify(obj): +def clean_dict(obj): + """Remove keys from the dictionary where the corresponding value is None. + + Parameters + ---------- + obj: dict + The dictionary to clean. If None, initialize as an empty dictionary. + + Returns + ------- + dict: + The cleaned dictionary with keys removed where the value is None. """ - Convert None to an empty string. + obj = obj if obj is not None else {} + for key, value in copy(obj).items(): + if not value: + del obj[key] + return obj + + +def _stringify(obj): + """Convert None to an empty string. Parameters ---------- @@ -22,8 +41,7 @@ def _stringify(obj): def _load_config(file_path): - """ - Load configuration from a .json file. + """Load configuration from a .json file. Parameters ---------- @@ -34,7 +52,6 @@ def _load_config(file_path): ------- dict: The configuration dictionary or {} if the config file does not exist. - """ config_file = Path(file_path).resolve() if config_file.is_file(): @@ -46,8 +63,8 @@ def _load_config(file_path): def get_user_info(owner_name=None, owner_email=None, owner_orcid=None): - """ - Get name, email and orcid of the owner/user from various sources and return it as a metadata dictionary + """Get name, email and orcid of the owner/user from various sources and + return it as a metadata dictionary. The function looks for the information in json format configuration files with the name 'diffpyconfig.json'. These can be in the user's home directory and in the current working directory. The information in the @@ -79,7 +96,6 @@ def get_user_info(owner_name=None, owner_email=None, owner_orcid=None): dict: The dictionary containing username, email and orcid of the user/owner, and any other information stored in the global or local config files. - """ runtime_info = {"owner_name": owner_name, "owner_email": owner_email, "owner_orcid": owner_orcid} for key, value in copy(runtime_info).items(): @@ -104,8 +120,7 @@ def get_user_info(owner_name=None, owner_email=None, owner_orcid=None): def get_package_info(package_names, metadata=None): - """ - Fetches package version and updates it into (given) metadata. + """Fetches package version and updates it into (given) metadata. Package info stored in metadata as {'package_info': {'package_name': 'version_number'}}. @@ -119,7 +134,6 @@ def get_package_info(package_names, metadata=None): ------- dict: The updated metadata dict with package info inserted. - """ if metadata is None: metadata = {} diff --git a/src/diffpy/utils/transforms.py b/src/diffpy/utils/transforms.py index 1d50aeab..f2956879 100644 --- a/src/diffpy/utils/transforms.py +++ b/src/diffpy/utils/transforms.py @@ -29,8 +29,7 @@ def _validate_inputs(q, wavelength): def q_to_tth(q, wavelength): - r""" - Helper function to convert q to two-theta. + r"""Helper function to convert q to two-theta. If wavelength is missing, returns x-values that are integer indexes @@ -72,9 +71,7 @@ def q_to_tth(q, wavelength): def tth_to_q(tth, wavelength): - r""" - - Helper function to convert two-theta to q on independent variable axis. + r"""Helper function to convert two-theta to q on independent variable axis. If wavelength is missing, returns independent variable axis as integer indexes. @@ -120,8 +117,8 @@ def tth_to_q(tth, wavelength): def q_to_d(q): - r""" - Helper function to convert q to d on independent variable axis, using :math:`d = \frac{2 \pi}{q}`. + r"""Helper function to convert q to d on independent variable axis, using + :math:`d = \frac{2 \pi}{q}`. Parameters ---------- @@ -140,8 +137,7 @@ def q_to_d(q): def tth_to_d(tth, wavelength): - r""" - Helper function to convert two-theta to d on independent variable axis. + r"""Helper function to convert two-theta to d on independent variable axis. The formula is .. math:: d = \frac{\lambda}{2 \sin\left(\frac{2\theta}{2}\right)}. @@ -174,8 +170,7 @@ def tth_to_d(tth, wavelength): def d_to_q(d): - r""" - Helper function to convert q to d using :math:`d = \frac{2 \pi}{q}`. + r"""Helper function to convert q to d using :math:`d = \frac{2 \pi}{q}`. Parameters ---------- @@ -194,8 +189,7 @@ def d_to_q(d): def d_to_tth(d, wavelength): - r""" - Helper function to convert d to two-theta on independent variable axis. + r"""Helper function to convert d to two-theta on independent variable axis. The formula is .. math:: 2\theta = 2 \arcsin\left(\frac{\lambda}{2d}\right). diff --git a/src/diffpy/utils/version.py b/src/diffpy/utils/version.py index 0bc397e4..e74c47bd 100644 --- a/src/diffpy/utils/version.py +++ b/src/diffpy/utils/version.py @@ -12,7 +12,6 @@ # See LICENSE.rst for license information. # ############################################################################## - """Definition of __version__.""" # We do not use the other three variables, but can be added back if needed. diff --git a/src/diffpy/utils/wx/__init__.py b/src/diffpy/utils/wx/__init__.py index 3f7417ef..e2f08735 100644 --- a/src/diffpy/utils/wx/__init__.py +++ b/src/diffpy/utils/wx/__init__.py @@ -12,6 +12,4 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Utilities related wx Python GUIs. -""" +"""Utilities related wx Python GUIs.""" diff --git a/src/diffpy/utils/wx/gridutils.py b/src/diffpy/utils/wx/gridutils.py index c459ac30..a01e8f92 100644 --- a/src/diffpy/utils/wx/gridutils.py +++ b/src/diffpy/utils/wx/gridutils.py @@ -12,9 +12,7 @@ # See LICENSE_DANSE.txt for license information. # ############################################################################## - -"""Common functions for manipulating wx.grid.Grid. -""" +"""Common functions for manipulating wx.grid.Grid.""" import wx @@ -53,7 +51,9 @@ def getSelectionColumns(grid): def getSelectedCells(grid): """Get list of (row, col) pairs of all selected cells. - Unlike grid.GetSelectedCells this returns them all no matter how they were selected. + + Unlike grid.GetSelectedCells this returns them all no matter how + they were selected. """ rows = grid.GetNumberRows() cols = grid.GetNumberCols() @@ -75,8 +75,8 @@ def getSelectedCells(grid): def limitSelectionToRows(grid, indices): - """Limit selection to the specified row indices. - No action for empty indices. + """Limit selection to the specified row indices. No action for empty + indices. Parameters ---------- @@ -112,10 +112,10 @@ def limitSelectionToRows(grid, indices): def quickResizeColumns(grid, indices): """Resize the columns that were recently affected by cell changes. - This is faster than the normal grid AutoSizeColumns, since the latter loops - over the entire grid. In addition, this will not cause a - EVT_GRID_CMD_CELL_CHANGE event to be thrown, which can cause recursion. - This method will only increase column size. + This is faster than the normal grid AutoSizeColumns, since the + latter loops over the entire grid. In addition, this will not cause + a EVT_GRID_CMD_CELL_CHANGE event to be thrown, which can cause + recursion. This method will only increase column size. """ # Get the columns and maximum text width in each one dc = wx.ScreenDC() @@ -140,8 +140,9 @@ def quickResizeColumns(grid, indices): def _indicesToBlocks(indices): - """Convert a list of integer indices to a list of (start, stop) tuples. - The (start, stop) tuple defines a continuous block, where the stop index is included in the block. + """Convert a list of integer indices to a list of (start, stop) tuples. The + (start, stop) tuple defines a continuous block, where the stop index is + included in the block. Parameters ---------- diff --git a/tests/test_loaddata.py b/tests/test_loaddata.py index a7e273e7..f825139c 100644 --- a/tests/test_loaddata.py +++ b/tests/test_loaddata.py @@ -1,7 +1,6 @@ #!/usr/bin/env python -"""Unit tests for diffpy.utils.parsers.loaddata -""" +"""Unit tests for diffpy.utils.parsers.loaddata.""" import numpy as np import pytest @@ -10,7 +9,7 @@ def test_loadData_default(datafile): - """check loadData() with default options""" + """Check loadData() with default options.""" loaddata01 = datafile("loaddata01.txt") d2c = np.array([[3, 31], [4, 32], [5, 33]]) @@ -38,7 +37,7 @@ def test_loadData_default(datafile): def test_loadData_1column(datafile): - """check loading of one-column data.""" + """Check loading of one-column data.""" loaddata01 = datafile("loaddata01.txt") d1c = np.arange(1, 6) @@ -54,7 +53,7 @@ def test_loadData_1column(datafile): def test_loadData_headers(datafile): - """check loadData() with headers options enabled""" + """Check loadData() with headers options enabled.""" expected = { "wavelength": 0.1, "dataformat": "Qnm", diff --git a/tests/test_version.py b/tests/test_version.py index 421a96e4..4152a197 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -1,10 +1,10 @@ -"""Unit tests for __version__.py -""" +"""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.""" + """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"