lazy-bear 0.0.2.post1__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 (38) hide show
  1. lazy_bear-0.0.2.post1/.copier-answers.yml +19 -0
  2. lazy_bear-0.0.2.post1/.github/workflows/ci.yml +45 -0
  3. lazy_bear-0.0.2.post1/.github/workflows/release.yml +46 -0
  4. lazy_bear-0.0.2.post1/.gitignore +219 -0
  5. lazy_bear-0.0.2.post1/.python_version +1 -0
  6. lazy_bear-0.0.2.post1/CHANGELOG.md +8 -0
  7. lazy_bear-0.0.2.post1/PKG-INFO +91 -0
  8. lazy_bear-0.0.2.post1/README.md +82 -0
  9. lazy_bear-0.0.2.post1/config/coverage.ini +25 -0
  10. lazy_bear-0.0.2.post1/config/git-changelog.toml +9 -0
  11. lazy_bear-0.0.2.post1/config/lazy_bear/test.toml +4 -0
  12. lazy_bear-0.0.2.post1/config/pytest.ini +20 -0
  13. lazy_bear-0.0.2.post1/config/ruff.toml +142 -0
  14. lazy_bear-0.0.2.post1/directory_structure.xml +46 -0
  15. lazy_bear-0.0.2.post1/hatch_build.py +122 -0
  16. lazy_bear-0.0.2.post1/maskfile.md +121 -0
  17. lazy_bear-0.0.2.post1/noxfile.py +67 -0
  18. lazy_bear-0.0.2.post1/pyproject.toml +87 -0
  19. lazy_bear-0.0.2.post1/src/lazy_bear/__init__.py +13 -0
  20. lazy_bear-0.0.2.post1/src/lazy_bear/__main__.py +14 -0
  21. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/__init__.py +0 -0
  22. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/_cmds.py +49 -0
  23. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/_info.py +200 -0
  24. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/_version.pyi +6 -0
  25. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/_versioning.py +272 -0
  26. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/cli.py +45 -0
  27. lazy_bear-0.0.2.post1/src/lazy_bear/_internal/debug.py +101 -0
  28. lazy_bear-0.0.2.post1/src/lazy_bear/lazy_attribute.py +109 -0
  29. lazy_bear-0.0.2.post1/src/lazy_bear/lazy_imports.py +132 -0
  30. lazy_bear-0.0.2.post1/src/lazy_bear/py.typed +0 -0
  31. lazy_bear-0.0.2.post1/tests/__init__.py +7 -0
  32. lazy_bear-0.0.2.post1/tests/conftest.py +7 -0
  33. lazy_bear-0.0.2.post1/tests/test_api.py +140 -0
  34. lazy_bear-0.0.2.post1/tests/test_cli.py +94 -0
  35. lazy_bear-0.0.2.post1/tests/test_config.py +16 -0
  36. lazy_bear-0.0.2.post1/tests/test_lazy_attr.py +61 -0
  37. lazy_bear-0.0.2.post1/tests/test_lazy_imports.py +124 -0
  38. lazy_bear-0.0.2.post1/tests/test_misc_funcs.py +57 -0
@@ -0,0 +1,19 @@
1
+ # Changes here will be overwritten by Copier.
2
+ _commit: v0.3.3
3
+ _src_path: gh:sicksubroutine/python-template
4
+ author_email: bright.lid5647@fastmail.com
5
+ author_fullname: chaz
6
+ include_cli: true
7
+ include_docker: false
8
+ include_docs: false
9
+ include_fastapi: false
10
+ interactive_cli: false
11
+ minimum_python_version: '3.13'
12
+ project_description: A lazy import package for both modules and items within modules.
13
+ project_name: Lazy Bear
14
+ python_package_command_line_name: lazy-bear
15
+ python_package_distribution_name: lazy-bear
16
+ python_package_import_name: lazy_bear
17
+ setup_project: true
18
+ starting_version: 0.0.1
19
+
@@ -0,0 +1,45 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+ branches:
7
+ - main
8
+
9
+ defaults:
10
+ run:
11
+ shell: bash
12
+
13
+ env:
14
+ LANG: en_US.utf-8
15
+ LC_ALL: en_US.utf-8
16
+ PYTHONIOENCODING: UTF-8
17
+
18
+ jobs:
19
+ quality:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - name: Setup UV
24
+ uses: astral-sh/setup-uv@v5
25
+ with:
26
+ enable-cache: true
27
+ cache-dependency-glob: pyproject.toml
28
+ python-version: "3.13"
29
+
30
+ - name: Install Dependencies
31
+ run: |
32
+ uv sync
33
+ source .venv/bin/activate
34
+
35
+ - name: Install Nox
36
+ run: uv tool install nox
37
+
38
+ - name: Check the Code Quality
39
+ run: nox -s ruff_fix
40
+
41
+ - name: Check if the code is correctly typed
42
+ run: nox -s pyright
43
+
44
+ - name: Run Tests
45
+ run: pytest -v
@@ -0,0 +1,46 @@
1
+ name: release
2
+
3
+ on: push
4
+ permissions:
5
+ contents: write
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ if: startsWith(github.ref, 'refs/tags/')
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+ fetch-tags: true
17
+ #
18
+ token: ${{ secrets.GITHUB_TOKEN }}
19
+ #
20
+ name: Setup Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.13"
24
+ - name: Setup uv
25
+ uses: astral-sh/setup-uv@v5
26
+ - name: Update changelog
27
+ run: uv tool run git-changelog --config-file config/git-changelog.toml
28
+ - name: Commit updated changelog
29
+ run: |
30
+ git config --local user.email "action@github.com"
31
+ git config --local user.name "GitHub Action"
32
+ git add CHANGELOG.md
33
+ if git diff --staged --quiet; then
34
+ echo "No changelog changes to commit"
35
+ else
36
+ git commit -m "chore: update changelog for $(git describe --tags --abbrev=0)"
37
+ #
38
+ git push origin HEAD:${{ github.event.repository.default_branch }} || echo "Failed to push changelog update, but continuing with release"
39
+ #
40
+ fi
41
+ - name: Prepare release notes
42
+ run: uv tool run git-changelog --release-notes > release-notes.md
43
+ - name: Create release
44
+ uses: softprops/action-gh-release@v2
45
+ with:
46
+ body_path: release-notes.md
@@ -0,0 +1,219 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python,macos,shell
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,macos,shell
3
+
4
+ ### macOS ###
5
+ # General
6
+ .DS_Store
7
+ .AppleDouble
8
+ .LSOverride
9
+
10
+ # Icon must end with two \r
11
+ Icon
12
+
13
+
14
+ # Thumbnails
15
+ ._*
16
+
17
+ # Files that might appear in the root of a volume
18
+ .DocumentRevisions-V100
19
+ .fseventsd
20
+ .Spotlight-V100
21
+ .TemporaryItems
22
+ .Trashes
23
+ .VolumeIcon.icns
24
+ .com.apple.timemachine.donotpresent
25
+
26
+ # Directories potentially created on remote AFP share
27
+ .AppleDB
28
+ .AppleDesktop
29
+ Network Trash Folder
30
+ Temporary Items
31
+ .apdisk
32
+
33
+ ### macOS Patch ###
34
+ # iCloud generated files
35
+ *.icloud
36
+
37
+ ### Python ###
38
+ # Byte-compiled / optimized / DLL files
39
+ __pycache__/
40
+ *.py[cod]
41
+ *$py.class
42
+
43
+ # C extensions
44
+ *.so
45
+
46
+ # Distribution / packaging
47
+ .Python
48
+ build/
49
+ develop-eggs/
50
+ dist/
51
+ downloads/
52
+ eggs/
53
+ .eggs/
54
+ lib/
55
+ lib64/
56
+ parts/
57
+ sdist/
58
+ var/
59
+ wheels/
60
+ share/python-wheels/
61
+ *.egg-info/
62
+ .installed.cfg
63
+ *.egg
64
+ MANIFEST
65
+
66
+ # PyInstaller
67
+ # Usually these files are written by a python script from a template
68
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
69
+ *.manifest
70
+ *.spec
71
+
72
+ # Installer logs
73
+ pip-log.txt
74
+ pip-delete-this-directory.txt
75
+
76
+ # Unit test / coverage reports
77
+ htmlcov/
78
+ .tox/
79
+ .nox/
80
+ .coverage
81
+ .coverage.*
82
+ .cache
83
+ nosetests.xml
84
+ coverage.xml
85
+ *.cover
86
+ *.py,cover
87
+ .hypothesis/
88
+ .pytest_cache/
89
+ cover/
90
+
91
+ # Translations
92
+ *.mo
93
+ *.pot
94
+
95
+ # Django stuff:
96
+ *.log
97
+ local_settings.py
98
+ db.sqlite3
99
+ db.sqlite3-journal
100
+
101
+ # Flask stuff:
102
+ instance/
103
+ .webassets-cache
104
+
105
+ # Scrapy stuff:
106
+ .scrapy
107
+
108
+ # Sphinx documentation
109
+ docs/_build/
110
+
111
+ # PyBuilder
112
+ .pybuilder/
113
+ target/
114
+
115
+ # Jupyter Notebook
116
+ .ipynb_checkpoints
117
+
118
+ # IPython
119
+ profile_default/
120
+ ipython_config.py
121
+
122
+ # pyenv
123
+ # For a library or package, you might want to ignore these files since the code is
124
+ # intended to run in multiple environments; otherwise, check them in:
125
+ .python-version
126
+
127
+ # pipenv
128
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
129
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
130
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
131
+ # install all needed dependencies.
132
+ #Pipfile.lock
133
+
134
+ # poetry
135
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
136
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
137
+ # commonly ignored for libraries.
138
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
139
+ #poetry.lock
140
+
141
+ # pdm
142
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
143
+ #pdm.lock
144
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
145
+ # in version control.
146
+ # https://pdm.fming.dev/#use-with-ide
147
+ .pdm.toml
148
+
149
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
150
+ __pypackages__/
151
+
152
+ # Celery stuff
153
+ celerybeat-schedule
154
+ celerybeat.pid
155
+
156
+ # SageMath parsed files
157
+ *.sage.py
158
+
159
+ # Environments
160
+ .env
161
+ .venv
162
+ env/
163
+ venv/
164
+ ENV/
165
+ env.bak/
166
+ venv.bak/
167
+
168
+ # Spyder project settings
169
+ .spyderproject
170
+ .spyproject
171
+
172
+ # Rope project settings
173
+ .ropeproject
174
+
175
+ # mkdocs documentation
176
+ /site
177
+
178
+ # mypy
179
+ .mypy_cache/
180
+ .dmypy.json
181
+ dmypy.json
182
+ ``
183
+ # Pyre type checker
184
+ .pyre/
185
+
186
+ # pytype static type analyzer
187
+ .pytype/
188
+
189
+ # Cython debug symbols
190
+ cython_debug/
191
+
192
+ # PyCharm
193
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
194
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
195
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
196
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
197
+ .idea/
198
+
199
+ ### Python Patch ###
200
+ # Poetry local configuration file `
201
+
202
+ # ruff
203
+ .ruff_cache/
204
+
205
+ # LSP config files
206
+ pyrightconfig.json
207
+
208
+ .vscode/
209
+
210
+ *.db
211
+ *.log
212
+ **/_internal/_version.py
213
+ uv.lock
214
+
215
+ !/project/.vscode
216
+
217
+ **/prod.toml
218
+
219
+ **/reports
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
+
8
+ <!-- insertion marker -->
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.4
2
+ Name: lazy-bear
3
+ Version: 0.0.2.post1
4
+ Summary: A lazy import package for both modules and items within modules.
5
+ Author-email: chaz <bright.lid5647@fastmail.com>
6
+ Requires-Python: >=3.13
7
+ Requires-Dist: pydantic>=2.11.5
8
+ Description-Content-Type: text/markdown
9
+
10
+ # Lazy Bear
11
+
12
+ [![pypi version](https://img.shields.io/pypi/v/lazy-bear.svg)](https://pypi.org/project/lazy-bear/)
13
+ [![python](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/)
14
+
15
+ Lazy Bear is a lightweight toolkit for deferring Python imports until the first time you actually need them. Keep startup fast, trim optional dependencies, and expose a clean API without fighting `import` order.
16
+
17
+ ## Highlights
18
+
19
+ - Drop-in `lazy("package.module")` helper that mirrors a regular module object once touched.
20
+ - `LazyLoader.to()` and `LazyLoader.to_many()` for lazily binding one or more attributes without importing the whole module up front.
21
+ - `LazyAttr.value`/`LazyAttr.unwrap()` for grabbing the underlying attribute (dicts, constants, classes) without changing call semantics.
22
+ - Thread-safe module caching that updates `sys.modules` and the caller's globals exactly once.
23
+ - Debug-friendly repr and `dir()` support so interactive sessions stay intuitive even before loading.
24
+ - Batteries-included CLI with version info, environment diagnostics, and release bump helpers.
25
+
26
+ ## Installation
27
+
28
+ Requires Python 3.13 or newer.
29
+
30
+ ```bash
31
+ pip install lazy-bear
32
+ ```
33
+
34
+ With [`uv`](https://docs.astral.sh/uv/):
35
+
36
+ ```bash
37
+ uv tool install lazy-bear
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ```python
43
+ from lazy_bear import lazy
44
+
45
+ json = lazy("json") # nothing imported yet
46
+
47
+ payload = {"hello": "lazy bear"}
48
+ print(json.dumps(payload, sort_keys=True))
49
+ # Module is imported the first time .dumps is accessed.
50
+ ```
51
+
52
+ Under the hood `lazy()` returns a `LazyLoader` (a `types.ModuleType` subclass). Once you touch an attribute it:
53
+
54
+ 1. Imports the target module.
55
+ 2. Registers it in both `sys.modules` and the globals of the caller.
56
+ 3. Proxies the module so future access is indistinguishable from a normal import.
57
+
58
+ ## Lazily Accessing Attributes
59
+
60
+ Sometimes you only need a specific callable or attribute, not the whole module namespace:
61
+
62
+ ```python
63
+ from lazy_bear import LazyAttr, lazy
64
+
65
+ console = lazy("rich.console")
66
+ Console: LazyAttr = console.to("Console")
67
+
68
+ if __name__ == "__main__":
69
+ rich_console = Console(width=100) # `rich.console` is imported here
70
+ rich_console.print("[bold green]Hello from Lazy Bear![/]")
71
+ ```
72
+
73
+ Need multiple attributes or callables? Use `to_many`:
74
+
75
+ ```python
76
+ math = lazy("math")
77
+ sqrt_attr, pow_attr = math.to_many("sqrt", "pow")
78
+
79
+ print(sqrt_attr(25)) # LazyAttr stays callable
80
+ pow_func = pow_attr.value # or pow_attr.unwrap()
81
+ print(pow_func(2, 3))
82
+ ```
83
+
84
+ `LazyAttr` proxies most dunder methods (`__call__`, `__iter__`, `__getitem__`, etc.), so lazily loaded attributes behave just like the originals.
85
+
86
+ When you need the underlying object—say a dictionary of settings—forgo calling and reach for `.value` (or its alias `.unwrap()`):
87
+
88
+ ```python
89
+ env = lazy("os").to("environ").value # returns the real os._Environ mapping
90
+ letters = lazy("string").to("ascii_letters").unwrap() # works for constants too
91
+ ```
@@ -0,0 +1,82 @@
1
+ # Lazy Bear
2
+
3
+ [![pypi version](https://img.shields.io/pypi/v/lazy-bear.svg)](https://pypi.org/project/lazy-bear/)
4
+ [![python](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/)
5
+
6
+ Lazy Bear is a lightweight toolkit for deferring Python imports until the first time you actually need them. Keep startup fast, trim optional dependencies, and expose a clean API without fighting `import` order.
7
+
8
+ ## Highlights
9
+
10
+ - Drop-in `lazy("package.module")` helper that mirrors a regular module object once touched.
11
+ - `LazyLoader.to()` and `LazyLoader.to_many()` for lazily binding one or more attributes without importing the whole module up front.
12
+ - `LazyAttr.value`/`LazyAttr.unwrap()` for grabbing the underlying attribute (dicts, constants, classes) without changing call semantics.
13
+ - Thread-safe module caching that updates `sys.modules` and the caller's globals exactly once.
14
+ - Debug-friendly repr and `dir()` support so interactive sessions stay intuitive even before loading.
15
+ - Batteries-included CLI with version info, environment diagnostics, and release bump helpers.
16
+
17
+ ## Installation
18
+
19
+ Requires Python 3.13 or newer.
20
+
21
+ ```bash
22
+ pip install lazy-bear
23
+ ```
24
+
25
+ With [`uv`](https://docs.astral.sh/uv/):
26
+
27
+ ```bash
28
+ uv tool install lazy-bear
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```python
34
+ from lazy_bear import lazy
35
+
36
+ json = lazy("json") # nothing imported yet
37
+
38
+ payload = {"hello": "lazy bear"}
39
+ print(json.dumps(payload, sort_keys=True))
40
+ # Module is imported the first time .dumps is accessed.
41
+ ```
42
+
43
+ Under the hood `lazy()` returns a `LazyLoader` (a `types.ModuleType` subclass). Once you touch an attribute it:
44
+
45
+ 1. Imports the target module.
46
+ 2. Registers it in both `sys.modules` and the globals of the caller.
47
+ 3. Proxies the module so future access is indistinguishable from a normal import.
48
+
49
+ ## Lazily Accessing Attributes
50
+
51
+ Sometimes you only need a specific callable or attribute, not the whole module namespace:
52
+
53
+ ```python
54
+ from lazy_bear import LazyAttr, lazy
55
+
56
+ console = lazy("rich.console")
57
+ Console: LazyAttr = console.to("Console")
58
+
59
+ if __name__ == "__main__":
60
+ rich_console = Console(width=100) # `rich.console` is imported here
61
+ rich_console.print("[bold green]Hello from Lazy Bear![/]")
62
+ ```
63
+
64
+ Need multiple attributes or callables? Use `to_many`:
65
+
66
+ ```python
67
+ math = lazy("math")
68
+ sqrt_attr, pow_attr = math.to_many("sqrt", "pow")
69
+
70
+ print(sqrt_attr(25)) # LazyAttr stays callable
71
+ pow_func = pow_attr.value # or pow_attr.unwrap()
72
+ print(pow_func(2, 3))
73
+ ```
74
+
75
+ `LazyAttr` proxies most dunder methods (`__call__`, `__iter__`, `__getitem__`, etc.), so lazily loaded attributes behave just like the originals.
76
+
77
+ When you need the underlying object—say a dictionary of settings—forgo calling and reach for `.value` (or its alias `.unwrap()`):
78
+
79
+ ```python
80
+ env = lazy("os").to("environ").value # returns the real os._Environ mapping
81
+ letters = lazy("string").to("ascii_letters").unwrap() # works for constants too
82
+ ```
@@ -0,0 +1,25 @@
1
+ [coverage:run]
2
+ branch = true
3
+ parallel = true
4
+ source =
5
+ src/
6
+ tests/
7
+
8
+ [coverage:paths]
9
+ equivalent =
10
+ src/
11
+ .venv/lib/*/site-packages/
12
+ .venvs/*/lib/*/site-packages/
13
+
14
+ [coverage:report]
15
+ precision = 2
16
+ omit =
17
+ src/*/__init__.py
18
+ src/*/__main__.py
19
+ tests/__init__.py
20
+ exclude_lines =
21
+ pragma: no cover
22
+ if TYPE_CHECKING
23
+
24
+ [coverage:json]
25
+ output = htmlcov/coverage.json
@@ -0,0 +1,9 @@
1
+ bump = "auto"
2
+ convention = "angular"
3
+ in-place = true
4
+ output = "CHANGELOG.md"
5
+ parse-refs = false
6
+ parse-trailers = true
7
+ sections = ["build", "deps", "feat", "fix", "refactor"]
8
+ template = "keepachangelog"
9
+ versioning = "pep440"
@@ -0,0 +1,4 @@
1
+ [database]
2
+
3
+
4
+ [environment]
@@ -0,0 +1,20 @@
1
+ [pytest]
2
+ python_files =
3
+ test_*.py
4
+ asyncio_mode = auto
5
+ pythonpath = src
6
+ addopts =
7
+ -v
8
+ -s
9
+ --cov
10
+ --cov-config config/coverage.ini
11
+ --cov-report=html:reports/coverage_html
12
+ testpaths =
13
+ tests
14
+ filterwarnings =
15
+ ignore::DeprecationWarning
16
+ ignore::PendingDeprecationWarning
17
+ ignore::FutureWarning
18
+ ignore::ImportWarning
19
+ ignore::ResourceWarning
20
+ ignore::UserWarning