winipedia-utils 0.1.0__tar.gz → 0.1.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 (65) hide show
  1. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/PKG-INFO +3 -1
  2. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/pyproject.toml +6 -7
  3. winipedia_utils-0.1.2/winipedia_utils/git/gitignore/__init__.py +1 -0
  4. {winipedia_utils-0.1.0/winipedia_utils/git → winipedia_utils-0.1.2/winipedia_utils/git/gitignore}/gitignore.py +63 -7
  5. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/modules/package.py +11 -3
  6. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/projects/poetry/config.py +1 -1
  7. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/setup.py +5 -2
  8. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/session.py +24 -0
  9. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/LICENSE +0 -0
  10. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/README.md +0 -0
  11. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/__init__.py +0 -0
  12. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/concurrent/__init__.py +0 -0
  13. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/concurrent/concurrent.py +0 -0
  14. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/concurrent/multiprocessing.py +0 -0
  15. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/concurrent/multithreading.py +0 -0
  16. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/consts.py +0 -0
  17. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/data/__init__.py +0 -0
  18. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/data/dataframe.py +0 -0
  19. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/django/__init__.py +0 -0
  20. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/django/bulk.py +0 -0
  21. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/django/command.py +0 -0
  22. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/django/database.py +0 -0
  23. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/git/__init__.py +0 -0
  24. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/git/pre_commit/__init__.py +0 -0
  25. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/git/pre_commit/config.py +0 -0
  26. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/git/pre_commit/hooks.py +0 -0
  27. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/git/pre_commit/run_hooks.py +0 -0
  28. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/iterating/__init__.py +0 -0
  29. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/iterating/iterate.py +0 -0
  30. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/logging/__init__.py +0 -0
  31. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/logging/ansi.py +0 -0
  32. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/logging/config.py +0 -0
  33. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/logging/logger.py +0 -0
  34. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/modules/__init__.py +0 -0
  35. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/modules/class_.py +0 -0
  36. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/modules/function.py +0 -0
  37. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/modules/module.py +0 -0
  38. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/oop/__init__.py +0 -0
  39. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/oop/mixins/__init__.py +0 -0
  40. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/oop/mixins/meta.py +0 -0
  41. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/oop/mixins/mixin.py +0 -0
  42. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/os/__init__.py +0 -0
  43. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/os/os.py +0 -0
  44. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/projects/__init__.py +0 -0
  45. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/projects/poetry/__init__.py +0 -0
  46. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/projects/poetry/poetry.py +0 -0
  47. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/__init__.py +0 -0
  48. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/assertions.py +0 -0
  49. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/convention.py +0 -0
  50. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/create_tests.py +0 -0
  51. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/fixtures.py +0 -0
  52. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/__init__.py +0 -0
  53. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/__init__.py +0 -0
  54. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/__init__.py +0 -0
  55. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/fixture.py +0 -0
  56. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/__init__.py +0 -0
  57. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +0 -0
  58. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/function.py +0 -0
  59. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/module.py +0 -0
  60. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/fixtures/scopes/package.py +0 -0
  61. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/utils/__init__.py +0 -0
  62. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/base/utils/utils.py +0 -0
  63. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/testing/tests/conftest.py +0 -0
  64. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/text/__init__.py +0 -0
  65. {winipedia_utils-0.1.0 → winipedia_utils-0.1.2}/winipedia_utils/text/string.py +0 -0
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: winipedia-utils
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: A package with many utility functions
5
5
  License: MIT
6
6
  Author: Winipedia
7
+ Author-email: win.steveker@gmx.de
7
8
  Requires-Python: >=3.12
8
9
  Classifier: License :: OSI Approved :: MIT License
9
10
  Classifier: Programming Language :: Python :: 3
@@ -12,6 +13,7 @@ Classifier: Programming Language :: Python :: 3.13
12
13
  Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
13
14
  Requires-Dist: django (>=5.2.1,<6.0.0)
14
15
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)
16
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
15
17
  Requires-Dist: setuptools (>=80.3.1,<81.0.0)
16
18
  Requires-Dist: tomlkit (>=0.13.2,<0.14.0)
17
19
  Requires-Dist: tqdm (>=4.67.1,<5.0.0)
@@ -1,16 +1,15 @@
1
1
  # Project section
2
2
  [project]
3
3
  name = "winipedia-utils"
4
- version = "0.1.0"
4
+ version = "0.1.2"
5
5
  description = "A package with many utility functions"
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.12"
8
8
  dynamic = [ "dependencies",]
9
- [[project.authors]]
10
- name = "Winipedia"
11
-
12
- [project.license]
13
- text = "MIT"
9
+ authors = [
10
+ { name = "Winipedia", email = "win.steveker@gmx.de"}
11
+ ]
12
+ license = { text = "MIT" }
14
13
 
15
14
  # Build system section
16
15
  [build-system]
@@ -18,7 +17,6 @@ requires = [ "poetry-core>=2.0.0,<3.0.0",]
18
17
  build-backend = "poetry.core.masonry.api"
19
18
 
20
19
  # Poetry section
21
- [tool.poetry]
22
20
  [[tool.poetry.packages]]
23
21
  include = "winipedia_utils"
24
22
 
@@ -29,6 +27,7 @@ defusedxml = "^0.7.1"
29
27
  tomlkit = "^0.13.2"
30
28
  pathspec = "^0.12.1"
31
29
  django = "^5.2.1"
30
+ pyyaml = "^6.0.2"
32
31
 
33
32
  [tool.poetry.group.dev.dependencies]
34
33
  ruff = "^0.11.7"
@@ -0,0 +1 @@
1
+ """__init__ module for winipedia_utils.git.gitignore."""
@@ -37,13 +37,7 @@ def path_is_in_gitignore(relative_path: str | Path) -> bool:
37
37
  if is_dir and not as_posix.endswith("/"):
38
38
  as_posix += "/"
39
39
 
40
- gitignore_path = Path(".gitignore")
41
- if not gitignore_path.exists():
42
- return False # No ignore rules
43
-
44
- spec = pathspec.PathSpec.from_lines(
45
- "gitwildmatch", gitignore_path.read_text().splitlines()
46
- )
40
+ spec = pathspec.PathSpec.from_lines("gitwildmatch", load_gitignore())
47
41
 
48
42
  return spec.match_file(as_posix)
49
43
 
@@ -78,3 +72,65 @@ def walk_os_skipping_gitignore_patterns(
78
72
  valid_dirs = [d for d in dirs if not path_is_in_gitignore(rel_root / d)]
79
73
 
80
74
  yield rel_root, valid_dirs, valid_files
75
+
76
+
77
+ def load_gitignore() -> list[str]:
78
+ """Load the .gitignore file."""
79
+ gitignore_path = Path(".gitignore")
80
+ if not gitignore_path.exists():
81
+ gitignore_path.touch()
82
+ return gitignore_path.read_text().splitlines()
83
+
84
+
85
+ def dump_gitignore(patterns: list[str]) -> None:
86
+ """Dump the given patterns to a .gitignore file (overwrites it)."""
87
+ gitignore_path = Path(".gitignore")
88
+ gitignore_path.write_text("\n".join(patterns))
89
+
90
+
91
+ def add_patterns_to_gitignore(patterns: list[str]) -> None:
92
+ """Add the given patterns to the .gitignore file."""
93
+ existing_patterns = load_gitignore()
94
+ new_patterns = [p for p in patterns if p not in existing_patterns]
95
+ if new_patterns:
96
+ logger.info("Adding patterns to .gitignore: %s", new_patterns)
97
+ dump_gitignore(existing_patterns + new_patterns)
98
+
99
+
100
+ def _get_gitignore_patterns() -> list[str]:
101
+ """Get the patterns that should be in the .gitignore file.
102
+
103
+ Those are the patterns that should be in there when using winipedia_utils.
104
+ """
105
+ return [
106
+ "__pycache__/",
107
+ ".idea/",
108
+ ".mypy_cache/",
109
+ ".pytest_cache/",
110
+ ".ruff_cache/",
111
+ ".vscode/",
112
+ "dist/",
113
+ "test.py", # I use this for testing code
114
+ ".git/", # ignore the .git folder for walk_os_skipping_gitignore_patterns func
115
+ ]
116
+
117
+
118
+ def _get_missing_patterns() -> list[str]:
119
+ """Get the patterns that are in the .gitignore file but shouldn't be."""
120
+ needed_patterns = _get_gitignore_patterns()
121
+ existing_patterns = load_gitignore()
122
+ return [p for p in needed_patterns if p not in existing_patterns]
123
+
124
+
125
+ def _gitignore_is_correct() -> bool:
126
+ """Check if the .gitignore file contains all the patterns it should."""
127
+ missing_patterns = _get_missing_patterns()
128
+ return not missing_patterns
129
+
130
+
131
+ def _add_package_patterns_to_gitignore() -> None:
132
+ """Add any missing patterns to the .gitignore file."""
133
+ if _gitignore_is_correct():
134
+ return
135
+ missing_patterns = _get_missing_patterns()
136
+ add_patterns_to_gitignore(missing_patterns)
@@ -19,7 +19,10 @@ from types import ModuleType
19
19
  from setuptools import find_namespace_packages as _find_namespace_packages
20
20
  from setuptools import find_packages as _find_packages
21
21
 
22
- from winipedia_utils.git.gitignore import walk_os_skipping_gitignore_patterns
22
+ from winipedia_utils.git.gitignore.gitignore import (
23
+ load_gitignore,
24
+ walk_os_skipping_gitignore_patterns,
25
+ )
23
26
  from winipedia_utils.logging.logger import get_logger
24
27
 
25
28
  logger = get_logger(__name__)
@@ -148,7 +151,7 @@ def find_packages(
148
151
  depth: int | None = None,
149
152
  include_namespace_packages: bool = False,
150
153
  where: str = ".",
151
- exclude: Iterable[str] = (),
154
+ exclude: Iterable[str] | None = None,
152
155
  include: Iterable[str] = ("*",),
153
156
  ) -> list[str]:
154
157
  """Discover Python packages in the specified directory.
@@ -172,6 +175,11 @@ def find_packages(
172
175
  find_packages(depth=1) might return ["package1", "package2"]
173
176
 
174
177
  """
178
+ if exclude is None:
179
+ exclude = load_gitignore()
180
+ exclude = [
181
+ p.replace("/", ".").removesuffix(".") for p in exclude if p.endswith("/")
182
+ ]
175
183
  if include_namespace_packages:
176
184
  package_names = _find_namespace_packages(
177
185
  where=where, exclude=exclude, include=include
@@ -193,7 +201,7 @@ def find_packages_as_modules(
193
201
  depth: int | None = None,
194
202
  include_namespace_packages: bool = False,
195
203
  where: str = ".",
196
- exclude: Iterable[str] = (),
204
+ exclude: Iterable[str] | None = None,
197
205
  include: Iterable[str] = ("*",),
198
206
  ) -> list[ModuleType]:
199
207
  """Discover and import Python packages in the specified directory.
@@ -75,7 +75,7 @@ def _pyproject_tool_configs_are_correct() -> bool:
75
75
  return True
76
76
 
77
77
 
78
- def _add_tool_configurations_to_pyproject_toml() -> None:
78
+ def _add_configurations_to_pyproject_toml() -> None:
79
79
  """Add tool.* configurations to pyproject.toml."""
80
80
  expected_tool_dict = _get_pyproject_toml_tool_configs()
81
81
  toml = laod_pyproject_toml()
@@ -6,11 +6,12 @@ This package assumes you are using poetry and pre-commit.
6
6
  This script is intended to be called once at the beginning of a project.
7
7
  """
8
8
 
9
+ from winipedia_utils.git.gitignore.gitignore import _add_package_patterns_to_gitignore
9
10
  from winipedia_utils.git.pre_commit.config import _add_package_hook_to_pre_commit_config
10
11
  from winipedia_utils.git.pre_commit.run_hooks import _run_all_hooks
11
12
  from winipedia_utils.logging.logger import get_logger
12
13
  from winipedia_utils.projects.poetry.config import (
13
- _add_tool_configurations_to_pyproject_toml,
14
+ _add_configurations_to_pyproject_toml,
14
15
  )
15
16
  from winipedia_utils.projects.poetry.poetry import (
16
17
  _install_dev_dependencies,
@@ -25,8 +26,10 @@ def _setup() -> None:
25
26
  _install_dev_dependencies()
26
27
  # create pre-commit config
27
28
  _add_package_hook_to_pre_commit_config()
29
+ # add patterns to .gitignore
30
+ _add_package_patterns_to_gitignore()
28
31
  # add tool.* configurations to pyproject.toml
29
- _add_tool_configurations_to_pyproject_toml()
32
+ _add_configurations_to_pyproject_toml()
30
33
  # run pre-commit once, create tests is included here
31
34
  _run_all_hooks()
32
35
  logger.info("Setup complete!")
@@ -10,6 +10,7 @@ from importlib import import_module
10
10
  from pathlib import Path
11
11
 
12
12
  from winipedia_utils.consts import _DEV_DEPENDENCIES
13
+ from winipedia_utils.git.gitignore.gitignore import _gitignore_is_correct
13
14
  from winipedia_utils.git.pre_commit.config import (
14
15
  _pre_commit_config_is_correct,
15
16
  )
@@ -130,6 +131,29 @@ def _test_pre_commit_config_yaml_is_correct() -> None:
130
131
  )
131
132
 
132
133
 
134
+ @autouse_session_fixture
135
+ def _test_gitignore_is_correct() -> None:
136
+ """Verify that the .gitignore file exists and has the correct content.
137
+
138
+ This fixture runs once per test session and checks that the .gitignore file
139
+ exists in the root directory and contains the correct content.
140
+
141
+ Raises:
142
+ AssertionError: If the .gitignore file doesn't exist
143
+ or has incorrect content
144
+
145
+ """
146
+ gitignore_path = Path(".gitignore")
147
+ assert_with_msg(
148
+ gitignore_path.is_file(),
149
+ f"Expected {gitignore_path} to exist but it doesn't.",
150
+ )
151
+ assert_with_msg(
152
+ _gitignore_is_correct(),
153
+ "Gitignore is not correct.",
154
+ )
155
+
156
+
133
157
  @autouse_session_fixture
134
158
  def _test_no_namespace_packages() -> None:
135
159
  """Verify that there are no namespace packages in the project.
File without changes