Simple job queues for Python
This report presents the forensic synthetic code analysis of rq/rq, a Python project with 10,665 GitHub stars. SynthScan v2.0 examined 33,374 lines of code across 139 source files, recording 623 pattern matches distributed across 14 syntactic categories. The overall adjusted score of 21.1 places this repository in the Moderate AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 623 distinct pattern matches across 14 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_job.py | 116 | def test_create_job_from_string_function(self): | CODE |
| LOW⚡ | tests/test_job.py | 125 | def test_create_job_from_callable_class(self): | CODE |
| LOW⚡ | tests/test_job.py | 133 | def test_job_properties_set_data_property(self): | CODE |
| LOW⚡ | tests/test_job.py | 522 | def test_job_status_always_exists(self): | CODE |
| LOW⚡ | tests/test_job.py | 529 | def test_get_status_fails_when_job_deleted_from_redis(self): | CODE |
| LOW⚡ | tests/test_job.py | 538 | def test_job_access_outside_job_fails(self): | CODE |
| LOW⚡ | tests/test_job.py | 542 | def test_job_access_within_job_function(self): | CODE |
| LOW⚡ | tests/test_job.py | 551 | def test_job_access_within_synchronous_job_function(self): | CODE |
| LOW⚡ | tests/test_job.py | 555 | def test_job_async_status_finished(self): | CODE |
| LOW⚡ | tests/test_job.py | 561 | def test_enqueue_job_async_status_finished(self): | CODE |
| LOW⚡ | tests/test_job.py | 781 | def test_get_call_string_unicode(self): | CODE |
| LOW⚡ | tests/test_job.py | 789 | def test_create_job_from_static_method(self): | CODE |
| LOW⚡ | tests/test_job.py | 797 | def test_create_job_with_ttl_should_have_ttl_after_enqueued(self): | CODE |
| LOW⚡ | tests/test_job.py | 804 | def test_create_job_with_ttl_should_expire(self): | CODE |
| LOW⚡ | tests/test_job.py | 811 | def test_create_and_cancel_job(self): | CODE |
| LOW⚡ | tests/test_job.py | 848 | def test_create_and_cancel_job_with_serializer(self): | CODE |
| LOW⚡ | tests/test_job.py | 856 | def test_key_for_should_return_prefixed_job_id(self): | CODE |
| LOW⚡ | tests/test_job.py | 864 | def test_blocking_result_fetch(self): | CODE |
| LOW | tests/test_job.py | 95 | def test_create_instance_method_job(self): | CODE |
| LOW | tests/test_job.py | 105 | def test_create_job_with_serializer(self): | CODE |
| LOW | tests/test_job.py | 144 | def test_data_property_sets_job_properties(self): | CODE |
| LOW | tests/test_job.py | 221 | def test_persistence_of_empty_jobs(self): # noqa | CODE |
| LOW | tests/test_job.py | 227 | def test_persistence_of_typical_jobs(self): | CODE |
| LOW | tests/test_job.py | 261 | def test_persistence_of_parent_job(self): | CODE |
| LOW | tests/test_job.py | 292 | def test_persistence_of_callbacks(self): | CODE |
| LOW | tests/test_job.py | 345 | def test_fetching_unreadable_data(self): | CODE |
| LOW | tests/test_job.py | 376 | def test_compressed_exc_info_handling(self): | CODE |
| LOW | tests/test_job.py | 397 | def test_compressed_job_data_handling(self): | CODE |
| LOW | tests/test_job.py | 411 | def test_custom_meta_is_persisted(self): | CODE |
| LOW | tests/test_job.py | 439 | def test_custom_meta_is_rewriten_by_save_meta(self): | CODE |
| LOW | tests/test_job.py | 470 | def test_result_ttl_is_persisted(self): | CODE |
| LOW | tests/test_job.py | 482 | def test_failure_ttl_is_persisted(self): | CODE |
| LOW | tests/test_job.py | 494 | def test_description_is_persisted(self): | CODE |
| LOW | tests/test_job.py | 509 | def test_prepare_for_execution(self): | CODE |
| LOW | tests/test_job.py | 622 | def test_job_delete_removes_itself_from_registries(self): | CODE |
| LOW | tests/test_job.py | 715 | def test_job_delete_execution_registry(self): | CODE |
| LOW | tests/test_job.py | 738 | def test_create_job_with_invalid_id(self): | CODE |
| LOW | tests/test_job.py | 766 | def test_create_job_with_async(self): | CODE |
| LOW | tests/test_job.py | 826 | def test_create_and_cancel_job_fails_already_canceled(self): | CODE |
| LOW | tests/test_job.py | 880 | def test_should_enqueue_at_front(self): | CODE |
| LOW | tests/test_retry.py | 22 | def test_persistence_of_retry_data(self): | CODE |
| LOW | tests/test_retry.py | 137 | def test_job_create_with_retry(self): | CODE |
| LOW | tests/test_retry.py | 172 | def test_cleanup_handles_retries(self): | CODE |
| LOW | tests/test_retry.py | 263 | def test_handle_job_retry_max_retries_exceeded(self): | CODE |
| LOW | tests/test_retry.py | 325 | def test_job_handle_retry_with_interval_increments_number_of_retries(self): | CODE |
| LOW | tests/test_retry.py | 336 | def test_worker_handles_max_retry(self): | CODE |
| LOW | tests/test_retry.py | 363 | def test_worker_handles_retry_interval(self): | CODE |
| LOW | tests/test_retry.py | 396 | def test_worker_handles_max_retry_with_interval(self): | CODE |
| LOW | tests/test_retry.py | 414 | def test_worker_handles_enqueue_at_front_on_retry(self): | CODE |
| LOW | tests/test_retry.py | 428 | def test_worker_handles_enqueue_at_front_on_retry_with_interval(self): | CODE |
| LOW | tests/test_registry.py | 126 | def test_add_and_remove_with_serializer(self): | CODE |
| LOW | tests/test_registry.py | 202 | def test_clean_registries_with_serializer(self): | CODE |
| LOW | tests/test_registry.py | 255 | def test_jobs_are_put_in_registry(self): | CODE |
| LOW | tests/test_registry.py | 292 | def test_add_with_deferred_ttl(self): | CODE |
| LOW | tests/test_registry.py | 360 | def test_delete_removes_ready_job_from_registry(self): | CODE |
| LOW | tests/test_registry.py | 371 | def test_job_is_ready_to_enqueue(self): | CODE |
| LOW | tests/test_registry.py | 379 | def test_enqueue_jobs_moves_ready_jobs_to_queue(self): | CODE |
| LOW | tests/test_registry.py | 406 | def test_enqueue_jobs_drops_stale_entries(self): | CODE |
| LOW | tests/test_registry.py | 429 | def test_enqueue_jobs_isolates_failures(self): | CODE |
| LOW | tests/test_registry.py | 454 | def test_cleanup_recovers_ready_jobs(self): | CODE |
| 403 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | rq/queue.py | 154 | Returns a Queue instance, based on the naming conventions for naming the internal Redis keys. Can be used to re | STRING |
| HIGH | rq/queue.py | 573 | Creates a job based on parameters given Args: func (FunctionReferenceType): The function reference: | STRING |
| HIGH | rq/queue.py | 1217 | Enqueues a job for delayed execution checking dependencies. Args: job (Job): The job to enqueue | STRING |
| HIGH | rq/queue.py | 1625 | Helper method to abstract away from some Redis API details where LPOP accepts only a single key, whereas BLPOP | STRING |
| HIGH | rq/queue.py | 1701 | Class method returning the job_class instance at the front of the given set of Queues, where the order of the qu | STRING |
| HIGH | rq/registry.py | 197 | Requeues the job with the given job ID. Args: job_or_id (Union['Job', str]): The Job or the | STRING |
| HIGH | rq/registry.py | 686 | Returns datetime (UTC) at which job is scheduled to be enqueued Args: job_or_id (Union[Job, str]): | STRING |
| HIGH | rq/job.py | 271 | Creates a new Job instance for the given function, arguments, and keyword arguments. Args: | STRING |
| HIGH | rq/job.py | 416 | Gets the Job Status Args: refresh (bool, optional): Whether to refresh the Job. Defaults to True. | STRING |
| HIGH | rq/job.py | 1204 | Cancels the given job, which will prevent the job from ever being ran (or inspected). This method merel | STRING |
| HIGH | rq/utils.py | 80 | Resolve a function reference into instance and function name components. Args: func: The function reference | STRING |
| HIGH | rq/utils.py | 119 | Converts a bytes value to a string using `utf-8`. Args: v (Union[bytes, str]): The value (bytes or string) | STRING |
| HIGH | rq/utils.py | 167 | Returns an attribute from a dotted path name. Example: `path.to.func`. When the attribute we look for is a staticme | STRING |
| HIGH | rq/utils.py | 265 | Normalize configuration path to dotted module path format. Converts file paths like 'directory/config_file.py' or ' | STRING |
| HIGH | rq/utils.py | 308 | Validate that an absolute file path exists and points to a file. Args: file_path: The absolute file path to | STRING |
| HIGH | rq/scripts.py | 59 | Atomically check uniqueness, save job, and optionally push to queue using Lua script. Args: connection: Red | STRING |
| HIGH | rq/scripts.py | 165 | Atomically check uniqueness, save job, and add to scheduled registry using Lua script. Args: connection: Re | STRING |
| HIGH | rq/worker_registration.py | 58 | Returns a list of worker keys for a given queue. Args: queue (Optional['Queue'], optional): The Que | STRING |
| HIGH | rq/worker/base.py | 282 | Returns a Worker instance, based on the naming conventions for naming the internal Redis keys. Can be used to r | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/fixtures.py | 6 | CODE | |
| LOW | rq/queue.py | 1 | CODE | |
| LOW | rq/executions.py | 1 | CODE | |
| LOW | rq/worker_pool.py | 1 | CODE | |
| LOW | rq/command.py | 7 | CODE | |
| LOW | rq/command.py | 9 | CODE | |
| LOW | rq/results.py | 1 | CODE | |
| LOW | rq/webhook.py | 1 | CODE | |
| LOW | rq/maintenance.py | 8 | CODE | |
| LOW | rq/registry.py | 1 | CODE | |
| LOW | rq/cron.py | 1 | CODE | |
| LOW | rq/job.py | 1 | CODE | |
| LOW | rq/serializers.py | 1 | CODE | |
| LOW | rq/cron_scheduler_registry.py | 1 | CODE | |
| LOW | rq/__init__.py | 2 | CODE | |
| LOW | rq/__init__.py | 2 | CODE | |
| LOW | rq/__init__.py | 2 | CODE | |
| LOW | rq/__init__.py | 2 | CODE | |
| LOW | rq/__init__.py | 2 | CODE | |
| LOW | rq/__init__.py | 3 | CODE | |
| LOW | rq/__init__.py | 4 | CODE | |
| LOW | rq/__init__.py | 5 | CODE | |
| LOW | rq/__init__.py | 7 | CODE | |
| LOW | rq/__init__.py | 8 | CODE | |
| LOW | rq/__init__.py | 8 | CODE | |
| LOW | rq/__init__.py | 8 | CODE | |
| LOW | rq/suspension.py | 1 | CODE | |
| LOW | rq/types.py | 1 | CODE | |
| LOW | rq/types.py | 10 | CODE | |
| LOW | rq/types.py | 12 | CODE | |
| LOW | rq/types.py | 12 | CODE | |
| LOW | rq/logutils.py | 1 | CODE | |
| LOW | rq/intermediate_queue.py | 1 | CODE | |
| LOW | rq/repeat.py | 1 | CODE | |
| LOW | rq/utils.py | 8 | CODE | |
| LOW | rq/rate_limit.py | 1 | CODE | |
| LOW | rq/group.py | 1 | CODE | |
| LOW | rq/scheduler.py | 1 | CODE | |
| LOW | rq/worker_registration.py | 1 | CODE | |
| LOW | rq/job_lifecycle.py | 1 | CODE | |
| LOW | rq/decorators.py | 1 | CODE | |
| LOW | rq/cli/__init__.py | 2 | CODE | |
| LOW | rq/cli/__init__.py | 6 | CODE | |
| LOW | rq/cli/__init__.py | 7 | CODE | |
| LOW | rq/cli/__init__.py | 8 | CODE | |
| LOW | rq/worker/__init__.py | 1 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 2 | CODE | |
| LOW | rq/worker/__init__.py | 10 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/__init__.py | 11 | CODE | |
| LOW | rq/worker/worker_classes.py | 1 | CODE | |
| 1 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_worker.py | 1827 | except Exception: | CODE |
| LOW | rq/queue.py | 1585 | except Exception: | CODE |
| LOW | rq/queue.py | 1749 | except Exception as e: | CODE |
| LOW | rq/webhook.py | 99 | except Exception: | CODE |
| LOW | rq/registry.py | 298 | except Exception: | CODE |
| LOW | rq/registry.py | 623 | except Exception: | CODE |
| LOW | rq/cron.py | 424 | except Exception as e: | CODE |
| LOW | rq/cron.py | 446 | except Exception as e: | CODE |
| LOW | rq/cron.py | 460 | except Exception as e: | CODE |
| LOW | rq/job.py | 606 | except Exception as e: | CODE |
| LOW | rq/job.py | 996 | except Exception: | CODE |
| LOW | rq/job.py | 1028 | except Exception: | CODE |
| LOW | rq/job.py | 1041 | except Exception: # depends on the serializer | CODE |
| LOW | rq/job.py | 1294 | except Exception: | CODE |
| LOW | rq/job.py | 1634 | except Exception: # noqa | CODE |
| LOW | rq/job.py | 1647 | except Exception: # noqa | CODE |
| LOW | rq/cli/workers.py | 169 | except Exception as e: | CODE |
| LOW | rq/cli/helpers.py | 259 | except Exception: | CODE |
| LOW | rq/worker/worker_classes.py | 159 | except Exception: | CODE |
| LOW | rq/worker/base.py | 795 | except Exception as e: | CODE |
| LOW | rq/worker/base.py | 1445 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | rq/queue.py | 660 | CODE | |
| LOW | rq/registry.py | 563 | CODE | |
| LOW | rq/cron.py | 148 | CODE | |
| LOW | rq/job.py | 1198 | CODE | |
| LOW | rq/job.py | 1333 | CODE | |
| LOW | rq/job.py | 1941 | CODE | |
| LOW | rq/repeat.py | 29 | CODE | |
| LOW | rq/utils.py | 79 | CODE | |
| LOW | rq/dependency.py | 11 | CODE | |
| LOW | rq/scheduler.py | 219 | CODE | |
| LOW | rq/cli/helpers.py | 267 | CODE | |
| LOW | rq/worker/base.py | 594 | CODE | |
| LOW | rq/worker/base.py | 719 | CODE | |
| LOW | rq/worker/base.py | 832 | CODE | |
| LOW | rq/worker/base.py | 1134 | CODE | |
| LOW | rq/worker/base.py | 1388 | CODE | |
| LOW | rq/worker/base.py | 1476 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | rq/worker_pool.py | 0 | installs signal handlers for handling sigint and sigterm gracefully. | STRING |
| HIGH | rq/scheduler.py | 0 | installs signal handlers for handling sigint and sigterm gracefully. | STRING |
| HIGH | rq/worker/base.py | 0 | installs signal handlers for handling sigint and sigterm gracefully. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/test_repeat.py | 68 | # Create a job with repeat settings | COMMENT |
| MEDIUM | tests/test_results.py | 66 | # Create a result without any execution info (simulates pre-upgrade data). | COMMENT |
| MEDIUM | tests/test_cron.py | 255 | # Create a Cron instance first | COMMENT |
| MEDIUM | .github/workflows/valkey.yml | 27 | # Define the service container for Valkey | COMMENT |
| MEDIUM | rq/registry.py | 247 | """This method is automatically called by `count()` and `get_job_ids()` methods | STRING |
| MEDIUM | rq/worker/base.py | 1120 | """This method is called by the main `Worker` (not the horse) as it prepares for execution. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | rq/queue.py | 549 | CODE | |
| LOW | rq/queue.py | 719 | CODE | |
| LOW | rq/queue.py | 805 | CODE | |
| LOW | rq/worker_pool.py | 256 | CODE | |
| LOW | rq/results.py | 29 | CODE | |
| LOW | rq/results.py | 278 | CODE | |
| LOW | rq/cron.py | 609 | CODE | |
| LOW | rq/cron.py | 44 | CODE | |
| LOW | rq/cron.py | 264 | CODE | |
| LOW | rq/job.py | 246 | CODE | |
| LOW | rq/decorators.py | 21 | CODE | |
| LOW | rq/cli/helpers.py | 334 | CODE | |
| LOW | rq/worker/base.py | 133 | CODE | |
| LOW | rq/worker/base.py | 594 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | rq/cron.py | 140 | def set_enqueue_time(self, time: datetime) -> None: | CODE |
| LOW | rq/job.py | 434 | def set_status(self, status: JobStatus, pipeline: Pipeline | None = None) -> None: | CODE |
| LOW | rq/__init__.py | 10 | __all__ = [ | CODE |
| LOW | rq/utils.py | 45 | logger = logging.getLogger(__name__) | CODE |
| LOW | rq/worker/__init__.py | 20 | __all__ = [ | CODE |
| LOW | rq/worker/base.py | 250 | def _set_ip_address(self, connection: Redis) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | rq/local.py | 87 | >>> ls.push(42) | STRING |
| HIGH | rq/local.py | 90 | >>> ls.push(23) | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_cli.py | 971 | # Make the start method just return to avoid infinite loop | COMMENT |
| LOW | rq/local.py | 12 | # Since each thread has its own greenlet we can just use those as identifiers | COMMENT |
| LOW | rq/timeouts.py | 50 | # just pass through, BaseTimeoutException being handled normally to the | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | rq/repeat.py | 104 | # Decrement repeats_left | COMMENT |
| LOW | rq/utils.py | 283 | # Check if it's already a dotted path (no path separators and no .py extension) | COMMENT |
| LOW | rq/worker/base.py | 1413 | # Check if job has exceeded max retries | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_scheduler.py | 81 | job = Job.create('myfunc', connection=self.connection) | COMMENT |
| LOW | .github/workflows/codeql.yaml | 21 | - name: Initialize CodeQL | COMMENT |
| LOW | rq/worker_pool.py | 121 | self.handle_dead_worker(data) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/test_queue.py | 612 | pipe.watch(b'fake_key') # Test watch then enqueue | CODE |
| LOW⚡ | tests/test_queue.py | 619 | pipe.set(b'fake_key', b'fake_value') | CODE |