From 91cc5c2547a4b17216b9edd0a208ffc5053f82d9 Mon Sep 17 00:00:00 2001 From: Domenico DiNicola Date: Tue, 7 Jan 2025 06:31:46 -0600 Subject: [PATCH] ruff --- .github/workflows/lint.yml | 15 ++-- .github/workflows/test.yml | 8 +- ruff.toml | 81 +++++++++++++++++++ src/django_celery_boost/admin.py | 22 ++--- src/django_celery_boost/models.py | 75 +++++++++-------- tests/conftest.py | 3 +- tests/demoapp/demo/__init__.py | 63 --------------- tests/demoapp/demo/backends.py | 13 +-- tests/demoapp/demo/factories.py | 5 +- tests/demoapp/demo/messages.py | 1 + tests/demoapp/demo/migrations/0001_initial.py | 24 ++---- tests/demoapp/demo/models.py | 12 ++- tests/demoapp/demo/settings.py | 5 -- tests/demoapp/demo/tasks.py | 2 +- tests/test_admin.py | 24 +----- tests/test_celery.py | 19 +---- tests/test_model.py | 4 - tests/test_utils.py | 5 -- 18 files changed, 173 insertions(+), 208 deletions(-) create mode 100644 ruff.toml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 49f1873..2b59e33 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -29,10 +29,10 @@ jobs: lint: ${{steps.changes.outputs.lint }} steps: - name: Checkout code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4 - id: changes name: Check for file changes - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 + uses: dorny/paths-filter@v3 with: base: ${{ github.ref }} token: ${{ github.token }} @@ -47,16 +47,19 @@ jobs: if: needs.changes.outputs.lint steps: - name: Checkout code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: 3.12 architecture: 'x64' - - uses: yezz123/setup-uv@v4 + - uses: yezz123/setup-uv@v5 + with: + version: "latest" - name: lint if: needs.changes.outputs.lint run: | - uv run isort src/ --check-only - uv run flake8 src/ + pip install ruff + ruff check -e + ruff format --check diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d5d3067..58b6939 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,10 +30,10 @@ jobs: lint: ${{steps.changes.outputs.lint }} steps: - name: Checkout code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4 - id: changes name: Check for file changes - uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0 + uses: dorny/paths-filter@v3 with: base: ${{ github.ref }} token: ${{ github.token }} @@ -74,7 +74,7 @@ jobs: DB_PASSWORD: "postgres" steps: - name: Checkout code - uses: actions/checkout@v4.1.7 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -119,7 +119,7 @@ jobs: if: ${{ always() }} - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 if: matrix.python-version == 3.12 continue-on-error: true with: diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..d49f722 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,81 @@ +target-version = "py313" +line-length = 120 + +[lint.isort] +case-sensitive = true + +[lint] +select = [ + "A", # prevent using keywords that clobber python builtins +# "ANN", # flake8 annotations + "B", # bugbear: security warnings + "BLE", # blind exceptions + "C4", # flake8-comprehensions + "C90", # McCabe complexity + "COM", # flake8-commas + "D", # pydocstyle + "DJ", # flake8-django + "E", # pycodestylex + "E4", "E7", "E9", + "ERA", # eradicate + "F", # pyflakes + "FLY", # flynt + "FURB", # refurb + "I", # isort + "ICN", # flake8-import-conventions + "ISC", # implicit string concatenation + "N", # Pep* naming + "PERF", # perflint + "PIE", # flake8-pie + "PL", # PyLint +# "PT", # flake8-pytest-style + "Q", # flake8-quotes + "R", # PyLint Refactor + "RET", # flake8-return + "S", # bandit, + "SIM", # flake8-simplify + "T10", # flake8-debugger + "T20", # flake8-print + "TC", # flake8-type-checking + "UP", # pyupgrade + "W", # pycodestyle warnings + "YTT", # flake8 2020 +] +extend-select = ["UP", ] +ignore = [ + "ANN401", + "B904", # raise-without-from-inside-except: syntax not compatible with py2 + "COM812", + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D103", # Missing docstring in public function + "D104", # Missing docstring in public package + "D105", # Missing docstring in magic method + "D106", # Missing docstring in public nested class + "D107", # Missing docstring in `__init__` + "D203", # one-blank-line-before-class +# "D212", # multi-line-summary-first-line + "D213", # multi-line-summary-second-line + "E731", # lambda-assignment: lambdas are substential in maintenance of py2/3 codebase + "ISC001", # conflicts with ruff format command + "RUF005", # collection-literal-concatenation: syntax not compatible with py2 + "RUF012", # mutable-class-default: typing is not available for py2 + "I001", # unsorted imports https://docs.astral.sh/ruff/rules/unsorted-imports/#unsorted-imports-i001 + "UP037", # [*] Remove quotes from type annotation + "UP035", # Import from `collections.abc` instead: `Sequence` + "UP031", # Use format specifiers instead of percent format + "SIM108", # Use ternary operator instead of... + "PLR2004", # Magic value used in comparison + "DJ001", # Avoid using `null=True` on string-based fields such as `CharField` +] + +[format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[lint.per-file-ignores] +"tests/**.py" = ["S101", "PLR2004", "S", "SIM117", "D", "UP", "PLR0913", "ANN", "N999"] +"src/**/versioning/**.py" = ["N999", ] diff --git a/src/django_celery_boost/admin.py b/src/django_celery_boost/admin.py index b983967..121ceb7 100644 --- a/src/django_celery_boost/admin.py +++ b/src/django_celery_boost/admin.py @@ -1,4 +1,4 @@ -from typing import Any, Optional, Sequence +from typing import Any, Sequence from admin_extra_buttons.decorators import button from admin_extra_buttons.mixins import ExtraButtonsMixin, confirm_action @@ -19,7 +19,7 @@ class CeleryTaskModelAdmin(ExtraButtonsMixin, admin.ModelAdmin): inspect_template = None queue_template = None - def get_readonly_fields(self, request: HttpRequest, obj: "Optional[Model]" = None) -> Sequence[str]: + def get_readonly_fields(self, request: HttpRequest, obj: Model | None = None) -> Sequence[str]: ret = list(super().get_readonly_fields(request, obj)) ret.append("curr_async_result_id") return ret @@ -53,7 +53,7 @@ def celery_inspect(self, request: HttpRequest, pk: str) -> HttpResponse: ctx, ) - def has_queue_permission(self, perm, request: HttpRequest, o: Optional[CeleryTaskModel]) -> bool: + def has_queue_permission(self, perm, request: HttpRequest, o: CeleryTaskModel | None) -> bool: perm = "%s.%s_%s" % ( self.model._meta.app_label, perm, @@ -83,7 +83,7 @@ def celery_terminate(self, request: "HttpRequest", pk: str) -> "HttpResponse": return self._celery_terminate(request, pk) def _celery_queue(self, request: "HttpRequest", pk: str) -> "HttpResponse": # type: ignore - obj: Optional[CeleryTaskModel] + obj: CeleryTaskModel | None obj = self.get_object(request, pk) ctx = self.get_common_context(request, pk, title=f"Confirm queue action for {obj}") @@ -100,10 +100,10 @@ def doit(request: "HttpRequest") -> HttpResponseRedirect: if obj.is_queued(): self.message_user(request, "Task has already been queued.", messages.WARNING) - return + return None if obj.is_terminated() and not obj.repeatable: self.message_user(request, "Task is already terminated.", messages.WARNING) - return + return None return confirm_action( self, @@ -122,15 +122,15 @@ def doit(request: "HttpRequest") -> HttpResponseRedirect: ) def _celery_revoke(self, request: "HttpRequest", pk: str) -> "HttpResponse": # type: ignore - obj: Optional[CeleryTaskModel] + obj: CeleryTaskModel | None obj = self.get_object(request, pk) if not obj.is_queued(): self.message_user(request, "Task not queued.", messages.WARNING) - return + return None if obj.is_terminated(): self.message_user(request, "Task is already terminated.", messages.WARNING) - return + return None ctx = self.get_common_context(request, pk, title=f"Confirm revoking action for {obj}") def doit(request: "HttpRequest") -> HttpResponseRedirect: @@ -161,10 +161,10 @@ def _celery_terminate(self, request: HttpRequest, pk: str) -> "HttpResponse": # obj: CeleryTaskModel = self.get_object(request, pk) if not obj.is_queued(): self.message_user(request, "Task not queued.", messages.WARNING) - return + return None if obj.is_terminated(): self.message_user(request, "Task is already terminated.", messages.WARNING) - return + return None ctx = self.get_common_context(request, pk, title=f"Confirm termination request for {obj}") def doit(request: "HttpRequest") -> HttpResponseRedirect: diff --git a/src/django_celery_boost/models.py b/src/django_celery_boost/models.py index be4a480..fe26721 100644 --- a/src/django_celery_boost/models.py +++ b/src/django_celery_boost/models.py @@ -1,7 +1,7 @@ import base64 import json import logging -from typing import TYPE_CHECKING, Any, Callable, Generator, Optional +from typing import TYPE_CHECKING, Any, Callable, Generator import sentry_sdk from celery import states @@ -32,19 +32,6 @@ class CeleryManager: class CeleryTaskModel(models.Model): - class Meta: - abstract = True - default_permissions = ( - "add", - "change", - "delete", - "view", - "queue", - "terminate", - "inspect", - "revoke", - ) - STARTED = states.STARTED # (task has been started) SUCCESS = states.SUCCESS # (task executed successfully) PENDING = states.PENDING # (waiting for execution or unknown task id) @@ -113,13 +100,26 @@ class Meta: """Name of the queue where revoked tasks are stored. Only need to be specified if different from `settings.CELERY_TASK_REVOKED_QUEUE`""" - _celery_app: Optional[Celery] = None + _celery_app: Celery | None = None + + class Meta: + abstract = True + default_permissions = ( + "add", + "change", + "delete", + "view", + "queue", + "terminate", + "inspect", + "revoke", + ) def __str__(self): return self.description or f"Background Job #{self.pk}" @classproperty - def celery_app(cls) -> "celery.app.base.Celery": + def celery_app(cls) -> "celery.app.base.Celery": # noqa if not cls._celery_app: from celery import current_app as app @@ -152,7 +152,7 @@ def check(cls, **kwargs): ) else: cls.celery_app.autodiscover_tasks() - if cls.celery_task_name not in cls.celery_app.tasks.keys(): + if cls.celery_task_name not in cls.celery_app.tasks: errors.append( checks.Error( "'%s' is using a non registered Celery task. (%s)" % (cls._meta, cls.celery_task_name), @@ -174,11 +174,11 @@ def get_queue_size(cls) -> "int": @property def queue_position(self) -> int: - """ - Returns the position of the current task in the queue. + """Return the position of the current task in the queue. Returns: int task position in queue + """ if self.is_terminated(): return 0 @@ -193,17 +193,16 @@ def queue_position(self) -> int: @classmethod def celery_queue_entries(cls) -> "Generator": with cls.celery_app.pool.acquire(block=True) as conn: - for entry in conn.default_channel.client.lrange(cls.celery_task_queue, 0, -1): - yield entry + yield from conn.default_channel.client.lrange(cls.celery_task_queue, 0, -1) @classmethod def celery_queue_info(cls) -> "dict[str, int]": - """Returns information about the Queue + """Return information about the queue. Returns: - Dictionary with size,pendig, canceled, revoked tasks - """ + Dictionary with size,pending, canceled, revoked tasks + """ conn: Connection channel: Channel with cls.celery_app.pool.acquire(block=True) as conn: @@ -222,15 +221,14 @@ def celery_queue_info(cls) -> "dict[str, int]": @property def async_result(self) -> "AsyncResult|None": - """Returns the AsyncResult object of the current instance""" + """Return the AsyncResult object of the current instance.""" if self.curr_async_result_id: return AsyncResult(self.curr_async_result_id) - else: - return None + return None @property def queue_entry(self) -> "dict[str, Any]": - """Returns the queue entry of the current instance""" + """Return the queue entry of the current instance.""" if self.async_result: for task in self.celery_queue_entries(): j = json.loads(task) @@ -241,10 +239,11 @@ def queue_entry(self) -> "dict[str, Any]": @property def task_info(self) -> "dict[str, Any]": - """Returns the task meta information of the current instance + """Return the task meta information of the current instance. Returns: Dictionary with task information + """ ret = {"status": self.task_status, "completed_at": ""} if self.async_result: @@ -268,7 +267,6 @@ def task_info(self) -> "dict[str, Any]": query_result_id = None return { **info, - # "id": self.async_result.id, "started_at": started_at, "completed_at": date_done, "last_update": date_done, @@ -286,12 +284,12 @@ def started(self) -> str: return "=" @classproperty - def task_handler(cls: "type[CeleryTaskModel]") -> "Callable[[Any], Any]": - """Return the task assigned to this model""" + def task_handler(cls: "type[CeleryTaskModel]") -> "Callable[[Any], Any]": # noqa + """Return the task assigned to this model.""" return import_string(cls.celery_task_name) def is_queued(self) -> bool: - """Check if the job is queued""" + """Check if the job is queued.""" try: with self.celery_app.pool.acquire(block=True) as conn: tasks = conn.default_channel.client.lrange(self.celery_task_queue, 0, -1) @@ -304,7 +302,7 @@ def is_queued(self) -> bool: return False def is_terminated(self) -> bool: - """Check if the job is queued""" + """Check if the job is queued.""" return self.task_status and self.task_status in self.TERMINATED_STATUSES def log_task_action(self, action, user): @@ -320,7 +318,7 @@ def verbose_status(self) -> str: @property def task_status(self) -> str: - """Returns the task status querying Celery API""" + """Return the task status querying Celery API.""" try: if self.curr_async_result_id: result = self.async_result.state @@ -332,14 +330,13 @@ def task_status(self) -> str: else: result = self.NOT_SCHEDULED return result - except Exception as e: + except Exception as e: # noqa return str(e) def queue(self, use_version: bool = True) -> str | None: """Queue the record processing. - Parameters: - use_version: if True the task fails if the record is changed after it has been queued. + use_version: if True the task fails if the record is changed after it has been queued. """ if self.task_status not in self.ACTIVE_STATUSES: res = self.task_handler.delay(self.pk, self.version if use_version else None) @@ -357,7 +354,7 @@ def revoke(self, wait=False, timeout=None) -> None: task_revoked.send(sender=self.__class__, task=self) def terminate(self, wait=False, timeout=None) -> str: - """Revoke the task. Does not need Running workers""" + """Revoke the task. Does not need Running workers.""" if self.task_status in ["QUEUED", "PENDING"]: with self.celery_app.pool.acquire(block=True) as conn: conn.default_channel.client.sadd( diff --git a/tests/conftest.py b/tests/conftest.py index 5845f76..6abeba1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -45,7 +45,6 @@ def pytest_configure(config): @pytest.fixture(autouse=True) def reset_queue(): - # from demo.celery import app from demo.models import Job Job.purge() @@ -54,7 +53,7 @@ def reset_queue(): conn.default_channel.client.delete(CELERY_TASK_REVOKED_QUEUE) -@pytest.fixture() +@pytest.fixture def std_user(db) -> "User": from demo.factories import UserFactory diff --git a/tests/demoapp/demo/__init__.py b/tests/demoapp/demo/__init__.py index 90d1822..e69de29 100644 --- a/tests/demoapp/demo/__init__.py +++ b/tests/demoapp/demo/__init__.py @@ -1,63 +0,0 @@ -# from smart_env import SmartEnv -# -# CONFIG = { -# "CELERY_VISIBILITY_TIMEOUT": ( -# int, -# 60, -# 60, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#debug", -# ), -# "CELERY_TASK_ALWAYS_EAGER": ( -# bool, -# True, -# False, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#debug", -# ), -# "CELERY_TASK_EAGER_PROPAGATES": ( -# bool, -# True, -# False, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#debug", -# ), -# "DEBUG": ( -# bool, -# False, -# True, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#debug", -# ), -# "CELERY_BROKER_URL": ( -# str, -# "redis://localhost:6379/0", -# "", -# True, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#DATABASES", -# ), -# "USE_TZ": ( -# bool, -# True, -# True, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#debug", -# ), -# "SECURE_SSL_REDIRECT": ( -# bool, -# True, -# False, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#SECURE_SSL_REDIRECT", -# ), -# "SESSION_COOKIE_SECURE": ( -# bool, -# True, -# False, -# False, -# "https://docs.djangoproject.com/en/5.1/ref/settings/#SESSION_COOKIE_SECURE", -# ), -# "SECRET_KEY": (str, "", "", True, "Django SECRET_KEY"), -# } -# -# env = SmartEnv(**CONFIG) diff --git a/tests/demoapp/demo/backends.py b/tests/demoapp/demo/backends.py index bcdaed9..e8e6dba 100644 --- a/tests/demoapp/demo/backends.py +++ b/tests/demoapp/demo/backends.py @@ -7,11 +7,12 @@ def authenticate(self, request, username=None, password=None, **kwargs): if username: user, __ = User.objects.update_or_create( username=username, - defaults=dict( - is_staff=True, - is_active=True, - is_superuser=True, - email=f"{username}@demo.org", - ), + defaults={ + "is_staff": True, + "is_active": True, + "is_superuser": True, + "email": f"{username}@demo.org", + }, ) return user + return None diff --git a/tests/demoapp/demo/factories.py b/tests/demoapp/demo/factories.py index 1ea1efe..3a60a34 100644 --- a/tests/demoapp/demo/factories.py +++ b/tests/demoapp/demo/factories.py @@ -56,7 +56,7 @@ def _after_postgeneration(cls, instance, create, results=None): instance.save() -class user_grant_permission: +class user_grant_permission: # noqa def __init__(self, user: User, permissions: Optional[list[str]] = None): self.user = user self.permissions = permissions @@ -77,8 +77,7 @@ def __exit__(self, *exc_info): def start(self): """Activate a patch, returning any created mock.""" - result = self.__enter__() - return result + return self.__enter__() def stop(self): """Stop an active patch.""" diff --git a/tests/demoapp/demo/messages.py b/tests/demoapp/demo/messages.py index 95cff1c..0489107 100644 --- a/tests/demoapp/demo/messages.py +++ b/tests/demoapp/demo/messages.py @@ -150,6 +150,7 @@ def _encode(self, messages: str, encode_empty: bool = False) -> Any: encoder = MessageEncoder(separators=(",", ":")) value = encoder.encode(messages) return self.signer.sign(value) + return None def _decode(self, data: str) -> Optional[Message]: """ diff --git a/tests/demoapp/demo/migrations/0001_initial.py b/tests/demoapp/demo/migrations/0001_initial.py index 30c0dee..e8a069e 100644 --- a/tests/demoapp/demo/migrations/0001_initial.py +++ b/tests/demoapp/demo/migrations/0001_initial.py @@ -28,9 +28,7 @@ class Migration(migrations.Migration): ), ( "version", - concurrency.fields.AutoIncVersionField( - default=0, help_text="record revision number" - ), + concurrency.fields.AutoIncVersionField(default=0, help_text="record revision number"), ), ( "description", @@ -58,9 +56,7 @@ class Migration(migrations.Migration): ), ( "datetime_created", - models.DateTimeField( - auto_now_add=True, help_text="Creation date and time" - ), + models.DateTimeField(auto_now_add=True, help_text="Creation date and time"), ), ( "datetime_queued", @@ -143,9 +139,7 @@ class Migration(migrations.Migration): ), ( "version", - concurrency.fields.AutoIncVersionField( - default=0, help_text="record revision number" - ), + concurrency.fields.AutoIncVersionField(default=0, help_text="record revision number"), ), ( "description", @@ -173,9 +167,7 @@ class Migration(migrations.Migration): ), ( "datetime_created", - models.DateTimeField( - auto_now_add=True, help_text="Creation date and time" - ), + models.DateTimeField(auto_now_add=True, help_text="Creation date and time"), ), ( "datetime_queued", @@ -275,9 +267,7 @@ class Migration(migrations.Migration): ), ( "version", - concurrency.fields.AutoIncVersionField( - default=0, help_text="record revision number" - ), + concurrency.fields.AutoIncVersionField(default=0, help_text="record revision number"), ), ( "description", @@ -305,9 +295,7 @@ class Migration(migrations.Migration): ), ( "datetime_created", - models.DateTimeField( - auto_now_add=True, help_text="Creation date and time" - ), + models.DateTimeField(auto_now_add=True, help_text="Creation date and time"), ), ( "datetime_queued", diff --git a/tests/demoapp/demo/models.py b/tests/demoapp/demo/models.py index 01726b9..050edb9 100644 --- a/tests/demoapp/demo/models.py +++ b/tests/demoapp/demo/models.py @@ -7,9 +7,6 @@ class Job(CeleryTaskModel, models.Model): name = models.CharField(max_length=100) number = models.IntegerField(default=0) - class Meta(CeleryTaskModel.Meta): - verbose_name = "Job" - op = models.CharField( max_length=100, choices=( @@ -25,6 +22,12 @@ class Meta(CeleryTaskModel.Meta): celery_task_name = "demo.tasks.process_job" + class Meta(CeleryTaskModel.Meta): + verbose_name = "Job" + + def __str__(self): + return self.description or f"Background Job #{self.pk}" + class AlternativeJob(CeleryTaskModel, models.Model): class Meta(CeleryTaskModel.Meta): @@ -32,6 +35,9 @@ class Meta(CeleryTaskModel.Meta): celery_task_name = "demo.tasks.process_job" + def __str__(self): + return self.description or f"Background Job #{self.pk}" + class MultipleJob(AsyncJobModel): class Meta(AsyncJobModel.Meta): diff --git a/tests/demoapp/demo/settings.py b/tests/demoapp/demo/settings.py index 2a04e9e..8915fcf 100644 --- a/tests/demoapp/demo/settings.py +++ b/tests/demoapp/demo/settings.py @@ -136,12 +136,9 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" CELERY_ACCEPT_CONTENT = ["pickle", "json", "application/text", "application/json"] -# CELERY_BROKER_TRANSPORT_OPTIONS = {"visibility_timeout": int(CELERY_BROKER_VISIBILITY_VAR)} CELERY_BROKER_URL = os.environ.get("CELERY_BROKER_URL", "redis://localhost:6379/0") CELERY_BROKER_VISIBILITY_VAR = os.environ.get("CELERY_VISIBILITY_TIMEOUT", 5) -# CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers.DatabaseScheduler" - CELERY_TASK_ACKS_LATE = True CELERY_TASK_ALWAYS_EAGER = False CELERY_TASK_DEFAULT_QUEUE = os.environ.get("CELERY_TASK_DEFAULT_QUEUE", "demo_queue") @@ -158,8 +155,6 @@ CELERY_SEND_TASK_ERROR_EMAILS = False -# CELERY_CACHE_BACKEND = "django-cache" - CELERY_RESULT_BACKEND = CELERY_BROKER_URL CELERY_RESULT_EXPIRES = None CELERY_RESULT_EXTENDED = True diff --git a/tests/demoapp/demo/tasks.py b/tests/demoapp/demo/tasks.py index 5882ea7..bf37278 100644 --- a/tests/demoapp/demo/tasks.py +++ b/tests/demoapp/demo/tasks.py @@ -22,7 +22,7 @@ def process_job(self, pk, version=None): time.sleep(0.5) elif job.op == "loop": start = time.time() - for i in range(job.value): + for _ in range(job.value): time.sleep(1) elapsed = time.time() - start return {"loops": job.value, "elapsed": elapsed} diff --git a/tests/test_admin.py b/tests/test_admin.py index 364a1d6..5a73796 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -8,14 +8,14 @@ pytestmark = [pytest.mark.admin] -@pytest.fixture() +@pytest.fixture def job(): from demo.factories import JobFactory return JobFactory() -@pytest.fixture() +@pytest.fixture def queued(): from demo.factories import JobFactory @@ -40,18 +40,6 @@ def test_celery_change(django_app, std_user, job): assert res.status_code == 200 -# def test_celery_discard_all(django_app, std_user): -# url = reverse("admin:demo_job_celery_discard_all") -# res = django_app.get(url, user=std_user) -# assert res.status_code == 302 - - -# def test_celery_purge(django_app, std_user): -# url = reverse("admin:demo_job_celery_purge") -# res = django_app.get(url, user=std_user) -# assert res.status_code == 302 - - def test_celery_inspect(django_app, std_user, job): url = reverse("admin:demo_job_celery_inspect", args=[job.pk]) job.queue() @@ -63,14 +51,6 @@ def test_celery_inspect(django_app, std_user, job): assert res.status_code == 200 -# def test_celery_result(request, django_app, admin_user, job): -# url = reverse("admin:demo_job_celery_result", args=[job.pk]) -# job.queue() -# res = django_app.get(url, user=admin_user) -# assert res.status_code == 302 -# - - def test_celery_queue(request, django_app, std_user, job): url = reverse("admin:demo_job_celery_queue", args=[job.pk]) res = django_app.get(url, user=std_user, expect_errors=True) diff --git a/tests/test_celery.py b/tests/test_celery.py index efeba44..2ea7c4f 100644 --- a/tests/test_celery.py +++ b/tests/test_celery.py @@ -3,9 +3,8 @@ from unittest.mock import patch import pytest -from demo.factories import GroupFactory, JobFactory +from demo.factories import JobFactory from demo.models import Job, MultipleJob -from django.contrib.auth.models import Group from django.core.cache import cache from django_celery_boost.models import AsyncJobModel @@ -31,7 +30,7 @@ def celery_worker_parameters(): } -@pytest.fixture() +@pytest.fixture def celery_app(celery_app): from demo.models import Job @@ -60,18 +59,6 @@ def test_tasks_fail(transactional_db, celery_app, celery_worker): assert job1.task_info["error"] == job1.name -# -# def test_task_terminate(transactional_db): -# job1: Job = JobFactory(name="Progress", op="progress", value=5) -# -# aid = job1.curr_async_result_id -# job1.queue() -# job1.terminate() -# assert list(job1.celery_queue_entries()) == [] -# job1.terminate() -# - - def test_tasks_progress(transactional_db, celery_app, celery_worker): job1: Job = JobFactory(name="Progress", op="progress", value=5) job1.queue() @@ -212,6 +199,6 @@ def test_async_raise(mock, transactional_db, celery_app, celery_worker, reset_qu async_job: MultipleJob = AsyncJobModelFactory(type=AsyncJobModel.JobType.JOB_TASK, action="demo.tasks.raise_task") mock.return_value = 1 - with pytest.raises(Exception): + with pytest.raises(Exception): # noqa async_job.execute() assert async_job.sentry_id == 1 diff --git a/tests/test_model.py b/tests/test_model.py index 1f52900..d13e47c 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -8,8 +8,6 @@ from demo.factories import AsyncJobModelFactory, JobFactory from demo.models import Job -from django_celery_boost.models import CeleryTaskModel - def test_model_initialize_new(db): job: Job = Job() @@ -32,8 +30,6 @@ def test_model_initialize_new(db): def test_model_queue(db): - # from celery import current_app - job1: Job = JobFactory() job2: Job = JobFactory() diff --git a/tests/test_utils.py b/tests/test_utils.py index 46a1dc4..8fb8517 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -31,8 +31,3 @@ def test_discard_all(db): def test_purge(db): Job.purge() - - -# -# def test_celery_stats(db): -# Job.celery_stats()