valarray 0.4rc1__tar.gz → 0.4.2__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 (106) hide show
  1. {valarray-0.4rc1 → valarray-0.4.2}/.gitignore +1 -0
  2. {valarray-0.4rc1 → valarray-0.4.2}/PKG-INFO +71 -35
  3. {valarray-0.4rc1 → valarray-0.4.2}/README.md +70 -34
  4. valarray-0.4.2/docs/dependency_graphs/core.mmd +30 -0
  5. valarray-0.4.2/docs/dependency_graphs/core_validation_errors.mmd +13 -0
  6. valarray-0.4.2/docs/dependency_graphs/core_validation_functions.mmd +15 -0
  7. valarray-0.4.2/docs/dependency_graphs/numpy.mmd +25 -0
  8. {valarray-0.4rc1 → valarray-0.4.2}/pyproject.toml +1 -1
  9. {valarray-0.4rc1 → valarray-0.4.2}/requirements_dev.txt +2 -1
  10. valarray-0.4.2/requirements_dev_optional.txt +1 -0
  11. valarray-0.4.2/test_data/core/string_utils.py +54 -0
  12. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/array_and_dtype.py +6 -0
  13. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/array_type_adapter.py +6 -2
  14. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/comparisons.py +1 -1
  15. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/errors_exceptions.py +6 -4
  16. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/validators.py +18 -0
  17. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/errors_exceptions/test_values_errors.py +1 -1
  18. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/test_array.py +51 -1
  19. valarray-0.4.2/tests/core/test_axes_and_fields.py +22 -0
  20. valarray-0.4rc1/tests/core/test_axes_and_fields.py → valarray-0.4.2/tests/core/test_data_structures.py +1 -1
  21. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/test_misc.py +1 -1
  22. valarray-0.4.2/tests/core/test_string_utils.py +226 -0
  23. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/test_utils.py +1 -1
  24. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/test_validators.py +34 -10
  25. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/field_values/test_ax_and_field_strings.py +13 -9
  26. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/field_values/test_val_field_values_core.py +4 -8
  27. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/field_values/test_val_field_values_utils.py +28 -21
  28. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/test_val_array.py +3 -2
  29. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/test_val_array_values.py +4 -3
  30. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/test_val_shape.py +7 -7
  31. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/test_adapter.py +2 -1
  32. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/test_numpy_array.py +51 -1
  33. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/test_validation.py +3 -3
  34. {valarray-0.4rc1 → valarray-0.4.2}/tests/test_imports.py +17 -4
  35. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/__init__.py +5 -2
  36. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/array.py +37 -4
  37. valarray-0.4.2/valarray/core/array_type_adapter/__init__.py +13 -0
  38. valarray-0.4rc1/valarray/core/array_type_adapter.py → valarray-0.4.2/valarray/core/array_type_adapter/adapter.py +27 -8
  39. {valarray-0.4rc1/valarray/core → valarray-0.4.2/valarray/core/array_type_adapter}/comparisons.py +3 -0
  40. valarray-0.4rc1/valarray/core/errors_exceptions/generic.py → valarray-0.4.2/valarray/core/array_type_adapter/errors.py +26 -7
  41. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/axes_and_fields.py +23 -60
  42. valarray-0.4.2/valarray/core/data_structures.py +65 -0
  43. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/__init__.py +0 -3
  44. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/exceptions.py +4 -7
  45. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/values.py +17 -11
  46. valarray-0.4.2/valarray/core/string_utils/__init__.py +28 -0
  47. valarray-0.4.2/valarray/core/string_utils/array.py +112 -0
  48. valarray-0.4.2/valarray/core/string_utils/field.py +36 -0
  49. valarray-0.4.2/valarray/core/string_utils/general.py +74 -0
  50. valarray-0.4.2/valarray/core/string_utils/headings.py +5 -0
  51. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/types/other.py +3 -1
  52. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/utils.py +12 -4
  53. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/array.py +26 -7
  54. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/array_values.py +11 -10
  55. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/field_values/core.py +21 -9
  56. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/field_values/types_and_data_structures.py +12 -12
  57. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/field_values/utils.py +12 -13
  58. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validators/__init__.py +11 -0
  59. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validators/base.py +26 -4
  60. valarray-0.4.2/valarray/core/validators/types.py +29 -0
  61. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validators/value_comparisons.py +9 -8
  62. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/__init__.py +3 -2
  63. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/array.py +2 -5
  64. valarray-0.4.2/valarray/numpy/array_type_adapter/__init__.py +13 -0
  65. valarray-0.4rc1/valarray/numpy/array_type_adapter.py → valarray-0.4.2/valarray/numpy/array_type_adapter/adapter.py +9 -5
  66. {valarray-0.4rc1/valarray/numpy → valarray-0.4.2/valarray/numpy/array_type_adapter}/comparisons.py +2 -2
  67. valarray-0.4.2/valarray/numpy/array_type_adapter/errors.py +30 -0
  68. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/axes_and_fields.py +2 -2
  69. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/errors_exceptions.py +2 -22
  70. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/validation_functions.py +11 -6
  71. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/validators.py +18 -2
  72. valarray-0.4.2/valarray/settings.py +23 -0
  73. {valarray-0.4rc1 → valarray-0.4.2}/.coveragerc +0 -0
  74. {valarray-0.4rc1 → valarray-0.4.2}/assets/images/valarray_logo.svg +0 -0
  75. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue1_problem.py +0 -0
  76. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue1_solution.py +0 -0
  77. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue2_problem.py +0 -0
  78. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue2_solution.py +0 -0
  79. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue_3_problem.py +0 -0
  80. {valarray-0.4rc1 → valarray-0.4.2}/docs/example_code/introduction/issue_3_solution.py +0 -0
  81. {valarray-0.4rc1 → valarray-0.4.2}/requirements.txt +0 -0
  82. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/__init__.py +0 -0
  83. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/classes_for_testing/validated_array.py +0 -0
  84. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/errors_exceptions/test_axes_errors.py +0 -0
  85. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/errors_exceptions/test_dtype_errors.py +0 -0
  86. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/errors_exceptions/test_error_list.py +0 -0
  87. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/errors_exceptions/test_exceptions.py +0 -0
  88. {valarray-0.4rc1 → valarray-0.4.2}/tests/core/validation_functions/test_val_dtype.py +0 -0
  89. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/common.py +0 -0
  90. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/test_numpy_comparisons.py +0 -0
  91. {valarray-0.4rc1 → valarray-0.4.2}/tests/numpy/test_numpy_errors_and_exceptions.py +0 -0
  92. {valarray-0.4rc1 → valarray-0.4.2}/valarray/__init__.py +0 -0
  93. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/error_list.py +0 -0
  94. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/__init__.py +0 -0
  95. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/array_creation.py +0 -0
  96. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/axes.py +0 -0
  97. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/base.py +0 -0
  98. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/errors_exceptions/validation_errors/dtype.py +0 -0
  99. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/types/__init__.py +0 -0
  100. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/types/generics.py +0 -0
  101. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/__init__.py +0 -0
  102. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/dtype.py +0 -0
  103. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/field_values/__init__.py +0 -0
  104. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/shape.py +0 -0
  105. {valarray-0.4rc1 → valarray-0.4.2}/valarray/core/validation_functions/utils.py +0 -0
  106. {valarray-0.4rc1 → valarray-0.4.2}/valarray/numpy/types.py +0 -0
@@ -3,6 +3,7 @@
3
3
  .coverage
4
4
  *egg-info
5
5
  dist*
6
+ tach*
6
7
 
7
8
  ut_*
8
9
  temp*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: valarray
3
- Version: 0.4rc1
3
+ Version: 0.4.2
4
4
  Summary: Library for validating numpy arrays.
5
5
  Project-URL: Homepage, https://codeberg.org/jfranek/valarray
6
6
  Author-email: "J. Franek" <franek.j27@email.cz>
@@ -14,11 +14,11 @@ Requires-Python: >=3.7
14
14
  Requires-Dist: numpy>=2
15
15
  Description-Content-Type: text/markdown
16
16
 
17
- ![](assets/images/valarray_logo.svg)
17
+ ![valarray logo](https://codeberg.org/jfranek/valarray/raw/branch/main/assets/images/valarray_logo.svg)
18
18
 
19
19
  In short, library for validating numpy arrays that also helps with static analysis and documentation. In long, see [Library rationale](#library-rationale).
20
20
 
21
- Currently intended primarily as a personal/hobby project (see [Caveats](#caveats))
21
+ Currently intended primarily as a personal/hobby project (see [Caveats](#caveats)). Also not considered stable (see [Breaking changes](#breaking-changes)).
22
22
 
23
23
  I have gotten away with using it in a professional setting, but YMMV.
24
24
 
@@ -55,8 +55,10 @@ except ValidationException as v_exc:
55
55
  >>> [-2.0, -6.0]
56
56
  ```
57
57
 
58
- # Table of contents
59
- - [Table of contents](#table-of-contents)
58
+ <!-- NOTE: Headings that are used as relative links (so most of them) must have id tag defined
59
+ (see https://github.com/pypa/readme_renderer/issues/169#issuecomment-808577486) otherwise links do not work on pypi.-->
60
+
61
+ # Table of contents <!-- omit from toc -->
60
62
  - [Library rationale](#library-rationale)
61
63
  - [1) Invalid values causing unintended behaviour](#1-invalid-values-causing-unintended-behaviour)
62
64
  - [Problem](#problem)
@@ -83,13 +85,19 @@ except ValidationException as v_exc:
83
85
  - [Catching exceptions](#catching-exceptions)
84
86
  - [Special exceptions and errors](#special-exceptions-and-errors)
85
87
  - [Generic Errors](#generic-errors)
88
+ - [Settings](#settings)
86
89
  - [Caveats](#caveats)
90
+ - [Changelog](#changelog)
91
+ - [0.4.2](#042)
92
+ - [0.4.1](#041)
93
+ - [0.4](#04)
94
+ - [Breaking changes](#breaking-changes)
87
95
 
88
- # Library rationale
96
+ # Library rationale<a id="library-rationale"></a>
89
97
  This library aims to help with 3 issues encountered when working with numpy arrays:
90
98
 
91
- ## 1) Invalid values causing unintended behaviour
92
- ### Problem
99
+ ## 1) Invalid values causing unintended behaviour<a id="1-invalid-values-causing-unintended-behaviour"></a>
100
+ ### Problem<a id="problem"></a>
93
101
  Invalid values can cause crashes, or worse, cause silent failures.
94
102
 
95
103
  For example the following code fails silently when attempting to cut patches from image using bounding boxes with invalid coordinates.
@@ -123,7 +131,7 @@ for patch in patches:
123
131
  >>> (50, 200, 3)
124
132
  ```
125
133
 
126
- ### Solution
134
+ ### Solution<a id="solution"></a>
127
135
  Validate boxes array first. If errors are encountered, print descriptive error message(s).
128
136
 
129
137
  ```python
@@ -177,8 +185,8 @@ except ValidationException as exc:
177
185
  >>> Field < 0 >: [-10]
178
186
  ```
179
187
 
180
- ## 2) Limited support for static analysis
181
- ### Problem
188
+ ## 2) Limited support for static analysis<a id="2-limited-support-for-static-analysis"></a>
189
+ ### Problem<a id="problem-1"></a>
182
190
  Support for static analysis is limited. Tools can only check whether the datatype is correct, but not shape, values or what those values actually represent.
183
191
 
184
192
  For example, the function to crop patches needs the boxes to be defined by `xmin, ymin, xmax, ymax` but doesn't throw an error if input boxes are defined by `x_center, y_center, width, height` and static analysis tools cannot detect this error using bulit-in numpy types.
@@ -222,7 +230,7 @@ for patch in patches_inv:
222
230
  >>> (0, 200, 3)
223
231
  ```
224
232
 
225
- ### Solution
233
+ ### Solution<a id="solution-1"></a>
226
234
  `ValidatedNumpyArray` subclasses can represent these two types of boxes arrays, and can be used instead of bare numpy arrays in function/method signatures and such.
227
235
  ```python
228
236
  import numpy as np
@@ -289,8 +297,8 @@ for patch in patches_inv:
289
297
  print(patch.shape)
290
298
  ```
291
299
 
292
- ## 3) Need for explicit documentation
293
- ### Problem
300
+ ## 3) Need for explicit documentation<a id="3-need-for-explicit-documentation"></a>
301
+ ### Problem<a id="problem-2"></a>
294
302
  Using built-in numpy types provides only documentation for data types. Shape, values, constraints and what the array represents need to be explicitly documented either in comments or docstrings.
295
303
 
296
304
  If this type of array is used in multiple places / functions, this can cause duplicated documentation.
@@ -319,7 +327,7 @@ def cut_patches(
319
327
  return patches
320
328
  ```
321
329
 
322
- ### Solution
330
+ ### Solution<a id="solution-2"></a>
323
331
  Defining data type, schema and constraints on a `ValidatedNumpyArray` subclass already implicitly documents them.
324
332
 
325
333
  This can be complemented by adding additional (or summary) documentation in the class docstring.
@@ -367,8 +375,8 @@ def cut_patches(
367
375
  ```
368
376
 
369
377
 
370
- # Validated Array
371
- ## Defining a validated array
378
+ # Validated Array<a id="validated-array"></a>
379
+ ## Defining a validated array<a id="defining-a-validated-array"></a>
372
380
  Subclass `ValidatedNumpyArray` and define:
373
381
  - `dtype` - expected data type specification (such as `float`, `"float64"`, `np.float64`).
374
382
  If not specified, data type is not validated.
@@ -377,7 +385,7 @@ Subclass `ValidatedNumpyArray` and define:
377
385
  - `schema` - expected shape specification (of type `valarray.numpy.axes_and_fields.AxesTuple`). For details, see [Array Schema](#array-schema).
378
386
  If not specified, shape is not validated (and no field validators are applied).
379
387
  - `lt`/`le`/`ge`/`gt`/`eq` - basic array value constraints -> less (or equal) than, greater (or equal) than, equal to
380
- - `validators` - optional list of validators applied to the whole array. For details, see [Validators](##validators).
388
+ - `validators` - optional validator or a tuple of validators applied to the whole array. For details, see [Validators](##validators).
381
389
 
382
390
  ```python
383
391
  import numpy as np
@@ -388,7 +396,7 @@ class ExampleValidatedNumpyArray(ValidatedNumpyArray):
388
396
  schema = ('batch_size', 3, 5)
389
397
  ```
390
398
 
391
- ## Creating a validated array instance
399
+ ## Creating a validated array instance<a id="creating-a-validated-array-instance"></a>
392
400
  There are 4 ways to create a validated array instance:
393
401
  - validate an existing array
394
402
  ```python
@@ -431,7 +439,7 @@ v_arr = ExampleValidatedNumpyArray(np.array([1,2],dtype=np.float32), coerce_dtyp
431
439
  v_arr = ExampleValidatedNumpyArray(np.array([1,2],dtype=np.float32), coerce_dtype=True, validate=False)
432
440
  ```
433
441
 
434
- ## Accessing array values
442
+ ## Accessing array values<a id="accessing-array-values"></a>
435
443
  You can access the underlying array using the `.array`/`.a_` property:
436
444
  ```python
437
445
  arr = v_arr.array
@@ -454,7 +462,7 @@ class SpecifiedDataTypeArray(ValidatedNumpyArray[np.float32]): ...
454
462
  arr = SpecifiedDataTypeArray(...).array # np.typing.NDArray[np.float32]
455
463
  ```
456
464
 
457
- # Validation functions
465
+ # Validation functions<a id="validation-functions"></a>
458
466
  Array validation is designed to be modular and composable and validation functions can be used on they own if only runtime validation is required.
459
467
  Each validation function returns a list of errors, from which a `ValidationException` can be raised. For details see [Catching exceptions](#catching-exceptions).
460
468
  ```python
@@ -493,7 +501,7 @@ and a "composite" validation function:
493
501
  - *returns* `NumpyInvalidArrayValuesError`/`NumpyInvalidFieldValuesError` or no errors.
494
502
 
495
503
 
496
- # Array schema
504
+ # Array schema<a id="array-schema"></a>
497
505
  Schema defines expected axes, and for each axis its' fields and optionally constraints on the field values.
498
506
 
499
507
  Axes can be defined with:
@@ -514,11 +522,11 @@ schema = (
514
522
  ("field_a", Field())
515
523
  )
516
524
  ```
517
- ## Field
525
+ ## Field<a id="field"></a>
518
526
  Defines (optional) name and value constrints for array field. More specifically:
519
527
  - `name` - descriptive name used in error messages (if missing, field index is used instead)
520
528
  - `lt`/`le`/`ge`/`gt`/`eq` - basic array value constraints -> less (or equal) than, greater (or equal) than, equal to
521
- - `validators` - other validators of fields values. For details, see [Validators](##validators).
529
+ - `validators` - optional validator or a tuple of validators applied to fields values. For details, see [Validators](##validators).
522
530
 
523
531
  ```python
524
532
  from typing import Any
@@ -533,8 +541,8 @@ f1 = Field("example_named_field", ge=0)
533
541
  f2 = Field(gt=10, validators=(ExampleNumpyValidator(),))
534
542
  ```
535
543
 
536
- ## Array schema examples
537
- ### rectangles
544
+ ## Array schema examples<a id="array-schema-examples"></a>
545
+ ### rectangles<a id="rectangles"></a>
538
546
  An array of arbitrary number of rectangles defined by min and max coordinates which has two axes: *n_rects* and *rect*.
539
547
  Axis *rect* is has 4 fields: *x_min*,*y_min*,*x_max*,*y_max*, where values must be greater or equal to zero.
540
548
 
@@ -567,10 +575,10 @@ arr = np.array(
567
575
  Rect.validate(arr)
568
576
  ```
569
577
 
570
- # Validators
578
+ # Validators<a id="validators"></a>
571
579
  Validators are objects that perform arbitrary validation of array or field values defined by user.
572
580
 
573
- ## Defining a validator
581
+ ## Defining a validator<a id="defining-a-validator"></a>
574
582
  Validators must subclass `valarray.numpy.NumpyValidator` Abstract Base Class
575
583
  and implement the `.validate()` method that takes an array as an input and results in success/failure of validation using these options:
576
584
 
@@ -583,7 +591,7 @@ and implement the `.validate()` method that takes an array as an input and resul
583
591
  - *returns* `False`
584
592
  - *raises* `ValueError`
585
593
 
586
- ### ValidationResult
594
+ ### ValidationResult<a id="validationresult"></a>
587
595
  Contains result status of validation `status="OK"`/`status="FAIL"`
588
596
 
589
597
  Can also optionally contain:
@@ -615,7 +623,7 @@ indices = (np.array([0, 1, 1]), np.array([1, 0, 1]))
615
623
  res = ValidationResult(status="FAIL", indices_invalid=indices, msg="Optional error message.")
616
624
  ```
617
625
 
618
- ### Example Validator
626
+ ### Example Validator<a id="example-validator"></a>
619
627
  ```python
620
628
  from dataclasses import dataclass
621
629
  from typing import Literal
@@ -652,7 +660,7 @@ class ExampleIsEvenValidator(NumpyValidator[np.uint8]):
652
660
  return ValidationResult("FAIL", indices_invalid=~even)
653
661
  ```
654
662
 
655
- # Catching exceptions
663
+ # Catching exceptions<a id="catching-exceptions"></a>
656
664
  Failed validation results in `valarray.core.errors_exceptions.ValidationException` being raised containing list of errors responsible (and name of array class if available).
657
665
 
658
666
  Main error types are:
@@ -678,21 +686,49 @@ except ValidationException as exc:
678
686
  axis_errs = exc.errs[(IncorrectAxSizesError, IncorrectAxNumberError)]
679
687
  ```
680
688
 
681
- ## Special exceptions and errors
689
+ ## Special exceptions and errors<a id="special-exceptions-and-errors"></a>
682
690
  There are two special subclasses of `ValidationException` with associated validation errors raised during [instantiation](#creating-a-validated-array-instance):
683
691
  - `CreateArrayException` -> `CannotCreateArrayError` - Array cannot be created from supplied object.
684
692
  - `CoerceDTypeException` -> `CannotCoerceDTypeError` - If array data type cannot be coerced when creating array with `ValidatedArray(coerce_dtype=True)`
685
693
 
686
694
 
687
- ## Generic Errors
695
+ ## Generic Errors<a id="generic-errors"></a>
688
696
  These error types have subclasses ensuring proper type hints:
689
697
  - `IncorrectDTypeError` -> `NumpyIncorrectDTypeError`
690
698
  - `CannotCoerceDTypeError` -> `NumpyCannotCoerceDTypeError`
691
699
  - `InvalidArrayValuesError` -> `NumpyInvalidArrayValuesError`
692
700
  - `InvalidFieldValuesError` -> `NumpyInvalidFieldValuesError`
693
701
 
702
+ # Settings<a id="settings"></a>
703
+ Global settings for the library are defined in `valarray.settings` and can be modified using environment variables.
704
+ | ***variable name*** | ***environment variable*** | default value | description |
705
+ |---------------------|------------------------------|---------------|-----------------------------------------------------|
706
+ | function_cache_size | VALARRAY_FUNCTION_CACHE_SIZE | 512 | cache size for (internal) frequently used functions |
694
707
 
695
- # Caveats
708
+ # Caveats<a id="caveats"></a>
696
709
  - I cannot guarantee that the test suite is foolproof ATM as I'm currently the only one testing this library.
697
710
  - Library has so far only been tested with `python==3.12` and `numpy==2.4.0`
698
- - Library isn't tested for performance, use in production only if the primary bottleneck is brain and not hardware.
711
+ - Library isn't tested for performance, use in production only if the primary bottleneck is brain and not hardware.
712
+
713
+ # Changelog<a id="changelog"></a>
714
+ ## 0.4.2<a id="042"></a>
715
+ - changed `ValidatedArray`, `Field` classes and `validate_array`, `validate_array_values` to accept a single validator as a parameter.
716
+
717
+ ## 0.4.1<a id="041"></a>
718
+ - added cache for often used functions
719
+ - added __str__ and __len__ methods
720
+
721
+ ## 0.4<a id="04"></a>
722
+ - first version with all basic features: creating a validated array, validating dtype, shape, array and field values
723
+
724
+
725
+ # Breaking changes<a id="breaking-changes"></a>
726
+ - **0.4** -> **0.4.1**
727
+ - changed __str__ method for `Validator` to `.error_string` property (to allow different string representation for error messages and general printing)
728
+ - changed imports due to refactoring to simplify dependencies:
729
+ - `GenericErrors`
730
+ - from `valarray.core.errors_exceptions` -> from `valarray.core`
731
+ - `NumpyErrors`
732
+ - from `valarray.numpy.errors_exceptions` -> from `valarray.numpy`
733
+ - `AxisNameAndIdx`, `FieldNameAndIdx`
734
+ - from `valarray.core.axes_and_fields` -> from `valarray.core.data_structures`
@@ -1,8 +1,8 @@
1
- ![](assets/images/valarray_logo.svg)
1
+ ![valarray logo](https://codeberg.org/jfranek/valarray/raw/branch/main/assets/images/valarray_logo.svg)
2
2
 
3
3
  In short, library for validating numpy arrays that also helps with static analysis and documentation. In long, see [Library rationale](#library-rationale).
4
4
 
5
- Currently intended primarily as a personal/hobby project (see [Caveats](#caveats))
5
+ Currently intended primarily as a personal/hobby project (see [Caveats](#caveats)). Also not considered stable (see [Breaking changes](#breaking-changes)).
6
6
 
7
7
  I have gotten away with using it in a professional setting, but YMMV.
8
8
 
@@ -39,8 +39,10 @@ except ValidationException as v_exc:
39
39
  >>> [-2.0, -6.0]
40
40
  ```
41
41
 
42
- # Table of contents
43
- - [Table of contents](#table-of-contents)
42
+ <!-- NOTE: Headings that are used as relative links (so most of them) must have id tag defined
43
+ (see https://github.com/pypa/readme_renderer/issues/169#issuecomment-808577486) otherwise links do not work on pypi.-->
44
+
45
+ # Table of contents <!-- omit from toc -->
44
46
  - [Library rationale](#library-rationale)
45
47
  - [1) Invalid values causing unintended behaviour](#1-invalid-values-causing-unintended-behaviour)
46
48
  - [Problem](#problem)
@@ -67,13 +69,19 @@ except ValidationException as v_exc:
67
69
  - [Catching exceptions](#catching-exceptions)
68
70
  - [Special exceptions and errors](#special-exceptions-and-errors)
69
71
  - [Generic Errors](#generic-errors)
72
+ - [Settings](#settings)
70
73
  - [Caveats](#caveats)
74
+ - [Changelog](#changelog)
75
+ - [0.4.2](#042)
76
+ - [0.4.1](#041)
77
+ - [0.4](#04)
78
+ - [Breaking changes](#breaking-changes)
71
79
 
72
- # Library rationale
80
+ # Library rationale<a id="library-rationale"></a>
73
81
  This library aims to help with 3 issues encountered when working with numpy arrays:
74
82
 
75
- ## 1) Invalid values causing unintended behaviour
76
- ### Problem
83
+ ## 1) Invalid values causing unintended behaviour<a id="1-invalid-values-causing-unintended-behaviour"></a>
84
+ ### Problem<a id="problem"></a>
77
85
  Invalid values can cause crashes, or worse, cause silent failures.
78
86
 
79
87
  For example the following code fails silently when attempting to cut patches from image using bounding boxes with invalid coordinates.
@@ -107,7 +115,7 @@ for patch in patches:
107
115
  >>> (50, 200, 3)
108
116
  ```
109
117
 
110
- ### Solution
118
+ ### Solution<a id="solution"></a>
111
119
  Validate boxes array first. If errors are encountered, print descriptive error message(s).
112
120
 
113
121
  ```python
@@ -161,8 +169,8 @@ except ValidationException as exc:
161
169
  >>> Field < 0 >: [-10]
162
170
  ```
163
171
 
164
- ## 2) Limited support for static analysis
165
- ### Problem
172
+ ## 2) Limited support for static analysis<a id="2-limited-support-for-static-analysis"></a>
173
+ ### Problem<a id="problem-1"></a>
166
174
  Support for static analysis is limited. Tools can only check whether the datatype is correct, but not shape, values or what those values actually represent.
167
175
 
168
176
  For example, the function to crop patches needs the boxes to be defined by `xmin, ymin, xmax, ymax` but doesn't throw an error if input boxes are defined by `x_center, y_center, width, height` and static analysis tools cannot detect this error using bulit-in numpy types.
@@ -206,7 +214,7 @@ for patch in patches_inv:
206
214
  >>> (0, 200, 3)
207
215
  ```
208
216
 
209
- ### Solution
217
+ ### Solution<a id="solution-1"></a>
210
218
  `ValidatedNumpyArray` subclasses can represent these two types of boxes arrays, and can be used instead of bare numpy arrays in function/method signatures and such.
211
219
  ```python
212
220
  import numpy as np
@@ -273,8 +281,8 @@ for patch in patches_inv:
273
281
  print(patch.shape)
274
282
  ```
275
283
 
276
- ## 3) Need for explicit documentation
277
- ### Problem
284
+ ## 3) Need for explicit documentation<a id="3-need-for-explicit-documentation"></a>
285
+ ### Problem<a id="problem-2"></a>
278
286
  Using built-in numpy types provides only documentation for data types. Shape, values, constraints and what the array represents need to be explicitly documented either in comments or docstrings.
279
287
 
280
288
  If this type of array is used in multiple places / functions, this can cause duplicated documentation.
@@ -303,7 +311,7 @@ def cut_patches(
303
311
  return patches
304
312
  ```
305
313
 
306
- ### Solution
314
+ ### Solution<a id="solution-2"></a>
307
315
  Defining data type, schema and constraints on a `ValidatedNumpyArray` subclass already implicitly documents them.
308
316
 
309
317
  This can be complemented by adding additional (or summary) documentation in the class docstring.
@@ -351,8 +359,8 @@ def cut_patches(
351
359
  ```
352
360
 
353
361
 
354
- # Validated Array
355
- ## Defining a validated array
362
+ # Validated Array<a id="validated-array"></a>
363
+ ## Defining a validated array<a id="defining-a-validated-array"></a>
356
364
  Subclass `ValidatedNumpyArray` and define:
357
365
  - `dtype` - expected data type specification (such as `float`, `"float64"`, `np.float64`).
358
366
  If not specified, data type is not validated.
@@ -361,7 +369,7 @@ Subclass `ValidatedNumpyArray` and define:
361
369
  - `schema` - expected shape specification (of type `valarray.numpy.axes_and_fields.AxesTuple`). For details, see [Array Schema](#array-schema).
362
370
  If not specified, shape is not validated (and no field validators are applied).
363
371
  - `lt`/`le`/`ge`/`gt`/`eq` - basic array value constraints -> less (or equal) than, greater (or equal) than, equal to
364
- - `validators` - optional list of validators applied to the whole array. For details, see [Validators](##validators).
372
+ - `validators` - optional validator or a tuple of validators applied to the whole array. For details, see [Validators](##validators).
365
373
 
366
374
  ```python
367
375
  import numpy as np
@@ -372,7 +380,7 @@ class ExampleValidatedNumpyArray(ValidatedNumpyArray):
372
380
  schema = ('batch_size', 3, 5)
373
381
  ```
374
382
 
375
- ## Creating a validated array instance
383
+ ## Creating a validated array instance<a id="creating-a-validated-array-instance"></a>
376
384
  There are 4 ways to create a validated array instance:
377
385
  - validate an existing array
378
386
  ```python
@@ -415,7 +423,7 @@ v_arr = ExampleValidatedNumpyArray(np.array([1,2],dtype=np.float32), coerce_dtyp
415
423
  v_arr = ExampleValidatedNumpyArray(np.array([1,2],dtype=np.float32), coerce_dtype=True, validate=False)
416
424
  ```
417
425
 
418
- ## Accessing array values
426
+ ## Accessing array values<a id="accessing-array-values"></a>
419
427
  You can access the underlying array using the `.array`/`.a_` property:
420
428
  ```python
421
429
  arr = v_arr.array
@@ -438,7 +446,7 @@ class SpecifiedDataTypeArray(ValidatedNumpyArray[np.float32]): ...
438
446
  arr = SpecifiedDataTypeArray(...).array # np.typing.NDArray[np.float32]
439
447
  ```
440
448
 
441
- # Validation functions
449
+ # Validation functions<a id="validation-functions"></a>
442
450
  Array validation is designed to be modular and composable and validation functions can be used on they own if only runtime validation is required.
443
451
  Each validation function returns a list of errors, from which a `ValidationException` can be raised. For details see [Catching exceptions](#catching-exceptions).
444
452
  ```python
@@ -477,7 +485,7 @@ and a "composite" validation function:
477
485
  - *returns* `NumpyInvalidArrayValuesError`/`NumpyInvalidFieldValuesError` or no errors.
478
486
 
479
487
 
480
- # Array schema
488
+ # Array schema<a id="array-schema"></a>
481
489
  Schema defines expected axes, and for each axis its' fields and optionally constraints on the field values.
482
490
 
483
491
  Axes can be defined with:
@@ -498,11 +506,11 @@ schema = (
498
506
  ("field_a", Field())
499
507
  )
500
508
  ```
501
- ## Field
509
+ ## Field<a id="field"></a>
502
510
  Defines (optional) name and value constrints for array field. More specifically:
503
511
  - `name` - descriptive name used in error messages (if missing, field index is used instead)
504
512
  - `lt`/`le`/`ge`/`gt`/`eq` - basic array value constraints -> less (or equal) than, greater (or equal) than, equal to
505
- - `validators` - other validators of fields values. For details, see [Validators](##validators).
513
+ - `validators` - optional validator or a tuple of validators applied to fields values. For details, see [Validators](##validators).
506
514
 
507
515
  ```python
508
516
  from typing import Any
@@ -517,8 +525,8 @@ f1 = Field("example_named_field", ge=0)
517
525
  f2 = Field(gt=10, validators=(ExampleNumpyValidator(),))
518
526
  ```
519
527
 
520
- ## Array schema examples
521
- ### rectangles
528
+ ## Array schema examples<a id="array-schema-examples"></a>
529
+ ### rectangles<a id="rectangles"></a>
522
530
  An array of arbitrary number of rectangles defined by min and max coordinates which has two axes: *n_rects* and *rect*.
523
531
  Axis *rect* is has 4 fields: *x_min*,*y_min*,*x_max*,*y_max*, where values must be greater or equal to zero.
524
532
 
@@ -551,10 +559,10 @@ arr = np.array(
551
559
  Rect.validate(arr)
552
560
  ```
553
561
 
554
- # Validators
562
+ # Validators<a id="validators"></a>
555
563
  Validators are objects that perform arbitrary validation of array or field values defined by user.
556
564
 
557
- ## Defining a validator
565
+ ## Defining a validator<a id="defining-a-validator"></a>
558
566
  Validators must subclass `valarray.numpy.NumpyValidator` Abstract Base Class
559
567
  and implement the `.validate()` method that takes an array as an input and results in success/failure of validation using these options:
560
568
 
@@ -567,7 +575,7 @@ and implement the `.validate()` method that takes an array as an input and resul
567
575
  - *returns* `False`
568
576
  - *raises* `ValueError`
569
577
 
570
- ### ValidationResult
578
+ ### ValidationResult<a id="validationresult"></a>
571
579
  Contains result status of validation `status="OK"`/`status="FAIL"`
572
580
 
573
581
  Can also optionally contain:
@@ -599,7 +607,7 @@ indices = (np.array([0, 1, 1]), np.array([1, 0, 1]))
599
607
  res = ValidationResult(status="FAIL", indices_invalid=indices, msg="Optional error message.")
600
608
  ```
601
609
 
602
- ### Example Validator
610
+ ### Example Validator<a id="example-validator"></a>
603
611
  ```python
604
612
  from dataclasses import dataclass
605
613
  from typing import Literal
@@ -636,7 +644,7 @@ class ExampleIsEvenValidator(NumpyValidator[np.uint8]):
636
644
  return ValidationResult("FAIL", indices_invalid=~even)
637
645
  ```
638
646
 
639
- # Catching exceptions
647
+ # Catching exceptions<a id="catching-exceptions"></a>
640
648
  Failed validation results in `valarray.core.errors_exceptions.ValidationException` being raised containing list of errors responsible (and name of array class if available).
641
649
 
642
650
  Main error types are:
@@ -662,21 +670,49 @@ except ValidationException as exc:
662
670
  axis_errs = exc.errs[(IncorrectAxSizesError, IncorrectAxNumberError)]
663
671
  ```
664
672
 
665
- ## Special exceptions and errors
673
+ ## Special exceptions and errors<a id="special-exceptions-and-errors"></a>
666
674
  There are two special subclasses of `ValidationException` with associated validation errors raised during [instantiation](#creating-a-validated-array-instance):
667
675
  - `CreateArrayException` -> `CannotCreateArrayError` - Array cannot be created from supplied object.
668
676
  - `CoerceDTypeException` -> `CannotCoerceDTypeError` - If array data type cannot be coerced when creating array with `ValidatedArray(coerce_dtype=True)`
669
677
 
670
678
 
671
- ## Generic Errors
679
+ ## Generic Errors<a id="generic-errors"></a>
672
680
  These error types have subclasses ensuring proper type hints:
673
681
  - `IncorrectDTypeError` -> `NumpyIncorrectDTypeError`
674
682
  - `CannotCoerceDTypeError` -> `NumpyCannotCoerceDTypeError`
675
683
  - `InvalidArrayValuesError` -> `NumpyInvalidArrayValuesError`
676
684
  - `InvalidFieldValuesError` -> `NumpyInvalidFieldValuesError`
677
685
 
686
+ # Settings<a id="settings"></a>
687
+ Global settings for the library are defined in `valarray.settings` and can be modified using environment variables.
688
+ | ***variable name*** | ***environment variable*** | default value | description |
689
+ |---------------------|------------------------------|---------------|-----------------------------------------------------|
690
+ | function_cache_size | VALARRAY_FUNCTION_CACHE_SIZE | 512 | cache size for (internal) frequently used functions |
678
691
 
679
- # Caveats
692
+ # Caveats<a id="caveats"></a>
680
693
  - I cannot guarantee that the test suite is foolproof ATM as I'm currently the only one testing this library.
681
694
  - Library has so far only been tested with `python==3.12` and `numpy==2.4.0`
682
- - Library isn't tested for performance, use in production only if the primary bottleneck is brain and not hardware.
695
+ - Library isn't tested for performance, use in production only if the primary bottleneck is brain and not hardware.
696
+
697
+ # Changelog<a id="changelog"></a>
698
+ ## 0.4.2<a id="042"></a>
699
+ - changed `ValidatedArray`, `Field` classes and `validate_array`, `validate_array_values` to accept a single validator as a parameter.
700
+
701
+ ## 0.4.1<a id="041"></a>
702
+ - added cache for often used functions
703
+ - added __str__ and __len__ methods
704
+
705
+ ## 0.4<a id="04"></a>
706
+ - first version with all basic features: creating a validated array, validating dtype, shape, array and field values
707
+
708
+
709
+ # Breaking changes<a id="breaking-changes"></a>
710
+ - **0.4** -> **0.4.1**
711
+ - changed __str__ method for `Validator` to `.error_string` property (to allow different string representation for error messages and general printing)
712
+ - changed imports due to refactoring to simplify dependencies:
713
+ - `GenericErrors`
714
+ - from `valarray.core.errors_exceptions` -> from `valarray.core`
715
+ - `NumpyErrors`
716
+ - from `valarray.numpy.errors_exceptions` -> from `valarray.numpy`
717
+ - `AxisNameAndIdx`, `FieldNameAndIdx`
718
+ - from `valarray.core.axes_and_fields` -> from `valarray.core.data_structures`
@@ -0,0 +1,30 @@
1
+ graph TD
2
+ valarray.core.validators --> valarray.core.types
3
+ valarray.core.validators --> valarray.core.array_type_adapter
4
+ valarray.core.axes_and_fields --> valarray.core.validators
5
+ valarray.core.axes_and_fields --> valarray.core.types
6
+ valarray.core.errors_exceptions --> valarray.core.validators
7
+ valarray.core.errors_exceptions --> valarray.core.types
8
+ valarray.core.errors_exceptions --> valarray.core.data_structures
9
+ valarray.core.utils --> valarray.core.validators
10
+ valarray.core.utils --> valarray.core.errors_exceptions
11
+ valarray.core.utils --> valarray.core.axes_and_fields
12
+ valarray.core.utils --> valarray.core.types
13
+ valarray.core.utils --> valarray.core.array_type_adapter
14
+ valarray.core.array --> valarray.core.errors_exceptions
15
+ valarray.core.array --> valarray.core.axes_and_fields
16
+ valarray.core.array --> valarray.core.utils
17
+ valarray.core.array --> valarray.core.validation_functions
18
+ valarray.core.array --> valarray.core.validators
19
+ valarray.core.array --> valarray.core.array_type_adapter
20
+ valarray.core.array --> valarray.core.types
21
+ valarray.core.array_type_adapter --> valarray.core.types
22
+ valarray.core.validation_functions --> valarray.core.axes_and_fields
23
+ valarray.core.validation_functions --> valarray.core.utils
24
+ valarray.core.validation_functions --> valarray.core.validators
25
+ valarray.core.validation_functions --> valarray.core.errors_exceptions
26
+ valarray.core.validation_functions --> valarray.core.data_structures
27
+ valarray.core.validation_functions --> valarray.core.types
28
+ valarray.core.validation_functions --> valarray.core.array_type_adapter
29
+ valarray.core.data_structures
30
+ valarray.core.types
@@ -0,0 +1,13 @@
1
+ graph TD
2
+ valarray.core.errors_exceptions.validation_errors.values --> valarray.core.errors_exceptions.validation_errors.base
3
+ valarray.core.errors_exceptions.error_list --> valarray.core.errors_exceptions.validation_errors.base
4
+ valarray.core.errors_exceptions.error_list --> valarray.core.errors_exceptions.exceptions
5
+ valarray.core.errors_exceptions.validation_errors.array_creation --> valarray.core.errors_exceptions.validation_errors.base
6
+ valarray.core.errors_exceptions.validation_errors.dtype --> valarray.core.errors_exceptions.validation_errors.base
7
+ valarray.core.errors_exceptions.validation_errors.axes --> valarray.core.errors_exceptions.validation_errors.base
8
+ valarray.core.errors_exceptions.exceptions --> valarray.core.errors_exceptions.validation_errors.dtype
9
+ valarray.core.errors_exceptions.exceptions --> valarray.core.errors_exceptions.validation_errors.array_creation
10
+ valarray.core.errors_exceptions.exceptions --> valarray.core.errors_exceptions.validation_errors.base
11
+ valarray.core.errors_exceptions.exceptions --> valarray.core.errors_exceptions.error_list
12
+ valarray.core.errors_exceptions.validation_errors.base
13
+ valarray.core.errors_exceptions.validation_errors
@@ -0,0 +1,15 @@
1
+ graph TD
2
+ valarray.core.validation_functions.array_values --> valarray.core.validation_functions.utils
3
+ valarray.core.validation_functions.field_values.utils --> valarray.core.validation_functions.field_values.types_and_data_structures
4
+ valarray.core.validation_functions.field_values.utils --> valarray.core.validation_functions.utils
5
+ valarray.core.validation_functions.field_values.core --> valarray.core.validation_functions.field_values.utils
6
+ valarray.core.validation_functions.field_values.core --> valarray.core.validation_functions.field_values.types_and_data_structures
7
+ valarray.core.validation_functions.field_values.core --> valarray.core.validation_functions.shape
8
+ valarray.core.validation_functions.array --> valarray.core.validation_functions.shape
9
+ valarray.core.validation_functions.array --> valarray.core.validation_functions.dtype
10
+ valarray.core.validation_functions.array --> valarray.core.validation_functions.field_values.core
11
+ valarray.core.validation_functions.array --> valarray.core.validation_functions.array_values
12
+ valarray.core.validation_functions.field_values.types_and_data_structures
13
+ valarray.core.validation_functions.utils
14
+ valarray.core.validation_functions.shape
15
+ valarray.core.validation_functions.dtype
@@ -0,0 +1,25 @@
1
+ graph TD
2
+ valarray.numpy.array_type_adapter --> valarray.numpy.array_type_adapter.errors
3
+ valarray.numpy.array_type_adapter --> valarray.numpy.array_type_adapter.comparisons
4
+ valarray.numpy.array_type_adapter --> valarray.numpy.array_type_adapter.adapter
5
+ valarray.numpy.array_type_adapter.adapter --> valarray.numpy.types
6
+ valarray.numpy.array_type_adapter.adapter --> valarray.numpy.array_type_adapter.comparisons
7
+ valarray.numpy.array_type_adapter.adapter --> valarray.numpy.array_type_adapter.errors
8
+ valarray.numpy.validators --> valarray.numpy.types
9
+ valarray.numpy.array_type_adapter.errors --> valarray.numpy.types
10
+ valarray.numpy.array_type_adapter.errors --> valarray.numpy.errors_exceptions
11
+ valarray.numpy.array --> valarray.numpy.array_type_adapter
12
+ valarray.numpy.array --> valarray.numpy.types
13
+ valarray.numpy.array --> valarray.numpy.axes_and_fields
14
+ valarray.numpy.errors_exceptions --> valarray.numpy.types
15
+ valarray.numpy --> valarray.numpy.array_type_adapter
16
+ valarray.numpy --> valarray.numpy.axes_and_fields
17
+ valarray.numpy --> valarray.numpy.array
18
+ valarray.numpy --> valarray.numpy.validators
19
+ valarray.numpy.validation_functions --> valarray.numpy.array_type_adapter
20
+ valarray.numpy.validation_functions --> valarray.numpy.types
21
+ valarray.numpy.validation_functions --> valarray.numpy.validators
22
+ valarray.numpy.validation_functions --> valarray.numpy.axes_and_fields
23
+ valarray.numpy.axes_and_fields --> valarray.numpy.types
24
+ valarray.numpy.array_type_adapter.comparisons --> valarray.numpy.types
25
+ valarray.numpy.types
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "valarray"
7
- version = "0.4rc1"
7
+ version = "0.4.2"
8
8
  authors = [
9
9
  { name="J. Franek", email="franek.j27@email.cz" },
10
10
  ]
@@ -2,4 +2,5 @@ setuptools
2
2
  pytest
3
3
  pytest-cov
4
4
  build
5
- twine
5
+ twine
6
+ dotenv
@@ -0,0 +1 @@
1
+ tach #creating dependency graphs