pyvista-validation 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. pyvista_validation-0.1.0/.github/dependabot.yml +16 -0
  2. pyvista_validation-0.1.0/.github/release.yml +9 -0
  3. pyvista_validation-0.1.0/.github/workflows/ci.yml +168 -0
  4. pyvista_validation-0.1.0/.gitignore +13 -0
  5. pyvista_validation-0.1.0/.pre-commit-config.yaml +38 -0
  6. pyvista_validation-0.1.0/LICENSE +21 -0
  7. pyvista_validation-0.1.0/PKG-INFO +222 -0
  8. pyvista_validation-0.1.0/README.md +186 -0
  9. pyvista_validation-0.1.0/doc/Makefile +14 -0
  10. pyvista_validation-0.1.0/doc/_static/.gitkeep +0 -0
  11. pyvista_validation-0.1.0/doc/_templates/autosummary/module.rst +65 -0
  12. pyvista_validation-0.1.0/doc/api.rst +19 -0
  13. pyvista_validation-0.1.0/doc/conf.py +82 -0
  14. pyvista_validation-0.1.0/doc/index.rst +47 -0
  15. pyvista_validation-0.1.0/pyproject.toml +139 -0
  16. pyvista_validation-0.1.0/pyvista_validation/__init__.py +36 -0
  17. pyvista_validation-0.1.0/pyvista_validation/_cast_array.py +134 -0
  18. pyvista_validation-0.1.0/pyvista_validation/_lazy_import.py +46 -0
  19. pyvista_validation-0.1.0/pyvista_validation/_typing/__init__.py +15 -0
  20. pyvista_validation-0.1.0/pyvista_validation/_typing/_aliases.py +23 -0
  21. pyvista_validation-0.1.0/pyvista_validation/_typing/_array_like.py +86 -0
  22. pyvista_validation-0.1.0/pyvista_validation/_version.py +24 -0
  23. pyvista_validation-0.1.0/pyvista_validation/check.py +1235 -0
  24. pyvista_validation-0.1.0/pyvista_validation/py.typed +0 -0
  25. pyvista_validation-0.1.0/pyvista_validation/validate.py +1246 -0
  26. pyvista_validation-0.1.0/pyvista_validation.egg-info/PKG-INFO +222 -0
  27. pyvista_validation-0.1.0/pyvista_validation.egg-info/SOURCES.txt +34 -0
  28. pyvista_validation-0.1.0/pyvista_validation.egg-info/dependency_links.txt +1 -0
  29. pyvista_validation-0.1.0/pyvista_validation.egg-info/requires.txt +10 -0
  30. pyvista_validation-0.1.0/pyvista_validation.egg-info/scm_file_list.json +30 -0
  31. pyvista_validation-0.1.0/pyvista_validation.egg-info/scm_version.json +8 -0
  32. pyvista_validation-0.1.0/pyvista_validation.egg-info/top_level.txt +1 -0
  33. pyvista_validation-0.1.0/setup.cfg +4 -0
  34. pyvista_validation-0.1.0/tests/test_validation.py +1211 -0
  35. pyvista_validation-0.1.0/tools/downstream_parity.py +55 -0
  36. pyvista_validation-0.1.0/tools/downstream_shim.py +28 -0
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ labels: [maintenance, dependencies]
8
+ open-pull-requests-limit: 20
9
+ - package-ecosystem: github-actions
10
+ directory: /.github/workflows
11
+ schedule:
12
+ interval: weekly
13
+ labels: [maintenance, dependencies]
14
+ groups:
15
+ artifacts:
16
+ patterns: [actions/upload-artifact, actions/download-artifact]
@@ -0,0 +1,9 @@
1
+ changelog:
2
+ exclude:
3
+ authors:
4
+ - dependabot
5
+ - dependabot[bot]
6
+ - pre-commit-ci
7
+ - pre-commit-ci[bot]
8
+ - github-actions
9
+ - github-actions[bot]
@@ -0,0 +1,168 @@
1
+ name: CI
2
+
3
+ # `pull_request` is deliberately unfiltered: filtering it by base branch would
4
+ # skip every pull request in a stack that does not target main.
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ tags: [v*]
9
+ pull_request:
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ pre-commit:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
+ with:
24
+ persist-credentials: false
25
+ fetch-depth: 0
26
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
27
+ with:
28
+ enable-cache: false
29
+ - run: uv sync --group dev
30
+ - run: uv run pre-commit run --all-files --show-diff-on-failure
31
+ env:
32
+ # This hook exists to stop *local* commits straight to main; it
33
+ # would always fail here since CI checks out that branch/tag directly.
34
+ SKIP: no-commit-to-branch
35
+
36
+ test:
37
+ runs-on: ubuntu-latest
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
42
+ steps:
43
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
44
+ with:
45
+ persist-credentials: false
46
+ fetch-depth: 0
47
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
48
+ with:
49
+ enable-cache: false
50
+ - run: uv sync --group dev --extra all --python ${{ matrix.python-version }}
51
+ - run: uv run pytest tests/ --cov --cov-report=xml
52
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
53
+ with:
54
+ files: ./coverage.xml
55
+ env:
56
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
57
+
58
+ test-minimal:
59
+ # numpy is the only hard dependency; this proves the VTK and SciPy code
60
+ # paths stay optional rather than quietly becoming required.
61
+ runs-on: ubuntu-latest
62
+ strategy:
63
+ fail-fast: false
64
+ matrix:
65
+ python-version: ['3.10', '3.14']
66
+ steps:
67
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
68
+ with:
69
+ persist-credentials: false
70
+ fetch-depth: 0
71
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
72
+ with:
73
+ enable-cache: false
74
+ - run: uv sync --group dev --python ${{ matrix.python-version }}
75
+ - run: uv run python -c "import pyvista_validation, sys; assert not [m for m in sys.modules if m.startswith(('vtkmodules', 'scipy'))]"
76
+ - run: uv run pytest tests/ --no-cov
77
+
78
+ downstream:
79
+ name: Downstream PyVista
80
+ runs-on: ubuntu-latest
81
+ env:
82
+ VIRTUAL_ENV: ${{ github.workspace }}/.venv
83
+ PYVISTA_OFF_SCREEN: 'true'
84
+ steps:
85
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
86
+ with:
87
+ persist-credentials: false
88
+ fetch-depth: 0
89
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
90
+ with:
91
+ enable-cache: false
92
+ - run: sudo apt-get update && sudo apt-get install --yes libgl1 libxrender1 xvfb
93
+ - name: Clone the PyVista main branch
94
+ run: git clone --depth=1 --branch main --single-branch https://github.com/pyvista/pyvista.git "${{ runner.temp }}/pyvista"
95
+ - name: Install PyVista and this package into one environment
96
+ run: |
97
+ uv venv
98
+ uv pip install --editable "${{ runner.temp }}/pyvista" --group test --directory "${{ runner.temp }}/pyvista"
99
+ uv pip install --editable '.[all]'
100
+ - name: Check the public API still matches PyVista's
101
+ run: .venv/bin/python tools/downstream_parity.py
102
+ - name: Run PyVista's validation suite against this package
103
+ working-directory: ${{ runner.temp }}/pyvista
104
+ env:
105
+ PYTHONPATH: ${{ github.workspace }}/tools
106
+ run: xvfb-run ${{ github.workspace }}/.venv/bin/python -m pytest tests/core/test_validation.py -p downstream_shim -v
107
+
108
+ docs:
109
+ runs-on: ubuntu-latest
110
+ steps:
111
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
112
+ with:
113
+ persist-credentials: false
114
+ fetch-depth: 0
115
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
116
+ with:
117
+ enable-cache: false
118
+ - run: uv sync --group docs --extra all --python 3.14
119
+ - run: uv run --no-sync sphinx-build -W --keep-going -b html doc doc/_build/html
120
+ - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
121
+ with:
122
+ path: doc/_build/html/
123
+
124
+ deploy-docs:
125
+ # Publishes directly from the workflow artifact; no gh-pages branch.
126
+ needs: docs
127
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
128
+ runs-on: ubuntu-latest
129
+ environment:
130
+ name: github-pages
131
+ url: ${{ steps.deployment.outputs.page_url }}
132
+ permissions:
133
+ pages: write
134
+ id-token: write
135
+ steps:
136
+ - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
137
+ id: deployment
138
+
139
+ build:
140
+ needs: [pre-commit, test, test-minimal, downstream, docs]
141
+ runs-on: ubuntu-latest
142
+ steps:
143
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
144
+ with:
145
+ persist-credentials: false
146
+ fetch-depth: 0
147
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
148
+ with:
149
+ enable-cache: false
150
+ - run: uv build
151
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
152
+ with:
153
+ name: dist
154
+ path: dist/
155
+
156
+ publish:
157
+ needs: build
158
+ if: startsWith(github.ref, 'refs/tags/v')
159
+ runs-on: ubuntu-latest
160
+ environment: release
161
+ permissions:
162
+ id-token: write
163
+ steps:
164
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
165
+ with:
166
+ name: dist
167
+ path: dist/
168
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
@@ -0,0 +1,13 @@
1
+ .DS_Store
2
+ .coverage
3
+ .coverage.*
4
+ .idea/
5
+ .venv/
6
+ build/
7
+ dist/
8
+ doc/_autosummary/
9
+ doc/_build/
10
+ *.egg-info/
11
+ __pycache__/
12
+ pyvista_validation/_version.py
13
+ uv.lock
@@ -0,0 +1,38 @@
1
+ ci:
2
+ autoupdate_commit_msg: 'chore: update pre-commit hooks'
3
+ autofix_prs: true
4
+ autoupdate_schedule: quarterly
5
+
6
+ repos:
7
+ - repo: https://github.com/pre-commit/pre-commit-hooks
8
+ rev: v5.0.0
9
+ hooks:
10
+ - id: check-merge-conflict
11
+ - id: debug-statements
12
+ - id: no-commit-to-branch
13
+ args: [--branch, main]
14
+
15
+ - repo: https://github.com/astral-sh/ruff-pre-commit
16
+ rev: v0.16.0
17
+ hooks:
18
+ - id: ruff-check
19
+ args: [--fix, --show-fixes]
20
+ - id: ruff-format
21
+
22
+ - repo: https://github.com/zizmorcore/zizmor-pre-commit
23
+ rev: v1.11.0
24
+ hooks:
25
+ - id: zizmor
26
+
27
+ - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
28
+ rev: v2.15.0
29
+ hooks:
30
+ - id: pretty-format-yaml
31
+ args: [--autofix, --indent, '2']
32
+
33
+ - repo: https://github.com/ComPWA/taplo-pre-commit
34
+ rev: v0.9.3
35
+ hooks:
36
+ - id: taplo-format
37
+ # See options: https://taplo.tamasfe.dev/configuration/formatter-options.html
38
+ args: [--option, reorder_arrays=true, --option, reorder_keys=true, --option, align_comments=false]
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2026 The PyVista Developers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to
7
+ deal in the Software without restriction, including without limitation the
8
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ sell copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ IN THE SOFTWARE.
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyvista-validation
3
+ Version: 0.1.0
4
+ Summary: Validate and standardize array-like input.
5
+ Author-email: The PyVista Developers <info@pyvista.org>
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://validation.pyvista.org/
8
+ Project-URL: Homepage, https://github.com/pyvista/pyvista-validation
9
+ Keywords: array,numpy,validation
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: MacOS
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: numpy>=1.21.0
29
+ Provides-Extra: all
30
+ Requires-Dist: pyvista-validation[scipy,vtk]; extra == "all"
31
+ Provides-Extra: scipy
32
+ Requires-Dist: scipy; extra == "scipy"
33
+ Provides-Extra: vtk
34
+ Requires-Dist: vtk; extra == "vtk"
35
+ Dynamic: license-file
36
+
37
+ # pyvista-validation
38
+
39
+ Validate and standardize array-like input.
40
+
41
+ These are the input validation functions developed for
42
+ [PyVista](https://github.com/pyvista/pyvista), extracted into a standalone package so any
43
+ project can use them. NumPy is the only required dependency: PyVista is not needed, and
44
+ VTK and SciPy are optional.
45
+
46
+ The functions are useful when writing Python methods that accept flexible array-like
47
+ input, wrapping VTK, or anywhere you want one standard representation out of many
48
+ possible inputs.
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install pyvista-validation
54
+ ```
55
+
56
+ VTK and SciPy are only needed to validate their own object types, so they ship as extras:
57
+
58
+ ```bash
59
+ pip install pyvista-validation[vtk] # accept vtkMatrix3x3, vtkMatrix4x4, vtkTransform
60
+ pip install pyvista-validation[scipy] # accept scipy.spatial.transform.Rotation
61
+ pip install pyvista-validation[all] # both
62
+ ```
63
+
64
+ Neither is imported unless you actually pass one of their objects in.
65
+
66
+ ## Two families of function
67
+
68
+ A **`check`** function:
69
+
70
+ * Performs a simple validation on a single input variable.
71
+ * Raises an error if the check fails due to invalid input.
72
+ * Does not modify input or return anything.
73
+
74
+ A **`validate`** function:
75
+
76
+ * Uses `check` functions to check the type and/or value of input arguments.
77
+ * Applies optional constraints -- for example input or output must have a specific
78
+ length, shape, type, data-type, etc.
79
+ * Accepts many different input types or values and standardizes the output as a single
80
+ representation with known properties.
81
+
82
+ ## Usage
83
+
84
+ `validate` functions return a standard representation:
85
+
86
+ ```python
87
+ >>> import numpy as np
88
+ >>> from pyvista_validation import validate_array3
89
+ >>> from pyvista_validation import validate_arrayNx3
90
+ >>> from pyvista_validation import validate_data_range
91
+
92
+ >>> validate_array3([1, 2, 3])
93
+ array([1, 2, 3])
94
+
95
+ >>> validate_arrayNx3([[1, 2, 3], [4, 5, 6]])
96
+ array([[1, 2, 3],
97
+ [4, 5, 6]])
98
+
99
+ >>> validate_data_range([0, 1])
100
+ (0, 1)
101
+ ```
102
+
103
+ A 3x3 input to `validate_transform4x4` is padded into a 4x4 matrix:
104
+
105
+ ```python
106
+ >>> from pyvista_validation import validate_transform4x4
107
+
108
+ >>> validate_transform4x4(np.eye(3))
109
+ array([[1., 0., 0., 0.],
110
+ [0., 1., 0., 0.],
111
+ [0., 0., 1., 0.],
112
+ [0., 0., 0., 1.]])
113
+ ```
114
+
115
+ `validate_array` is the general-purpose entry point that the others build on, and takes
116
+ the constraints as keyword arguments:
117
+
118
+ ```python
119
+ >>> from pyvista_validation import validate_array
120
+
121
+ >>> validate_array(
122
+ ... [1, 2, 3], must_have_shape=(3,), must_be_in_range=[0, 5], dtype_out=float
123
+ ... )
124
+ array([1., 2., 3.])
125
+ ```
126
+
127
+ `check` functions return nothing and raise on failure:
128
+
129
+ ```python
130
+ >>> from pyvista_validation import check_range
131
+ >>> from pyvista_validation import check_subdtype
132
+
133
+ >>> check_range([1, 5], rng=[0, 3])
134
+ Traceback (most recent call last):
135
+ ...
136
+ ValueError: Array values must all be less than or equal to 3.
137
+
138
+ >>> check_subdtype(np.array([1.0]), np.integer)
139
+ Traceback (most recent call last):
140
+ ...
141
+ TypeError: Input has incorrect dtype of 'float64'. The dtype must be a subtype of <class 'numpy.integer'>.
142
+ ```
143
+
144
+ Error messages name the offending value and the constraint it violated:
145
+
146
+ ```python
147
+ >>> validate_array3([1, 2])
148
+ Traceback (most recent call last):
149
+ ...
150
+ ValueError: Array has shape (2,) which is not allowed. Shape must be one of [(3,), (1, 3), (3, 1)].
151
+ ```
152
+
153
+ Pass `name=` to any function to control how the input is described in that message.
154
+
155
+ ## Common use cases
156
+
157
+ | To validate | Use |
158
+ | --- | --- |
159
+ | A 3-element vector | `validate_array3` |
160
+ | An Nx3 point or vector array | `validate_arrayNx3` |
161
+ | Point or cell IDs | `validate_arrayN_unsigned` |
162
+ | A transformation matrix | `validate_transform4x4` |
163
+ | A rotation matrix | `validate_rotation` |
164
+
165
+ ## API reference
166
+
167
+ ### `validate` functions
168
+
169
+ | Function | Description |
170
+ | --- | --- |
171
+ | `validate_array` | Check and validate a numeric array meets specific requirements. |
172
+ | `validate_array3` | Validate a numeric 1D array with 3 elements. |
173
+ | `validate_arrayN` | Validate a numeric 1D array. |
174
+ | `validate_arrayN_unsigned` | Validate a numeric 1D array of non-negative (unsigned) integers. |
175
+ | `validate_arrayNx3` | Validate an array is numeric and has shape Nx3. |
176
+ | `validate_axes` | Validate 3D axes vectors. |
177
+ | `validate_data_range` | Validate a data range. |
178
+ | `validate_dimensionality` | Validate a dimensionality. |
179
+ | `validate_number` | Validate a real, finite number. |
180
+ | `validate_rotation` | Validate a rotation as a 3x3 matrix. |
181
+ | `validate_transform3x3` | Validate transform-like input as a 3x3 `ndarray`. |
182
+ | `validate_transform4x4` | Validate transform-like input as a 4x4 `ndarray`. |
183
+
184
+ ### `check` functions
185
+
186
+ | Function | Description |
187
+ | --- | --- |
188
+ | `check_contains` | Check if an item is in a container. |
189
+ | `check_finite` | Check if an array has finite values, that is, no NaN or Inf values. |
190
+ | `check_greater_than` | Check if an array's elements are all greater than some value. |
191
+ | `check_instance` | Check if an object is an instance of the given type or types. |
192
+ | `check_integer` | Check if an array has integer or integer-like float values. |
193
+ | `check_iterable` | Check if an object is an instance of `Iterable`. |
194
+ | `check_iterable_items` | Check if an iterable's items all have a specified type. |
195
+ | `check_length` | Check if the length of an array meets specific requirements. |
196
+ | `check_less_than` | Check if an array's elements are all less than some value. |
197
+ | `check_ndim` | Check if an array has the specified number of dimensions. |
198
+ | `check_nonnegative` | Check if an array's elements are all nonnegative. |
199
+ | `check_number` | Check if an object is an instance of `Number`. |
200
+ | `check_range` | Check if an array's values are all within a specific range. |
201
+ | `check_real` | Check if an array has real numbers (float or integer type). |
202
+ | `check_sequence` | Check if an object is an instance of `Sequence`. |
203
+ | `check_shape` | Check if an array has the specified shape. |
204
+ | `check_sorted` | Check if an array's values are sorted. |
205
+ | `check_string` | Check if an object is an instance of `str`. |
206
+ | `check_subdtype` | Check if an input's data-type is a subtype of another data-type or data-types. |
207
+ | `check_type` | Check if an object is one of the given type or types. |
208
+
209
+ Every function has a full docstring with parameters and examples.
210
+
211
+ ## Relationship to PyVista
212
+
213
+ This code began as `pyvista.core._validation` and keeps its full commit history here.
214
+ PyVista is a downstream consumer, and CI runs PyVista's own validation test suite against
215
+ this package on every change.
216
+
217
+ One PyVista-specific helper, `_validate_color_sequence`, was not moved: it is built on
218
+ `pyvista.plotting`'s `Color` class and stays with PyVista.
219
+
220
+ ## License
221
+
222
+ MIT
@@ -0,0 +1,186 @@
1
+ # pyvista-validation
2
+
3
+ Validate and standardize array-like input.
4
+
5
+ These are the input validation functions developed for
6
+ [PyVista](https://github.com/pyvista/pyvista), extracted into a standalone package so any
7
+ project can use them. NumPy is the only required dependency: PyVista is not needed, and
8
+ VTK and SciPy are optional.
9
+
10
+ The functions are useful when writing Python methods that accept flexible array-like
11
+ input, wrapping VTK, or anywhere you want one standard representation out of many
12
+ possible inputs.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install pyvista-validation
18
+ ```
19
+
20
+ VTK and SciPy are only needed to validate their own object types, so they ship as extras:
21
+
22
+ ```bash
23
+ pip install pyvista-validation[vtk] # accept vtkMatrix3x3, vtkMatrix4x4, vtkTransform
24
+ pip install pyvista-validation[scipy] # accept scipy.spatial.transform.Rotation
25
+ pip install pyvista-validation[all] # both
26
+ ```
27
+
28
+ Neither is imported unless you actually pass one of their objects in.
29
+
30
+ ## Two families of function
31
+
32
+ A **`check`** function:
33
+
34
+ * Performs a simple validation on a single input variable.
35
+ * Raises an error if the check fails due to invalid input.
36
+ * Does not modify input or return anything.
37
+
38
+ A **`validate`** function:
39
+
40
+ * Uses `check` functions to check the type and/or value of input arguments.
41
+ * Applies optional constraints -- for example input or output must have a specific
42
+ length, shape, type, data-type, etc.
43
+ * Accepts many different input types or values and standardizes the output as a single
44
+ representation with known properties.
45
+
46
+ ## Usage
47
+
48
+ `validate` functions return a standard representation:
49
+
50
+ ```python
51
+ >>> import numpy as np
52
+ >>> from pyvista_validation import validate_array3
53
+ >>> from pyvista_validation import validate_arrayNx3
54
+ >>> from pyvista_validation import validate_data_range
55
+
56
+ >>> validate_array3([1, 2, 3])
57
+ array([1, 2, 3])
58
+
59
+ >>> validate_arrayNx3([[1, 2, 3], [4, 5, 6]])
60
+ array([[1, 2, 3],
61
+ [4, 5, 6]])
62
+
63
+ >>> validate_data_range([0, 1])
64
+ (0, 1)
65
+ ```
66
+
67
+ A 3x3 input to `validate_transform4x4` is padded into a 4x4 matrix:
68
+
69
+ ```python
70
+ >>> from pyvista_validation import validate_transform4x4
71
+
72
+ >>> validate_transform4x4(np.eye(3))
73
+ array([[1., 0., 0., 0.],
74
+ [0., 1., 0., 0.],
75
+ [0., 0., 1., 0.],
76
+ [0., 0., 0., 1.]])
77
+ ```
78
+
79
+ `validate_array` is the general-purpose entry point that the others build on, and takes
80
+ the constraints as keyword arguments:
81
+
82
+ ```python
83
+ >>> from pyvista_validation import validate_array
84
+
85
+ >>> validate_array(
86
+ ... [1, 2, 3], must_have_shape=(3,), must_be_in_range=[0, 5], dtype_out=float
87
+ ... )
88
+ array([1., 2., 3.])
89
+ ```
90
+
91
+ `check` functions return nothing and raise on failure:
92
+
93
+ ```python
94
+ >>> from pyvista_validation import check_range
95
+ >>> from pyvista_validation import check_subdtype
96
+
97
+ >>> check_range([1, 5], rng=[0, 3])
98
+ Traceback (most recent call last):
99
+ ...
100
+ ValueError: Array values must all be less than or equal to 3.
101
+
102
+ >>> check_subdtype(np.array([1.0]), np.integer)
103
+ Traceback (most recent call last):
104
+ ...
105
+ TypeError: Input has incorrect dtype of 'float64'. The dtype must be a subtype of <class 'numpy.integer'>.
106
+ ```
107
+
108
+ Error messages name the offending value and the constraint it violated:
109
+
110
+ ```python
111
+ >>> validate_array3([1, 2])
112
+ Traceback (most recent call last):
113
+ ...
114
+ ValueError: Array has shape (2,) which is not allowed. Shape must be one of [(3,), (1, 3), (3, 1)].
115
+ ```
116
+
117
+ Pass `name=` to any function to control how the input is described in that message.
118
+
119
+ ## Common use cases
120
+
121
+ | To validate | Use |
122
+ | --- | --- |
123
+ | A 3-element vector | `validate_array3` |
124
+ | An Nx3 point or vector array | `validate_arrayNx3` |
125
+ | Point or cell IDs | `validate_arrayN_unsigned` |
126
+ | A transformation matrix | `validate_transform4x4` |
127
+ | A rotation matrix | `validate_rotation` |
128
+
129
+ ## API reference
130
+
131
+ ### `validate` functions
132
+
133
+ | Function | Description |
134
+ | --- | --- |
135
+ | `validate_array` | Check and validate a numeric array meets specific requirements. |
136
+ | `validate_array3` | Validate a numeric 1D array with 3 elements. |
137
+ | `validate_arrayN` | Validate a numeric 1D array. |
138
+ | `validate_arrayN_unsigned` | Validate a numeric 1D array of non-negative (unsigned) integers. |
139
+ | `validate_arrayNx3` | Validate an array is numeric and has shape Nx3. |
140
+ | `validate_axes` | Validate 3D axes vectors. |
141
+ | `validate_data_range` | Validate a data range. |
142
+ | `validate_dimensionality` | Validate a dimensionality. |
143
+ | `validate_number` | Validate a real, finite number. |
144
+ | `validate_rotation` | Validate a rotation as a 3x3 matrix. |
145
+ | `validate_transform3x3` | Validate transform-like input as a 3x3 `ndarray`. |
146
+ | `validate_transform4x4` | Validate transform-like input as a 4x4 `ndarray`. |
147
+
148
+ ### `check` functions
149
+
150
+ | Function | Description |
151
+ | --- | --- |
152
+ | `check_contains` | Check if an item is in a container. |
153
+ | `check_finite` | Check if an array has finite values, that is, no NaN or Inf values. |
154
+ | `check_greater_than` | Check if an array's elements are all greater than some value. |
155
+ | `check_instance` | Check if an object is an instance of the given type or types. |
156
+ | `check_integer` | Check if an array has integer or integer-like float values. |
157
+ | `check_iterable` | Check if an object is an instance of `Iterable`. |
158
+ | `check_iterable_items` | Check if an iterable's items all have a specified type. |
159
+ | `check_length` | Check if the length of an array meets specific requirements. |
160
+ | `check_less_than` | Check if an array's elements are all less than some value. |
161
+ | `check_ndim` | Check if an array has the specified number of dimensions. |
162
+ | `check_nonnegative` | Check if an array's elements are all nonnegative. |
163
+ | `check_number` | Check if an object is an instance of `Number`. |
164
+ | `check_range` | Check if an array's values are all within a specific range. |
165
+ | `check_real` | Check if an array has real numbers (float or integer type). |
166
+ | `check_sequence` | Check if an object is an instance of `Sequence`. |
167
+ | `check_shape` | Check if an array has the specified shape. |
168
+ | `check_sorted` | Check if an array's values are sorted. |
169
+ | `check_string` | Check if an object is an instance of `str`. |
170
+ | `check_subdtype` | Check if an input's data-type is a subtype of another data-type or data-types. |
171
+ | `check_type` | Check if an object is one of the given type or types. |
172
+
173
+ Every function has a full docstring with parameters and examples.
174
+
175
+ ## Relationship to PyVista
176
+
177
+ This code began as `pyvista.core._validation` and keeps its full commit history here.
178
+ PyVista is a downstream consumer, and CI runs PyVista's own validation test suite against
179
+ this package on every change.
180
+
181
+ One PyVista-specific helper, `_validate_color_sequence`, was not moved: it is built on
182
+ `pyvista.plotting`'s `Color` class and stays with PyVista.
183
+
184
+ ## License
185
+
186
+ MIT
@@ -0,0 +1,14 @@
1
+ # Minimal makefile for Sphinx documentation
2
+
3
+ SPHINXOPTS ?= -W --keep-going
4
+ SPHINXBUILD ?= sphinx-build
5
+ SOURCEDIR = .
6
+ BUILDDIR = _build
7
+
8
+ help:
9
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
10
+
11
+ .PHONY: help Makefile
12
+
13
+ %: Makefile
14
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
File without changes