instant-python 0.24.2__py3-none-any.whl → 0.26.0__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.
@@ -1 +1 @@
1
- __version__ = "0.24.2"
1
+ __version__ = "0.26.0"
@@ -9,15 +9,13 @@ class ConfigGenerator:
9
9
  self._repository = repository
10
10
 
11
11
  def execute(self) -> None:
12
- answers = self._ask_project_configuration_to_user()
13
- config = self._create_configuration_based_on_answers(answers)
12
+ config = self._ask_project_configuration_to_user()
13
+ if not config:
14
+ return
14
15
  self._save_configuration(config)
15
16
 
16
- def _create_configuration_based_on_answers(self, answers: dict) -> ConfigSchema:
17
- return ConfigSchema.from_primitives(answers)
18
-
19
17
  def _save_configuration(self, config: ConfigSchema) -> None:
20
18
  self._repository.write(config)
21
19
 
22
- def _ask_project_configuration_to_user(self) -> dict:
20
+ def _ask_project_configuration_to_user(self) -> ConfigSchema | None:
23
21
  return self._question_wizard.run()
@@ -1,6 +1,7 @@
1
1
  import typer
2
2
 
3
3
  from instant_python.config.application.config_generator import ConfigGenerator
4
+ from instant_python.config.infra.question_wizard.console_answers_review_formatter import ConsoleAnswersReviewFormatter
4
5
  from instant_python.config.infra.question_wizard.questionary_console_wizard import QuestionaryConsoleWizard
5
6
  from instant_python.config.infra.question_wizard.step.questionary import Questionary
6
7
  from instant_python.shared.infra.persistence.yaml_config_repository import YamlConfigRepository
@@ -12,7 +13,7 @@ app = typer.Typer()
12
13
  def generate_ipy_configuration_file() -> None:
13
14
  config_generator = ConfigGenerator(
14
15
  question_wizard=QuestionaryConsoleWizard(
15
- questionary=Questionary(),
16
+ questionary=Questionary(), review_formatter=ConsoleAnswersReviewFormatter()
16
17
  ),
17
18
  repository=YamlConfigRepository(),
18
19
  )
@@ -0,0 +1,7 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class AnswersReviewFormatter(ABC):
5
+ @abstractmethod
6
+ def print_answers(self, answers: dict) -> None:
7
+ raise NotImplementedError
@@ -1,7 +1,9 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
+ from instant_python.shared.domain.config_schema import ConfigSchema
4
+
3
5
 
4
6
  class QuestionWizard(ABC):
5
7
  @abstractmethod
6
- def run(self) -> dict:
8
+ def run(self) -> ConfigSchema | None:
7
9
  raise NotImplementedError
@@ -0,0 +1,34 @@
1
+ from typing import ClassVar
2
+
3
+ from instant_python.config.domain.answers_review_formatter import AnswersReviewFormatter
4
+
5
+
6
+ class ConsoleAnswersReviewFormatter(AnswersReviewFormatter):
7
+ _TITLE = "Review Configuration"
8
+ _SECTION_TITLES: ClassVar[dict[str, str]] = {
9
+ "general": "General",
10
+ "template": "Template",
11
+ "git": "Git",
12
+ "dependencies": "Dependencies",
13
+ }
14
+
15
+ def print_answers(self, answers: dict) -> None:
16
+ summary = [self._TITLE]
17
+ for section_key, section_content in answers.items():
18
+ section_title = self._SECTION_TITLES[section_key]
19
+ summary.append(section_title)
20
+ if not section_content:
21
+ summary.append(" None")
22
+ continue
23
+ if isinstance(section_content, list):
24
+ for dependency in section_content:
25
+ env_content = "(prod)"
26
+ if dependency["is_dev"] is True:
27
+ env_content = f"(dev, group: {dependency['group']})" if dependency["group"] != "" else "(dev)"
28
+ summary.append(f" {dependency['name']}=={dependency['version']} {env_content}")
29
+ continue
30
+ for field_title, field_content in section_content.items():
31
+ if isinstance(field_content, list):
32
+ field_content = "None" if not field_content else ", ".join(field_content)
33
+ summary.append(f" {field_title.title().replace('_', ' ')}: {field_content}")
34
+ print("\n".join(summary))
@@ -1,3 +1,4 @@
1
+ from instant_python.config.domain.answers_review_formatter import AnswersReviewFormatter
1
2
  from instant_python.config.domain.question_wizard import QuestionWizard
2
3
  from instant_python.config.infra.question_wizard.step.dependencies_step import DependenciesStep
3
4
  from instant_python.config.infra.question_wizard.step.general_step import GeneralStep
@@ -5,25 +6,41 @@ from instant_python.config.infra.question_wizard.step.git_step import GitStep
5
6
  from instant_python.config.infra.question_wizard.step.questionary import Questionary
6
7
  from instant_python.config.infra.question_wizard.step.steps import Steps
7
8
  from instant_python.config.infra.question_wizard.step.template_step import TemplateStep
9
+ from instant_python.shared.domain.config_schema import ConfigSchema
8
10
 
9
11
 
10
12
  class QuestionaryConsoleWizard(QuestionWizard):
11
- def __init__(self, questionary: Questionary) -> None:
13
+ def __init__(self, questionary: Questionary, review_formatter: AnswersReviewFormatter) -> None:
12
14
  self._steps = Steps(
13
15
  GeneralStep(questionary=questionary),
14
16
  TemplateStep(questionary=questionary),
15
17
  GitStep(questionary=questionary),
16
18
  DependenciesStep(questionary=questionary),
17
19
  )
20
+ self._review_formatter = review_formatter
21
+ self._questionary = questionary
18
22
  self._answers = {}
19
23
 
20
- def run(self) -> dict:
24
+ def run(self) -> ConfigSchema | None:
21
25
  for position, step in enumerate(self._steps, start=1):
22
26
  self._show_section_heading(position, step.title)
23
27
  answer = step.run()
24
28
  self._answers.update(answer)
25
29
 
26
- return self._answers
30
+ config = ConfigSchema.from_primitives(self._answers)
31
+ self._show_answers_summary(config)
32
+ if self._user_wants_to_discard_config():
33
+ print("Configuration has been discarded. No 'ipy.yml' will be created.")
34
+ return None
35
+ return config
27
36
 
28
37
  def _show_section_heading(self, position: int, section_title: str) -> None:
29
38
  print(f"[{position}/{len(self._steps)}] {section_title}")
39
+
40
+ def _show_answers_summary(self, config: ConfigSchema) -> None:
41
+ self._review_formatter.print_answers(dict(**config.to_primitives()))
42
+
43
+ def _user_wants_to_discard_config(self) -> bool:
44
+ return not self._questionary.boolean_question(
45
+ message="Do you want to save this project configuration?", default=True
46
+ )
@@ -1,4 +1,5 @@
1
1
  from collections.abc import Callable
2
+ from datetime import datetime, timezone
2
3
  from typing import Any, ClassVar
3
4
 
4
5
  from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PackageLoader
@@ -32,6 +33,7 @@ class JinjaEnvironment:
32
33
  self.add_filter("compute_base_path", _compute_base_path)
33
34
  self.add_filter("has_dependency", _has_dependency)
34
35
  self.add_filter("resolve_import_path", _resolve_import_path)
36
+ self._env.globals["current_year"] = datetime.now(tz=timezone.utc).year
35
37
 
36
38
  def render_template(self, name: str, context: dict[str, Any] | None = None) -> str:
37
39
  template = self._env.get_template(name)
@@ -21,6 +21,9 @@ _TEMPLATE = "template"
21
21
  _GIT = "git"
22
22
  _REQUIRED_CONFIG_KEYS = [_GENERAL, _DEPENDENCIES, _TEMPLATE, _GIT]
23
23
 
24
+ # Dropped rather than rejected so config files saved by older versions still load.
25
+ _LEGACY_GENERAL_KEYS = {"year"}
26
+
24
27
 
25
28
  @dataclass
26
29
  class ConfigSchema:
@@ -36,8 +39,9 @@ class ConfigSchema:
36
39
  def from_primitives(cls, content: dict[str, dict | list], custom_config_path: Path | None = None) -> "ConfigSchema":
37
40
  cls._ensure_config_is_not_empty(content)
38
41
  cls._ensure_all_required_sections_are_present(content)
42
+ general_content = {k: v for k, v in content[_GENERAL].items() if k not in _LEGACY_GENERAL_KEYS}
39
43
  return cls(
40
- general=GeneralConfig(**content[_GENERAL]),
44
+ general=GeneralConfig(**general_content),
41
45
  dependencies=[DependencyConfig(**dep) for dep in content[_DEPENDENCIES]] if content[_DEPENDENCIES] else [],
42
46
  template=TemplateConfig(**content[_TEMPLATE]),
43
47
  git=GitConfig(**content[_GIT]),
@@ -1,6 +1,5 @@
1
1
  import re
2
- from dataclasses import asdict, dataclass, field
3
- from datetime import datetime, timezone
2
+ from dataclasses import asdict, dataclass
4
3
 
5
4
  from instant_python.shared.application_error import ApplicationError
6
5
  from instant_python.shared.supported_licenses import SupportedLicenses
@@ -18,17 +17,16 @@ class GeneralConfig:
18
17
  license: str
19
18
  python_version: str
20
19
  dependency_manager: str
21
- year: int = field(default=datetime.now(tz=timezone.utc).year)
22
20
 
23
21
  def __post_init__(self) -> None:
24
22
  self.version = str(self.version)
25
23
  self.python_version = str(self.python_version)
26
- self._remove_invalid_characters_from_slug_and_normalyze_hyphens()
24
+ self._remove_invalid_characters_from_slug_and_normalize_hyphens()
27
25
  self._ensure_license_is_supported()
28
26
  self._ensure_python_version_is_supported()
29
27
  self._ensure_dependency_manager_is_supported()
30
28
 
31
- def _remove_invalid_characters_from_slug_and_normalyze_hyphens(self) -> None:
29
+ def _remove_invalid_characters_from_slug_and_normalize_hyphens(self) -> None:
32
30
  normalized_slug = re.sub(r"[^a-z0-9]+", "-", self.slug.lower()).strip("-")
33
31
  if not normalized_slug:
34
32
  raise InvalidSlugValue(self.slug)
@@ -187,7 +187,7 @@
187
187
  same "printed page" as the copyright notice for easier
188
188
  identification within third-party archives.
189
189
 
190
- Copyright [{{ general.year }}] [{{ general.author }}]
190
+ Copyright [{{ current_year }}] [{{ general.author }}]
191
191
 
192
192
  Licensed under the Apache License, Version 2.0 (the "License");
193
193
  you may not use this file except in compliance with the License.
@@ -198,7 +198,7 @@
198
198
  {% elif general.license == 'MIT' %}
199
199
  MIT License
200
200
 
201
- Copyright (c) {{ general.year }} {{ general.author }}
201
+ Copyright (c) {{ current_year }} {{ general.author }}
202
202
 
203
203
  Permission is hereby granted, free of charge, to any person obtaining a copy
204
204
  of this software and associated documentation files (the "Software"), to deal
@@ -873,7 +873,7 @@ Also add information on how to contact you by electronic and paper mail.
873
873
  If the program does terminal interaction, make it output a short
874
874
  notice like this when it starts in an interactive mode:
875
875
 
876
- <program> Copyright (C) <{{ general.year }}> <{{ general.author }}>
876
+ <program> Copyright (C) <{{ current_year }}> <{{ general.author }}>
877
877
  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
878
878
  This is free software, and you are welcome to redistribute it
879
879
  under certain conditions; type `show c' for details.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: instant-python
3
- Version: 0.24.2
3
+ Version: 0.26.0
4
4
  Summary: Instant boilerplate generation for Python projects
5
5
  Project-URL: documentation, https://dimanu-py.github.io/instant-python/
6
6
  Project-URL: repository, https://github.com/dimanu-py/instant-python/
@@ -264,6 +264,20 @@ commands like `ng new` or `create-react-app`, but for Python projects.
264
264
 
265
265
  </td></tr></table></div>
266
266
 
267
+ ## 🚀 Quick Start
268
+
269
+ Once [installed](https://dimanu-py.github.io/instant-python/getting_started/installation/), generating a project takes two commands:
270
+
271
+ ```bash
272
+ ipy config # answer a few questions through an interactive wizard to create your ipy.yml configuration file
273
+ ipy init # generate the project from that configuration file
274
+ ```
275
+
276
+ - `ipy config` asks you about your project (name, Python version, project manager, template, dependencies, and more) and writes an `ipy.yml` configuration file in the current directory.
277
+ - `ipy init` reads that `ipy.yml` file and generates your new project.
278
+
279
+ See the [First Steps](https://dimanu-py.github.io/instant-python/getting_started/first_steps/) guide for a full walkthrough.
280
+
267
281
  ## ✨ NEW ✨ Create Fully Customized Projects
268
282
 
269
283
  Take full control of your project generation! With **custom templates**, you can:
@@ -1,17 +1,19 @@
1
- instant_python/__init__.py,sha256=UBF3OYTcBAovta3ux5ybxb0MZYAGpGO79WH_ax2NGeI,23
1
+ instant_python/__init__.py,sha256=S1dNBNSmHJkAHkq1vL1Yg-dFpQk0fri_CstNlL1u5qw,23
2
2
  instant_python/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  instant_python/cli/cli.py,sha256=JJBJ48YFf7mwjyGjZLSZBzBVDF6syEt5B2n-hkQR1lg,1618
4
4
  instant_python/cli/instant_python_typer.py,sha256=qChUAmoTT49FIHc94MJhzAXvxztXJwaCPUpD-4ml5ZU,1250
5
5
  instant_python/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  instant_python/config/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- instant_python/config/application/config_generator.py,sha256=idsAvVjcOuk4_6DcEiziUHIMt9-hKKJ7c3JEQq5ITwM,971
7
+ instant_python/config/application/config_generator.py,sha256=2J691YoAa2VHZ5D9VLsIP0Y3ImRm3WbQin3zPb43uv4,818
8
8
  instant_python/config/delivery/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- instant_python/config/delivery/cli.py,sha256=XD8nOCQjDhBzyyq3H9N8aS14NmDEIYXH7Y6AQpdsu9Y,753
9
+ instant_python/config/delivery/cli.py,sha256=JWKDK_wzZiVmMEEq--7FQ8532_fsKatdh279h853qW8,921
10
10
  instant_python/config/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- instant_python/config/domain/question_wizard.py,sha256=mSqESa4xC6F2OEJZ338dokXZ34Y22aBMAGmARhBQSnY,146
11
+ instant_python/config/domain/answers_review_formatter.py,sha256=b2K2abu9mzVhEXji_foPGWD9fu0kMvKLSyAQA9WOIeQ,179
12
+ instant_python/config/domain/question_wizard.py,sha256=Dwp6_JngrPYNY3nBZlyY6v1ccsTa5EwFEVjTgYaqy48,230
12
13
  instant_python/config/infra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  instant_python/config/infra/question_wizard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- instant_python/config/infra/question_wizard/questionary_console_wizard.py,sha256=AdDZI_2ajfTzJF4k35Xr9NA3tIi7ub7DKMtj9EJMqD8,1356
15
+ instant_python/config/infra/question_wizard/console_answers_review_formatter.py,sha256=Hg16vPloyDqsLbVvxVvrR3Z7O4L7ZFQ4KjyPb0o_rg4,1536
16
+ instant_python/config/infra/question_wizard/questionary_console_wizard.py,sha256=AeuHWXDZ7QBuIDXy_67a9lEzrZPo0kvYkPqc-ohpmnU,2263
15
17
  instant_python/config/infra/question_wizard/step/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
18
  instant_python/config/infra/question_wizard/step/dependencies_step.py,sha256=1744qPP8jEpHHp1irZu6SuN7qwtJtUDKslcxwGzKva8,2661
17
19
  instant_python/config/infra/question_wizard/step/general_step.py,sha256=RJmd-0wCB78UqSAPVgqJEgQTAGOapQLaeg8qomPVogw,3076
@@ -41,7 +43,7 @@ instant_python/initialize/infra/env_manager/uv_env_manager.py,sha256=kYYDO7spQeD
41
43
  instant_python/initialize/infra/formatter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
44
  instant_python/initialize/infra/formatter/ruff_project_formatter.py,sha256=AE3DYoDC-NZse3Mv2MW5VqsUigiIMscCCETPJ_Rr_Io,398
43
45
  instant_python/initialize/infra/renderer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
- instant_python/initialize/infra/renderer/jinja_environment.py,sha256=lfH5kaUOans2uJRKSYaJE59iiRWE1tdNFc6tbPF5j2c,2863
46
+ instant_python/initialize/infra/renderer/jinja_environment.py,sha256=OHOYkXNh_84w67rTjW6hSNTPK-PbsnVBbk0O83HLZA0,2982
45
47
  instant_python/initialize/infra/renderer/jinja_project_renderer.py,sha256=GeHGZYfLKj-cxevKk3B87iW3OmXrWmUWw7cnaDO9ABI,2831
46
48
  instant_python/initialize/infra/version_control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
49
  instant_python/initialize/infra/version_control/git_configurer.py,sha256=W4WzoHbZ3RtAjmpRzeBGsreHxBCX_vtYSB2GpNF4Tcg,1232
@@ -71,9 +73,9 @@ instant_python/shared/supported_python_versions.py,sha256=KTtD8Cu7zJiLW_9C6quWCR
71
73
  instant_python/shared/supported_templates.py,sha256=Sl6pFsyrb2F8hUsy-_ZP4RIX0Kr_Q_zw9a0shevCp8M,304
72
74
  instant_python/shared/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
75
  instant_python/shared/domain/config_repository.py,sha256=8iHVflpRMFA_qpSPux8v9b3Yulp73oJHdH2ZiEOqhwM,498
74
- instant_python/shared/domain/config_schema.py,sha256=-Pt-9QS9lJSGp70cfG86-w48DYzr7KgRJG2ZeofUXIc,4277
76
+ instant_python/shared/domain/config_schema.py,sha256=12uITyxvTsy7_utOTd0mmMTt5Zz6ty9s-qKBijGk9Q0,4495
75
77
  instant_python/shared/domain/dependency_config.py,sha256=SH5CubFFv6NHAc75Jy16MNbtebdP1jZRmZ9OOm8bD44,1412
76
- instant_python/shared/domain/general_config.py,sha256=gGhZMVqnRrJMAGXLh0OnaSbHH8uh51FiVKk8PQl0PEc,3214
78
+ instant_python/shared/domain/general_config.py,sha256=HE8vq6LpOb8BN9mBek5thqHjuiMrvx-SKJOkEy1Vauo,3101
77
79
  instant_python/shared/domain/git_config.py,sha256=_5FKISV1oaZM9MHHKYrqQJrY2BtS0dMR3XagKws0or4,1081
78
80
  instant_python/shared/domain/template_config.py,sha256=doylcLSPYrBiBbQOQjd5S6uZow9lmpEQ58ADUkK0fDw,3299
79
81
  instant_python/shared/infra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -83,7 +85,7 @@ instant_python/templates/boilerplate/.gitignore,sha256=ViomTBHDFOJHHeRAL6UugoaNy
83
85
  instant_python/templates/boilerplate/.pre-commit-config.yaml,sha256=BiF6JdygrPbXhJjUc_eJm-iSL8RkGQE20RfQakVynsc,1724
84
86
  instant_python/templates/boilerplate/.python-version,sha256=7b_kfEdqh7QsWx4IDCSWhbwielSfsmsAEZPM3kjSuBA,28
85
87
  instant_python/templates/boilerplate/CITATION.cff,sha256=m1fHRwEfq7HvL9uMJ8H1sPk91teJYldVlD3M2OiyFAE,401
86
- instant_python/templates/boilerplate/LICENSE,sha256=wzw1JFV1qGbnRMfokpku4CO4ZKvtreFsyIksljC7hLI,47428
88
+ instant_python/templates/boilerplate/LICENSE,sha256=VLwfNpljs2YkwgDmcP5qs1fsr-Ik5TEJlwpQKhLUJ84,47428
87
89
  instant_python/templates/boilerplate/README.md,sha256=qlaO6Tnd8k0A_ccRNVI8yt5Vn1dQP6AwxW_WH80P8Is,238
88
90
  instant_python/templates/boilerplate/SECURITY.md,sha256=l2T8a7mcV3PUs1vloUDqFXlRXKseInsT_nR71wlLvGo,2024
89
91
  instant_python/templates/boilerplate/mkdocs.yml,sha256=WOp2M_SWQAoyEMhTCZhg7loi4MuuqkFkXAb6GicoEjM,1727
@@ -240,8 +242,8 @@ instant_python/templates/project_structure/standard_project/test.yml,sha256=k5dE
240
242
  instant_python/templates/project_structure/standard_project/layers/source_features.yml,sha256=iVFOa5juIaiZObznHuSFoBCQXWwlDdX3UcO9GfBMAH4,781
241
243
  instant_python/templates/project_structure/standard_project/layers/test_event_bus.yml,sha256=81fC2jIvK-0bLOIDSRi2Uab3dXigfjiEk6xT8PbzP0w,165
242
244
  instant_python/templates/project_structure/standard_project/layers/test_features.yml,sha256=MfyuXbdF2K8zCXdDYRYTqDnWQ0_kkE1XeEfJVio_ALs,302
243
- instant_python-0.24.2.dist-info/METADATA,sha256=NMdxXXd_5K10b4bG0WwC-adpmCwoQufO63DlCJl_Flk,19911
244
- instant_python-0.24.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
245
- instant_python-0.24.2.dist-info/entry_points.txt,sha256=M8YUHQaTszBM3np_x9j7wmc1ngrmpfrd4ajBv2EzQuk,51
246
- instant_python-0.24.2.dist-info/licenses/LICENSE,sha256=kf7wA-1IsqXkzXjlsG95sdQJtsqUON_lNXombfPlklo,11353
247
- instant_python-0.24.2.dist-info/RECORD,,
245
+ instant_python-0.26.0.dist-info/METADATA,sha256=npnFI6FByLQ8g8yaY8nzkCh84oIXX9D3e-ghhxeY7Lk,20638
246
+ instant_python-0.26.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
247
+ instant_python-0.26.0.dist-info/entry_points.txt,sha256=M8YUHQaTszBM3np_x9j7wmc1ngrmpfrd4ajBv2EzQuk,51
248
+ instant_python-0.26.0.dist-info/licenses/LICENSE,sha256=kf7wA-1IsqXkzXjlsG95sdQJtsqUON_lNXombfPlklo,11353
249
+ instant_python-0.26.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.31.0
2
+ Generator: hatchling 1.32.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any