Skip to content

Commit f9abac4

Browse files
authored
Contrib stubs (#206)
Hello, I added several files with annotations, updated the Celery class to the current release, and expanded the readme a bit. This also closes: #86 #112
1 parent ac14596 commit f9abac4

File tree

16 files changed

+1219
-88
lines changed

16 files changed

+1219
-88
lines changed

.vscode/extensions.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"recommendations": [
3+
"charliermarsh.ruff",
4+
"detachhead.basedpyright"
5+
]
6+
}

README.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
# celery-types [![PyPI](https://img.shields.io/pypi/v/celery-types.svg)](https://pypi.org/project/celery-types/)
1+
# celery-types
2+
[![PyPI](https://img.shields.io/pypi/v/celery-types.svg)](https://pypi.org/project/celery-types/)
3+
[![Downloads](https://static.pepy.tech/personalized-badge/celery-types?period=month&units=international_system&left_color=black&right_color=orange&left_text=PyPI%20downloads%20per%20month)](https://pepy.tech/project/celery-types)
4+
![PyPI - Types](https://img.shields.io/pypi/types/celery-types)
5+
[![image](https://img.shields.io/pypi/pyversions/celery-types.svg)](https://pypi.python.org/pypi/celery-types)
6+
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
7+
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
8+
29

310
Type stubs for celery related projects:
411

@@ -16,11 +23,35 @@ Type stubs for celery related projects:
1623
pip install celery-types
1724
```
1825

19-
You'll also need to monkey patch `Task` so generic params can be provided:
26+
You'll also need to monkey patch the classes from the example below (you can delete anything you don't intend to use) so generic params can be provided:
2027

2128
```python
29+
from celery import Celery, Signature
2230
from celery.app.task import Task
23-
Task.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls) # type: ignore[attr-defined]
31+
from celery.contrib.abortable import AbortableAsyncResult, AbortableTask
32+
from celery.contrib.django.task import DjangoTask
33+
from celery.local import class_property
34+
from celery.result import AsyncResult
35+
from celery.utils.objects import FallbackContext
36+
37+
classes = [
38+
Celery,
39+
Task,
40+
DjangoTask,
41+
AbortableTask,
42+
AsyncResult,
43+
AbortableAsyncResult,
44+
Signature,
45+
FallbackContext,
46+
class_property,
47+
]
48+
49+
for cls in classes:
50+
setattr( # noqa: B010
51+
cls,
52+
"__class_getitem__",
53+
classmethod(lambda cls, *args, **kwargs: cls),
54+
)
2455
```
2556

2657
## dev

billiard-stubs/process.pyi

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
__all__ = ["BaseProcess", "Process"]
1+
from collections.abc import Callable
2+
3+
__all__ = ["BaseProcess", "Process", "active_children", "current_process"]
4+
5+
def current_process() -> BaseProcess: ...
6+
def active_children(_cleanup: Callable[[], None] = ...) -> list[BaseProcess]: ...
27

38
class BaseProcess:
9+
name: str
410
def __init__(
511
self,
612
) -> None: ...
@@ -9,6 +15,25 @@ class BaseProcess:
915
def close(self) -> None: ...
1016
def terminate(self) -> None: ...
1117
def terminate_controlled(self) -> None: ...
18+
def join(self, timeout: int | None = None) -> None: ...
19+
def is_alive(self) -> bool: ...
20+
@property
21+
def daemon(self) -> bool: ...
22+
@daemon.setter
23+
def daemon(self, name: bool) -> None: ...
24+
@property
25+
def authkey(self) -> AuthenticationString: ...
26+
@authkey.setter
27+
def authkey(self, authkey: AuthenticationString) -> None: ...
28+
@property
29+
def exitcode(self) -> int | None: ...
30+
@property
31+
def ident(self) -> int | None: ...
32+
33+
pid = ident
34+
35+
@property
36+
def sentinel(self) -> int: ...
1237

1338
class AuthenticationString(bytes): ...
1439

celery-stubs/app/base.pyi

Lines changed: 117 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ from celery.worker import WorkController as CeleryWorkController
3636
from typing_extensions import ParamSpec, Self, TypeVar
3737

3838
_T = TypeVar("_T", bound=CeleryTask[Any, Any])
39+
_T_1 = TypeVar("_T_1")
3940
_T_Global = TypeVar(
4041
"_T_Global",
4142
bound=CeleryTask[Any, Any],
@@ -51,27 +52,28 @@ class Celery(Generic[_T_Global]):
5152
on_after_configure: Signal
5253
on_after_finalize: Signal
5354
on_after_fork: Signal
55+
5456
def __init__(
5557
self,
56-
main: str | None = ...,
57-
loader: Any | None = ...,
58-
backend: str | type[Backend] | None = ...,
59-
amqp: str | type[AMQP] | None = ...,
60-
events: str | type[celery.app.events.Events] | None = ...,
61-
log: str | type[Logging] | None = ...,
62-
control: str | type[celery.app.control.Control] | None = ...,
63-
set_as_current: bool = ...,
64-
tasks: str | type[TaskRegistry] | None = ...,
65-
broker: str | None = ...,
66-
imports: list[str] | tuple[str, ...] | None = ...,
67-
include: list[str] | tuple[str, ...] | None = ...,
68-
changes: dict[str, Any] | None = ...,
69-
config_source: str | object | None = ...,
70-
fixups: list[str] | None = ...,
71-
task_cls: str | type[_T_Global] | None = ...,
72-
autofinalize: bool = ...,
73-
namespace: str | None = ...,
74-
strict_typing: bool = ...,
58+
main: str | None = None,
59+
loader: Any | None = None,
60+
backend: str | type[Backend] | None = None,
61+
amqp: str | type[AMQP] | None = None,
62+
events: str | type[celery.app.events.Events] | None = None,
63+
log: str | type[Logging] | None = None,
64+
control: str | type[celery.app.control.Control] | None = None,
65+
set_as_current: bool = True,
66+
tasks: str | type[TaskRegistry] | None = None,
67+
broker: str | None = None,
68+
imports: list[str] | tuple[str, ...] | None = None,
69+
include: list[str] | tuple[str, ...] | None = None,
70+
changes: dict[str, Any] | None = None,
71+
config_source: str | object | None = None,
72+
fixups: list[str] | None = None,
73+
task_cls: str | type[_T_Global] | None = None,
74+
autofinalize: bool = True,
75+
namespace: str | None = None,
76+
strict_typing: bool = True,
7577
broker_connection_retry: bool = ...,
7678
broker_connection_max_retries: int = ...,
7779
broker_channel_error_retry: bool = ...,
@@ -151,8 +153,8 @@ class Celery(Generic[_T_Global]):
151153
def set_current(self) -> None: ...
152154
def set_default(self) -> None: ...
153155
def close(self) -> None: ...
154-
def start(self, argv: list[str] | None = ...) -> NoReturn: ...
155-
def worker_main(self, argv: list[str] | None = ...) -> NoReturn: ...
156+
def start(self, argv: list[str] | None = None) -> NoReturn: ...
157+
def worker_main(self, argv: list[str] | None = None) -> NoReturn: ...
156158
@overload
157159
def task(self, fun: Callable[_P, _R]) -> _T_Global: ...
158160
@overload
@@ -275,115 +277,147 @@ class Celery(Generic[_T_Global]):
275277
on_retry: Callable[..., Any] = ...,
276278
**options: Any,
277279
) -> Callable[[Callable[Concatenate[_T_Global, _P], _R]], _T_Global]: ...
278-
def register_task(self, task: _T | type[_T], **options: Any) -> _T: ...
280+
def type_checker(
281+
self, fun: Callable[_P, _T_1], bound: bool = False
282+
) -> Callable[_P, _T_1]: ...
283+
def register_task(
284+
self,
285+
task: _T | type[_T],
286+
*,
287+
autoretry_for: Sequence[type[BaseException]] = ...,
288+
dont_autoretry_for: Sequence[type[BaseException]] = ...,
289+
retry_kwargs: dict[str, Any] = ...,
290+
retry_backoff: bool | int = ...,
291+
retry_backoff_max: int = ...,
292+
retry_jitter: bool = ...,
293+
) -> _T: ...
279294
def gen_task_name(self, name: str, module: str) -> str: ...
280-
def finalize(self, auto: bool = ...) -> None: ...
295+
def finalize(self, auto: bool = False) -> None: ...
281296
def add_defaults(self, fun: Callable[[], dict[str, Any]]) -> None: ...
282297
def config_from_object(
283298
self,
284299
obj: Any,
285-
silent: bool = ...,
286-
force: bool = ...,
287-
namespace: str | None = ...,
300+
silent: bool = False,
301+
force: bool = False,
302+
namespace: str | None = None,
288303
) -> Settings: ...
289304
def config_from_envvar(
290-
self, variable_name: str, silent: bool = ..., force: bool = ...
305+
self, variable_name: str, silent: bool = False, force: bool = False
306+
) -> None: ...
307+
def config_from_cmdline(
308+
self, argv: list[str], namespace: str = "celery"
291309
) -> None: ...
292-
def config_from_cmdline(self, argv: list[str], namespace: str = ...) -> None: ...
293310
def setup_security(
294311
self,
295-
allowed_serializers: set[str] | None = ...,
296-
key: str | None = ...,
297-
cert: str | None = ...,
298-
store: str | None = ...,
312+
allowed_serializers: set[str] | None = None,
313+
key: str | None = None,
314+
cert: str | None = None,
315+
store: str | None = None,
299316
digest: str = ...,
300-
serializer: str = ...,
317+
serializer: str = "json",
301318
) -> None: ...
302319
def autodiscover_tasks(
303320
self,
304-
packages: list[str] | Callable[[], list[str]] | None = ...,
305-
related_name: str = ...,
306-
force: bool = ...,
321+
packages: list[str] | Callable[[], list[str]] | None = None,
322+
related_name: str = "tasks",
323+
force: bool = False,
307324
) -> None: ...
308325
def send_task(
309326
self,
310327
name: str,
311-
args: Sequence[Any] | None = ...,
312-
kwargs: dict[str, Any] | None = ...,
313-
countdown: float | None = ...,
314-
eta: datetime.datetime | None = ...,
315-
task_id: str | None = ...,
316-
producer: kombu.Producer | None = ...,
317-
connection: kombu.Connection | None = ...,
318-
router: Router | None = ...,
319-
result_cls: type[celery.result.AsyncResult[Any]] | None = ...,
320-
expires: float | datetime.datetime | None = ...,
321-
publisher: kombu.Producer | None = ...,
322-
link: Signature[Any] | None = ...,
323-
link_error: Signature[Any] | None = ...,
324-
add_to_parent: bool = ...,
325-
group_id: str | None = ...,
326-
retries: int = ...,
327-
chord: chord | None = ...,
328-
reply_to: str | None = ...,
329-
time_limit: int | None = ...,
330-
soft_time_limit: int | None = ...,
331-
root_id: str | None = ...,
332-
parent_id: str | None = ...,
333-
route_name: str | None = ...,
334-
shadow: str | None = ...,
335-
chain: Any | None = ...,
336-
task_type: Any | None = ...,
328+
args: Sequence[Any] | None = None,
329+
kwargs: dict[str, Any] | None = None,
330+
countdown: float | None = None,
331+
eta: datetime.datetime | None = None,
332+
task_id: str | None = None,
333+
producer: kombu.Producer | None = None,
334+
connection: kombu.Connection | None = None,
335+
router: Router | None = None,
336+
result_cls: type[celery.result.AsyncResult[Any]] | None = None,
337+
expires: float | datetime.datetime | None = None,
338+
publisher: kombu.Producer | None = None,
339+
link: Signature[Any] | None = None,
340+
link_error: Signature[Any] | None = None,
341+
add_to_parent: bool = True,
342+
group_id: str | None = None,
343+
retries: int = 0,
344+
chord: chord | None = None,
345+
reply_to: str | None = None,
346+
time_limit: int | None = None,
347+
soft_time_limit: int | None = None,
348+
root_id: str | None = None,
349+
parent_id: str | None = None,
350+
route_name: str | None = None,
351+
shadow: str | None = None,
352+
chain: Any | None = None,
353+
task_type: Any | None = None,
354+
replaced_task_nesting: int = 0,
337355
# options
338356
ignore_result: bool = ...,
339357
**options: Any,
340358
) -> celery.result.AsyncResult[Any]: ...
341359
def connection_for_read(
342-
self, url: str | None = ..., **kwargs: Any
360+
self, url: str | None = None, **kwargs: Any
343361
) -> kombu.Connection: ...
344362
def connection_for_write(
345-
self, url: str | None = ..., **kwargs: Any
363+
self, url: str | None = None, **kwargs: Any
346364
) -> kombu.Connection: ...
347365
def connection(
348366
self,
349-
hostname: str | None = ...,
350-
userid: str | None = ...,
351-
password: str | None = ...,
352-
virtual_host: str | None = ...,
353-
port: int | None = ...,
354-
ssl: bool | dict[str, Any] | None = ...,
355-
connect_timeout: int | None = ...,
356-
transport: str | None = ...,
357-
transport_options: dict[str, Any] | None = ...,
358-
heartbeat: int | None = ...,
359-
login_method: int | None = ...,
360-
failover_strategy: str | Callable[[], Any] | None = ...,
367+
hostname: str | None = None,
368+
userid: str | None = None,
369+
password: str | None = None,
370+
virtual_host: str | None = None,
371+
port: int | None = None,
372+
ssl: bool | dict[str, Any] | None = None,
373+
connect_timeout: int | None = None,
374+
transport: str | None = None,
375+
transport_options: dict[str, Any] | None = None,
376+
heartbeat: int | None = None,
377+
login_method: int | None = None,
378+
failover_strategy: str | Callable[[], Any] | None = None,
361379
**kwargs: Any,
362380
) -> kombu.Connection: ...
381+
363382
broker_connection = connection
383+
364384
def connection_or_acquire(
365-
self, connection: kombu.Connection | None = ..., pool: bool = ...
385+
self, connection: kombu.Connection | None = None, pool: bool = True
366386
) -> FallbackContext[Any, Any]: ...
387+
367388
default_connection = connection_or_acquire
389+
368390
def producer_or_acquire(
369-
self, producer: kombu.Producer | None = ...
391+
self, producer: kombu.Producer | None = None
370392
) -> FallbackContext[Any, Any]: ...
393+
371394
default_producer = producer_or_acquire
395+
372396
def prepare_config(self, c: Settings) -> Settings: ...
373397
def now(self) -> datetime.datetime: ...
374-
def select_queues(self, queues: Sequence[str] | None = ...) -> None: ...
398+
def select_queues(self, queues: Sequence[str] | None = None) -> None: ...
375399
def either(self, default_key: str, *defaults: Any) -> Any: ...
376400
def bugreport(self) -> str: ...
377401
def signature(self, *args: Any, **kwargs: Any) -> Signature[Any]: ...
378402
def add_periodic_task(
379403
self,
380404
schedule: BaseSchedule | float,
381405
sig: Signature[Any],
382-
args: tuple[Any, ...] = ...,
406+
args: tuple[Any, ...] = (),
383407
kwargs: dict[str, Any] = ...,
384-
name: str | None = ...,
408+
name: str | None = None,
385409
**opts: Any,
386410
) -> str: ...
411+
def create_task_cls(self) -> type[Any]: ...
412+
def subclass_with_self(
413+
self,
414+
Class: type[Any],
415+
name: str | None = None,
416+
attribute: str = "app",
417+
reverse: str | None = None,
418+
keep_reduce: bool = False,
419+
**kw: Any,
420+
) -> type[Any]: ...
387421
def __enter__(self) -> Self: ...
388422
def __exit__(
389423
self,
@@ -416,6 +450,8 @@ class Celery(Generic[_T_Global]):
416450
@property
417451
def oid(self) -> str: ...
418452
@property
453+
def thread_oid(self) -> str: ...
454+
@property
419455
def amqp(self) -> AMQP: ...
420456
@property
421457
def backend(self) -> Backend: ...

celery-stubs/canvas.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ class chunks(Signature[Any]):
301301
def group(self) -> _group: ...
302302

303303
class group(Signature[Any]):
304+
tasks: list[Signature[Any]]
305+
304306
@overload
305307
def __init__(
306308
self,

0 commit comments

Comments
 (0)