winiutils 4.1.3__tar.gz → 4.2.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 (31) hide show
  1. {winiutils-4.1.3 → winiutils-4.2.0}/PKG-INFO +26 -16
  2. {winiutils-4.1.3 → winiutils-4.2.0}/README.md +19 -7
  3. winiutils-4.2.0/pyproject.toml +122 -0
  4. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/dataframe/cleaning.py +9 -8
  5. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/structures/text/string_.py +0 -6
  6. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/concurrent/multiprocessing.py +1 -1
  7. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/oop/mixins/meta.py +16 -7
  8. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/security/cryptography.py +6 -2
  9. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/security/keyring.py +7 -2
  10. winiutils-4.1.3/pyproject.toml +0 -122
  11. {winiutils-4.1.3 → winiutils-4.2.0}/LICENSE +0 -0
  12. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/__init__.py +0 -0
  13. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/__init__.py +0 -0
  14. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/__init__.py +0 -0
  15. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/dataframe/__init__.py +0 -0
  16. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/structures/__init__.py +0 -0
  17. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/structures/dicts.py +0 -0
  18. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/data/structures/text/__init__.py +0 -0
  19. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/__init__.py +0 -0
  20. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/concurrent/__init__.py +0 -0
  21. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/concurrent/concurrent.py +0 -0
  22. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/concurrent/multithreading.py +0 -0
  23. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/iterating/iterate.py +0 -0
  24. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/oop/__init__.py +0 -0
  25. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/oop/mixins/__init__.py +0 -0
  26. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/oop/mixins/mixin.py +0 -0
  27. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/core/security/__init__.py +0 -0
  28. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/py.typed +0 -0
  29. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/rig/__init__.py +0 -0
  30. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/rig/tools/__init__.py +0 -0
  31. {winiutils-4.1.3 → winiutils-4.2.0}/src/winiutils/rig/tools/pyrigger.py +0 -0
@@ -1,58 +1,68 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: winiutils
3
- Version: 4.1.3
3
+ Version: 4.2.0
4
4
  Summary: A utility library for Python development
5
5
  Keywords: pyrig
6
6
  Author: Winipedia
7
7
  License-Expression: MIT
8
8
  License-File: LICENSE
9
- Classifier: Programming Language :: Python
10
- Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
11
10
  Classifier: Programming Language :: Python :: 3 :: Only
12
11
  Classifier: Programming Language :: Python :: 3.12
13
12
  Classifier: Programming Language :: Python :: 3.13
14
13
  Classifier: Programming Language :: Python :: 3.14
15
- Classifier: Operating System :: OS Independent
16
14
  Classifier: Typing :: Typed
17
15
  Requires-Dist: cryptography>=49.0.0
18
16
  Requires-Dist: defusedxml>=0.7.1
19
17
  Requires-Dist: keyring>=25.7.0
20
18
  Requires-Dist: keyrings-alt>=5.0.2
21
19
  Requires-Dist: polars>=1.42.1
22
- Requires-Dist: pyrig>=17.6.0
23
- Requires-Dist: pyrig-runtime>=3.0.5
20
+ Requires-Dist: pyrig>=18.3.4
21
+ Requires-Dist: pyrig-runtime>=3.5.2
24
22
  Requires-Dist: tqdm>=4.68.4
25
23
  Maintainer: Winipedia
26
24
  Requires-Python: >=3.12
27
- Project-URL: Homepage, https://github.com/Winipedia/winiutils
25
+ Project-URL: Changelog, https://github.com/Winipedia/winiutils/releases
28
26
  Project-URL: Documentation, https://Winipedia.github.io/winiutils
29
- Project-URL: Source, https://github.com/Winipedia/winiutils
27
+ Project-URL: Homepage, https://github.com/Winipedia/winiutils
30
28
  Project-URL: Issues, https://github.com/Winipedia/winiutils/issues
31
- Project-URL: Changelog, https://github.com/Winipedia/winiutils/releases
29
+ Project-URL: Source, https://github.com/Winipedia/winiutils
32
30
  Description-Content-Type: text/markdown
33
31
 
34
32
  # winiutils
35
33
 
36
- <!-- ci/cd -->
34
+ <!-- project-status -->
37
35
  [![CI](https://img.shields.io/github/actions/workflow/status/Winipedia/winiutils/health_check.yml?label=CI&logo=github)](https://github.com/Winipedia/winiutils/actions/workflows/health_check.yml)
38
36
  [![CD](https://img.shields.io/github/actions/workflow/status/Winipedia/winiutils/deploy.yml?label=CD&logo=github)](https://github.com/Winipedia/winiutils/actions/workflows/deploy.yml)
39
- <!-- testing -->
40
- [![CoverageTester](https://img.shields.io/badge/coverage->=90%25-hsl(108,80%25,45%25)?logo=codecov&logoColor=white)](https://github.com/pytest-dev/pytest-cov)
41
- [![ProjectTester](https://img.shields.io/badge/tested%20with-pytest-46a2f1.svg?logo=pytest)](https://pytest.org)
37
+ [![ProjectTester](https://img.shields.io/badge/coverage->=90%25-hsl(108,80%25,45%25)?logo=codecov&logoColor=white)](https://pytest.org)
42
38
  <!-- code-quality -->
39
+ [![ByteOrderMarkerFormatter](https://img.shields.io/badge/BOM-fix--byte--order--marker-orange)](https://github.com/pre-commit/pre-commit-hooks)
40
+ [![CaseConflictChecker](https://img.shields.io/badge/case--conflict-check--case--conflict-blue)](https://github.com/pre-commit/pre-commit-hooks)
43
41
  [![DependencyAuditor](https://img.shields.io/badge/security-pip--audit-blue?logo=python)](https://github.com/pypa/pip-audit)
44
42
  [![DependencyChecker](https://img.shields.io/badge/dependencies-deptry-blue)](https://github.com/osprey-oss/deptry)
45
- [![MarkdownLinter](https://img.shields.io/badge/markdown-rumdl-darkgreen)](https://github.com/rvben/rumdl)
43
+ [![EndOfFileFormatter](https://img.shields.io/badge/EOF-end--of--file--fixer-orange)](https://github.com/pre-commit/pre-commit-hooks)
44
+ [![EndOfLineFormatter](https://img.shields.io/badge/EOL-mixed--line--ending-orange)](https://github.com/pre-commit/pre-commit-hooks)
45
+ [![JSONFormatter](https://img.shields.io/badge/JSON-pretty--format--json-orange)](https://github.com/pre-commit/pre-commit-hooks)
46
+ [![JSONLinter](https://img.shields.io/badge/JSON-check--json-blue)](https://github.com/pre-commit/pre-commit-hooks)
47
+ [![LargeFileChecker](https://img.shields.io/badge/large--files-check--added--large--files-blue)](https://github.com/pre-commit/pre-commit-hooks)
48
+ [![MarkdownLinter](https://img.shields.io/badge/Markdown-rumdl-darkgreen)](https://github.com/rvben/rumdl)
49
+ [![MergeConflictChecker](https://img.shields.io/badge/merge--conflict-check--merge--conflict-blue)](https://github.com/pre-commit/pre-commit-hooks)
50
+ [![ModuleTestNamingChecker](https://img.shields.io/badge/test--naming-name--tests--test-blue)](https://github.com/pre-commit/pre-commit-hooks)
46
51
  [![PythonLinter](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
47
52
  [![SecretsChecker](https://img.shields.io/badge/secrets-detect--secrets-blue)](https://github.com/Yelp/detect-secrets)
48
- [![SecurityLinter](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
53
+ [![SecurityChecker](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
54
+ [![ShellFormatter](https://img.shields.io/badge/shell-shfmt-orange)](https://github.com/mvdan/sh)
55
+ [![ShellLinter](https://img.shields.io/badge/shell-shellcheck-blue)](https://github.com/koalaman/shellcheck)
49
56
  [![SpellChecker](https://img.shields.io/badge/spell--check-typos-blue)](https://github.com/crate-ci/typos)
57
+ [![TOMLLinter](https://img.shields.io/badge/TOML-tombi-blueviolet)](https://github.com/tombi-toml/tombi)
58
+ [![TrailingWhitespaceFormatter](https://img.shields.io/badge/whitespace-trailing--whitespace--fixer-orange)](https://github.com/pre-commit/pre-commit-hooks)
50
59
  [![TypeChecker](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty)
51
- [![VersionControlHookManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
60
+ [![YAMLLinter](https://img.shields.io/badge/YAML-ryl-red)](https://github.com/owenlamont/ryl)
52
61
  <!-- tooling -->
53
62
  [![PackageManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
54
63
  [![Pyrigger](https://img.shields.io/badge/built%20with-pyrig-3776AB?logo=buildkite&logoColor=black)](https://github.com/Winipedia/pyrig)
55
64
  [![RemoteVersionController](https://img.shields.io/github/stars/Winipedia/winiutils?style=social)](https://github.com/Winipedia/winiutils)
65
+ [![VersionControlHookManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
56
66
  [![VersionController](https://img.shields.io/badge/Git-F05032?logo=git&logoColor=white)](https://git-scm.com)
57
67
  <!-- project-info -->
58
68
  [![DocsBuilder](https://img.shields.io/badge/MkDocs-Documentation-326CE5?logo=mkdocs&logoColor=white)](https://Winipedia.github.io/winiutils)
@@ -1,25 +1,37 @@
1
1
  # winiutils
2
2
 
3
- <!-- ci/cd -->
3
+ <!-- project-status -->
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/Winipedia/winiutils/health_check.yml?label=CI&logo=github)](https://github.com/Winipedia/winiutils/actions/workflows/health_check.yml)
5
5
  [![CD](https://img.shields.io/github/actions/workflow/status/Winipedia/winiutils/deploy.yml?label=CD&logo=github)](https://github.com/Winipedia/winiutils/actions/workflows/deploy.yml)
6
- <!-- testing -->
7
- [![CoverageTester](https://img.shields.io/badge/coverage->=90%25-hsl(108,80%25,45%25)?logo=codecov&logoColor=white)](https://github.com/pytest-dev/pytest-cov)
8
- [![ProjectTester](https://img.shields.io/badge/tested%20with-pytest-46a2f1.svg?logo=pytest)](https://pytest.org)
6
+ [![ProjectTester](https://img.shields.io/badge/coverage->=90%25-hsl(108,80%25,45%25)?logo=codecov&logoColor=white)](https://pytest.org)
9
7
  <!-- code-quality -->
8
+ [![ByteOrderMarkerFormatter](https://img.shields.io/badge/BOM-fix--byte--order--marker-orange)](https://github.com/pre-commit/pre-commit-hooks)
9
+ [![CaseConflictChecker](https://img.shields.io/badge/case--conflict-check--case--conflict-blue)](https://github.com/pre-commit/pre-commit-hooks)
10
10
  [![DependencyAuditor](https://img.shields.io/badge/security-pip--audit-blue?logo=python)](https://github.com/pypa/pip-audit)
11
11
  [![DependencyChecker](https://img.shields.io/badge/dependencies-deptry-blue)](https://github.com/osprey-oss/deptry)
12
- [![MarkdownLinter](https://img.shields.io/badge/markdown-rumdl-darkgreen)](https://github.com/rvben/rumdl)
12
+ [![EndOfFileFormatter](https://img.shields.io/badge/EOF-end--of--file--fixer-orange)](https://github.com/pre-commit/pre-commit-hooks)
13
+ [![EndOfLineFormatter](https://img.shields.io/badge/EOL-mixed--line--ending-orange)](https://github.com/pre-commit/pre-commit-hooks)
14
+ [![JSONFormatter](https://img.shields.io/badge/JSON-pretty--format--json-orange)](https://github.com/pre-commit/pre-commit-hooks)
15
+ [![JSONLinter](https://img.shields.io/badge/JSON-check--json-blue)](https://github.com/pre-commit/pre-commit-hooks)
16
+ [![LargeFileChecker](https://img.shields.io/badge/large--files-check--added--large--files-blue)](https://github.com/pre-commit/pre-commit-hooks)
17
+ [![MarkdownLinter](https://img.shields.io/badge/Markdown-rumdl-darkgreen)](https://github.com/rvben/rumdl)
18
+ [![MergeConflictChecker](https://img.shields.io/badge/merge--conflict-check--merge--conflict-blue)](https://github.com/pre-commit/pre-commit-hooks)
19
+ [![ModuleTestNamingChecker](https://img.shields.io/badge/test--naming-name--tests--test-blue)](https://github.com/pre-commit/pre-commit-hooks)
13
20
  [![PythonLinter](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
14
21
  [![SecretsChecker](https://img.shields.io/badge/secrets-detect--secrets-blue)](https://github.com/Yelp/detect-secrets)
15
- [![SecurityLinter](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
22
+ [![SecurityChecker](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
23
+ [![ShellFormatter](https://img.shields.io/badge/shell-shfmt-orange)](https://github.com/mvdan/sh)
24
+ [![ShellLinter](https://img.shields.io/badge/shell-shellcheck-blue)](https://github.com/koalaman/shellcheck)
16
25
  [![SpellChecker](https://img.shields.io/badge/spell--check-typos-blue)](https://github.com/crate-ci/typos)
26
+ [![TOMLLinter](https://img.shields.io/badge/TOML-tombi-blueviolet)](https://github.com/tombi-toml/tombi)
27
+ [![TrailingWhitespaceFormatter](https://img.shields.io/badge/whitespace-trailing--whitespace--fixer-orange)](https://github.com/pre-commit/pre-commit-hooks)
17
28
  [![TypeChecker](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty)
18
- [![VersionControlHookManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
29
+ [![YAMLLinter](https://img.shields.io/badge/YAML-ryl-red)](https://github.com/owenlamont/ryl)
19
30
  <!-- tooling -->
20
31
  [![PackageManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
21
32
  [![Pyrigger](https://img.shields.io/badge/built%20with-pyrig-3776AB?logo=buildkite&logoColor=black)](https://github.com/Winipedia/pyrig)
22
33
  [![RemoteVersionController](https://img.shields.io/github/stars/Winipedia/winiutils?style=social)](https://github.com/Winipedia/winiutils)
34
+ [![VersionControlHookManager](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
23
35
  [![VersionController](https://img.shields.io/badge/Git-F05032?logo=git&logoColor=white)](https://git-scm.com)
24
36
  <!-- project-info -->
25
37
  [![DocsBuilder](https://img.shields.io/badge/MkDocs-Documentation-326CE5?logo=mkdocs&logoColor=white)](https://Winipedia.github.io/winiutils)
@@ -0,0 +1,122 @@
1
+ [project]
2
+ name = "winiutils"
3
+ version = "4.2.0"
4
+ description = "A utility library for Python development"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ license-files = [
9
+ "LICENSE",
10
+ ]
11
+ authors = [
12
+ { name = "Winipedia" },
13
+ ]
14
+ maintainers = [
15
+ { name = "Winipedia" },
16
+ ]
17
+ keywords = [
18
+ "pyrig",
19
+ ]
20
+ classifiers = [
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Typing :: Typed",
27
+ ]
28
+ dependencies = [
29
+ "cryptography>=49.0.0",
30
+ "defusedxml>=0.7.1",
31
+ "keyring>=25.7.0",
32
+ "keyrings-alt>=5.0.2",
33
+ "polars>=1.42.1",
34
+ "pyrig>=18.3.4",
35
+ "pyrig-runtime>=3.5.2",
36
+ "tqdm>=4.68.4",
37
+ ]
38
+
39
+ [project.urls]
40
+ Changelog = "https://github.com/Winipedia/winiutils/releases"
41
+ Documentation = "https://Winipedia.github.io/winiutils"
42
+ Homepage = "https://github.com/Winipedia/winiutils"
43
+ Issues = "https://github.com/Winipedia/winiutils/issues"
44
+ Source = "https://github.com/Winipedia/winiutils"
45
+
46
+ [project.scripts]
47
+ winiutils = "pyrig_runtime.rig.cli.main:main"
48
+
49
+ [dependency-groups]
50
+ dev = [
51
+ "bandit>=1.9.4",
52
+ "deptry>=0.25.1",
53
+ "detect-secrets>=1.5.0",
54
+ "mkdocs>=1.6.1",
55
+ "mkdocs-material>=9.7.6",
56
+ "mkdocs-mermaid2-plugin>=1.2.3",
57
+ "mkdocstrings[python]>=1.0.5",
58
+ "pip-audit>=2.10.1",
59
+ "pre-commit-hooks",
60
+ "prek>=0.4.8",
61
+ "pyrig>=18.3.4",
62
+ "pyrig-pypi>=3.1.2",
63
+ "pytest>=9.1.1",
64
+ "pytest-cov>=7.1.0",
65
+ "pytest-mock>=3.15.1",
66
+ "pytest-randomly",
67
+ "ruff>=0.15.21",
68
+ "rumdl>=0.2.30",
69
+ "ryl",
70
+ "shellcheck-py",
71
+ "shfmt-py",
72
+ "tombi",
73
+ "ty>=0.0.58",
74
+ "types-defusedxml>=0.7.0.20260504",
75
+ "types-tqdm>=4.68.0.20260608",
76
+ "typos>=1.48.0",
77
+ ]
78
+
79
+ [build-system]
80
+ requires = [
81
+ "uv-build",
82
+ ]
83
+ build-backend = "uv_build"
84
+
85
+ [tool.deptry]
86
+ root = "src"
87
+
88
+ [tool.deptry.per_rule_ignores]
89
+ DEP002 = [
90
+ "pyrig-runtime",
91
+ ]
92
+
93
+ [tool.pytest]
94
+ addopts = [
95
+ "--cov-branch",
96
+ "--cov-fail-under=90",
97
+ "--cov-report=term-missing:skip-covered",
98
+ "--cov=winiutils",
99
+ ]
100
+ filterwarnings = [
101
+ "error",
102
+ ]
103
+ strict = true
104
+ testpaths = [
105
+ "tests",
106
+ ]
107
+
108
+ [tool.ruff.format]
109
+ docstring-code-format = true
110
+
111
+ [tool.ruff.lint]
112
+ select = [
113
+ "ALL",
114
+ ]
115
+
116
+ [tool.ruff.lint.per-file-ignores]
117
+ "tests/**/*.py" = [
118
+ "S101",
119
+ ]
120
+
121
+ [tool.ruff.lint.pydocstyle]
122
+ convention = "google"
@@ -332,8 +332,8 @@ class CleaningDF(ABCLoggingMixin):
332
332
 
333
333
  def __init__(
334
334
  self,
335
- *args: Any,
336
- **kwargs: Any,
335
+ *args: Any, # noqa: ANN401
336
+ **kwargs: Any, # noqa: ANN401
337
337
  ) -> None:
338
338
  """Initialize the CleaningDF and execute the cleaning pipeline.
339
339
 
@@ -466,7 +466,7 @@ class CleaningDF(ABCLoggingMixin):
466
466
  [
467
467
  pl.col(col_name).fill_null(fill_value)
468
468
  for col_name, fill_value in self.get_fill_null_map().items()
469
- ]
469
+ ],
470
470
  )
471
471
 
472
472
  def convert_cols(self) -> None:
@@ -497,7 +497,7 @@ class CleaningDF(ABCLoggingMixin):
497
497
  else:
498
498
  continue
499
499
  self.df = self.df.with_columns(
500
- pl.col(col_name).map_batches(converter, return_dtype=dtype)
500
+ pl.col(col_name).map_batches(converter, return_dtype=dtype),
501
501
  )
502
502
 
503
503
  def custom_convert_cols(self) -> None:
@@ -509,11 +509,12 @@ class CleaningDF(ABCLoggingMixin):
509
509
  self.df = self.df.with_columns(
510
510
  [
511
511
  pl.col(col_name).map_batches(
512
- converter, return_dtype=self.get_col_dtype_map()[col_name]
512
+ converter,
513
+ return_dtype=self.get_col_dtype_map()[col_name],
513
514
  )
514
515
  for col_name, converter in self.get_col_converter_map().items()
515
516
  if converter.__name__ != self.skip_col_converter.__name__ # ty:ignore[unresolved-attribute]
516
- ]
517
+ ],
517
518
  )
518
519
 
519
520
  @classmethod
@@ -704,7 +705,7 @@ class CleaningDF(ABCLoggingMixin):
704
705
  no_null_cols = self.get_no_null_cols()
705
706
  # Use a single select to check all columns at once
706
707
  null_flags = self.df.select(
707
- [pl.col(col).is_null().any() for col in no_null_cols]
708
+ [pl.col(col).is_null().any() for col in no_null_cols],
708
709
  )
709
710
  # Iterate over columns and check if any have nulls
710
711
  for col in no_null_cols:
@@ -727,7 +728,7 @@ class CleaningDF(ABCLoggingMixin):
727
728
  if issubclass(dtype, FloatType)
728
729
  ]
729
730
  has_nan = self.df.select(
730
- pl.any_horizontal(pl.col(float_cols).is_nan().any())
731
+ pl.any_horizontal(pl.col(float_cols).is_nan().any()),
731
732
  ).item()
732
733
  if has_nan:
733
734
  msg = "NaN values found in the dataframe"
@@ -143,12 +143,6 @@ def get_reusable_hash(value: object) -> str:
143
143
  Note:
144
144
  Two objects with the same string representation will produce the same
145
145
  hash, even if they are different types or have different internal state.
146
-
147
- Example:
148
- >>> get_reusable_hash("test")
149
- '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08'
150
- >>> get_reusable_hash({"key": "value"}) # doctest: +ELLIPSIS
151
- '...'
152
146
  """
153
147
  value_str = str(value)
154
148
  return hashlib.sha256(value_str.encode("utf-8")).hexdigest()
@@ -35,7 +35,7 @@ from winiutils.core.iterating.concurrent.concurrent import concurrent_loop
35
35
  logger = logging.getLogger(__name__)
36
36
 
37
37
 
38
- def get_spawn_pool(*args: Any, **kwargs: Any) -> Pool:
38
+ def get_spawn_pool(*args: Any, **kwargs: Any) -> Pool: # noqa: ANN401
39
39
  """Create a multiprocessing pool with the spawn context.
40
40
 
41
41
  Uses the 'spawn' start method which creates a fresh Python interpreter
@@ -82,17 +82,23 @@ class ABCLoggingMeta(ABCMeta):
82
82
  if mcs.is_loggable_method(attr_value):
83
83
  if isinstance(attr_value, classmethod):
84
84
  wrapped_method = mcs.wrap_with_logging(
85
- func=attr_value.__func__, class_name=name, call_times={}
85
+ func=attr_value.__func__,
86
+ class_name=name,
87
+ call_times={},
86
88
  )
87
89
  dct[attr_name] = classmethod(wrapped_method)
88
90
  elif isinstance(attr_value, staticmethod):
89
91
  wrapped_method = mcs.wrap_with_logging(
90
- func=attr_value.__func__, class_name=name, call_times={}
92
+ func=attr_value.__func__,
93
+ class_name=name,
94
+ call_times={},
91
95
  )
92
96
  dct[attr_name] = staticmethod(wrapped_method)
93
97
  else:
94
98
  dct[attr_name] = mcs.wrap_with_logging(
95
- func=attr_value, class_name=name, call_times={}
99
+ func=attr_value,
100
+ class_name=name,
101
+ call_times={},
96
102
  )
97
103
 
98
104
  return super().__new__(mcs, name, bases, dct)
@@ -119,7 +125,7 @@ class ABCLoggingMeta(ABCMeta):
119
125
  return (
120
126
  inspect.isfunction(unwrap_obj(method)) # must be a method-like attribute
121
127
  and not getattr(method, "__name__", "__").startswith(
122
- "__"
128
+ "__",
123
129
  ) # must not be a magic method
124
130
  )
125
131
 
@@ -172,11 +178,13 @@ class ABCLoggingMeta(ABCMeta):
172
178
 
173
179
  if do_logging:
174
180
  args_str = value_to_truncated_string(
175
- value=args, max_length=max_log_length
181
+ value=args,
182
+ max_length=max_log_length,
176
183
  )
177
184
 
178
185
  kwargs_str = value_to_truncated_string(
179
- value=kwargs, max_length=max_log_length
186
+ value=kwargs,
187
+ max_length=max_log_length,
180
188
  )
181
189
 
182
190
  logger.info(
@@ -195,7 +203,8 @@ class ABCLoggingMeta(ABCMeta):
195
203
  duration = time_time() - current_time
196
204
 
197
205
  result_str = value_to_truncated_string(
198
- value=result, max_length=max_log_length
206
+ value=result,
207
+ max_length=max_log_length,
199
208
  )
200
209
 
201
210
  logger.info(
@@ -30,7 +30,9 @@ AES-GCM requires a 12-byte (96-bit) IV for optimal performance and security.
30
30
 
31
31
 
32
32
  def encrypt_with_aes_gcm(
33
- aes_gcm: AESGCM, data: bytes, aad: bytes | None = None
33
+ aes_gcm: AESGCM,
34
+ data: bytes,
35
+ aad: bytes | None = None,
34
36
  ) -> bytes:
35
37
  """Encrypt data using AES-GCM with a random initialization vector.
36
38
 
@@ -65,7 +67,9 @@ def encrypt_with_aes_gcm(
65
67
 
66
68
 
67
69
  def decrypt_with_aes_gcm(
68
- aes_gcm: AESGCM, data: bytes, aad: bytes | None = None
70
+ aes_gcm: AESGCM,
71
+ data: bytes,
72
+ aad: bytes | None = None,
69
73
  ) -> bytes:
70
74
  """Decrypt data that was encrypted with AES-GCM.
71
75
 
@@ -77,7 +77,10 @@ def get_or_create_aes_gcm(service_name: str, username: str) -> tuple[AESGCM, byt
77
77
  >>> encrypted = encrypt_with_aes_gcm(aes_gcm, b"secret")
78
78
  """
79
79
  return get_or_create_key(
80
- service_name, username, AESGCM, lambda: AESGCM.generate_key(bit_length=256)
80
+ service_name,
81
+ username,
82
+ AESGCM,
83
+ lambda: AESGCM.generate_key(bit_length=256),
81
84
  )
82
85
 
83
86
 
@@ -129,7 +132,9 @@ def get_or_create_key[T](
129
132
 
130
133
 
131
134
  def get_key_as_str[T](
132
- service_name: str, username: str, key_class: Callable[[bytes], T]
135
+ service_name: str,
136
+ username: str,
137
+ key_class: Callable[[bytes], T],
133
138
  ) -> str | None:
134
139
  """Retrieve a key from the keyring as a base64-encoded string.
135
140
 
@@ -1,122 +0,0 @@
1
- [project]
2
- name = "winiutils"
3
- version = "4.1.3"
4
- description = "A utility library for Python development"
5
- license = "MIT"
6
- requires-python = ">=3.12"
7
- readme = "README.md"
8
- dependencies = [
9
- "cryptography>=49.0.0",
10
- "defusedxml>=0.7.1",
11
- "keyring>=25.7.0",
12
- "keyrings-alt>=5.0.2",
13
- "polars>=1.42.1",
14
- "pyrig>=17.6.0",
15
- "pyrig-runtime>=3.0.5",
16
- "tqdm>=4.68.4",
17
- ]
18
- license-files = [
19
- "LICENSE",
20
- ]
21
- classifiers = [
22
- "Programming Language :: Python",
23
- "Programming Language :: Python :: 3",
24
- "Programming Language :: Python :: 3 :: Only",
25
- "Programming Language :: Python :: 3.12",
26
- "Programming Language :: Python :: 3.13",
27
- "Programming Language :: Python :: 3.14",
28
- "Operating System :: OS Independent",
29
- "Typing :: Typed",
30
- ]
31
- keywords = [
32
- "pyrig",
33
- ]
34
-
35
- [[project.authors]]
36
- name = "Winipedia"
37
-
38
- [[project.maintainers]]
39
- name = "Winipedia"
40
-
41
- [project.scripts]
42
- winiutils = "pyrig_runtime.rig.cli.main:main"
43
-
44
- [project.urls]
45
- Homepage = "https://github.com/Winipedia/winiutils"
46
- Documentation = "https://Winipedia.github.io/winiutils"
47
- Source = "https://github.com/Winipedia/winiutils"
48
- Issues = "https://github.com/Winipedia/winiutils/issues"
49
- Changelog = "https://github.com/Winipedia/winiutils/releases"
50
-
51
- [dependency-groups]
52
- dev = [
53
- "bandit>=1.9.4",
54
- "deptry>=0.25.1",
55
- "detect-secrets",
56
- "mkdocs>=1.6.1",
57
- "mkdocs-material>=9.7.6",
58
- "mkdocs-mermaid2-plugin>=1.2.3",
59
- "mkdocstrings[python]>=1.0.4",
60
- "pip-audit>=2.10.1",
61
- "prek>=0.4.8",
62
- "pyrig>=17.6.0",
63
- "pyrig-pypi>=3.0.10",
64
- "pytest>=9.1.1",
65
- "pytest-cov>=7.1.0",
66
- "pytest-mock>=3.15.1",
67
- "ruff>=0.15.20",
68
- "rumdl>=0.2.28",
69
- "ty>=0.0.56",
70
- "types-defusedxml>=0.7.0.20260504",
71
- "types-tqdm>=4.68.0.20260608",
72
- "typos>=1.48.0",
73
- ]
74
-
75
- [build-system]
76
- requires = [
77
- "uv_build",
78
- ]
79
- build-backend = "uv_build"
80
-
81
- [tool.ruff.lint]
82
- select = [
83
- "ALL",
84
- ]
85
- ignore = [
86
- "COM812",
87
- "ANN401",
88
- ]
89
-
90
- [tool.ruff.lint.per-file-ignores]
91
- "tests/**/*.py" = [
92
- "S101",
93
- ]
94
-
95
- [tool.ruff.lint.pydocstyle]
96
- convention = "google"
97
-
98
- [tool.ruff.format]
99
- docstring-code-format = true
100
-
101
- [tool.pytest]
102
- testpaths = [
103
- "tests",
104
- ]
105
- addopts = [
106
- "--cov=winiutils",
107
- "--cov-branch",
108
- "--cov-fail-under=90",
109
- "--cov-report=term-missing:skip-covered",
110
- ]
111
- filterwarnings = [
112
- "error",
113
- ]
114
- strict = true
115
-
116
- [tool.deptry]
117
- root = "src"
118
-
119
- [tool.deptry.per_rule_ignores]
120
- DEP002 = [
121
- "pyrig-runtime",
122
- ]
File without changes