Skip to content

Commit

Permalink
feat: parallel dependencies resolving (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lancetnik authored Jan 9, 2024
1 parent db6318b commit 114c463
Show file tree
Hide file tree
Showing 16 changed files with 387 additions and 193 deletions.
43 changes: 9 additions & 34 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.

### Virtual environment with `venv`
## Virtual environment with `venv`

You can create a virtual environment in a directory using Python's `venv` module:

Expand All @@ -12,20 +12,21 @@ python -m venv venv

That will create a directory `./venv/` with the Python binaries and then you will be able to install packages for that isolated environment.

### Activate the environment
## Activate the environment

Activate the new environment with:

```bash
source ./venv/bin/activate
```

Make sure you have the latest pip version on your virtual environment to
Make sure you have the latest pip version on your virtual environment to

```bash
python -m pip install --upgrade pip
```

### pip
## pip

After activating the environment as described above:

Expand All @@ -35,17 +36,18 @@ pip install -e ."[dev]"

It will install all the dependencies and your local FastDepends in your local environment.

#### Using your local FastDepends
### Using your local FastDepends

If you create a Python file that imports and uses FastDepends, and run it with the Python from your local environment, it will use your local FastDepends source code.

And if you update that local FastDepends source code, as it is installed with `-e`, when you run that Python file again, it will use the fresh version of FastDepends you just edited.

That way, you don't have to "install" your local version to be able to test every change.

### Tests
## Tests

### Pytests

#### Pytests
To run tests with your current FastDepends application and Python environment use:

```bash
Expand All @@ -55,30 +57,3 @@ bash ./scripts/test.sh
# with coverage output
bash ./scripts/test-cov.sh
```

#### Hatch

If you are using **hatch** use following environments to run tests:

##### **TEST**

Run tests at all python 3.8-3.12 versions.

All python versions should be avalilable at your system.

```bash
# Run test at all python 3.8-3.12 versions
hatch run test:run
```

##### **TEST-LAST**

Run tests at python 3.12 version.

```bash
# Run tests at python 3.12
hatch run test-last:run

# Run all tests at python 3.12 and show coverage
hatch run test-last:cov
```
3 changes: 1 addition & 2 deletions docs/docs/alternatives.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Key features:
* Composable: decoupled internal APIs give you the flixibility to customize wiring, execution and binding.
* Performant: `di` can execute dependencies in parallel and cache results ins scopes.


## [Dependency Injector](https://python-dependency-injector.etc-labs.org)

Dependency Injector is a dependency injection framework for Python.
Expand All @@ -37,4 +36,4 @@ Key features:
* Asynchronous
* Typing
* Perfomance
* Maturity
* Maturity
43 changes: 9 additions & 34 deletions docs/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.

### Virtual environment with `venv`
## Virtual environment with `venv`

You can create a virtual environment in a directory using Python's `venv` module:

Expand All @@ -12,20 +12,21 @@ python -m venv venv

That will create a directory `./venv/` with the Python binaries and then you will be able to install packages for that isolated environment.

### Activate the environment
## Activate the environment

Activate the new environment with:

```bash
source ./venv/bin/activate
```

Make sure you have the latest pip version on your virtual environment to
Make sure you have the latest pip version on your virtual environment to

```bash
python -m pip install --upgrade pip
```

### pip
## pip

After activating the environment as described above:

Expand All @@ -35,17 +36,18 @@ pip install -e ."[dev]"

It will install all the dependencies and your local FastDepends in your local environment.

#### Using your local FastDepends
### Using your local FastDepends

If you create a Python file that imports and uses FastDepends, and run it with the Python from your local environment, it will use your local FastDepends source code.

And if you update that local FastDepends source code, as it is installed with `-e`, when you run that Python file again, it will use the fresh version of FastDepends you just edited.

That way, you don't have to "install" your local version to be able to test every change.

### Tests
## Tests

### Pytests

#### Pytests
To run tests with your current FastDepends application and Python environment use:

```bash
Expand All @@ -55,30 +57,3 @@ bash ./scripts/test.sh
# with coverage output
bash ./scripts/test-cov.sh
```

#### Hatch

If you are using **hatch** use following environments to run tests:

##### **TEST**

Run tests at all python 3.8-3.12 versions.

All python versions should be avalilable at your system.

```bash
# Run test at all python 3.8-3.12 versions
hatch run test:run
```

##### **TEST-LAST**

Run tests at python 3.12 version.

```bash
# Run tests at python 3.12
hatch run test-last:run

# Run all tests at python 3.12 and show coverage
hatch run test-last:cov
```
2 changes: 1 addition & 1 deletion fast_depends/__about__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""FastDepends - extracted and cleared from HTTP domain FastAPI Dependency Injection System"""

__version__ = "2.2.8"
__version__ = "2.3.0"
14 changes: 14 additions & 0 deletions fast_depends/_compat.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys
from importlib.metadata import version as get_version
from typing import Any, Dict, Optional, Type

from pydantic import BaseModel, create_model
Expand All @@ -12,6 +14,7 @@
"get_config_base",
"get_model_fields",
"ConfigDict",
"ExceptionGroup",
)


Expand Down Expand Up @@ -55,3 +58,14 @@ class CreateBaseModel(BaseModel): # type: ignore[no-redef]

class Config:
arbitrary_types_allowed = True


ANYIO_V3 = get_version("anyio").startswith("3.")

if ANYIO_V3:
from anyio import ExceptionGroup as ExceptionGroup
else:
if sys.version_info < (3, 11):
from exceptiongroup import ExceptionGroup as ExceptionGroup
else:
ExceptionGroup = ExceptionGroup
17 changes: 14 additions & 3 deletions fast_depends/core/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
Annotated,
ParamSpec,
TypeVar,
assert_never,
get_args,
get_origin,
)
Expand All @@ -25,7 +24,12 @@
from fast_depends.core.model import CallModel, ResponseModel
from fast_depends.dependencies import Depends
from fast_depends.library import CustomField
from fast_depends.utils import get_typed_signature, is_coroutine_callable
from fast_depends.utils import (
get_typed_signature,
is_async_gen_callable,
is_coroutine_callable,
is_gen_callable,
)

CUSTOM_ANNOTATIONS = (Depends, CustomField)

Expand Down Expand Up @@ -57,6 +61,12 @@ def build_call_model(
), f"You cannot use async dependency `{name}` at sync main"

typed_params, return_annotation = get_typed_signature(call)
if (
(is_call_generator := is_gen_callable(call) or
is_async_gen_callable(call)) and
(return_args := get_args(return_annotation))
):
return_annotation = return_args[0]

class_fields: Dict[str, Tuple[Any, Any]] = {}
dependencies: Dict[str, "CallModel[..., Any]"] = {}
Expand Down Expand Up @@ -89,7 +99,7 @@ def build_call_model(
elif isinstance(next_custom, CustomField):
custom = next_custom
else: # pragma: no cover
assert_never()
raise AssertionError("unreachable")

annotation = type_annotation
else:
Expand Down Expand Up @@ -185,6 +195,7 @@ def build_call_model(
cast=cast,
use_cache=use_cache,
is_async=is_call_async,
is_generator=is_call_generator,
dependencies=dependencies,
custom_fields=custom_fields,
positional_args=positional_args,
Expand Down
Loading

0 comments on commit 114c463

Please sign in to comment.