-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added missing docstrings; fixed type hints; fixed issues detected by …
…pylint; run pre-commit auto refactor
- Loading branch information
1 parent
9ba89e5
commit 5fd802f
Showing
13 changed files
with
158 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,59 @@ | ||
import ast | ||
from typing import Iterable | ||
|
||
from typing import Sequence, TypeVar | ||
from typing_extensions import Self | ||
from pydantic import BaseModel | ||
from typing_extensions import Self, TypeAlias | ||
|
||
from dbally.context.exceptions import ContextNotAvailableError | ||
|
||
|
||
CustomContext = TypeVar('CustomContext', bound='BaseCallerContext', covariant=True) | ||
CustomContextsList = Sequence[CustomContext] # TODO confirm the naming | ||
# CustomContext = TypeVar('CustomContext', bound='BaseCallerContext', covariant=True) | ||
CustomContext: TypeAlias = "BaseCallerContext" | ||
|
||
|
||
class BaseCallerContext(BaseModel): | ||
""" | ||
Base class for contexts that are used to pass additional knowledge about the caller environment to the filters. It is not made abstract for the convinience of IQL parsing. | ||
LLM will always return `BaseCallerContext()` when the context is required and this call will be later substitue by a proper subclass instance selected based on the filter method signature (type hints). | ||
Pydantic-based record class. Base class for contexts that are used to pass additional knowledge about | ||
the caller environment to the filters. It is not made abstract for the convinience of IQL parsing. | ||
LLM will always return `BaseCallerContext()` when the context is required and this call will be | ||
later substituted by a proper subclass instance selected based on the filter method signature (type hints). | ||
""" | ||
|
||
@classmethod | ||
def select_context(cls, contexts: CustomContextsList) -> Self: | ||
def select_context(cls, contexts: Iterable[CustomContext]) -> Self: | ||
""" | ||
Typically called from a subclass of BaseCallerContext, selects a member object from `contexts` being | ||
an instance of the same class. Effectively provides a type dispatch mechanism, substituting the context | ||
class by its right instance. | ||
Args: | ||
contexts: A sequence of objects, each being an instance of a different BaseCallerContext subclass. | ||
Returns: | ||
An instance of the same BaseCallerContext subclass this method is caller from. | ||
Raises: | ||
ContextNotAvailableError: If the sequence of context objects passed as argument is empty. | ||
""" | ||
|
||
if not contexts: | ||
raise ContextNotAvailableError("The LLM detected that the context is required to execute the query and the filter signature allows contextualization while the context was not provided.") | ||
raise ContextNotAvailableError( | ||
"The LLM detected that the context is required to execute the query +\ | ||
and the filter signature allows contextualization while the context was not provided." | ||
) | ||
|
||
# this method is called from the subclass of BaseCallerContext pointing the right type of custom context | ||
return next(filter(lambda obj: isinstance(obj, cls), contexts)) | ||
# TODO confirm whether it is possible to design a correct type hints here and skipping `type: ignore` | ||
return next(filter(lambda obj: isinstance(obj, cls), contexts)) # type: ignore | ||
|
||
@classmethod | ||
def is_context_call(cls, node: ast.expr) -> bool: | ||
""" | ||
Verifies whether an AST node indicates context substitution. | ||
Args: | ||
node: An AST node (expression) to verify: | ||
Returns: | ||
Verification result. | ||
""" | ||
|
||
return isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == cls.__name__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.