Skip to content

Commit

Permalink
Better linting (#12)
Browse files Browse the repository at this point in the history
* misc lint improvements

* just use ruff

* more lint fixes

* fix test

* fix project scripts

* fix lint
  • Loading branch information
rmorshea authored Nov 20, 2024
1 parent 233d847 commit 3054af8
Show file tree
Hide file tree
Showing 19 changed files with 673 additions and 349 deletions.
129 changes: 64 additions & 65 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -1,68 +1,67 @@
---
name: Python package

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

push:
branches: [main]
pull_request:
branches: [main]
jobs:
check-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up UV cache
if: runner.os == 'Linux'
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }}
restore-keys: ${{ runner.os }}-uv-
- name: Install UV
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Run tests
run: uv run project.py test cov --no-report
- name: Run lint
run: uv run project.py lint style types
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}
path: ${{ github.workspace }}/.coverage
include-hidden-files: true
- name: Build dist
run: uv build
check-coverage:
runs-on: ubuntu-latest
needs: check-tests
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50
- name: Set up UV cache
if: runner.os == 'Linux'
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }}
restore-keys: ${{ runner.os }}-uv-
- name: Download coverage
uses: actions/download-artifact@v4
with:
name: coverage-3.12
- run: git fetch origin main
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install UV
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Check coverage
run: uv run project.py test cov --no-test
check-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up UV cache
if: runner.os == 'Linux'
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }}
restore-keys: ${{ runner.os }}-uv-
- name: Install UV
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Run tests
run: uv run project.py cov --no-report
- name: Run lint
run: uv run project.py lint
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}
path: ${{ github.workspace }}/.coverage
include-hidden-files: true
- name: Build dist
run: uv build
check-coverage:
runs-on: ubuntu-latest
needs: check-tests
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50
- name: Set up UV cache
if: runner.os == 'Linux'
uses: actions/cache@v3
with:
path: ~/.cache/uv
key: ${{ runner.os }}-uv-${{ hashFiles('pyproject.toml') }}
restore-keys: ${{ runner.os }}-uv-
- name: Download coverage
uses: actions/download-artifact@v4
with:
name: coverage-3.12
- run: git fetch origin main
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install UV
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Check coverage
run: uv run project.py cov --no-test
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pip install -U pybooster
Getting started with PyBooster involves a few steps:

1. Define a [provider](https://ryanmorshead.com/pybooster/features#providers) function
for a [dependency](https://ryanmorshead.com/pybooster/features#dependencies).
2. Add an [injector](https://ryanmorshead.com/pybooster/features#injectors) to a
function that will use that dependency.
3. Enter the
[provider's scope](https://ryanmorshead.com/pybooster/features#scoping-providers) and
call the dependent function in it.
for a [dependency](https://ryanmorshead.com/pybooster/features#dependencies).
1. Add an [injector](https://ryanmorshead.com/pybooster/features#injectors) to a
function that will use that dependency.
1. Enter the
[provider's scope](https://ryanmorshead.com/pybooster/features#scoping-providers) and
call the dependent function in it.

The example below injects a `sqlite3.Connection` into a function that executes a query:

Expand Down
138 changes: 66 additions & 72 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,83 +1,77 @@
---
site_author: Ryan Morshead
site_description: A modern dependency injection framework for Python.
site_name: PyBooster
docs_dir: src

repo_url: https://github.com/rmorshea/pybooster

nav:
- Home: index.md
- Concepts: concepts.md
- Recipes: recipes.md
- Integrations: integrations.md
- Examples: examples.md
- Reference: reference.md

- Home: index.md
- Concepts: concepts.md
- Recipes: recipes.md
- Integrations: integrations.md
- Examples: examples.md
- Reference: reference.md
theme:
name: material
icon:
repo: fontawesome/brands/git-alt
logo: material/needle
features:
- content.code.copy
palette:
# Palette toggle for automatic mode
- media: "(prefers-color-scheme)"
toggle:
icon: material/brightness-auto
name: Switch to light mode
name: material
icon:
repo: fontawesome/brands/git-alt
logo: material/needle
features: [content.code.copy, toc.integrate]
palette:
# Palette toggle for automatic mode
- media: (prefers-color-scheme)
toggle:
icon: material/brightness-auto
name: Switch to light mode
# Palette toggle for light mode
- media: "(prefers-color-scheme: light)"
scheme: default
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: '(prefers-color-scheme: light)'
scheme: default
toggle:
icon: material/brightness-7
name: Switch to dark mode
# Palette toggle for dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to system preference

- media: '(prefers-color-scheme: dark)'
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to system preference
plugins:
- search
- open-in-new-tab
- mkdocstrings:
handlers:
python:
import:
- https://docs.sqlalchemy.org/en/latest/objects.inv
options:
load_external_modules: true
docstring_style: google
members_order: alphabetical
merge_init_into_class: true
separate_signature: true
show_labels: false
show_object_full_path: true
show_root_heading: true
show_signature_annotations: true
show_source: true
show_submodules: true
show_symbol_type_heading: true
show_symbol_type_toc: true
signature_crossrefs: true

- search
- open-in-new-tab
- mkdocstrings:
handlers:
python:
import: [https://docs.sqlalchemy.org/en/latest/objects.inv]
options:
load_external_modules: true
docstring_style: google
members_order: alphabetical
merge_init_into_class: true
separate_signature: true
show_labels: false
show_object_full_path: true
show_root_heading: true
show_signature_annotations: true
show_source: true
show_submodules: true
show_symbol_type_heading: true
show_symbol_type_toc: true
signature_crossrefs: true
markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- admonition
- pymdownx.details
- pymdownx.superfences
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
36 changes: 11 additions & 25 deletions docs/src/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def get_message(*, recipient: Recipient = required) -> str:
```

!!! warning

Don't forget to add the `required` default value. Without it, PyBooster will not
know that the argument is a dependency that needs to be injected.

Expand Down Expand Up @@ -129,12 +128,12 @@ with solution(recipient_provider):

PyBooster supports decorators for the following types of functions or methods:

- [`injector.function`][pybooster.core.injector.function]
- [`injector.iterator`][pybooster.core.injector.iterator]
- [`injector.contextmanager`][pybooster.core.injector.contextmanager]
- [`injector.asyncfunction`][pybooster.core.injector.asyncfunction]
- [`injector.asynciterator`][pybooster.core.injector.asynciterator]
- [`injector.asynccontextmanager`][pybooster.core.injector.asynccontextmanager]
- [`injector.function`][pybooster.core.injector.function]
- [`injector.iterator`][pybooster.core.injector.iterator]
- [`injector.contextmanager`][pybooster.core.injector.contextmanager]
- [`injector.asyncfunction`][pybooster.core.injector.asyncfunction]
- [`injector.asynciterator`][pybooster.core.injector.asynciterator]
- [`injector.asynccontextmanager`][pybooster.core.injector.asynccontextmanager]

#### Overwrite Parameters

Expand Down Expand Up @@ -178,9 +177,7 @@ def profile_provider(*, user_id: UserId = required) -> Profile:


@injector.function
def get_profile_summary(
*, user_id: UserId = required, profile: Profile = required
) -> str:
def get_profile_summary(*, user_id: UserId = required, profile: Profile = required) -> str:
return f"#{user_id} {profile.name}: {profile.bio}"


Expand Down Expand Up @@ -247,7 +244,6 @@ def get_auth(*, auth: Auth = required) -> Auth:


with solution(auth):

assert get_auth() is not get_auth()

with injector.current(Auth) as auth:
Expand Down Expand Up @@ -296,9 +292,7 @@ def profile_provider(*, user_id: UserId = required) -> Profile:


@injector.function
def get_profile_summary(
*, user_id: UserId = required, profile: Profile = required
) -> str:
def get_profile_summary(*, user_id: UserId = required, profile: Profile = required) -> str:
return f"#{user_id} {profile.name}: {profile.bio}"


Expand Down Expand Up @@ -430,7 +424,6 @@ with solution(sqlite_connection.bind(":memory:")):
```

!!! note

Bindable parameters are not allowed to be dependencies.

### Generic Providers
Expand Down Expand Up @@ -474,9 +467,7 @@ def get_config(*, config: ConfigDict = required) -> ConfigDict:

tempfile = NamedTemporaryFile()
json_file = Path(tempfile.name)
json_file.write_text(
'{"app_name": "MyApp", "app_version": 1, "debug_mode": true}'
)
json_file.write_text('{"app_name": "MyApp", "app_version": 1, "debug_mode": true}')

with solution(json_provider[ConfigDict].bind(json_file)):
assert get_config() == {
Expand Down Expand Up @@ -535,18 +526,13 @@ def get_config(*, config: Config = required) -> Config:

tempfile = NamedTemporaryFile()
json_file = Path(tempfile.name)
json_file.write_text(
'{"app_name": "MyApp", "app_version": 1, "debug_mode": true}'
)
json_file.write_text('{"app_name": "MyApp", "app_version": 1, "debug_mode": true}')

with solution(config_file_provider.bind(Config, json_file)):
assert get_config() == Config(
app_name="MyApp", app_version=1, debug_mode=True
)
assert get_config() == Config(app_name="MyApp", app_version=1, debug_mode=True)
```

!!! tip

This approach also works great for a provider that has `overload` implementations.

### Singleton Providers
Expand Down
Loading

0 comments on commit 3054af8

Please sign in to comment.