Skip to content

Commit 4a5b20c

Browse files
test type annotations with mypy (#668)
1 parent 77bc4ff commit 4a5b20c

File tree

20 files changed

+136
-61
lines changed

20 files changed

+136
-61
lines changed

.github/workflows/test.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,24 @@ jobs:
3939
- name: Run Test
4040
run: |
4141
`which django-admin` test django_rq --settings=django_rq.tests.settings --pythonpath=.
42+
43+
mypy:
44+
runs-on: ubuntu-latest
45+
name: Type check
46+
47+
steps:
48+
- uses: actions/checkout@v3
49+
50+
- name: Set up Python 3.8
51+
uses: actions/[email protected]
52+
with:
53+
python-version: "3.8"
54+
55+
- name: Install dependencies
56+
run: |
57+
python -m pip install --upgrade pip
58+
pip install django-stubs[compatible-mypy] rq types-redis
59+
60+
- name: Run Test
61+
run: |
62+
mypy django_rq

django_rq/admin.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
from typing import Any, Dict, Optional
2+
13
from django.contrib import admin
4+
from django.http.request import HttpRequest
5+
from django.http.response import HttpResponse
26

37
from . import views, settings, models
48

@@ -9,10 +13,10 @@ class QueueAdmin(admin.ModelAdmin):
913
def has_add_permission(self, request):
1014
return False # Hide the admin "+ Add" link for Queues
1115

12-
def has_change_permission(self, request):
16+
def has_change_permission(self, request: HttpRequest, obj: Optional[Any] = None) -> bool:
1317
return True
1418

15-
def has_module_permission(self, request):
19+
def has_module_permission(self, request: HttpRequest):
1620
"""
1721
return True if the given request has any permission in the given
1822
app label.
@@ -23,9 +27,9 @@ def has_module_permission(self, request):
2327
does not restrict access to the add, change or delete views. Use
2428
`ModelAdmin.has_(add|change|delete)_permission` for that.
2529
"""
26-
return request.user.has_module_perms('django_rq')
30+
return request.user.has_module_perms('django_rq') # type: ignore[union-attr]
2731

28-
def changelist_view(self, request):
32+
def changelist_view(self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = None) -> HttpResponse:
2933
"""The 'change list' admin view for this model."""
3034
# proxy request to stats view
3135
return views.stats(request)

django_rq/decorators.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
from rq.decorators import job as _rq_job
2+
from typing import TYPE_CHECKING, Union
23

34
from django.conf import settings
45

56
from .queues import get_queue
67

8+
if TYPE_CHECKING:
9+
from rq import Queue
10+
711

812
def job(func_or_queue, connection=None, *args, **kwargs):
913
"""
@@ -18,7 +22,7 @@ def job(func_or_queue, connection=None, *args, **kwargs):
1822
"""
1923
if callable(func_or_queue):
2024
func = func_or_queue
21-
queue = 'default'
25+
queue: Union['Queue', str] = 'default'
2226
else:
2327
func = None
2428
queue = func_or_queue
@@ -30,13 +34,17 @@ def job(func_or_queue, connection=None, *args, **kwargs):
3034
connection = queue.connection
3135
except KeyError:
3236
pass
37+
else:
38+
if connection is None:
39+
connection = queue.connection
3340

3441
RQ = getattr(settings, 'RQ', {})
3542
default_result_ttl = RQ.get('DEFAULT_RESULT_TTL')
3643
if default_result_ttl is not None:
3744
kwargs.setdefault('result_ttl', default_result_ttl)
3845

39-
decorator = _rq_job(queue, connection=connection, *args, **kwargs)
46+
kwargs['connection'] = connection
47+
decorator = _rq_job(queue, *args, **kwargs)
4048
if func:
4149
return decorator(func)
4250
return decorator

django_rq/management/commands/rqenqueue.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ def handle(self, *args, **options):
2222
Queues the function given with the first argument with the
2323
parameters given with the rest of the argument list.
2424
"""
25-
verbosity = int(options.get('verbosity', 1))
26-
timeout = options.get('timeout')
27-
queue = get_queue(options.get('queue'))
28-
job = queue.enqueue_call(args[0], args=args[1:], timeout=timeout)
29-
if verbosity:
25+
queue = get_queue(options['queue'])
26+
job = queue.enqueue_call(args[0], args=args[1:], timeout=options['timeout'])
27+
if options['verbosity']:
3028
print('Job %s created' % job.id)

django_rq/management/commands/rqscheduler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def handle(self, *args, **options):
3636
fp.write(str(os.getpid()))
3737

3838
# Verbosity is defined by default in BaseCommand for all commands
39-
verbosity = options.get('verbosity')
39+
verbosity: int = options['verbosity']
4040
if verbosity >= 2:
4141
level = 'DEBUG'
4242
elif verbosity == 0:
@@ -46,5 +46,5 @@ def handle(self, *args, **options):
4646
setup_loghandlers(level)
4747

4848
scheduler = get_scheduler(
49-
name=options.get('queue'), interval=options.get('interval'))
49+
name=options['queue'], interval=options['interval'])
5050
scheduler.run()

django_rq/management/commands/rqstats.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Command(BaseCommand):
1111
Print RQ statistics
1212
"""
1313
help = __doc__
14+
_separator: str
1415

1516
def add_arguments(self, parser):
1617
# TODO: convert this to @click.command like rq does
@@ -89,7 +90,7 @@ def handle(self, *args, **options):
8990
raise CommandError("PyYAML is not installed.") from ex
9091

9192
# Disable YAML alias
92-
yaml.Dumper.ignore_aliases = lambda *args: True
93+
yaml.Dumper.ignore_aliases = lambda *args: True # type: ignore[method-assign]
9394
click.echo(yaml.dump(get_statistics(), default_flow_style=False))
9495
return
9596

django_rq/management/commands/rqworker-pool.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from rq.serializers import resolve_serializer
55
from rq.worker_pool import WorkerPool
66
from rq.logutils import setup_loghandlers
7+
from typing import cast
78

89
from django.core.management.base import BaseCommand
910

@@ -67,7 +68,7 @@ def handle(self, *args, **options):
6768
fp.write(str(os.getpid()))
6869

6970
# Verbosity is defined by default in BaseCommand for all commands
70-
verbosity = options.get('verbosity')
71+
verbosity: int = options['verbosity']
7172
if verbosity >= 2:
7273
logging_level = 'DEBUG'
7374
elif verbosity == 0:

django_rq/management/commands/rqworker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def handle(self, *args, **options):
6060
fp.write(str(os.getpid()))
6161

6262
# Verbosity is defined by default in BaseCommand for all commands
63-
verbosity = options.get('verbosity')
63+
verbosity = options['verbosity']
6464
if verbosity >= 2:
6565
level = 'DEBUG'
6666
elif verbosity == 0:

django_rq/py.typed

Whitespace-only changes.

django_rq/queues.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ def get_redis_connection(config, use_strict_redis=False):
105105
cache = caches[config['USE_REDIS_CACHE']]
106106
# We're using django-redis-cache
107107
try:
108-
return cache._client
108+
return cache._client # type: ignore[attr-defined]
109109
except AttributeError:
110110
# For django-redis-cache > 0.13.1
111-
return cache.get_master_client()
111+
return cache.get_master_client() # type: ignore[attr-defined]
112112

113113
if 'UNIX_SOCKET_PATH' in config:
114114
return redis_cls(unix_socket_path=config['UNIX_SOCKET_PATH'], db=config['DB'])
@@ -161,7 +161,7 @@ def get_queue(
161161
queue_class: Optional[Union[str, Type[DjangoRQ]]] = None,
162162
job_class: Optional[Union[str, Type[Job]]] = None,
163163
serializer: Any = None,
164-
**kwargs
164+
**kwargs: Any,
165165
) -> DjangoRQ:
166166
"""
167167
Returns an rq Queue using parameters defined in ``RQ_QUEUES``
@@ -366,5 +366,5 @@ def get_scheduler(
366366

367367
except ImportError:
368368

369-
def get_scheduler(*args, **kwargs):
369+
def get_scheduler(*args, **kwargs): # type: ignore[misc]
370370
raise ImproperlyConfigured('rq_scheduler not installed')

0 commit comments

Comments
 (0)