winipedia-utils 0.5.19__py3-none-any.whl → 0.5.29__py3-none-any.whl

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.

Potentially problematic release.


This version of winipedia-utils might be problematic. Click here for more details.

@@ -6,7 +6,6 @@ This workflow is used to run tests on pull requests.
6
6
  from typing import Any
7
7
 
8
8
  from winipedia_utils.git.github.workflows.base.base import Workflow
9
- from winipedia_utils.projects.poetry.config import PyprojectConfigFile
10
9
 
11
10
 
12
11
  class HealthCheckWorkflow(Workflow):
@@ -19,62 +18,53 @@ class HealthCheckWorkflow(Workflow):
19
18
  @classmethod
20
19
  def get_workflow_triggers(cls) -> dict[str, Any]:
21
20
  """Get the workflow triggers."""
22
- return {
23
- "pull_request": {
24
- "types": ["opened", "synchronize", "reopened"],
25
- },
26
- "schedule": [
27
- {
28
- # run every day at 6 am
29
- "cron": "0 6 * * *",
30
- },
31
- ],
32
- "workflow_dispatch": {},
33
- }
34
-
35
- @classmethod
36
- def get_permissions(cls) -> dict[str, Any]:
37
- """Get the workflow permissions."""
38
- return {}
21
+ triggers = super().get_workflow_triggers()
22
+ triggers.update(cls.on_pull_request())
23
+ triggers.update(cls.on_schedule(cron="0 6 * * *"))
24
+ return triggers
39
25
 
40
26
  @classmethod
41
27
  def get_jobs(cls) -> dict[str, Any]:
42
28
  """Get the workflow jobs."""
43
- matrix_job_name = f"{cls.get_filename()}_matrix"
44
- return {
45
- **cls.get_standard_job(
46
- name=matrix_job_name,
47
- runs_on="${{ matrix.os }}",
48
- strategy={
49
- "matrix": {
50
- "os": ["ubuntu-latest", "windows-latest", "macos-latest"],
51
- "python-version": [
52
- str(v)
53
- for v in PyprojectConfigFile.get_supported_python_versions()
54
- ],
55
- },
56
- "fail-fast": True,
57
- },
58
- steps=[
59
- *(
60
- cls.get_poetry_setup_steps(
61
- install_dependencies=True,
62
- repo_token=True,
63
- with_keyring=True,
64
- strategy_matrix=True,
65
- )
66
- ),
67
- cls.get_protect_repository_step(),
68
- cls.get_pre_commit_step(),
69
- ],
70
- ),
71
- **cls.get_standard_job(
72
- needs=[matrix_job_name],
73
- steps=[
74
- {
75
- "name": "Aggregate Matrix Results",
76
- "run": "echo 'Aggregating matrix results into one job.'",
77
- }
78
- ],
29
+ jobs: dict[str, Any] = {}
30
+ jobs.update(cls.job_health_check_matrix())
31
+ jobs.update(cls.job_health_check())
32
+ return jobs
33
+
34
+ @classmethod
35
+ def job_health_check_matrix(cls) -> dict[str, Any]:
36
+ """Get the health check matrix job."""
37
+ return cls.get_job(
38
+ job_func=cls.job_health_check_matrix,
39
+ strategy=cls.strategy_matrix_os_and_python_version(),
40
+ runs_on=cls.insert_matrix_os(),
41
+ steps=cls.steps_health_check_matrix(),
42
+ )
43
+
44
+ @classmethod
45
+ def job_health_check(cls) -> dict[str, Any]:
46
+ """Get the health check job."""
47
+ return cls.get_job(
48
+ job_func=cls.job_health_check,
49
+ needs=[cls.make_id_from_func(cls.job_health_check_matrix)],
50
+ steps=cls.steps_aggregate_matrix_results(),
51
+ )
52
+
53
+ @classmethod
54
+ def steps_health_check_matrix(cls) -> list[dict[str, Any]]:
55
+ """Get the health check matrix steps."""
56
+ return [
57
+ *cls.steps_core_matrix_setup(
58
+ python_version=cls.insert_matrix_python_version()
79
59
  ),
80
- }
60
+ cls.step_setup_keyring(),
61
+ cls.step_protect_repository(),
62
+ cls.step_run_pre_commit_hooks(),
63
+ ]
64
+
65
+ @classmethod
66
+ def steps_aggregate_matrix_results(cls) -> list[dict[str, Any]]:
67
+ """Get the aggregate matrix results step."""
68
+ return [
69
+ cls.step_aggregate_matrix_results(),
70
+ ]
@@ -19,31 +19,33 @@ class PublishWorkflow(Workflow):
19
19
  @classmethod
20
20
  def get_workflow_triggers(cls) -> dict[str, Any]:
21
21
  """Get the workflow triggers."""
22
- return {
23
- "workflow_run": {
24
- "workflows": [ReleaseWorkflow.get_workflow_name()],
25
- "types": ["completed"],
26
- },
27
- }
28
-
29
- @classmethod
30
- def get_permissions(cls) -> dict[str, Any]:
31
- """Get the workflow permissions."""
32
- return {
33
- "contents": "read",
34
- }
22
+ triggers = super().get_workflow_triggers()
23
+ triggers.update(
24
+ cls.on_workflow_run(workflows=[ReleaseWorkflow.get_workflow_name()])
25
+ )
26
+ return triggers
35
27
 
36
28
  @classmethod
37
29
  def get_jobs(cls) -> dict[str, Any]:
38
30
  """Get the workflow jobs."""
39
- return cls.get_standard_job(
40
- steps=[
41
- *(
42
- cls.get_poetry_setup_steps(
43
- configure_pipy_token=True,
44
- )
45
- ),
46
- cls.get_publish_to_pypi_step(),
47
- ],
48
- if_condition="${{ github.event.workflow_run.conclusion == 'success' }}",
31
+ jobs: dict[str, Any] = {}
32
+ jobs.update(cls.job_publish())
33
+ return jobs
34
+
35
+ @classmethod
36
+ def job_publish(cls) -> dict[str, Any]:
37
+ """Get the publish job."""
38
+ return cls.get_job(
39
+ job_func=cls.job_publish,
40
+ steps=cls.steps_publish(),
41
+ if_condition=cls.if_workflow_run_is_success(),
49
42
  )
43
+
44
+ @classmethod
45
+ def steps_publish(cls) -> list[dict[str, Any]]:
46
+ """Get the publish steps."""
47
+ return [
48
+ *cls.steps_core_setup(),
49
+ cls.step_add_pypi_token_to_poetry(),
50
+ cls.step_publish_to_pypi(),
51
+ ]
@@ -19,16 +19,10 @@ class ReleaseWorkflow(HealthCheckWorkflow):
19
19
  @classmethod
20
20
  def get_workflow_triggers(cls) -> dict[str, Any]:
21
21
  """Get the workflow triggers."""
22
- return {
23
- "push": {"branches": ["main"]},
24
- "workflow_dispatch": {},
25
- "schedule": [
26
- {
27
- # run every Tuesday at 6 am
28
- "cron": "0 6 * * 2",
29
- },
30
- ],
31
- }
22
+ triggers = super().get_workflow_triggers()
23
+ triggers.update(cls.on_push())
24
+ triggers.update(cls.on_schedule(cron="0 6 * * 2"))
25
+ return triggers
32
26
 
33
27
  @classmethod
34
28
  def get_permissions(cls) -> dict[str, Any]:
@@ -40,12 +34,58 @@ class ReleaseWorkflow(HealthCheckWorkflow):
40
34
  @classmethod
41
35
  def get_jobs(cls) -> dict[str, Any]:
42
36
  """Get the workflow jobs."""
43
- jobs = HealthCheckWorkflow.get_jobs()
44
- release_job = cls.get_standard_job(
45
- needs=[HealthCheckWorkflow.get_filename()],
46
- steps=[
47
- *cls.get_release_steps(),
48
- ],
49
- )
50
- jobs.update(release_job)
37
+ jobs = super().get_jobs()
38
+ last_job_name = list(jobs.keys())[-1]
39
+ jobs.update(cls.job_build(needs=[last_job_name]))
40
+ jobs.update(cls.job_release())
51
41
  return jobs
42
+
43
+ @classmethod
44
+ def job_build(cls, needs: list[str] | None = None) -> dict[str, Any]:
45
+ """Get the build job."""
46
+ return cls.get_job(
47
+ job_func=cls.job_build,
48
+ needs=needs,
49
+ strategy=cls.strategy_matrix_os(),
50
+ runs_on=cls.insert_matrix_os(),
51
+ steps=cls.steps_build(),
52
+ )
53
+
54
+ @classmethod
55
+ def job_release(cls) -> dict[str, Any]:
56
+ """Get the release job."""
57
+ return cls.get_job(
58
+ job_func=cls.job_release,
59
+ needs=[cls.make_id_from_func(cls.job_build)],
60
+ steps=cls.steps_release(),
61
+ )
62
+
63
+ @classmethod
64
+ def steps_build(cls) -> list[dict[str, Any]]:
65
+ """Get the build steps."""
66
+ if not cls.BUILD_SCRIPT_PATH.exists():
67
+ return [cls.step_no_build_script()]
68
+ return [
69
+ *cls.steps_core_matrix_setup(),
70
+ cls.step_create_artifacts_folder(),
71
+ cls.step_build_artifacts(),
72
+ cls.step_upload_artifacts(),
73
+ ]
74
+
75
+ @classmethod
76
+ def steps_release(cls) -> list[dict[str, Any]]:
77
+ """Get the release steps."""
78
+ return [
79
+ *cls.steps_core_setup(repo_token=True),
80
+ cls.step_install_python_dependencies(),
81
+ cls.step_setup_git(),
82
+ cls.step_setup_keyring(),
83
+ cls.step_run_pre_commit_hooks(),
84
+ cls.step_commit_added_changes(),
85
+ cls.step_push_commits(),
86
+ cls.step_create_and_push_tag(),
87
+ cls.step_extract_version(),
88
+ cls.step_download_artifacts(),
89
+ cls.step_build_changelog(),
90
+ cls.step_create_release(),
91
+ ]
@@ -5,9 +5,9 @@ from typing import Any
5
5
 
6
6
  import winipedia_utils
7
7
  from winipedia_utils.logging.logger import get_logger
8
- from winipedia_utils.modules.package import make_name_from_package
9
8
  from winipedia_utils.os.os import run_subprocess
10
9
  from winipedia_utils.text.config import YamlConfigFile
10
+ from winipedia_utils.text.string import make_name_from_obj
11
11
 
12
12
  logger = get_logger(__name__)
13
13
 
@@ -29,7 +29,7 @@ class PreCommitConfigConfigFile(YamlConfigFile):
29
29
  @classmethod
30
30
  def get_configs(cls) -> dict[str, Any]:
31
31
  """Get the config."""
32
- hook_name = make_name_from_package(winipedia_utils, capitalize=False)
32
+ hook_name = make_name_from_obj(winipedia_utils, capitalize=False)
33
33
  return {
34
34
  "repos": [
35
35
  {
@@ -409,33 +409,6 @@ def get_main_package() -> ModuleType:
409
409
  raise ValueError(msg)
410
410
 
411
411
 
412
- def make_name_from_package(
413
- package: ModuleType,
414
- split_on: str = "_",
415
- join_on: str = "-",
416
- *,
417
- capitalize: bool = True,
418
- ) -> str:
419
- """Make a name from a package.
420
-
421
- takes a package and makes a name from it that is readable by humans.
422
-
423
- Args:
424
- package (ModuleType): The package to make a name from
425
- split_on (str, optional): what to split the package name on. Defaults to "_".
426
- join_on (str, optional): what to join the package name with. Defaults to "-".
427
- capitalize (bool, optional): Whether to capitalize each part. Defaults to True.
428
-
429
- Returns:
430
- str: _description_
431
- """
432
- package_name = package.__name__.split(".")[-1]
433
- parts = package_name.split(split_on)
434
- if capitalize:
435
- parts = [part.capitalize() for part in parts]
436
- return join_on.join(parts)
437
-
438
-
439
412
  class DependencyGraph(nx.DiGraph): # type: ignore [type-arg]
440
413
  """A directed graph representing Python package dependencies."""
441
414
 
@@ -7,11 +7,12 @@ from typing import Any, cast
7
7
  import requests
8
8
  from packaging.version import Version
9
9
 
10
- from winipedia_utils.modules.package import get_src_package, make_name_from_package
10
+ from winipedia_utils.modules.package import get_src_package
11
11
  from winipedia_utils.projects.poetry.poetry import VersionConstraint
12
12
  from winipedia_utils.testing.config import ExperimentConfigFile
13
13
  from winipedia_utils.testing.convention import TESTS_PACKAGE_NAME
14
14
  from winipedia_utils.text.config import ConfigFile, TomlConfigFile
15
+ from winipedia_utils.text.string import make_name_from_obj
15
16
 
16
17
 
17
18
  class PyprojectConfigFile(TomlConfigFile):
@@ -27,7 +28,7 @@ class PyprojectConfigFile(TomlConfigFile):
27
28
  """Get the config."""
28
29
  return {
29
30
  "project": {
30
- "name": make_name_from_package(get_src_package(), capitalize=False),
31
+ "name": make_name_from_obj(get_src_package(), capitalize=False),
31
32
  "readme": "README.md",
32
33
  "dynamic": ["dependencies"],
33
34
  },
@@ -7,7 +7,10 @@ These utilities simplify common string manipulation tasks throughout the applica
7
7
 
8
8
  import hashlib
9
9
  import textwrap
10
+ from collections.abc import Callable
10
11
  from io import StringIO
12
+ from types import ModuleType
13
+ from typing import Any
11
14
 
12
15
  from defusedxml import ElementTree as DefusedElementTree
13
16
 
@@ -124,3 +127,30 @@ def split_on_uppercase(string: str) -> list[str]:
124
127
  current_part += letter
125
128
  parts.append(current_part)
126
129
  return parts
130
+
131
+
132
+ def make_name_from_obj(
133
+ package: ModuleType | Callable[..., Any] | type,
134
+ split_on: str = "_",
135
+ join_on: str = "-",
136
+ *,
137
+ capitalize: bool = True,
138
+ ) -> str:
139
+ """Make a name from a package.
140
+
141
+ takes a package and makes a name from it that is readable by humans.
142
+
143
+ Args:
144
+ package (ModuleType): The package to make a name from
145
+ split_on (str, optional): what to split the package name on. Defaults to "_".
146
+ join_on (str, optional): what to join the package name with. Defaults to "-".
147
+ capitalize (bool, optional): Whether to capitalize each part. Defaults to True.
148
+
149
+ Returns:
150
+ str: _description_
151
+ """
152
+ package_name = package.__name__.split(".")[-1]
153
+ parts = package_name.split(split_on)
154
+ if capitalize:
155
+ parts = [part.capitalize() for part in parts]
156
+ return join_on.join(parts)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: winipedia-utils
3
- Version: 0.5.19
3
+ Version: 0.5.29
4
4
  Summary: A package with many utility functions
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -136,7 +136,7 @@ The health check workflow consists of two jobs:
136
136
  - Add Poetry to PATH (Windows-specific step)
137
137
  - Install dependencies
138
138
  - Setup CI keyring
139
- - Protect repository (applies branch protection rules)
139
+ - Protect repository (applies branch protection rules and repository settings)
140
140
  - Run pre-commit hooks (linting, formatting, type checking, security, tests)
141
141
 
142
142
  2. **Aggregation Job** (`health_check`) - Aggregates matrix results into a single status check:
@@ -145,6 +145,7 @@ The health check workflow consists of two jobs:
145
145
  - Provides a single status check that can be marked as required in branch protection rules
146
146
 
147
147
  The release workflow extends the health check workflow and adds a release job that runs after all health checks pass.
148
+ A build job is added before the release job if a script src/artifacts/build.py exists. This script is created by the setup command and can be modified to create build artifacts for your project. This script then just needs to create artifacts in a folder called artifacts and those will be uploaded as artifacts to the release.
148
149
 
149
150
  ### Pre-commit Hook Workflow
150
151
 
@@ -1,4 +1,6 @@
1
1
  winipedia_utils/__init__.py,sha256=vOWZ8n-YemVIzDLd8eWw1HVPGH3jxuT6VtDKHbmxk_A,43
2
+ winipedia_utils/artifacts/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
3
+ winipedia_utils/artifacts/build.py,sha256=WMlNcHwozg3oTmGSJLzsGAb-d4xuMvq51jetJNBkw-g,617
2
4
  winipedia_utils/concurrent/__init__.py,sha256=Tu0ig4gVCk_f1n74G35hDwH-WS3P3STVQGWjxTIbbo8,54
3
5
  winipedia_utils/concurrent/concurrent.py,sha256=h2vgxeDFsagZ10LnHKkswwF2bjY_L1hXKutejeJo48U,8648
4
6
  winipedia_utils/concurrent/multiprocessing.py,sha256=1pnAU-CS3crNOKlp68gCCvNbTvNJs0in_VASMpZ7M1c,4721
@@ -16,15 +18,15 @@ winipedia_utils/git/github/repo/protect.py,sha256=nOVjb5GVinGIClp7k9_qqgKnAl_gk1
16
18
  winipedia_utils/git/github/repo/repo.py,sha256=OqoOfqDhe_Iik71dNqi4h3fGrMno33hSjk0bpNg3eZk,7865
17
19
  winipedia_utils/git/github/workflows/__init__.py,sha256=BPdntTwFEyBMJ6MyT7gddPHswvRdH9tsRtfK72VSV7Y,57
18
20
  winipedia_utils/git/github/workflows/base/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
19
- winipedia_utils/git/github/workflows/base/base.py,sha256=K8Lb19clzaw35YCXHFJ7BVKqeI8bkqDtA-4aSjxl9LM,12770
20
- winipedia_utils/git/github/workflows/health_check.py,sha256=rSz3cV5xEgMIV-SaAjKBonucS_xqz1-t9FUDUbctRy8,2523
21
- winipedia_utils/git/github/workflows/publish.py,sha256=TPbSp5QH2vVl55UdqE_kjf1HIkdubcgqWlkLjWFX5EA,1378
22
- winipedia_utils/git/github/workflows/release.py,sha256=GkObB3LcH9J-L9dWhK5N3aowggGFu3kvmEFKHmILBu4,1456
21
+ winipedia_utils/git/github/workflows/base/base.py,sha256=ycF32n99YzPrMzTn6ISUv3BlTR8RoUpu-SgipEonBHo,27605
22
+ winipedia_utils/git/github/workflows/health_check.py,sha256=Ghehk7LWV3ZH2283DRoNBEF3PDZtwNhiWwMq93CeDrk,2205
23
+ winipedia_utils/git/github/workflows/publish.py,sha256=dNCcSBu7eTjmzomk3qX7BZpTzhwT5oM3Ap3hw22uoJE,1470
24
+ winipedia_utils/git/github/workflows/release.py,sha256=WEAUglUFBE4OslzC_rnCHyLeIqo09majt2ps7UzA8jM,2928
23
25
  winipedia_utils/git/gitignore/__init__.py,sha256=k-2E26JaZPkF69UUOJkpQl8T_PudrC7EYCIOxwgIQVU,57
24
26
  winipedia_utils/git/gitignore/config.py,sha256=Oi1gAf2mbR7vxMi0zsAFpCGzDaLNDd5S2vXEmA3eKg4,2595
25
27
  winipedia_utils/git/gitignore/gitignore.py,sha256=uE2MdynWgQuTG-y2YLR0FU5_giSE7s_TqSVQ6vnNOf8,2419
26
28
  winipedia_utils/git/pre_commit/__init__.py,sha256=gFLVGQRmS6abgy5MfPQy_GZiF1_hGxuXtcOHX95WL-A,58
27
- winipedia_utils/git/pre_commit/config.py,sha256=6Qvb8hoSm7Dmt5KmHOGATuLGrQDWd2aRKtevWThePio,1834
29
+ winipedia_utils/git/pre_commit/config.py,sha256=t0CETAbworS_1g3U4BijVsI1pzcArWTT2-WOexh8aVA,1822
28
30
  winipedia_utils/git/pre_commit/hooks.py,sha256=d88F9Sgik3K6-lJpTio38_vx_ujL64BQ767xeBHHojY,4130
29
31
  winipedia_utils/git/pre_commit/run_hooks.py,sha256=3D8LDkVZVBw6q4RM0KmqMiNc299rjIrtxoL0bLGP2MU,1817
30
32
  winipedia_utils/iterating/__init__.py,sha256=rlF9hzxbowq5yOfcXvOKOQdB-EQmfrislQpf659Zeu4,53
@@ -38,7 +40,7 @@ winipedia_utils/modules/class_.py,sha256=LhhDoXh664h1ILP2lfxlF6M95lFoFNJhsTozxCQ
38
40
  winipedia_utils/modules/function.py,sha256=CvMosbeL2wyAu5eT3vjAvArn9j7aUPh_X3fGoIzwWBk,3479
39
41
  winipedia_utils/modules/inspection.py,sha256=XPSJfLN6WnNmbXn-6z9D01cmqmPS-HrTPy6-B6C34tw,1821
40
42
  winipedia_utils/modules/module.py,sha256=spyg4yI46BLMyhCrSSXIUbY1fHFjcpmRCdKQRUJB7pQ,12792
41
- winipedia_utils/modules/package.py,sha256=6Wb8Pu-SgRWGmKM2r1nhU-yftE7USSKWAuHQn2jRXlg,18058
43
+ winipedia_utils/modules/package.py,sha256=QJLejQDJx2dJS4J75NRQD9jwUjUhLAAUQBBym772c20,17221
42
44
  winipedia_utils/oop/__init__.py,sha256=wGjsVwLbTVEQWOfDJvN9nlvC-3NmAi8Doc2xIrm6e78,47
43
45
  winipedia_utils/oop/mixins/__init__.py,sha256=PDK-cJcdRUfDUCz36qQ5pmMW07G133WtN49OpmILGNI,54
44
46
  winipedia_utils/oop/mixins/meta.py,sha256=0G4CzzzCoeP1Eas3vWe-uxvB5n5ncyw7Wc-sI9zmEBc,11150
@@ -47,7 +49,7 @@ winipedia_utils/os/__init__.py,sha256=cBRq8hWhaWvYeC3cSBYL6Y70kM9COQWHj8vVxxSadI
47
49
  winipedia_utils/os/os.py,sha256=K_5FD1sC1h5aSdtqXAG0uq90sSweLYLkgkRPQS0Jfxg,1768
48
50
  winipedia_utils/projects/__init__.py,sha256=_iYHzUcTPmutpsExPDcMF9OQDgnz-kTSuWens9iP9bI,52
49
51
  winipedia_utils/projects/poetry/__init__.py,sha256=tbvV3wYd3H39hjjlKbF84Irj4hYgv1A7KWyXdCQzFro,59
50
- winipedia_utils/projects/poetry/config.py,sha256=D42eowQfkBCurmb-CenujFXudtt5j1joZk0kM29wujA,8570
52
+ winipedia_utils/projects/poetry/config.py,sha256=4SwzeqTVcnpcfuy1VSA9k2883xHJmJRS-xmbrS89Mfs,8601
51
53
  winipedia_utils/projects/poetry/poetry.py,sha256=e22_ltYXXF_y6UQbCwRX0NiQieyALkxDFfTLc2U9TSA,8478
52
54
  winipedia_utils/projects/project.py,sha256=rirg4xCIOTI6w7cLWufAVHAix7FGicvaCd9OnZQP8dA,521
53
55
  winipedia_utils/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
@@ -88,8 +90,8 @@ winipedia_utils/testing/tests/base/utils/utils.py,sha256=D7N-PW4N8853nJ2m4eYjO3j
88
90
  winipedia_utils/testing/tests/conftest.py,sha256=BLgUJtLecOwuEsIyJ__0buqovd5AhiGvbMNk8CHgSQs,888
89
91
  winipedia_utils/text/__init__.py,sha256=j2bwtK6kyeHI6SnoBjpRju0C1W2n2paXBDlNjNtaUxA,48
90
92
  winipedia_utils/text/config.py,sha256=jjKmn-tSbyaK6jGL0FxFHSREP6A6V1ZSX3RuIgvQ4io,7794
91
- winipedia_utils/text/string.py,sha256=yXmwOab5hXyVQG1NwlWDpy2prj0U7Vb2F5HKLT2Y77Q,3382
92
- winipedia_utils-0.5.19.dist-info/METADATA,sha256=idQGJhJSW-FtOVp7Jcph48nrILgsorcLdUy_k5wLz3Q,16129
93
- winipedia_utils-0.5.19.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
94
- winipedia_utils-0.5.19.dist-info/licenses/LICENSE,sha256=o316mE2gGzd__JT69p7S_zlOmKiHh8YjpImCCcWyTvM,1066
95
- winipedia_utils-0.5.19.dist-info/RECORD,,
93
+ winipedia_utils/text/string.py,sha256=uHqpm1yXumiSDD7MZxfdkRS_4paQ5wIJweeBJK2bCdQ,4332
94
+ winipedia_utils-0.5.29.dist-info/METADATA,sha256=dAH2DmCBs0CegRvpJ3n8N4Fv8xndXVjsdVDuzSBkDms,16481
95
+ winipedia_utils-0.5.29.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
96
+ winipedia_utils-0.5.29.dist-info/licenses/LICENSE,sha256=o316mE2gGzd__JT69p7S_zlOmKiHh8YjpImCCcWyTvM,1066
97
+ winipedia_utils-0.5.29.dist-info/RECORD,,