mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-08 04:54:48 +08:00
Merge pull request #23 from syastrov/better-types-for-transaction-atomic
Add better typings plus test for transaction.atomic.
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
from contextlib import ContextDecorator
|
from typing import Any, Callable, Optional, overload, TypeVar
|
||||||
from typing import Any, Callable, Optional, Union, Iterator, overload, ContextManager
|
|
||||||
|
|
||||||
from django.db import ProgrammingError
|
from django.db import ProgrammingError
|
||||||
|
|
||||||
@@ -18,19 +17,23 @@ def get_rollback(using: None = ...) -> bool: ...
|
|||||||
def set_rollback(rollback: bool, using: Optional[str] = ...) -> None: ...
|
def set_rollback(rollback: bool, using: Optional[str] = ...) -> None: ...
|
||||||
def on_commit(func: Callable, using: None = ...) -> None: ...
|
def on_commit(func: Callable, using: None = ...) -> None: ...
|
||||||
|
|
||||||
class Atomic(ContextDecorator):
|
_C = TypeVar("_C", bound=Callable) # Any callable
|
||||||
|
|
||||||
|
# Don't inherit from ContextDecorator, so we can provide a more specific signature for __call__
|
||||||
|
class Atomic:
|
||||||
using: Optional[str] = ...
|
using: Optional[str] = ...
|
||||||
savepoint: bool = ...
|
savepoint: bool = ...
|
||||||
def __init__(self, using: Optional[str], savepoint: bool) -> None: ...
|
def __init__(self, using: Optional[str], savepoint: bool) -> None: ...
|
||||||
|
# When decorating, return the decorated function as-is, rather than clobbering it as ContextDecorator does.
|
||||||
|
def __call__(self, func: _C) -> _C: ...
|
||||||
def __enter__(self) -> None: ...
|
def __enter__(self) -> None: ...
|
||||||
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
|
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
|
||||||
|
|
||||||
|
# Bare decorator
|
||||||
@overload
|
@overload
|
||||||
def atomic() -> Atomic: ...
|
def atomic(using: _C) -> _C: ...
|
||||||
|
|
||||||
|
# Decorator or context-manager with parameters
|
||||||
@overload
|
@overload
|
||||||
def atomic(using: Optional[str] = ...,) -> ContextManager[Atomic]: ...
|
def atomic(using: Optional[str] = None, savepoint: bool = True) -> Atomic: ...
|
||||||
@overload
|
|
||||||
def atomic(using: Callable = ...) -> Callable: ...
|
|
||||||
@overload
|
|
||||||
def atomic(using: Optional[str] = ..., savepoint: bool = ...) -> ContextManager[Atomic]: ...
|
|
||||||
def non_atomic_requests(using: Callable = ...) -> Callable: ...
|
def non_atomic_requests(using: Callable = ...) -> Callable: ...
|
||||||
|
|||||||
50
test-data/typecheck/transaction.test
Normal file
50
test-data/typecheck/transaction.test
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
[CASE test_transaction_atomic]
|
||||||
|
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
pass
|
||||||
|
|
||||||
|
with transaction.atomic(using="mydb"):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with transaction.atomic(using="mydb", savepoint=False):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic()
|
||||||
|
def decorated_func(param1: str, param2: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Ensure that the function's type is preserved
|
||||||
|
reveal_type(decorated_func) # E: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||||
|
|
||||||
|
@transaction.atomic(using="mydb")
|
||||||
|
def decorated_func_using(param1: str, param2: int) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Ensure that the function's type is preserved
|
||||||
|
reveal_type(decorated_func_using) # E: Revealed type is 'def (param1: builtins.str, param2: builtins.int) -> builtins.bool'
|
||||||
|
|
||||||
|
class ClassWithAtomicMethod:
|
||||||
|
# Bare decorator
|
||||||
|
@transaction.atomic
|
||||||
|
def atomic_method1(self, abc: int) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic(savepoint=True)
|
||||||
|
def atomic_method2(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@transaction.atomic(using="db", savepoint=True)
|
||||||
|
def atomic_method3(self, myparam: str) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
ClassWithAtomicMethod().atomic_method1("abc") # E: Argument 1 to "atomic_method1" of "ClassWithAtomicMethod" has incompatible type "str"; expected "int"
|
||||||
|
|
||||||
|
# Ensure that the method's type is preserved
|
||||||
|
reveal_type(ClassWithAtomicMethod().atomic_method1) # E: Revealed type is 'def (abc: builtins.int) -> builtins.str'
|
||||||
|
|
||||||
|
# Ensure that the method's type is preserved
|
||||||
|
reveal_type(ClassWithAtomicMethod().atomic_method3) # E: Revealed type is 'def (myparam: builtins.str) -> builtins.int'
|
||||||
|
|
||||||
|
[out]
|
||||||
Reference in New Issue
Block a user