-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/coderabbit auto improvements #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… auto-improvement rules - Updated .coderabbit.yaml to match official schema - Added assertive profile for maximum feedback - Enabled auto_apply_labels and auto_assign_reviewers - Added comprehensive path_instructions for Python, TypeScript, React - Enabled knowledge_base with code_guidelines from .cursorrules - Added code_generation settings for docstrings and unit_tests - Created .cursorrules with detailed coding standards for auto-fixes
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
WalkthroughThree new files are introduced: a Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant LocalRepo
participant GitHub
participant CodeRabbit
User->>LocalRepo: Run auto-improve.sh
LocalRepo->>GitHub: Push commit for CodeRabbit improvements
GitHub->>CodeRabbit: Trigger review and auto-improvement
CodeRabbit->>GitHub: Apply improvements (if any)
LocalRepo->>GitHub: Pull latest changes
User->>LocalRepo: Receives improved code
Poem
📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (3)
🧰 Additional context used📓 Path-based instructions (1)`**/*.py`: Apply black formatting, optimize imports with isort, fix flake8 issue...
⚙️ Source: CodeRabbit Configuration File List of files the instruction was applied to:
🧠 Learnings (3)📓 Common learningsscripts/auto-improve.sh (2)utils/helpers.py (1)🪛 Flake8 (7.2.0)llm/continuous_learning_system.py[warning] 97-97: blank line contains whitespace (W293) [warning] 100-100: blank line contains whitespace (W293) [warning] 103-103: blank line contains whitespace (W293) utils/helpers.py[warning] 15-15: blank line contains whitespace (W293) [warning] 18-18: blank line contains whitespace (W293) [warning] 21-21: blank line contains whitespace (W293) [warning] 37-37: blank line contains whitespace (W293) [warning] 41-41: blank line contains whitespace (W293) [warning] 44-44: blank line contains whitespace (W293) [warning] 58-58: blank line contains whitespace (W293) [warning] 61-61: blank line contains whitespace (W293) [warning] 64-64: blank line contains whitespace (W293) [warning] 77-77: blank line contains whitespace (W293) [warning] 79-79: blank line contains whitespace (W293) [warning] 84-84: blank line contains whitespace (W293) [warning] 87-87: blank line contains whitespace (W293) [warning] 90-90: blank line contains whitespace (W293) [warning] 113-113: blank line contains whitespace (W293) [warning] 117-117: blank line contains whitespace (W293) [warning] 120-120: blank line contains whitespace (W293) [warning] 138-138: blank line contains whitespace (W293) [warning] 141-141: blank line contains whitespace (W293) [warning] 144-144: blank line contains whitespace (W293) [warning] 157-157: blank line contains whitespace (W293) [warning] 160-160: blank line contains whitespace (W293) [warning] 163-163: blank line contains whitespace (W293) [warning] 182-182: blank line contains whitespace (W293) [warning] 186-186: blank line contains whitespace (W293) [warning] 189-189: blank line contains whitespace (W293) [warning] 206-206: blank line contains whitespace (W293) [warning] 210-210: blank line contains whitespace (W293) [warning] 213-213: blank line contains whitespace (W293) [warning] 224-224: blank line contains whitespace (W293) [warning] 227-227: blank line contains whitespace (W293) [warning] 230-230: blank line contains whitespace (W293) [warning] 246-246: no newline at end of file (W292) 🪛 Pylint (3.3.7)llm/continuous_learning_system.py[convention] 96-96: Line too long (176/100) (C0301) [convention] 99-99: Line too long (171/100) (C0301) utils/helpers.py[convention] 20-20: Line too long (123/100) (C0301) [convention] 60-60: Line too long (111/100) (C0301) [convention] 78-78: Line too long (186/100) (C0301) [convention] 137-137: Line too long (127/100) (C0301) [convention] 162-162: Line too long (228/100) (C0301) [convention] 181-181: Line too long (130/100) (C0301) [convention] 185-185: Line too long (120/100) (C0301) [convention] 212-212: Line too long (213/100) (C0301) [convention] 229-229: Line too long (170/100) (C0301) [convention] 246-246: Final newline missing (C0304) [warning] 103-103: Catching too general exception Exception (W0718) [refactor] 74-74: Either all return statements in a function should return an expression, or none of them should. (R1710) [convention] 168-168: Import outside toplevel (re) (C0415) [refactor] 239-246: Unnecessary "elif" after "return", remove the leading "el" from "elif" (R1705) 🪛 Shellcheck (0.10.0)scripts/auto-improve.sh[warning] 11-11: Declare and assign separately to avoid masking return values. (SC2155) [warning] 13-13: Declare and assign separately to avoid masking return values. (SC2155) [warning] 13-13: Quote this to prevent word splitting. (SC2046) [warning] 24-24: Declare and assign separately to avoid masking return values. (SC2155) [warning] 25-25: Declare and assign separately to avoid masking return values. (SC2155) [warning] 30-30: Declare and assign separately to avoid masking return values. (SC2155) [info] 33-33: Double quote to prevent globbing and word splitting. (SC2086) [info] 35-35: Double quote to prevent globbing and word splitting. (SC2086) [info] 45-45: Double quote to prevent globbing and word splitting. (SC2086) [style] 55-55: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?. (SC2181) [style] 62-62: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?. (SC2181) [style] 70-70: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?. (SC2181) 🪛 Ruff (0.11.9)utils/helpers.py8-8: (UP035) 8-8: (UP035) 12-12: Use Replace with (UP006) 34-34: Dynamically typed expressions (typing.Any) are disallowed in (ANN401) 74-74: Missing return type annotation for public function (ANN201) 74-74: Missing type annotation for function argument (ANN001) 100-107: Missing explicit Add explicit (RET503) 105-105: Use Remove exception name (TRY201) 110-110: Use Replace with (UP006) 110-110: Use Replace with (UP006) 179-179: Use Replace with (UP006) 179-179: Use Replace with (UP006) 179-179: Use Replace with (UP006) 203-203: Use Replace with (UP006) 203-203: Use Replace with (UP006) 203-203: Use Replace with (UP006) 241-241: Unnecessary Remove unnecessary (RET505) 🔇 Additional comments (1)
✨ Finishing Touches
🧪 Generate Unit Tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request introduces the "Feature/coderabbit auto improvements" feature, automating code improvement and review tasks through CodeRabbit configuration and scripts.
- Added an auto-improvement script (scripts/auto-improve.sh) to commit, push, wait, pull, and notify about application of improvements.
- Introduced a configuration file for coding standards (.cursorrules) and a CodeRabbit configuration (.coderabbit.yaml) to standardize auto-reviews and improvements.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| scripts/auto-improve.sh | New script to automate commit, push, and pull operations. |
| .cursorrules | Added coding standard guidelines for multiple languages. |
| .coderabbit.yaml | Introduced configuration for auto-review and code guidelines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @groupthinking, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request establishes an automated code improvement workflow by integrating and configuring CodeRabbit, an AI-driven code review and generation platform. It defines detailed coding standards that the AI will leverage for suggestions and automatic fixes, and provides a convenient script to orchestrate the entire process of triggering and incorporating these AI-generated enhancements.
Highlights
- Automated Code Review Configuration: Introduced a new
.coderabbit.yamlfile to configure CodeRabbit, an AI-powered code review and generation tool. This configuration sets an 'assertive' review profile, enables various review features like auto-labeling and auto-assigning reviewers, and defines path-specific instructions for auto-improvements across Python, TypeScript, React, and Markdown files. - Defined Coding Standards: Added a new
.cursorrulesfile that outlines comprehensive coding standards for multiple languages and domains, including Python, TypeScript/JavaScript, React/TSX, general practices, MCP integration, and quantum computing. This file also specifies a prioritized list for auto-fix suggestions, guiding the AI on which issues to address first. - Automated Improvement Script: Included a new
scripts/auto-improve.shbash script designed to automate the CodeRabbit improvement workflow. This script stages and commits changes, pushes them to GitHub to trigger CodeRabbit's analysis, waits for the AI to process, and then pulls any auto-applied improvements back into the local repository.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces configuration files for CodeRabbit and a shell script to facilitate automated code improvements. The configurations are well-defined and aim to enhance code quality and consistency. The .cursorrules file, in particular, provides a comprehensive set of coding standards that align well with the PROJECT_STANDARDS.md and CONTRIBUTING.md files. I have suggested adding set -euo pipefail to the shell script for improved robustness, checking for changes before committing, and addressing the unreliability of a fixed sleep duration. Also, adding a newline character at the end of the files is recommended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
.coderabbit.yaml(1 hunks).cursorrules(1 hunks)scripts/auto-improve.sh(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.coderabbit.yaml
[error] 24-24: trailing spaces
(trailing-spaces)
[error] 79-79: no new line character at the end of file
(new-line-at-end-of-file)
[error] 79-79: trailing spaces
(trailing-spaces)
🔇 Additional comments (3)
.coderabbit.yaml (2)
20-20: Confirm auto-apply labels setting
auto_apply_labels: trueenables automatic labeling. Verify that you intend to apply labels without manual review.
22-22: Confirm auto-assign reviewers setting
auto_assign_reviewers: truewill assign reviewers automatically. Ensure this aligns with your team's workflow..cursorrules (1)
1-92: Standards file looks comprehensive
The coding standards and auto-fix priorities cover relevant languages and practices. No changes required.
Co-authored-by: Copilot <[email protected]>
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (1)
scripts/auto-improve.sh (1)
34-37: Use fast-forward-only pull
To avoid unintended merge commits, replacegit pullwithgit pull --ff-onlyand handle errors explicitly:- git pull + if ! git pull --ff-only; then + echo "❌ Error: Failed to pull CodeRabbit improvements. Exiting..." + exit 1 + fi
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
scripts/auto-improve.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
scripts/auto-improve.sh
[style] 10-10: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
[style] 17-17: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
[style] 25-25: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
🔇 Additional comments (1)
scripts/auto-improve.sh (1)
1-2: Strict shell mode enabled
Includingset -euo pipefailensures the script exits on errors, treats unset variables as errors, and fails on pipeline errors.
✅ Actions performedComments resolved. |
1 similar comment
✅ Actions performedComments resolved. |
…tation - Add GitHub workflow for automated Claude Code integration - Create CLAUDE.md with complete project documentation - Add utils/helpers.py with comprehensive utility functions - Include comprehensive test suite for utils helpers - Update utils module exports 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 26
🔭 Outside diff range comments (1)
CLAUDE.md (1)
148-151: Surround Environment Setup numbered list with blank lines
The numbered items under “## Environment Setup” (lines 150–151) should be preceded and followed by a blank line.
♻️ Duplicate comments (1)
scripts/auto-improve.sh (1)
54-58: Use direct command failure checks instead of $?Replace indirect exit status checks with direct command failure checks for better readability and to follow shellcheck recommendations.
This issue has been flagged in previous reviews but appears to still be present in some locations.
Also applies to: 62-65, 69-73
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
.github/workflows/claude.yml(1 hunks)CLAUDE.md(1 hunks)llm/continuous_learning_system.py(0 hunks)scripts/auto-improve.sh(1 hunks)test_utils_helpers.py(1 hunks)utils/__init__.py(1 hunks)utils/helpers.py(1 hunks)
💤 Files with no reviewable changes (1)
- llm/continuous_learning_system.py
🧰 Additional context used
📓 Path-based instructions (3)
`**/*.py`: Apply black formatting, optimize imports with isort, fix flake8 issues, improve type hints, add docstrings to all public functions and classes, optimize performance, and...
**/*.py: Apply black formatting, optimize imports with isort, fix flake8 issues, improve type hints, add docstrings to all public functions and classes, optimize performance, and ensure security best practices.
utils/__init__.pytest_utils_helpers.pyutils/helpers.py
`**/*.md`: Fix formatting, improve readability, add missing sections, and ensure proper markdown syntax.
**/*.md: Fix formatting, improve readability, add missing sections, and ensure proper markdown syntax.
CLAUDE.md
`**/test_*.py`: Improve test coverage, add missing assertions, optimize test performance, and ensure proper mocking.
**/test_*.py: Improve test coverage, add missing assertions, optimize test performance, and ensure proper mocking.
test_utils_helpers.py
🪛 Ruff (0.11.9)
utils/__init__.py
5-5: __all__ is not sorted
Apply an isort-style sorting to __all__
(RUF022)
test_utils_helpers.py
1-1: Shebang is present but file is not executable
(EXE001)
10-10: time imported but unused
Remove unused import: time
(F401)
27-27: Trailing comma missing
Add trailing comma
(COM812)
34-34: Missing return type annotation for public function test_valid_json_string
Add return type annotation: None
(ANN201)
40-40: Missing return type annotation for public function test_valid_json_array
Add return type annotation: None
(ANN201)
46-46: Missing return type annotation for public function test_invalid_json_string
Add return type annotation: None
(ANN201)
52-52: Missing return type annotation for public function test_completely_malformed_json
Add return type annotation: None
(ANN201)
58-58: Missing return type annotation for public function test_none_input
Add return type annotation: None
(ANN201)
63-63: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
72-72: Missing return type annotation for public function test_valid_dict
Add return type annotation: None
(ANN201)
79-79: Missing return type annotation for public function test_valid_list
Add return type annotation: None
(ANN201)
86-86: Missing return type annotation for public function test_custom_indent
Add return type annotation: None
(ANN201)
92-92: Missing return type annotation for public function test_complex_object_with_datetime
Add return type annotation: None
(ANN201)
95-95: datetime.datetime.now() called without a tz argument
(DTZ005)
100-100: Missing return type annotation for public function test_circular_reference
Add return type annotation: None
(ANN201)
111-111: Missing return type annotation for public function test_string_input
Add return type annotation: None
(ANN201)
119-119: Missing return type annotation for public function test_bytes_input
Add return type annotation: None
(ANN201)
126-126: Missing return type annotation for public function test_consistent_hashing
Add return type annotation: None
(ANN201)
133-133: Missing return type annotation for public function test_different_inputs_different_hashes
Add return type annotation: None
(ANN201)
139-139: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
149-149: Missing return type annotation for public function test_successful_function
Add return type annotation: None
(ANN201)
151-151: Missing return type annotation for private function success_func
Add return type annotation: str
(ANN202)
157-157: Missing return type annotation for public function test_function_succeeds_after_retries
Add return type annotation: None
(ANN201)
161-161: Missing return type annotation for private function eventually_succeeds
Add return type annotation: str
(ANN202)
164-164: Avoid specifying long messages outside the exception class
(TRY003)
171-171: Missing return type annotation for public function test_function_fails_all_retries
Add return type annotation: None
(ANN201)
173-173: Missing return type annotation for private function always_fails
Add return type annotation: NoReturn
(ANN202)
174-174: Avoid specifying long messages outside the exception class
(TRY003)
180-180: Missing return type annotation for public function test_backoff_timing
Add return type annotation: None
(ANN201)
180-180: Missing type annotation for function argument mock_sleep
(ANN001)
182-182: Missing return type annotation for private function fails_twice
Add return type annotation: str
(ANN202)
199-199: Missing return type annotation for public function test_simple_dict
Add return type annotation: None
(ANN201)
205-205: Missing return type annotation for public function test_nested_dict
Add return type annotation: None
(ANN201)
212-212: Missing return type annotation for public function test_mixed_nested_dict
Add return type annotation: None
(ANN201)
217-217: Trailing comma missing
Add trailing comma
(COM812)
225-225: Trailing comma missing
Add trailing comma
(COM812)
229-229: Missing return type annotation for public function test_with_prefix
Add return type annotation: None
(ANN201)
235-235: Missing return type annotation for public function test_empty_dict
Add return type annotation: None
(ANN201)
244-244: Missing return type annotation for public function test_create_new_directory
Add return type annotation: None
(ANN201)
254-254: Missing return type annotation for public function test_existing_directory
Add return type annotation: None
(ANN201)
264-264: Missing return type annotation for public function test_nested_directory_creation
Add return type annotation: None
(ANN201)
274-274: Missing return type annotation for public function test_string_path_input
Add return type annotation: None
(ANN201)
288-288: Missing return type annotation for public function test_valid_filename
Add return type annotation: None
(ANN201)
294-294: Missing return type annotation for public function test_invalid_characters
Add return type annotation: None
(ANN201)
300-300: Missing return type annotation for public function test_leading_trailing_spaces_dots
Add return type annotation: None
(ANN201)
306-306: Missing return type annotation for public function test_empty_filename
Add return type annotation: None
(ANN201)
311-311: Missing return type annotation for public function test_only_invalid_characters
Add return type annotation: None
(ANN201)
317-317: Missing return type annotation for public function test_spaces_and_dots_only
Add return type annotation: None
(ANN201)
327-327: Missing return type annotation for public function test_simple_merge
Add return type annotation: None
(ANN201)
335-335: Missing return type annotation for public function test_overlapping_keys
Add return type annotation: None
(ANN201)
343-343: Missing return type annotation for public function test_nested_dict_merge
Add return type annotation: None
(ANN201)
351-351: Trailing comma missing
Add trailing comma
(COM812)
355-355: Missing return type annotation for public function test_empty_dicts
Add return type annotation: None
(ANN201)
360-360: Missing return type annotation for public function test_original_dicts_unchanged
Add return type annotation: None
(ANN201)
376-376: Missing return type annotation for public function test_even_chunks
Add return type annotation: None
(ANN201)
383-383: Missing return type annotation for public function test_uneven_chunks
Add return type annotation: None
(ANN201)
390-390: Missing return type annotation for public function test_chunk_size_larger_than_list
Add return type annotation: None
(ANN201)
397-397: Missing return type annotation for public function test_chunk_size_one
Add return type annotation: None
(ANN201)
404-404: Missing return type annotation for public function test_empty_list
Add return type annotation: None
(ANN201)
409-409: Missing return type annotation for public function test_mixed_data_types
Add return type annotation: None
(ANN201)
420-420: Missing return type annotation for public function test_seconds_format
Add return type annotation: None
(ANN201)
426-426: Missing return type annotation for public function test_minutes_format
Add return type annotation: None
(ANN201)
432-432: Missing return type annotation for public function test_hours_format
Add return type annotation: None
(ANN201)
438-438: Missing return type annotation for public function test_edge_cases
Add return type annotation: None
(ANN201)
445-445: Missing return type annotation for public function test_large_durations
Add return type annotation: None
(ANN201)
457-457: Missing return type annotation for public function test_json_and_hash_integration
Add return type annotation: None
(ANN201)
471-471: Missing return type annotation for public function test_file_operations_integration
Add return type annotation: None
(ANN201)
488-488: Missing return type annotation for public function test_data_processing_pipeline
Add return type annotation: None
(ANN201)
494-494: Trailing comma missing
Add trailing comma
(COM812)
496-496: Trailing comma missing
Add trailing comma
(COM812)
utils/helpers.py
8-8: typing.Dict is deprecated, use dict instead
(UP035)
8-8: typing.List is deprecated, use list instead
(UP035)
12-12: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
28-28: Dynamically typed expressions (typing.Any) are disallowed in data
(ANN401)
60-60: Missing return type annotation for public function retry_with_backoff
(ANN201)
60-60: Missing type annotation for function argument func
(ANN001)
72-79: Missing explicit return at the end of function able to return non-None value
Add explicit return statement
(RET503)
77-77: Use raise without specifying exception name
Remove exception name
(TRY201)
82-82: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
82-82: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
139-139: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
139-139: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
139-139: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
159-159: Use list instead of List for type annotation
Replace with list
(UP006)
159-159: Use list instead of List for type annotation
Replace with list
(UP006)
159-159: Use list instead of List for type annotation
Replace with list
(UP006)
185-185: Unnecessary elif after return statement
Remove unnecessary elif
(RET505)
🪛 Pylint (3.3.7)
utils/__init__.py
[convention] 5-5: Final newline missing
(C0304)
test_utils_helpers.py
[convention] 33-33: Trailing whitespace
(C0303)
[convention] 39-39: Trailing whitespace
(C0303)
[convention] 45-45: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 71-71: Trailing whitespace
(C0303)
[convention] 78-78: Trailing whitespace
(C0303)
[convention] 85-85: Trailing whitespace
(C0303)
[convention] 91-91: Trailing whitespace
(C0303)
[convention] 99-99: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 118-118: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[convention] 132-132: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 148-148: Trailing whitespace
(C0303)
[convention] 153-153: Trailing whitespace
(C0303)
[convention] 156-156: Trailing whitespace
(C0303)
[convention] 160-160: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 175-175: Trailing whitespace
(C0303)
[convention] 178-178: Trailing whitespace
(C0303)
[convention] 186-186: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 204-204: Trailing whitespace
(C0303)
[convention] 211-211: Trailing whitespace
(C0303)
[convention] 228-228: Trailing whitespace
(C0303)
[convention] 234-234: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 249-249: Trailing whitespace
(C0303)
[convention] 253-253: Trailing whitespace
(C0303)
[convention] 259-259: Trailing whitespace
(C0303)
[convention] 263-263: Trailing whitespace
(C0303)
[convention] 269-269: Trailing whitespace
(C0303)
[convention] 273-273: Trailing whitespace
(C0303)
[convention] 279-279: Trailing whitespace
(C0303)
[convention] 287-287: Trailing whitespace
(C0303)
[convention] 293-293: Trailing whitespace
(C0303)
[convention] 299-299: Trailing whitespace
(C0303)
[convention] 305-305: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 316-316: Trailing whitespace
(C0303)
[convention] 326-326: Trailing whitespace
(C0303)
[convention] 334-334: Trailing whitespace
(C0303)
[convention] 342-342: Trailing whitespace
(C0303)
[convention] 354-354: Trailing whitespace
(C0303)
[convention] 359-359: Trailing whitespace
(C0303)
[convention] 366-366: Trailing whitespace
(C0303)
[convention] 368-368: Trailing whitespace
(C0303)
[convention] 375-375: Trailing whitespace
(C0303)
[convention] 382-382: Trailing whitespace
(C0303)
[convention] 389-389: Trailing whitespace
(C0303)
[convention] 396-396: Trailing whitespace
(C0303)
[convention] 403-403: Trailing whitespace
(C0303)
[convention] 408-408: Trailing whitespace
(C0303)
[convention] 419-419: Trailing whitespace
(C0303)
[convention] 425-425: Trailing whitespace
(C0303)
[convention] 431-431: Trailing whitespace
(C0303)
[convention] 437-437: Trailing whitespace
(C0303)
[convention] 444-444: Trailing whitespace
(C0303)
[convention] 449-449: Trailing whitespace
(C0303)
[convention] 456-456: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 465-465: Trailing whitespace
(C0303)
[convention] 470-470: Trailing whitespace
(C0303)
[convention] 476-476: Trailing whitespace
(C0303)
[convention] 480-480: Trailing whitespace
(C0303)
[convention] 484-484: Trailing whitespace
(C0303)
[convention] 487-487: Trailing whitespace
(C0303)
[convention] 498-498: Trailing whitespace
(C0303)
[convention] 501-501: Trailing whitespace
(C0303)
[convention] 504-504: Trailing whitespace
(C0303)
[convention] 507-507: Trailing whitespace
(C0303)
[convention] 511-511: Trailing whitespace
(C0303)
[convention] 518-518: Final newline missing
(C0304)
[convention] 17-28: Import "from utils.helpers import safe_json_parse, safe_json_dumps, generate_hash, retry_with_backoff, flatten_dict, ensure_directory_exists, sanitize_filename, merge_dicts, chunk_list, format_duration" should be placed at the top of the module
(C0413)
[convention] 94-94: Import outside toplevel (datetime.datetime)
(C0415)
[convention] 238-238: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[convention] 358-358: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[convention] 8-8: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 9-9: standard import "tempfile" should be placed before third party import "pytest"
(C0411)
[convention] 10-10: standard import "time" should be placed before third party import "pytest"
(C0411)
[convention] 11-11: standard import "pathlib.Path" should be placed before third party import "pytest"
(C0411)
[convention] 12-12: standard import "unittest.mock.patch" should be placed before third party import "pytest"
(C0411)
[convention] 14-14: standard import "sys" should be placed before third party import "pytest"
(C0411)
[warning] 10-10: Unused import time
(W0611)
utils/helpers.py
[convention] 190-190: Final newline missing
(C0304)
[warning] 75-75: Catching too general exception Exception
(W0718)
[refactor] 60-60: Either all return statements in a function should return an expression, or none of them should.
(R1710)
[convention] 128-128: Import outside toplevel (re)
(C0415)
[refactor] 183-190: Unnecessary "elif" after "return", remove the leading "el" from "elif"
(R1705)
🪛 YAMLlint (1.37.1)
.github/workflows/claude.yml
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 19-19: trailing spaces
(trailing-spaces)
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 22-22: trailing spaces
(trailing-spaces)
[error] 28-28: no new line character at the end of file
(new-line-at-end-of-file)
🪛 Shellcheck (0.10.0)
scripts/auto-improve.sh
[warning] 11-11: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 13-13: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 13-13: Quote this to prevent word splitting.
(SC2046)
[warning] 24-24: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 25-25: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 30-30: Declare and assign separately to avoid masking return values.
(SC2155)
[info] 33-33: Double quote to prevent globbing and word splitting.
(SC2086)
[info] 35-35: Double quote to prevent globbing and word splitting.
(SC2086)
[info] 45-45: Double quote to prevent globbing and word splitting.
(SC2086)
[style] 55-55: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
[style] 62-62: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
[style] 70-70: Check exit code directly with e.g. 'if ! mycmd;', not indirectly with $?.
(SC2181)
🪛 LanguageTool
CLAUDE.md
[uncategorized] ~121-~121: The noun “decision-making” (= the process of deciding something) is spelled with a hyphen.
Context: ...tion_insights` - Generated insights for decision making ## Environment Setup The project uses...
(DECISION_MAKING)
🪛 markdownlint-cli2 (0.17.2)
CLAUDE.md
12-12: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
20-20: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
29-29: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
30-30: Fenced code blocks should be surrounded by blank lines
null
(MD031, blanks-around-fences)
39-39: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
40-40: Fenced code blocks should be surrounded by blank lines
null
(MD031, blanks-around-fences)
49-49: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
50-50: Fenced code blocks should be surrounded by blank lines
null
(MD031, blanks-around-fences)
57-57: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
58-58: Fenced code blocks should be surrounded by blank lines
null
(MD031, blanks-around-fences)
69-69: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
70-70: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
77-77: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
78-78: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
84-84: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
85-85: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
92-92: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
95-95: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
98-98: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
101-101: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
106-106: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
107-107: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
112-112: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
113-113: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
119-119: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
126-126: Lists should be surrounded by blank lines
null
(MD032, blanks-around-lists)
144-144: Files should end with a single newline character
null
(MD047, single-trailing-newline)
🔇 Additional comments (1)
test_utils_helpers.py (1)
31-518: Excellent test coverage!This test suite provides comprehensive coverage of all helper functions with excellent edge case testing, integration tests, and proper use of mocking for time-dependent operations. The test organization into classes and descriptive test names make it easy to understand what each test validates.
|
Note Unit test generation is an Early Access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
Docstrings generation was requested by @groupthinking. * #2 (comment) The following files were modified: * `llm/continuous_learning_system.py` * `scripts/auto-improve.sh` * `utils/helpers.py`
|
Note Generated docstrings for this pull request at #3 |
✅ Actions performedComments resolved. |
…M, workflows, config, and docs
|
Creating a local commit for the generated unit tests... The unit tests have been committed to the current branch. Commit ID: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 44
♻️ Duplicate comments (4)
test_utils_helpers.py (4)
1-1: Remove shebang or make file executableThe file has a shebang but is not executable. Since this is a test module that's typically imported rather than executed directly, remove the shebang line.
95-95: Use timezone-aware datetime
518-519: Add final newlineThe file is missing a final newline character.
7-16: Fix import orderReorganize imports according to PEP 8 standards (standard library first, then third-party, then local).
Apply this diff to fix the import order:
+import json +import sys +import tempfile +import time +from pathlib import Path +from unittest.mock import patch + import pytest -import json -import tempfile -import time -from pathlib import Path -from unittest.mock import patch -import sys sys.path.append(str(Path(__file__).parent))Note: The
timeimport appears unused in many places and could potentially be removed if not needed.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
pytest.ini(1 hunks)run_comprehensive_tests.py(1 hunks)test_config_files.py(1 hunks)test_github_workflows.py(1 hunks)test_llm_continuous_learning_system.py(1 hunks)test_utils_helpers.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
`**/*.py`: Follow PEP8, use 'black' and 'flake8' for code formatting and linting.
**/*.py: Follow PEP8, use 'black' and 'flake8' for code formatting and linting.
run_comprehensive_tests.pytest_github_workflows.pytest_config_files.pytest_utils_helpers.pytest_llm_continuous_learning_system.py
`**/*.py`: Apply black formatting, optimize imports with isort, fix flake8 issues, improve type hints, add docstrings to all public functions and classes, optimize performance, and...
**/*.py: Apply black formatting, optimize imports with isort, fix flake8 issues, improve type hints, add docstrings to all public functions and classes, optimize performance, and ensure security best practices.
run_comprehensive_tests.pytest_github_workflows.pytest_config_files.pytest_utils_helpers.pytest_llm_continuous_learning_system.py
`**/test_*.py`: Improve test coverage, add missing assertions, optimize test performance, and ensure proper mocking.
**/test_*.py: Improve test coverage, add missing assertions, optimize test performance, and ensure proper mocking.
test_github_workflows.pytest_config_files.pytest_utils_helpers.pytest_llm_continuous_learning_system.py
🪛 Flake8 (7.2.0)
run_comprehensive_tests.py
[error] 9-9: 'time' imported but unused
(F401)
[error] 11-11: expected 2 blank lines, found 1
(E302)
[warning] 15-15: blank line contains whitespace
(W293)
[warning] 19-19: trailing whitespace
(W291)
[warning] 20-20: trailing whitespace
(W291)
[warning] 24-24: blank line contains whitespace
(W293)
[warning] 31-31: blank line contains whitespace
(W293)
[warning] 35-35: trailing whitespace
(W291)
[warning] 36-36: trailing whitespace
(W291)
[warning] 40-40: blank line contains whitespace
(W293)
[warning] 47-47: blank line contains whitespace
(W293)
[error] 57-57: expected 2 blank lines after class or function definition, found 1
(E305)
[warning] 58-58: no newline at end of file
(W292)
test_github_workflows.py
[error] 7-7: 'json' imported but unused
(F401)
[error] 9-9: 'os' imported but unused
(F401)
[error] 10-10: 'unittest.mock.Mock' imported but unused
(F401)
[error] 10-10: 'unittest.mock.mock_open' imported but unused
(F401)
[error] 12-12: 'typing.Dict' imported but unused
(F401)
[error] 12-12: 'typing.List' imported but unused
(F401)
[error] 12-12: 'typing.Any' imported but unused
(F401)
[warning] 17-17: blank line contains whitespace
(W293)
[warning] 117-117: blank line contains whitespace
(W293)
[warning] 136-136: blank line contains whitespace
(W293)
[warning] 145-145: blank line contains whitespace
(W293)
[warning] 158-158: blank line contains whitespace
(W293)
[warning] 166-166: blank line contains whitespace
(W293)
[warning] 170-170: blank line contains whitespace
(W293)
[warning] 175-175: blank line contains whitespace
(W293)
[warning] 181-181: blank line contains whitespace
(W293)
[warning] 189-189: blank line contains whitespace
(W293)
[warning] 196-196: blank line contains whitespace
(W293)
[warning] 209-209: blank line contains whitespace
(W293)
[warning] 213-213: blank line contains whitespace
(W293)
[warning] 221-221: blank line contains whitespace
(W293)
[warning] 235-235: blank line contains whitespace
(W293)
[warning] 243-243: blank line contains whitespace
(W293)
[warning] 248-248: blank line contains whitespace
(W293)
[warning] 256-256: blank line contains whitespace
(W293)
[warning] 268-268: blank line contains whitespace
(W293)
[warning] 271-271: blank line contains whitespace
(W293)
[warning] 289-289: blank line contains whitespace
(W293)
[warning] 293-293: blank line contains whitespace
(W293)
[warning] 301-301: blank line contains whitespace
(W293)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 319-319: blank line contains whitespace
(W293)
[warning] 329-329: blank line contains whitespace
(W293)
[warning] 334-334: blank line contains whitespace
(W293)
[warning] 338-338: blank line contains whitespace
(W293)
[warning] 349-349: blank line contains whitespace
(W293)
[warning] 373-373: blank line contains whitespace
(W293)
[warning] 380-380: blank line contains whitespace
(W293)
[warning] 386-386: blank line contains whitespace
(W293)
[warning] 393-393: blank line contains whitespace
(W293)
[warning] 399-399: blank line contains whitespace
(W293)
[warning] 406-406: blank line contains whitespace
(W293)
[warning] 412-412: blank line contains whitespace
(W293)
[warning] 418-418: blank line contains whitespace
(W293)
[warning] 434-434: blank line contains whitespace
(W293)
[warning] 443-443: blank line contains whitespace
(W293)
[warning] 455-455: blank line contains whitespace
(W293)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 478-478: blank line contains whitespace
(W293)
[warning] 482-482: blank line contains whitespace
(W293)
[warning] 495-495: blank line contains whitespace
(W293)
[warning] 502-502: blank line contains whitespace
(W293)
[warning] 506-506: blank line contains whitespace
(W293)
[warning] 511-511: blank line contains whitespace
(W293)
[warning] 519-519: blank line contains whitespace
(W293)
[warning] 527-527: blank line contains whitespace
(W293)
[warning] 530-530: blank line contains whitespace
(W293)
[warning] 532-532: blank line contains whitespace
(W293)
[warning] 541-541: blank line contains whitespace
(W293)
[warning] 546-546: blank line contains whitespace
(W293)
[warning] 551-551: blank line contains whitespace
(W293)
[warning] 558-558: blank line contains whitespace
(W293)
[warning] 566-566: blank line contains whitespace
(W293)
[warning] 575-575: blank line contains whitespace
(W293)
[warning] 585-585: blank line contains whitespace
(W293)
[warning] 592-592: blank line contains whitespace
(W293)
[error] 599-599: 'sys' imported but unused
(F401)
[warning] 600-600: blank line contains whitespace
(W293)
[warning] 603-603: blank line contains whitespace
(W293)
[warning] 617-617: blank line contains whitespace
(W293)
[warning] 624-624: blank line contains whitespace
(W293)
[warning] 632-632: blank line contains whitespace
(W293)
[warning] 673-673: blank line contains whitespace
(W293)
[warning] 681-681: blank line contains whitespace
(W293)
[warning] 690-690: blank line contains whitespace
(W293)
[warning] 697-697: blank line contains whitespace
(W293)
[warning] 740-740: blank line contains whitespace
(W293)
[warning] 785-785: blank line contains whitespace
(W293)
[warning] 793-793: no newline at end of file
(W292)
test_config_files.py
[error] 7-7: 'unittest.mock.mock_open' imported but unused
(F401)
[error] 7-7: 'unittest.mock.MagicMock' imported but unused
(F401)
[error] 9-9: 'io.StringIO' imported but unused
(F401)
[warning] 14-14: blank line contains whitespace
(W293)
[warning] 20-20: blank line contains whitespace
(W293)
[warning] 40-40: blank line contains whitespace
(W293)
[warning] 57-57: blank line contains whitespace
(W293)
[warning] 66-66: blank line contains whitespace
(W293)
[warning] 71-71: blank line contains whitespace
(W293)
[warning] 80-80: blank line contains whitespace
(W293)
[warning] 86-86: blank line contains whitespace
(W293)
[warning] 89-89: blank line contains whitespace
(W293)
[warning] 94-94: blank line contains whitespace
(W293)
[warning] 100-100: blank line contains whitespace
(W293)
[warning] 104-104: blank line contains whitespace
(W293)
[warning] 110-110: blank line contains whitespace
(W293)
[warning] 113-113: blank line contains whitespace
(W293)
[warning] 115-115: blank line contains whitespace
(W293)
[warning] 121-121: blank line contains whitespace
(W293)
[warning] 124-124: blank line contains whitespace
(W293)
[warning] 127-127: blank line contains whitespace
(W293)
[warning] 131-131: blank line contains whitespace
(W293)
[warning] 135-135: blank line contains whitespace
(W293)
[warning] 146-146: blank line contains whitespace
(W293)
[warning] 150-150: blank line contains whitespace
(W293)
[warning] 153-153: blank line contains whitespace
(W293)
[warning] 164-164: blank line contains whitespace
(W293)
[warning] 170-170: blank line contains whitespace
(W293)
[warning] 173-173: blank line contains whitespace
(W293)
[warning] 177-177: blank line contains whitespace
(W293)
[warning] 183-183: blank line contains whitespace
(W293)
[warning] 187-187: blank line contains whitespace
(W293)
[warning] 194-194: blank line contains whitespace
(W293)
[warning] 198-198: blank line contains whitespace
(W293)
[warning] 203-203: blank line contains whitespace
(W293)
[warning] 207-207: blank line contains whitespace
(W293)
[warning] 210-210: blank line contains whitespace
(W293)
[warning] 215-215: blank line contains whitespace
(W293)
[warning] 221-221: blank line contains whitespace
(W293)
[warning] 224-224: blank line contains whitespace
(W293)
[warning] 230-230: blank line contains whitespace
(W293)
[warning] 236-236: blank line contains whitespace
(W293)
[warning] 239-239: blank line contains whitespace
(W293)
[warning] 243-243: blank line contains whitespace
(W293)
[warning] 249-249: blank line contains whitespace
(W293)
[warning] 252-252: blank line contains whitespace
(W293)
[warning] 255-255: blank line contains whitespace
(W293)
[warning] 258-258: blank line contains whitespace
(W293)
[warning] 264-264: blank line contains whitespace
(W293)
[warning] 267-267: blank line contains whitespace
(W293)
[warning] 270-270: blank line contains whitespace
(W293)
[warning] 273-273: blank line contains whitespace
(W293)
[warning] 282-282: blank line contains whitespace
(W293)
[warning] 286-286: blank line contains whitespace
(W293)
[warning] 289-289: blank line contains whitespace
(W293)
[warning] 296-296: blank line contains whitespace
(W293)
[warning] 300-300: blank line contains whitespace
(W293)
[warning] 304-304: blank line contains whitespace
(W293)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 313-313: blank line contains whitespace
(W293)
[warning] 321-321: blank line contains whitespace
(W293)
[error] 323-323: redefinition of unused 'mock_open' from line 7
(F811)
[warning] 332-332: blank line contains whitespace
(W293)
[warning] 337-337: blank line contains whitespace
(W293)
[warning] 341-341: blank line contains whitespace
(W293)
[warning] 345-345: blank line contains whitespace
(W293)
[warning] 349-349: blank line contains whitespace
(W293)
[warning] 352-352: blank line contains whitespace
(W293)
[warning] 356-356: blank line contains whitespace
(W293)
[warning] 360-360: blank line contains whitespace
(W293)
[warning] 362-362: blank line contains whitespace
(W293)
[warning] 367-367: blank line contains whitespace
(W293)
[warning] 370-370: blank line contains whitespace
(W293)
[warning] 373-373: blank line contains whitespace
(W293)
[warning] 376-376: blank line contains whitespace
(W293)
[warning] 380-380: blank line contains whitespace
(W293)
[warning] 383-383: blank line contains whitespace
(W293)
[warning] 390-390: blank line contains whitespace
(W293)
[warning] 398-398: blank line contains whitespace
(W293)
[warning] 402-402: blank line contains whitespace
(W293)
[warning] 406-406: blank line contains whitespace
(W293)
[warning] 409-409: blank line contains whitespace
(W293)
[warning] 412-412: blank line contains whitespace
(W293)
[warning] 414-414: blank line contains whitespace
(W293)
[warning] 417-417: blank line contains whitespace
(W293)
[warning] 423-423: blank line contains whitespace
(W293)
[warning] 429-429: blank line contains whitespace
(W293)
[warning] 436-436: blank line contains whitespace
(W293)
[warning] 441-441: blank line contains whitespace
(W293)
[warning] 446-446: blank line contains whitespace
(W293)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 464-464: blank line contains whitespace
(W293)
[warning] 481-481: blank line contains whitespace
(W293)
[warning] 488-488: blank line contains whitespace
(W293)
[error] 492-492: 'time' imported but unused
(F401)
[warning] 493-493: blank line contains whitespace
(W293)
[warning] 497-497: blank line contains whitespace
(W293)
[warning] 500-500: blank line contains whitespace
(W293)
[warning] 508-508: blank line contains whitespace
(W293)
[warning] 510-510: blank line contains whitespace
(W293)
[warning] 513-513: blank line contains whitespace
(W293)
[warning] 516-516: blank line contains whitespace
(W293)
[warning] 523-523: no newline at end of file
(W292)
test_utils_helpers.py
[error] 17-17: module level import not at top of file
(E402)
[warning] 33-33: blank line contains whitespace
(W293)
[warning] 39-39: blank line contains whitespace
(W293)
[warning] 45-45: blank line contains whitespace
(W293)
[warning] 51-51: blank line contains whitespace
(W293)
[warning] 57-57: blank line contains whitespace
(W293)
[warning] 62-62: blank line contains whitespace
(W293)
[warning] 71-71: blank line contains whitespace
(W293)
[warning] 78-78: blank line contains whitespace
(W293)
[warning] 85-85: blank line contains whitespace
(W293)
[warning] 91-91: blank line contains whitespace
(W293)
[warning] 99-99: blank line contains whitespace
(W293)
[warning] 110-110: blank line contains whitespace
(W293)
[warning] 118-118: blank line contains whitespace
(W293)
[warning] 125-125: blank line contains whitespace
(W293)
[warning] 132-132: blank line contains whitespace
(W293)
[warning] 138-138: blank line contains whitespace
(W293)
[warning] 148-148: blank line contains whitespace
(W293)
[warning] 153-153: blank line contains whitespace
(W293)
[warning] 156-156: blank line contains whitespace
(W293)
[warning] 160-160: blank line contains whitespace
(W293)
[warning] 166-166: blank line contains whitespace
(W293)
[warning] 170-170: blank line contains whitespace
(W293)
[warning] 175-175: blank line contains whitespace
(W293)
[warning] 178-178: blank line contains whitespace
(W293)
[warning] 186-186: blank line contains whitespace
(W293)
[warning] 189-189: blank line contains whitespace
(W293)
[warning] 198-198: blank line contains whitespace
(W293)
[warning] 204-204: blank line contains whitespace
(W293)
[warning] 211-211: blank line contains whitespace
(W293)
[warning] 228-228: blank line contains whitespace
(W293)
[warning] 234-234: blank line contains whitespace
(W293)
[warning] 243-243: blank line contains whitespace
(W293)
[warning] 249-249: blank line contains whitespace
(W293)
[warning] 253-253: blank line contains whitespace
(W293)
[warning] 259-259: blank line contains whitespace
(W293)
[warning] 263-263: blank line contains whitespace
(W293)
[warning] 269-269: blank line contains whitespace
(W293)
[warning] 273-273: blank line contains whitespace
(W293)
[warning] 279-279: blank line contains whitespace
(W293)
[warning] 287-287: blank line contains whitespace
(W293)
[warning] 293-293: blank line contains whitespace
(W293)
[warning] 299-299: blank line contains whitespace
(W293)
[warning] 305-305: blank line contains whitespace
(W293)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 316-316: blank line contains whitespace
(W293)
[warning] 326-326: blank line contains whitespace
(W293)
[warning] 334-334: blank line contains whitespace
(W293)
[warning] 342-342: blank line contains whitespace
(W293)
[warning] 354-354: blank line contains whitespace
(W293)
[warning] 359-359: blank line contains whitespace
(W293)
[warning] 366-366: blank line contains whitespace
(W293)
[warning] 368-368: blank line contains whitespace
(W293)
[warning] 375-375: blank line contains whitespace
(W293)
[warning] 382-382: blank line contains whitespace
(W293)
[warning] 389-389: blank line contains whitespace
(W293)
[warning] 396-396: blank line contains whitespace
(W293)
[warning] 403-403: blank line contains whitespace
(W293)
[warning] 408-408: blank line contains whitespace
(W293)
[warning] 419-419: blank line contains whitespace
(W293)
[warning] 425-425: blank line contains whitespace
(W293)
[warning] 431-431: blank line contains whitespace
(W293)
[warning] 437-437: blank line contains whitespace
(W293)
[warning] 444-444: blank line contains whitespace
(W293)
[warning] 449-449: blank line contains whitespace
(W293)
[warning] 456-456: blank line contains whitespace
(W293)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 465-465: blank line contains whitespace
(W293)
[warning] 470-470: blank line contains whitespace
(W293)
[warning] 476-476: blank line contains whitespace
(W293)
[warning] 480-480: blank line contains whitespace
(W293)
[warning] 484-484: blank line contains whitespace
(W293)
[warning] 487-487: blank line contains whitespace
(W293)
[warning] 498-498: blank line contains whitespace
(W293)
[warning] 501-501: blank line contains whitespace
(W293)
[warning] 504-504: blank line contains whitespace
(W293)
[warning] 507-507: blank line contains whitespace
(W293)
[warning] 511-511: blank line contains whitespace
(W293)
[error] 521-521: expected 2 blank lines, found 1
(E302)
[warning] 523-523: blank line contains whitespace
(W293)
[warning] 530-530: blank line contains whitespace
(W293)
[warning] 533-533: blank line contains whitespace
(W293)
[warning] 540-540: blank line contains whitespace
(W293)
[warning] 549-549: blank line contains whitespace
(W293)
[warning] 554-554: blank line contains whitespace
(W293)
[error] 559-559: at least two spaces before inline comment
(E261)
[error] 560-560: at least two spaces before inline comment
(E261)
[warning] 563-563: blank line contains whitespace
(W293)
[warning] 568-568: blank line contains whitespace
(W293)
[warning] 586-586: blank line contains whitespace
(W293)
[warning] 593-593: blank line contains whitespace
(W293)
[warning] 596-596: blank line contains whitespace
(W293)
[warning] 602-602: blank line contains whitespace
(W293)
[warning] 605-605: blank line contains whitespace
(W293)
[warning] 608-608: blank line contains whitespace
(W293)
[warning] 612-612: blank line contains whitespace
(W293)
[warning] 617-617: blank line contains whitespace
(W293)
[warning] 626-626: blank line contains whitespace
(W293)
[warning] 629-629: blank line contains whitespace
(W293)
[warning] 640-640: blank line contains whitespace
(W293)
[warning] 645-645: blank line contains whitespace
(W293)
[warning] 652-652: blank line contains whitespace
(W293)
[warning] 657-657: blank line contains whitespace
(W293)
[warning] 663-663: blank line contains whitespace
(W293)
[warning] 667-667: blank line contains whitespace
(W293)
[warning] 672-672: blank line contains whitespace
(W293)
[warning] 676-676: blank line contains whitespace
(W293)
[warning] 682-682: blank line contains whitespace
(W293)
[warning] 685-685: blank line contains whitespace
(W293)
[warning] 690-690: blank line contains whitespace
(W293)
[warning] 694-694: blank line contains whitespace
(W293)
[warning] 699-699: blank line contains whitespace
(W293)
[warning] 708-708: blank line contains whitespace
(W293)
[warning] 713-713: trailing whitespace
(W291)
[warning] 716-716: blank line contains whitespace
(W293)
[warning] 718-718: blank line contains whitespace
(W293)
[warning] 725-725: blank line contains whitespace
(W293)
[warning] 729-729: blank line contains whitespace
(W293)
[warning] 734-734: blank line contains whitespace
(W293)
[warning] 740-740: blank line contains whitespace
(W293)
[warning] 743-743: blank line contains whitespace
(W293)
[warning] 748-748: blank line contains whitespace
(W293)
[warning] 753-753: blank line contains whitespace
(W293)
[warning] 763-763: blank line contains whitespace
(W293)
[warning] 766-766: blank line contains whitespace
(W293)
[warning] 770-770: blank line contains whitespace
(W293)
[error] 771-771: local variable 'start_time' is assigned to but never used
(F841)
[warning] 773-773: blank line contains whitespace
(W293)
[warning] 779-779: blank line contains whitespace
(W293)
[warning] 781-781: blank line contains whitespace
(W293)
[warning] 784-784: blank line contains whitespace
(W293)
[warning] 794-794: blank line contains whitespace
(W293)
[warning] 818-818: blank line contains whitespace
(W293)
[warning] 820-820: blank line contains whitespace
(W293)
[warning] 831-831: blank line contains whitespace
(W293)
[warning] 834-834: blank line contains whitespace
(W293)
[error] 839-839: dictionary key 1 repeated with different values
(F601)
[error] 841-841: dictionary key 1 repeated with different values
(F601)
[warning] 845-845: blank line contains whitespace
(W293)
[warning] 847-847: blank line contains whitespace
(W293)
[warning] 850-850: trailing whitespace
(W291)
[warning] 854-854: blank line contains whitespace
(W293)
[warning] 856-856: blank line contains whitespace
(W293)
[warning] 860-860: blank line contains whitespace
(W293)
[warning] 864-864: blank line contains whitespace
(W293)
[warning] 874-874: blank line contains whitespace
(W293)
[warning] 887-887: blank line contains whitespace
(W293)
[warning] 892-892: blank line contains whitespace
(W293)
[warning] 895-895: blank line contains whitespace
(W293)
[warning] 902-902: blank line contains whitespace
(W293)
[warning] 907-907: blank line contains whitespace
(W293)
[warning] 912-912: blank line contains whitespace
(W293)
[warning] 919-919: blank line contains whitespace
(W293)
[warning] 926-926: blank line contains whitespace
(W293)
[warning] 930-930: blank line contains whitespace
(W293)
[warning] 936-936: blank line contains whitespace
(W293)
[error] 949-949: at least two spaces before inline comment
(E261)
[warning] 951-951: blank line contains whitespace
(W293)
[warning] 960-960: blank line contains whitespace
(W293)
[warning] 969-969: blank line contains whitespace
(W293)
[warning] 980-980: blank line contains whitespace
(W293)
[warning] 990-990: trailing whitespace
(W291)
[warning] 993-993: blank line contains whitespace
(W293)
[warning] 995-995: blank line contains whitespace
(W293)
[warning] 1000-1000: blank line contains whitespace
(W293)
[warning] 1005-1005: blank line contains whitespace
(W293)
[warning] 1007-1007: blank line contains whitespace
(W293)
[warning] 1011-1011: blank line contains whitespace
(W293)
[warning] 1026-1026: blank line contains whitespace
(W293)
[warning] 1028-1028: blank line contains whitespace
(W293)
[warning] 1033-1033: blank line contains whitespace
(W293)
[warning] 1038-1038: blank line contains whitespace
(W293)
[warning] 1042-1042: blank line contains whitespace
(W293)
[warning] 1044-1044: blank line contains whitespace
(W293)
[warning] 1048-1048: blank line contains whitespace
(W293)
[warning] 1057-1057: blank line contains whitespace
(W293)
[warning] 1062-1062: blank line contains whitespace
(W293)
[warning] 1067-1067: blank line contains whitespace
(W293)
[warning] 1070-1070: blank line contains whitespace
(W293)
[warning] 1075-1075: blank line contains whitespace
(W293)
[warning] 1080-1080: blank line contains whitespace
(W293)
[warning] 1082-1082: blank line contains whitespace
(W293)
[warning] 1086-1086: blank line contains whitespace
(W293)
[warning] 1090-1090: blank line contains whitespace
(W293)
[warning] 1094-1094: trailing whitespace
(W291)
[warning] 1095-1095: trailing whitespace
(W291)
[warning] 1098-1098: blank line contains whitespace
(W293)
[warning] 1100-1100: blank line contains whitespace
(W293)
[warning] 1106-1106: blank line contains whitespace
(W293)
[warning] 1110-1110: blank line contains whitespace
(W293)
[warning] 1117-1117: blank line contains whitespace
(W293)
[warning] 1121-1121: blank line contains whitespace
(W293)
[warning] 1125-1125: blank line contains whitespace
(W293)
[warning] 1133-1133: blank line contains whitespace
(W293)
[warning] 1144-1144: blank line contains whitespace
(W293)
[warning] 1157-1157: blank line contains whitespace
(W293)
[warning] 1165-1165: blank line contains whitespace
(W293)
[warning] 1172-1172: blank line contains whitespace
(W293)
[warning] 1179-1179: blank line contains whitespace
(W293)
[warning] 1187-1187: blank line contains whitespace
(W293)
[warning] 1201-1201: blank line contains whitespace
(W293)
[warning] 1210-1210: blank line contains whitespace
(W293)
[warning] 1215-1215: blank line contains whitespace
(W293)
[warning] 1220-1220: blank line contains whitespace
(W293)
[warning] 1224-1224: blank line contains whitespace
(W293)
[warning] 1228-1228: blank line contains whitespace
(W293)
[warning] 1232-1232: blank line contains whitespace
(W293)
[warning] 1235-1235: blank line contains whitespace
(W293)
[warning] 1242-1242: blank line contains whitespace
(W293)
[warning] 1247-1247: blank line contains whitespace
(W293)
[warning] 1253-1253: blank line contains whitespace
(W293)
[warning] 1256-1256: blank line contains whitespace
(W293)
[warning] 1262-1262: blank line contains whitespace
(W293)
[warning] 1270-1270: blank line contains whitespace
(W293)
[warning] 1283-1283: blank line contains whitespace
(W293)
[warning] 1286-1286: blank line contains whitespace
(W293)
[warning] 1293-1293: blank line contains whitespace
(W293)
[warning] 1297-1297: blank line contains whitespace
(W293)
[warning] 1306-1306: blank line contains whitespace
(W293)
[warning] 1308-1308: blank line contains whitespace
(W293)
[warning] 1314-1314: blank line contains whitespace
(W293)
[warning] 1317-1317: blank line contains whitespace
(W293)
[warning] 1320-1320: blank line contains whitespace
(W293)
[warning] 1330-1330: blank line contains whitespace
(W293)
[warning] 1334-1334: blank line contains whitespace
(W293)
[warning] 1336-1336: blank line contains whitespace
(W293)
[warning] 1339-1339: blank line contains whitespace
(W293)
[warning] 1344-1344: blank line contains whitespace
(W293)
[warning] 1355-1355: blank line contains whitespace
(W293)
[warning] 1361-1361: blank line contains whitespace
(W293)
[warning] 1364-1364: blank line contains whitespace
(W293)
[warning] 1375-1375: blank line contains whitespace
(W293)
[warning] 1381-1381: blank line contains whitespace
(W293)
[warning] 1383-1383: blank line contains whitespace
(W293)
[warning] 1386-1386: blank line contains whitespace
(W293)
[warning] 1393-1393: blank line contains whitespace
(W293)
[warning] 1397-1397: blank line contains whitespace
(W293)
[warning] 1402-1402: blank line contains whitespace
(W293)
[warning] 1409-1409: blank line contains whitespace
(W293)
[warning] 1418-1418: blank line contains whitespace
(W293)
[warning] 1420-1420: blank line contains whitespace
(W293)
[warning] 1425-1425: blank line contains whitespace
(W293)
[warning] 1430-1430: blank line contains whitespace
(W293)
[warning] 1435-1435: blank line contains whitespace
(W293)
[warning] 1440-1440: blank line contains whitespace
(W293)
test_llm_continuous_learning_system.py
[error] 20-20: 'json' imported but unused
(F401)
[error] 25-25: 'unittest.mock.patch' imported but unused
(F401)
[error] 25-25: 'unittest.mock.MagicMock' imported but unused
(F401)
[error] 25-25: 'unittest.mock.call' imported but unused
(F401)
[warning] 89-89: blank line contains whitespace
(W293)
[warning] 112-112: blank line contains whitespace
(W293)
[error] 163-163: continuation line under-indented for visual indent
(E128)
[warning] 173-173: blank line contains whitespace
(W293)
[warning] 218-218: blank line contains whitespace
(W293)
[warning] 220-220: blank line contains whitespace
(W293)
[warning] 227-227: blank line contains whitespace
(W293)
[warning] 237-237: blank line contains whitespace
(W293)
[warning] 244-244: blank line contains whitespace
(W293)
[warning] 251-251: blank line contains whitespace
(W293)
[warning] 258-258: blank line contains whitespace
(W293)
[warning] 265-265: blank line contains whitespace
(W293)
[warning] 272-272: blank line contains whitespace
(W293)
[warning] 280-280: blank line contains whitespace
(W293)
[warning] 287-287: blank line contains whitespace
(W293)
[warning] 298-298: blank line contains whitespace
(W293)
[warning] 307-307: blank line contains whitespace
(W293)
[warning] 309-309: blank line contains whitespace
(W293)
[warning] 319-319: blank line contains whitespace
(W293)
[warning] 321-321: blank line contains whitespace
(W293)
[warning] 333-333: blank line contains whitespace
(W293)
[warning] 335-335: blank line contains whitespace
(W293)
[warning] 380-380: blank line contains whitespace
(W293)
[warning] 382-382: blank line contains whitespace
(W293)
[warning] 396-396: blank line contains whitespace
(W293)
[warning] 399-399: blank line contains whitespace
(W293)
[warning] 406-406: blank line contains whitespace
(W293)
[warning] 415-415: blank line contains whitespace
(W293)
[warning] 417-417: blank line contains whitespace
(W293)
[warning] 426-426: blank line contains whitespace
(W293)
[warning] 428-428: blank line contains whitespace
(W293)
[warning] 436-436: blank line contains whitespace
(W293)
[warning] 439-439: blank line contains whitespace
(W293)
[warning] 446-446: blank line contains whitespace
(W293)
[warning] 448-448: blank line contains whitespace
(W293)
[warning] 456-456: blank line contains whitespace
(W293)
[warning] 458-458: blank line contains whitespace
(W293)
[warning] 466-466: blank line contains whitespace
(W293)
[warning] 468-468: blank line contains whitespace
(W293)
[warning] 475-475: blank line contains whitespace
(W293)
[warning] 528-528: blank line contains whitespace
(W293)
[warning] 530-530: blank line contains whitespace
(W293)
[warning] 538-538: blank line contains whitespace
(W293)
[warning] 540-540: blank line contains whitespace
(W293)
[warning] 547-547: blank line contains whitespace
(W293)
[warning] 554-554: blank line contains whitespace
(W293)
[warning] 561-561: blank line contains whitespace
(W293)
[warning] 580-580: blank line contains whitespace
(W293)
[warning] 582-582: blank line contains whitespace
(W293)
[warning] 593-593: trailing whitespace
(W291)
[error] 594-594: continuation line under-indented for visual indent
(E128)
[warning] 597-597: blank line contains whitespace
(W293)
[warning] 649-649: blank line contains whitespace
(W293)
[warning] 662-662: blank line contains whitespace
(W293)
[warning] 664-664: blank line contains whitespace
(W293)
[warning] 675-675: blank line contains whitespace
(W293)
[warning] 677-677: blank line contains whitespace
(W293)
[warning] 685-685: blank line contains whitespace
(W293)
[warning] 693-693: blank line contains whitespace
(W293)
[warning] 731-731: blank line contains whitespace
(W293)
[warning] 733-733: blank line contains whitespace
(W293)
[warning] 741-741: blank line contains whitespace
(W293)
[warning] 751-751: blank line contains whitespace
(W293)
[warning] 763-763: blank line contains whitespace
(W293)
[warning] 799-799: blank line contains whitespace
(W293)
[warning] 816-816: blank line contains whitespace
(W293)
[warning] 818-818: blank line contains whitespace
(W293)
[warning] 833-833: blank line contains whitespace
(W293)
[warning] 835-835: blank line contains whitespace
(W293)
[warning] 848-848: blank line contains whitespace
(W293)
[warning] 887-887: blank line contains whitespace
(W293)
[warning] 897-897: blank line contains whitespace
(W293)
[warning] 907-907: blank line contains whitespace
(W293)
[warning] 917-917: blank line contains whitespace
(W293)
[warning] 928-928: blank line contains whitespace
(W293)
[warning] 939-939: blank line contains whitespace
(W293)
[warning] 950-950: blank line contains whitespace
(W293)
[warning] 1005-1005: blank line contains whitespace
(W293)
[warning] 1014-1014: blank line contains whitespace
(W293)
[warning] 1016-1016: blank line contains whitespace
(W293)
[warning] 1019-1019: blank line contains whitespace
(W293)
[warning] 1022-1022: blank line contains whitespace
(W293)
[warning] 1025-1025: blank line contains whitespace
(W293)
[warning] 1036-1036: blank line contains whitespace
(W293)
[warning] 1039-1039: blank line contains whitespace
(W293)
[warning] 1043-1043: blank line contains whitespace
(W293)
[warning] 1053-1053: blank line contains whitespace
(W293)
[warning] 1055-1055: blank line contains whitespace
(W293)
[warning] 1058-1058: blank line contains whitespace
(W293)
[warning] 1061-1061: blank line contains whitespace
(W293)
[warning] 1099-1099: blank line contains whitespace
(W293)
[warning] 1101-1101: blank line contains whitespace
(W293)
[warning] 1112-1112: blank line contains whitespace
(W293)
[warning] 1122-1122: blank line contains whitespace
(W293)
[warning] 1133-1133: blank line contains whitespace
(W293)
[warning] 1146-1146: blank line contains whitespace
(W293)
[warning] 1156-1156: blank line contains whitespace
(W293)
[warning] 1158-1158: blank line contains whitespace
(W293)
[warning] 1167-1167: blank line contains whitespace
(W293)
[warning] 1169-1169: blank line contains whitespace
(W293)
[warning] 1177-1177: blank line contains whitespace
(W293)
[warning] 1182-1182: blank line contains whitespace
(W293)
[error] 1234-1234: undefined name 'Tuple'
(F821)
[error] 1254-1254: expected 2 blank lines, found 1
(E302)
[warning] 1259-1259: no newline at end of file
(W292)
🪛 Ruff (0.11.9)
run_comprehensive_tests.py
1-1: Shebang is present but file is not executable
(EXE001)
9-9: time imported but unused
Remove unused import: time
(F401)
11-11: Missing return type annotation for public function run_tests
Add return type annotation: int
(ANN201)
18-18: subprocess call: check for execution of untrusted input
(S603)
22-22: Trailing comma missing
Add trailing comma
(COM812)
34-34: subprocess call: check for execution of untrusted input
(S603)
38-38: Trailing comma missing
Add trailing comma
(COM812)
53-53: Unnecessary else after return statement
Remove unnecessary else
(RET505)
test_github_workflows.py
7-7: json imported but unused
Remove unused import: json
(F401)
9-9: os imported but unused
Remove unused import: os
(F401)
10-10: unittest.mock.Mock imported but unused
Remove unused import
(F401)
10-10: unittest.mock.mock_open imported but unused
Remove unused import
(F401)
12-12: typing.Dict is deprecated, use dict instead
(UP035)
12-12: typing.List is deprecated, use list instead
(UP035)
12-12: typing.Dict imported but unused
Remove unused import
(F401)
12-12: typing.List imported but unused
Remove unused import
(F401)
12-12: typing.Any imported but unused
Remove unused import
(F401)
19-19: Missing return type annotation for public function sample_workflow_yaml
Add return type annotation: str
(ANN201)
44-44: Missing return type annotation for public function invalid_workflow_yaml
Add return type annotation: str
(ANN201)
59-59: Missing return type annotation for public function complex_workflow_yaml
Add return type annotation: str
(ANN201)
107-107: Missing return type annotation for public function mock_workflow_file
(ANN201)
107-107: Missing type annotation for function argument tmp_path
(ANN001)
107-107: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
114-114: Missing return type annotation for public function test_parse_valid_workflow_yaml
Add return type annotation: None
(ANN201)
114-114: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
125-125: Missing return type annotation for public function test_parse_invalid_workflow_yaml
Add return type annotation: None
(ANN201)
125-125: Missing type annotation for function argument invalid_workflow_yaml
(ANN001)
130-130: Missing return type annotation for public function test_workflow_validation_missing_required_fields
Add return type annotation: None
(ANN201)
133-133: Trailing comma missing
Add trailing comma
(COM812)
141-141: Missing return type annotation for public function test_workflow_job_validation
Add return type annotation: None
(ANN201)
141-141: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
151-151: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
155-155: Missing return type annotation for public function test_workflow_triggers
Add return type annotation: None
(ANN201)
155-155: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
155-155: Missing type annotation for function argument trigger_event
(ANN001)
155-155: Missing type annotation for function argument expected_branches
(ANN001)
163-163: Missing return type annotation for public function test_complex_workflow_structure
Add return type annotation: None
(ANN201)
163-163: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
186-186: Missing return type annotation for public function test_workflow_environment_variables
Add return type annotation: None
(ANN201)
186-186: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
193-193: Missing return type annotation for public function test_workflow_outputs
Add return type annotation: None
(ANN201)
193-193: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
201-201: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
205-205: Missing return type annotation for public function test_workflow_step_types
Add return type annotation: None
(ANN201)
205-205: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
205-205: Missing type annotation for function argument step_type
(ANN001)
205-205: Unused method argument: step_type
(ARG002)
205-205: Missing type annotation for function argument required_field
(ANN001)
223-223: Missing return type annotation for public function validator_config
(ANN201)
229-229: Trailing comma missing
Add trailing comma
(COM812)
232-232: Missing return type annotation for public function test_validate_workflow_structure_valid
Add return type annotation: None
(ANN201)
232-232: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
232-232: Missing type annotation for function argument validator_config
(ANN001)
240-240: Missing return type annotation for public function test_validate_workflow_structure_missing_fields
Add return type annotation: None
(ANN201)
240-240: Missing type annotation for function argument validator_config
(ANN001)
253-253: Missing return type annotation for public function test_validate_runner_allowed
Add return type annotation: None
(ANN201)
253-253: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
253-253: Missing type annotation for function argument validator_config
(ANN001)
257-257: Loop control variable job_name not used within loop body
Rename unused job_name to _job_name
(B007)
260-262: Use a single if statement instead of nested if statements
(SIM102)
265-265: Missing return type annotation for public function test_validate_job_limits
Add return type annotation: None
(ANN201)
265-265: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
265-265: Missing type annotation for function argument validator_config
(ANN001)
273-273: Loop control variable job_name not used within loop body
Rename unused job_name to _job_name
(B007)
282-282: Missing return type annotation for public function test_validate_runner_not_allowed
Add return type annotation: None
(ANN201)
282-282: Missing type annotation for function argument invalid_runner
(ANN001)
282-282: Missing type annotation for function argument validator_config
(ANN001)
290-290: Missing return type annotation for public function test_read_workflow_file
Add return type annotation: None
(ANN201)
290-290: Missing type annotation for function argument mock_workflow_file
(ANN001)
298-298: Missing return type annotation for public function test_read_nonexistent_workflow_file
Add return type annotation: None
(ANN201)
298-298: Missing type annotation for function argument tmp_path
(ANN001)
307-307: Missing return type annotation for public function test_read_workflow_file_permission_error
Add return type annotation: None
(ANN201)
307-307: Missing type annotation for function argument mock_read_text
(ANN001)
315-315: Missing return type annotation for public function test_write_workflow_file
Add return type annotation: None
(ANN201)
315-315: Missing type annotation for function argument tmp_path
(ANN001)
315-315: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
324-324: Missing return type annotation for public function test_discover_workflow_files
Add return type annotation: None
(ANN201)
324-324: Missing type annotation for function argument tmp_path
(ANN001)
351-351: Missing return type annotation for public function insecure_workflow_yaml
Add return type annotation: str
(ANN201)
370-370: Missing return type annotation for public function test_detect_pull_request_target_trigger
Add return type annotation: None
(ANN201)
370-370: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
377-377: Missing return type annotation for public function test_detect_outdated_actions
Add return type annotation: None
(ANN201)
377-377: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
390-390: Missing return type annotation for public function test_detect_secret_exposure
Add return type annotation: None
(ANN201)
390-390: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
403-403: Missing return type annotation for public function test_detect_code_injection_risk
Add return type annotation: None
(ANN201)
403-403: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
419-419: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
425-425: Missing return type annotation for public function test_generate_workflow_filename
Add return type annotation: None
(ANN201)
425-425: Missing type annotation for function argument workflow_name
(ANN001)
425-425: Missing type annotation for function argument expected_filename
(ANN001)
431-431: Missing return type annotation for public function test_extract_workflow_metadata
Add return type annotation: None
(ANN201)
431-431: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
441-441: Trailing comma missing
Add trailing comma
(COM812)
452-452: Missing return type annotation for public function test_workflow_dependency_graph
Add return type annotation: None
(ANN201)
452-452: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
467-467: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
474-474: Missing return type annotation for public function test_validate_cron_expressions
Add return type annotation: None
(ANN201)
474-474: Missing type annotation for function argument cron_expression
(ANN001)
474-474: Missing type annotation for function argument is_valid
(ANN001)
484-487: Combine if branches using logical or operator
Combine if branches
(SIM114)
496-496: Missing return type annotation for public function test_end_to_end_workflow_processing
Add return type annotation: None
(ANN201)
496-496: Missing type annotation for function argument tmp_path
(ANN001)
496-496: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
517-517: Trailing comma missing
Add trailing comma
(COM812)
524-524: Missing return type annotation for public function test_workflow_processing_with_yaml_error
Add return type annotation: None
(ANN201)
524-524: Missing type annotation for function argument mock_yaml_load
(ANN001)
524-524: Missing type annotation for function argument tmp_path
(ANN001)
536-536: Missing return type annotation for public function test_batch_workflow_validation
Add return type annotation: None
(ANN201)
536-536: Missing type annotation for function argument tmp_path
(ANN001)
556-556: Do not catch blind exception: Exception
(BLE001)
567-567: Missing return type annotation for public function test_large_workflow_parsing_performance
Add return type annotation: None
(ANN201)
573-573: Trailing comma missing
Add trailing comma
(COM812)
582-582: Trailing comma missing
Add trailing comma
(COM812)
583-583: Trailing comma missing
Add trailing comma
(COM812)
597-597: Missing return type annotation for public function test_memory_usage_with_multiple_workflows
Add return type annotation: None
(ANN201)
597-597: Missing type annotation for function argument tmp_path
(ANN001)
599-599: sys imported but unused
Remove unused import: sys
(F401)
634-634: Missing return type annotation for public function edge_case_workflows
(ANN201)
644-644: Trailing comma missing
Add trailing comma
(COM812)
645-645: Trailing comma missing
Add trailing comma
(COM812)
646-646: Trailing comma missing
Add trailing comma
(COM812)
654-654: Trailing comma missing
Add trailing comma
(COM812)
655-655: Trailing comma missing
Add trailing comma
(COM812)
656-656: Trailing comma missing
Add trailing comma
(COM812)
664-664: Trailing comma missing
Add trailing comma
(COM812)
665-665: Trailing comma missing
Add trailing comma
(COM812)
666-666: Trailing comma missing
Add trailing comma
(COM812)
667-667: Trailing comma missing
Add trailing comma
(COM812)
670-670: Missing return type annotation for public function test_empty_workflow_handling
Add return type annotation: None
(ANN201)
670-670: Missing type annotation for function argument edge_case_workflows
(ANN001)
678-678: Missing return type annotation for public function test_minimal_workflow_validation
Add return type annotation: None
(ANN201)
678-678: Missing type annotation for function argument edge_case_workflows
(ANN001)
687-687: Missing return type annotation for public function test_unicode_support_in_workflows
Add return type annotation: None
(ANN201)
687-687: Missing type annotation for function argument edge_case_workflows
(ANN001)
694-694: Missing return type annotation for public function test_large_string_handling
Add return type annotation: None
(ANN201)
694-694: Missing type annotation for function argument edge_case_workflows
(ANN001)
707-707: Missing return type annotation for public function test_malformed_yaml_handling
Add return type annotation: None
(ANN201)
707-707: Missing type annotation for function argument invalid_yaml
(ANN001)
712-712: Missing return type annotation for public function test_deeply_nested_workflow_structure
Add return type annotation: None
(ANN201)
719-719: Trailing comma missing
Add trailing comma
(COM812)
723-723: Trailing comma missing
Add trailing comma
(COM812)
724-724: Trailing comma missing
Add trailing comma
(COM812)
733-733: Trailing comma missing
Add trailing comma
(COM812)
734-734: Trailing comma missing
Add trailing comma
(COM812)
735-735: Trailing comma missing
Add trailing comma
(COM812)
736-736: Trailing comma missing
Add trailing comma
(COM812)
737-737: Trailing comma missing
Add trailing comma
(COM812)
738-738: Trailing comma missing
Add trailing comma
(COM812)
745-745: Missing return type annotation for public function test_workflow_with_all_trigger_types
Add return type annotation: None
(ANN201)
776-776: Trailing comma missing
Add trailing comma
(COM812)
781-781: Trailing comma missing
Add trailing comma
(COM812)
782-782: Trailing comma missing
Add trailing comma
(COM812)
783-783: Trailing comma missing
Add trailing comma
(COM812)
test_config_files.py
7-7: unittest.mock.mock_open imported but unused
Remove unused import
(F401)
7-7: unittest.mock.MagicMock imported but unused
Remove unused import
(F401)
9-9: io.StringIO imported but unused
Remove unused import: io.StringIO
(F401)
16-16: Missing return type annotation for public function temp_config_dir
(ANN201)
22-22: Missing return type annotation for public function sample_json_config
(ANN201)
28-28: Trailing comma missing
Add trailing comma
(COM812)
33-33: Trailing comma missing
Add trailing comma
(COM812)
37-37: Trailing comma missing
Add trailing comma
(COM812)
38-38: Trailing comma missing
Add trailing comma
(COM812)
42-42: Missing return type annotation for public function sample_yaml_config
Add return type annotation: str
(ANN201)
59-59: Missing return type annotation for public function sample_ini_config
Add return type annotation: str
(ANN201)
81-81: Missing return type annotation for public function test_valid_json_config_loading
Add return type annotation: None
(ANN201)
81-81: Missing type annotation for function argument temp_config_dir
(ANN001)
81-81: Missing type annotation for function argument sample_json_config
(ANN001)
87-87: Unnecessary mode argument
Remove mode argument
(UP015)
95-95: Missing return type annotation for public function test_invalid_json_config_syntax
Add return type annotation: None
(ANN201)
95-95: Missing type annotation for function argument temp_config_dir
(ANN001)
101-102: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
102-102: Unnecessary mode argument
Remove mode argument
(UP015)
105-105: Missing return type annotation for public function test_empty_json_config
Add return type annotation: None
(ANN201)
105-105: Missing type annotation for function argument temp_config_dir
(ANN001)
111-111: Unnecessary mode argument
Remove mode argument
(UP015)
116-116: Missing return type annotation for public function test_json_config_schema_validation
Add return type annotation: None
(ANN201)
116-116: Missing type annotation for function argument temp_config_dir
(ANN001)
125-125: Unnecessary mode argument
Remove mode argument
(UP015)
136-136: Missing return type annotation for public function test_json_config_data_types
Add return type annotation: None
(ANN201)
136-136: Missing type annotation for function argument temp_config_dir
(ANN001)
144-144: Trailing comma missing
Add trailing comma
(COM812)
151-151: Unnecessary mode argument
Remove mode argument
(UP015)
165-165: Missing return type annotation for public function test_valid_yaml_config_loading
Add return type annotation: None
(ANN201)
165-165: Missing type annotation for function argument temp_config_dir
(ANN001)
165-165: Missing type annotation for function argument sample_yaml_config
(ANN001)
171-171: Unnecessary mode argument
Remove mode argument
(UP015)
178-178: Missing return type annotation for public function test_invalid_yaml_syntax
Add return type annotation: None
(ANN201)
178-178: Missing type annotation for function argument temp_config_dir
(ANN001)
184-185: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
185-185: Unnecessary mode argument
Remove mode argument
(UP015)
188-188: Missing return type annotation for public function test_yaml_config_with_references
Add return type annotation: None
(ANN201)
188-188: Missing type annotation for function argument temp_config_dir
(ANN001)
208-208: Unnecessary mode argument
Remove mode argument
(UP015)
216-216: Missing return type annotation for public function test_empty_yaml_config
Add return type annotation: None
(ANN201)
216-216: Missing type annotation for function argument temp_config_dir
(ANN001)
222-222: Unnecessary mode argument
Remove mode argument
(UP015)
231-231: Missing return type annotation for public function test_valid_ini_config_loading
Add return type annotation: None
(ANN201)
231-231: Missing type annotation for function argument temp_config_dir
(ANN001)
231-231: Missing type annotation for function argument sample_ini_config
(ANN001)
244-244: Missing return type annotation for public function test_ini_config_missing_section
Add return type annotation: None
(ANN201)
244-244: Missing type annotation for function argument temp_config_dir
(ANN001)
259-259: Missing return type annotation for public function test_ini_config_missing_option
Add return type annotation: None
(ANN201)
259-259: Missing type annotation for function argument temp_config_dir
(ANN001)
274-274: Missing return type annotation for public function test_ini_config_interpolation
Add return type annotation: None
(ANN201)
274-274: Missing type annotation for function argument temp_config_dir
(ANN001)
297-297: Missing return type annotation for public function test_file_not_found_error
Add return type annotation: None
(ANN201)
301-302: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
302-302: Unnecessary mode argument
Remove mode argument
(UP015)
305-305: Missing return type annotation for public function test_permission_denied_error
Add return type annotation: None
(ANN201)
305-305: Missing type annotation for function argument temp_config_dir
(ANN001)
315-316: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
316-316: Unnecessary mode argument
Remove mode argument
(UP015)
322-322: Replace aliased errors with OSError
Replace IOError with builtin OSError
(UP024)
323-323: Missing return type annotation for public function test_io_error_handling
Add return type annotation: None
(ANN201)
323-323: Missing type annotation for function argument mock_open
(ANN001)
323-323: Redefinition of unused mock_open from line 7
(F811)
323-323: Unused method argument: mock_open
(ARG002)
325-326: Use a single with statement with multiple contexts instead of nested with statements
Combine with statements
(SIM117)
325-325: pytest.raises(IOError) is too broad, set the match parameter or use a more specific exception
(PT011)
326-326: Unnecessary mode argument
Remove mode argument
(UP015)
333-333: Missing return type annotation for public function test_config_file_backup_and_restore
Add return type annotation: None
(ANN201)
333-333: Missing type annotation for function argument temp_config_dir
(ANN001)
333-333: Missing type annotation for function argument sample_json_config
(ANN001)
343-343: Unnecessary mode argument
Remove mode argument
(UP015)
354-354: Unnecessary mode argument
Remove mode argument
(UP015)
358-358: Unnecessary mode argument
Remove mode argument
(UP015)
363-363: Missing return type annotation for public function test_config_file_merging
Add return type annotation: None
(ANN201)
363-363: Missing type annotation for function argument temp_config_dir
(ANN001)
378-378: Unnecessary mode argument
Remove mode argument
(UP015)
381-381: Unnecessary mode argument
Remove mode argument
(UP015)
399-399: Missing return type annotation for public function test_large_json_config_loading
Add return type annotation: None
(ANN201)
399-399: Missing type annotation for function argument temp_config_dir
(ANN001)
410-410: Unnecessary mode argument
Remove mode argument
(UP015)
418-418: Missing return type annotation for public function test_config_file_caching
Add return type annotation: None
(ANN201)
418-418: Missing type annotation for function argument temp_config_dir
(ANN001)
418-418: Missing type annotation for function argument sample_json_config
(ANN001)
427-427: Unnecessary mode argument
Remove mode argument
(UP015)
438-438: Missing return type annotation for public function test_valid_port_numbers
Add return type annotation: None
(ANN201)
438-438: Missing type annotation for function argument port
(ANN001)
443-443: Missing return type annotation for public function test_invalid_port_numbers
Add return type annotation: None
(ANN201)
443-443: Missing type annotation for function argument port
(ANN001)
450-450: Trailing comma missing
Add trailing comma
(COM812)
452-452: Missing return type annotation for public function test_valid_urls
Add return type annotation: None
(ANN201)
452-452: Missing type annotation for function argument url
(ANN001)
469-469: Trailing comma missing
Add trailing comma
(COM812)
471-471: Missing return type annotation for public function test_invalid_urls
Add return type annotation: None
(ANN201)
471-471: Missing type annotation for function argument url
(ANN001)
489-489: Missing return type annotation for public function test_concurrent_config_access
Add return type annotation: None
(ANN201)
489-489: Missing type annotation for function argument temp_config_dir
(ANN001)
489-489: Missing type annotation for function argument sample_json_config
(ANN001)
492-492: time imported but unused
Remove unused import: time
(F401)
501-501: Missing return type annotation for private function read_config
Add return type annotation: None
(ANN202)
503-503: Unnecessary mode argument
Remove mode argument
(UP015)
506-506: Do not catch blind exception: Exception
(BLE001)
test_utils_helpers.py
1-1: Shebang is present but file is not executable
(EXE001)
27-27: Trailing comma missing
Add trailing comma
(COM812)
34-34: Missing return type annotation for public function test_valid_json_string
Add return type annotation: None
(ANN201)
40-40: Missing return type annotation for public function test_valid_json_array
Add return type annotation: None
(ANN201)
46-46: Missing return type annotation for public function test_invalid_json_string
Add return type annotation: None
(ANN201)
52-52: Missing return type annotation for public function test_completely_malformed_json
Add return type annotation: None
(ANN201)
58-58: Missing return type annotation for public function test_none_input
Add return type annotation: None
(ANN201)
63-63: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
72-72: Missing return type annotation for public function test_valid_dict
Add return type annotation: None
(ANN201)
79-79: Missing return type annotation for public function test_valid_list
Add return type annotation: None
(ANN201)
86-86: Missing return type annotation for public function test_custom_indent
Add return type annotation: None
(ANN201)
92-92: Missing return type annotation for public function test_complex_object_with_datetime
Add return type annotation: None
(ANN201)
95-95: datetime.datetime.now() called without a tz argument
(DTZ005)
100-100: Missing return type annotation for public function test_circular_reference
Add return type annotation: None
(ANN201)
111-111: Missing return type annotation for public function test_string_input
Add return type annotation: None
(ANN201)
119-119: Missing return type annotation for public function test_bytes_input
Add return type annotation: None
(ANN201)
126-126: Missing return type annotation for public function test_consistent_hashing
Add return type annotation: None
(ANN201)
133-133: Missing return type annotation for public function test_different_inputs_different_hashes
Add return type annotation: None
(ANN201)
139-139: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
149-149: Missing return type annotation for public function test_successful_function
Add return type annotation: None
(ANN201)
151-151: Missing return type annotation for private function success_func
Add return type annotation: str
(ANN202)
157-157: Missing return type annotation for public function test_function_succeeds_after_retries
Add return type annotation: None
(ANN201)
161-161: Missing return type annotation for private function eventually_succeeds
Add return type annotation: str
(ANN202)
164-164: Avoid specifying long messages outside the exception class
(TRY003)
171-171: Missing return type annotation for public function test_function_fails_all_retries
Add return type annotation: None
(ANN201)
173-173: Missing return type annotation for private function always_fails
Add return type annotation: NoReturn
(ANN202)
174-174: Avoid specifying long messages outside the exception class
(TRY003)
180-180: Missing return type annotation for public function test_backoff_timing
Add return type annotation: None
(ANN201)
180-180: Missing type annotation for function argument mock_sleep
(ANN001)
182-182: Missing return type annotation for private function fails_twice
Add return type annotation: str
(ANN202)
199-199: Missing return type annotation for public function test_simple_dict
Add return type annotation: None
(ANN201)
205-205: Missing return type annotation for public function test_nested_dict
Add return type annotation: None
(ANN201)
212-212: Missing return type annotation for public function test_mixed_nested_dict
Add return type annotation: None
(ANN201)
217-217: Trailing comma missing
Add trailing comma
(COM812)
225-225: Trailing comma missing
Add trailing comma
(COM812)
229-229: Missing return type annotation for public function test_with_prefix
Add return type annotation: None
(ANN201)
235-235: Missing return type annotation for public function test_empty_dict
Add return type annotation: None
(ANN201)
244-244: Missing return type annotation for public function test_create_new_directory
Add return type annotation: None
(ANN201)
254-254: Missing return type annotation for public function test_existing_directory
Add return type annotation: None
(ANN201)
264-264: Missing return type annotation for public function test_nested_directory_creation
Add return type annotation: None
(ANN201)
274-274: Missing return type annotation for public function test_string_path_input
Add return type annotation: None
(ANN201)
288-288: Missing return type annotation for public function test_valid_filename
Add return type annotation: None
(ANN201)
294-294: Missing return type annotation for public function test_invalid_characters
Add return type annotation: None
(ANN201)
300-300: Missing return type annotation for public function test_leading_trailing_spaces_dots
Add return type annotation: None
(ANN201)
306-306: Missing return type annotation for public function test_empty_filename
Add return type annotation: None
(ANN201)
311-311: Missing return type annotation for public function test_only_invalid_characters
Add return type annotation: None
(ANN201)
317-317: Missing return type annotation for public function test_spaces_and_dots_only
Add return type annotation: None
(ANN201)
327-327: Missing return type annotation for public function test_simple_merge
Add return type annotation: None
(ANN201)
335-335: Missing return type annotation for public function test_overlapping_keys
Add return type annotation: None
(ANN201)
343-343: Missing return type annotation for public function test_nested_dict_merge
Add return type annotation: None
(ANN201)
351-351: Trailing comma missing
Add trailing comma
(COM812)
355-355: Missing return type annotation for public function test_empty_dicts
Add return type annotation: None
(ANN201)
360-360: Missing return type annotation for public function test_original_dicts_unchanged
Add return type annotation: None
(ANN201)
376-376: Missing return type annotation for public function test_even_chunks
Add return type annotation: None
(ANN201)
383-383: Missing return type annotation for public function test_uneven_chunks
Add return type annotation: None
(ANN201)
390-390: Missing return type annotation for public function test_chunk_size_larger_than_list
Add return type annotation: None
(ANN201)
397-397: Missing return type annotation for public function test_chunk_size_one
Add return type annotation: None
(ANN201)
404-404: Missing return type annotation for public function test_empty_list
Add return type annotation: None
(ANN201)
409-409: Missing return type annotation for public function test_mixed_data_types
Add return type annotation: None
(ANN201)
420-420: Missing return type annotation for public function test_seconds_format
Add return type annotation: None
(ANN201)
426-426: Missing return type annotation for public function test_minutes_format
Add return type annotation: None
(ANN201)
432-432: Missing return type annotation for public function test_hours_format
Add return type annotation: None
(ANN201)
438-438: Missing return type annotation for public function test_edge_cases
Add return type annotation: None
(ANN201)
445-445: Missing return type annotation for public function test_large_durations
Add return type annotation: None
(ANN201)
457-457: Missing return type annotation for public function test_json_and_hash_integration
Add return type annotation: None
(ANN201)
471-471: Missing return type annotation for public function test_file_operations_integration
Add return type annotation: None
(ANN201)
488-488: Missing return type annotation for public function test_data_processing_pipeline
Add return type annotation: None
(ANN201)
494-494: Trailing comma missing
Add trailing comma
(COM812)
496-496: Trailing comma missing
Add trailing comma
(COM812)
524-524: Missing return type annotation for public function test_deeply_nested_json_performance
Add return type annotation: None
(ANN201)
528-528: Loop control variable i not used within loop body
Rename unused i to _i
(B007)
536-536: Loop control variable i not used within loop body
Rename unused i to _i
(B007)
541-541: Missing return type annotation for public function test_unicode_and_escape_sequences
Add return type annotation: None
(ANN201)
555-555: Missing return type annotation for public function test_json_with_large_numbers
Add return type annotation: None
(ANN201)
578-578: Missing return type annotation for public function test_malformed_json_variations
Add return type annotation: None
(ANN201)
578-578: Missing type annotation for function argument malformed_json
(ANN001)
587-587: Missing return type annotation for public function test_circular_reference_detection
Add return type annotation: None
(ANN201)
597-597: Missing return type annotation for public function test_custom_objects_with_str_method
Add return type annotation: None
(ANN201)
600-600: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
600-600: Missing type annotation for function argument value
(ANN001)
603-603: Missing return type annotation for special method __str__
Add return type annotation: str
(ANN204)
613-613: Missing return type annotation for public function test_mixed_data_types_edge_cases
Add return type annotation: None
(ANN201)
630-630: Missing return type annotation for public function test_performance_large_object
Add return type annotation: None
(ANN201)
636-636: Trailing comma missing
Add trailing comma
(COM812)
653-653: Missing return type annotation for public function test_hash_distribution
Add return type annotation: None
(ANN201)
668-668: Missing return type annotation for public function test_avalanche_effect
Add return type annotation: None
(ANN201)
686-686: Missing return type annotation for public function test_hash_consistency_across_runs
Add return type annotation: None
(ANN201)
695-695: Missing return type annotation for public function test_empty_and_whitespace_inputs
Add return type annotation: None
(ANN201)
709-709: Missing return type annotation for public function test_retry_with_different_exception_types
Add return type annotation: None
(ANN201)
719-719: Missing return type annotation for private function failing_function
Add return type annotation: str
(ANN202)
731-731: Missing return type annotation for public function test_exponential_backoff_progression
Add return type annotation: None
(ANN201)
731-731: Missing type annotation for function argument mock_sleep
(ANN001)
735-735: Missing return type annotation for private function always_fails
Add return type annotation: str
(ANN202)
738-738: Avoid specifying long messages outside the exception class
(TRY003)
749-749: Missing return type annotation for public function test_retry_with_return_values
Add return type annotation: None
(ANN201)
754-754: Missing return type annotation for private function function_with_varying_returns
(ANN202)
759-759: Avoid specifying long messages outside the exception class
(TRY003)
767-767: Missing return type annotation for public function test_retry_timeout_simulation
Add return type annotation: None
(ANN201)
771-771: Local variable start_time is assigned to but never used
Remove assignment to unused variable start_time
(F841)
774-774: Missing return type annotation for private function time_tracking_function
Add return type annotation: str
(ANN202)
777-777: Avoid specifying long messages outside the exception class
(TRY003)
795-795: Missing return type annotation for public function test_flatten_with_complex_nested_structures
Add return type annotation: None
(ANN201)
802-802: Trailing comma missing
Add trailing comma
(COM812)
807-807: Trailing comma missing
Add trailing comma
(COM812)
808-808: Trailing comma missing
Add trailing comma
(COM812)
814-814: Trailing comma missing
Add trailing comma
(COM812)
815-815: Trailing comma missing
Add trailing comma
(COM812)
816-816: Trailing comma missing
Add trailing comma
(COM812)
829-829: Trailing comma missing
Add trailing comma
(COM812)
835-835: Missing return type annotation for public function test_flatten_with_numeric_and_boolean_keys
Add return type annotation: None
(ANN201)
841-841: Dictionary key literal True repeated (True hashes to the same value as 1)
(F601)
842-842: Trailing comma missing
Add trailing comma
(COM812)
843-843: Trailing comma missing
Add trailing comma
(COM812)
852-852: Trailing comma missing
Add trailing comma
(COM812)
857-857: Missing return type annotation for public function test_flatten_with_custom_separator
Add return type annotation: None
(ANN201)
875-875: Missing return type annotation for public function test_flatten_performance_large_dict
Add return type annotation: None
(ANN201)
903-903: Missing return type annotation for public function test_ensure_directory_concurrent_creation
Add return type annotation: None
(ANN201)
913-913: Missing return type annotation for private function create_directory
Add return type annotation: None
(ANN202)
913-913: Missing type annotation for function argument thread_id
(ANN001)
917-917: Do not catch blind exception: Exception
(BLE001)
937-937: Missing return type annotation for public function test_sanitize_filename_edge_cases
Add return type annotation: None
(ANN201)
961-961: Missing return type annotation for public function test_sanitize_filename_preserves_extensions
Add return type annotation: None
(ANN201)
981-981: Missing return type annotation for public function test_merge_with_conflicting_types
Add return type annotation: None
(ANN201)
986-986: Trailing comma missing
Add trailing comma
(COM812)
991-991: Trailing comma missing
Add trailing comma
(COM812)
1001-1001: Missing return type annotation for public function test_merge_very_deep_nesting
Add return type annotation: None
(ANN201)
1012-1012: Missing return type annotation for public function test_merge_with_none_and_empty_values
Add return type annotation: None
(ANN201)
1018-1018: Trailing comma missing
Add trailing comma
(COM812)
1024-1024: Trailing comma missing
Add trailing comma
(COM812)
1034-1034: Missing return type annotation for public function test_merge_preserves_original_dicts
Add return type annotation: None
(ANN201)
1058-1058: Missing return type annotation for public function test_chunk_with_large_lists
Add return type annotation: None
(ANN201)
1076-1076: Missing return type annotation for public function test_chunk_memory_efficiency
Add return type annotation: None
(ANN201)
1091-1091: Missing return type annotation for public function test_chunk_with_various_data_types
Add return type annotation: None
(ANN201)
1096-1096: Unnecessary list literal (rewrite as a set literal)
Rewrite as a set literal
(C405)
1096-1096: Trailing comma missing
Add trailing comma
(COM812)
1111-1111: Missing return type annotation for public function test_chunk_edge_cases_comprehensive
Add return type annotation: None
(ANN201)
1134-1134: Missing return type annotation for public function test_duration_precision_requirements
Add return type annotation: None
(ANN201)
1158-1158: Missing return type annotation for public function test_duration_format_consistency
Add return type annotation: None
(ANN201)
1180-1180: Missing return type annotation for public function test_duration_extreme_values
Add return type annotation: None
(ANN201)
1202-1202: Missing return type annotation for public function test_configuration_management_workflow
Add return type annotation: None
(ANN201)
1208-1208: Trailing comma missing
Add trailing comma
(COM812)
1213-1213: Trailing comma missing
Add trailing comma
(COM812)
1218-1218: Trailing comma missing
Add trailing comma
(COM812)
1239-1239: Possible hardcoded password assigned to: "password"
(S105)
1248-1248: Missing return type annotation for public function test_data_processing_pipeline_with_retry
Add return type annotation: None
(ANN201)
1257-1257: Missing return type annotation for private function process_chunk_with_failure
(ANN202)
1257-1257: Missing type annotation for function argument chunk
(ANN001)
1261-1261: Avoid specifying long messages outside the exception class
(TRY003)
1267-1267: Trailing comma missing
Add trailing comma
(COM812)
1269-1269: Unnecessary assignment to processed before return statement
Remove unnecessary assignment
(RET504)
1275-1275: Function definition does not bind loop variable chunk
(B023)
1277-1277: Trailing comma missing
Add trailing comma
(COM812)
1280-1280: Do not catch blind exception: Exception
(BLE001)
1294-1294: Missing return type annotation for public function test_file_management_workflow
Add return type annotation: None
(ANN201)
1312-1312: Trailing comma missing
Add trailing comma
(COM812)
1328-1328: Trailing comma missing
Add trailing comma
(COM812)
1357-1357: Missing return type annotation for public function test_concurrent_mixed_operations
Add return type annotation: None
(ANN201)
1365-1365: Missing return type annotation for private function worker_thread
Add return type annotation: None
(ANN202)
1365-1365: Missing type annotation for function argument thread_id
(ANN001)
1378-1378: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
1384-1384: Do not catch blind exception: Exception
(BLE001)
1404-1404: Missing return type annotation for public function test_memory_usage_large_operations
Add return type annotation: None
(ANN201)
1414-1414: Local variable time referenced before assignment
(F823)
1415-1415: Trailing comma missing
Add trailing comma
(COM812)
1450-1450: Trailing comma missing
Add trailing comma
(COM812)
test_llm_continuous_learning_system.py
20-20: json imported but unused
Remove unused import: json
(F401)
25-25: unittest.mock.patch imported but unused
Remove unused import
(F401)
25-25: unittest.mock.MagicMock imported but unused
Remove unused import
(F401)
25-25: unittest.mock.call imported but unused
Remove unused import
(F401)
27-27: typing.List is deprecated, use list instead
(UP035)
27-27: typing.Dict is deprecated, use dict instead
(UP035)
42-42: Missing return type annotation for public function mock_model
(ANN201)
52-52: Missing return type annotation for public function mock_data_loader
(ANN201)
58-58: Trailing comma missing
Add trailing comma
(COM812)
63-63: Missing return type annotation for public function mock_feedback_collector
(ANN201)
67-67: datetime.datetime.now() called without a tz argument
(DTZ005)
68-68: datetime.datetime.now() called without a tz argument
(DTZ005)
69-69: datetime.datetime.now() called without a tz argument
(DTZ005)
69-69: Trailing comma missing
Add trailing comma
(COM812)
74-74: Missing return type annotation for public function learning_system
(ANN201)
74-74: Missing type annotation for function argument mock_model
(ANN001)
74-74: Missing type annotation for function argument mock_data_loader
(ANN001)
74-74: Missing type annotation for function argument mock_feedback_collector
(ANN001)
79-79: Trailing comma missing
Add trailing comma
(COM812)
82-82: Missing return type annotation for public function test_successful_initialization_with_defaults
Add return type annotation: None
(ANN201)
82-82: Missing type annotation for function argument mock_model
(ANN001)
82-82: Missing type annotation for function argument mock_data_loader
(ANN001)
82-82: Missing type annotation for function argument mock_feedback_collector
(ANN001)
87-87: Trailing comma missing
Add trailing comma
(COM812)
102-102: Missing return type annotation for public function test_successful_initialization_with_custom_parameters
Add return type annotation: None
(ANN201)
102-102: Missing type annotation for function argument mock_model
(ANN001)
102-102: Missing type annotation for function argument mock_data_loader
(ANN001)
102-102: Missing type annotation for function argument mock_feedback_collector
(ANN001)
110-110: Trailing comma missing
Add trailing comma
(COM812)
117-117: Missing return type annotation for public function test_initialization_fails_with_none_model
Add return type annotation: None
(ANN201)
117-117: Missing type annotation for function argument mock_data_loader
(ANN001)
117-117: Missing type annotation for function argument mock_feedback_collector
(ANN001)
123-123: Trailing comma missing
Add trailing comma
(COM812)
126-126: Missing return type annotation for public function test_initialization_fails_with_invalid_learning_rate
Add return type annotation: None
(ANN201)
126-126: Missing type annotation for function argument mock_model
(ANN001)
126-126: Missing type annotation for function argument mock_data_loader
(ANN001)
126-126: Missing type annotation for function argument mock_feedback_collector
(ANN001)
133-133: Trailing comma missing
Add trailing comma
(COM812)
136-136: Missing return type annotation for public function test_initialization_fails_with_zero_learning_rate
Add return type annotation: None
(ANN201)
136-136: Missing type annotation for function argument mock_model
(ANN001)
136-136: Missing type annotation for function argument mock_data_loader
(ANN001)
136-136: Missing type annotation for function argument mock_feedback_collector
(ANN001)
143-143: Trailing comma missing
Add trailing comma
(COM812)
146-146: Missing return type annotation for public function test_initialization_fails_with_invalid_batch_size
Add return type annotation: None
(ANN201)
146-146: Missing type annotation for function argument mock_model
(ANN001)
146-146: Missing type annotation for function argument mock_data_loader
(ANN001)
146-146: Missing type annotation for function argument mock_feedback_collector
(ANN001)
153-153: Trailing comma missing
Add trailing comma
(COM812)
156-156: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
160-160: Trailing comma missing
Add trailing comma
(COM812)
162-162: Missing return type annotation for public function test_initialization_with_various_valid_parameters
Add return type annotation: None
(ANN201)
162-162: Missing type annotation for function argument mock_model
(ANN001)
162-162: Missing type annotation for function argument mock_data_loader
(ANN001)
162-162: Missing type annotation for function argument mock_feedback_collector
(ANN001)
163-163: Missing type annotation for function argument learning_rate
(ANN001)
163-163: Missing type annotation for function argument batch_size
(ANN001)
163-163: Missing type annotation for function argument max_epochs
(ANN001)
171-171: Trailing comma missing
Add trailing comma
(COM812)
183-183: Missing return type annotation for public function mock_model
(ANN201)
188-188: Missing return type annotation for public function mock_data_loader
(ANN201)
193-193: Trailing comma missing
Add trailing comma
(COM812)
198-198: Missing return type annotation for public function mock_feedback_collector
(ANN201)
203-203: Missing return type annotation for public function learning_system
(ANN201)
203-203: Missing type annotation for function argument mock_model
(ANN001)
203-203: Missing type annotation for function argument mock_data_loader
(ANN001)
203-203: Missing type annotation for function argument mock_feedback_collector
(ANN001)
208-208: Trailing comma missing
Add trailing comma
(COM812)
211-211: Missing return type annotation for public function test_load_training_data_success
Add return type annotation: None
(ANN201)
211-211: Missing type annotation for function argument learning_system
(ANN001)
215-215: Trailing comma missing
Add trailing comma
(COM812)
224-224: Missing return type annotation for public function test_load_training_data_empty_dataset
Add return type annotation: None
(ANN201)
224-224: Missing type annotation for function argument learning_system
(ANN001)
231-231: Missing return type annotation for public function test_validate_training_data_valid_data
Add return type annotation: None
(ANN201)
231-231: Missing type annotation for function argument learning_system
(ANN001)
235-235: Trailing comma missing
Add trailing comma
(COM812)
241-241: Missing return type annotation for public function test_validate_training_data_missing_input_key
Add return type annotation: None
(ANN201)
241-241: Missing type annotation for function argument learning_system
(ANN001)
248-248: Missing return type annotation for public function test_validate_training_data_missing_output_key
Add return type annotation: None
(ANN201)
248-248: Missing type annotation for function argument learning_system
(ANN001)
255-255: Missing return type annotation for public function test_validate_training_data_empty_input
Add return type annotation: None
(ANN201)
255-255: Missing type annotation for function argument learning_system
(ANN001)
262-262: Missing return type annotation for public function test_validate_training_data_empty_output
Add return type annotation: None
(ANN201)
262-262: Missing type annotation for function argument learning_system
(ANN001)
269-269: Missing return type annotation for public function test_validate_training_data_none_input
Add return type annotation: None
(ANN201)
269-269: Missing type annotation for function argument learning_system
(ANN001)
276-276: Missing return type annotation for public function test_validate_training_data_input_too_long
Add return type annotation: None
(ANN201)
276-276: Missing type annotation for function argument learning_system
(ANN001)
284-284: Missing return type annotation for public function test_validate_training_data_non_dict_item
Add return type annotation: None
(ANN201)
284-284: Missing type annotation for function argument learning_system
(ANN001)
291-291: Missing return type annotation for public function test_validate_training_data_unicode_characters
Add return type annotation: None
(ANN201)
291-291: Missing type annotation for function argument learning_system
(ANN001)
296-296: Trailing comma missing
Add trailing comma
(COM812)
302-302: Missing return type annotation for public function test_create_training_batches_even_division
Add return type annotation: None
(ANN201)
302-302: Missing type annotation for function argument learning_system
(ANN001)
314-314: Missing return type annotation for public function test_create_training_batches_uneven_division
Add return type annotation: None
(ANN201)
314-314: Missing type annotation for function argument learning_system
(ANN001)
328-328: Missing return type annotation for public function test_create_training_batches_single_batch
Add return type annotation: None
(ANN201)
328-328: Missing type annotation for function argument learning_system
(ANN001)
344-344: Missing return type annotation for public function mock_model
(ANN201)
352-352: Missing return type annotation for public function mock_data_loader
(ANN201)
357-357: Trailing comma missing
Add trailing comma
(COM812)
362-362: Missing return type annotation for public function mock_feedback_collector
(ANN201)
367-367: Missing return type annotation for public function learning_system
(ANN201)
367-367: Missing type annotation for function argument mock_model
(ANN001)
367-367: Missing type annotation for function argument mock_data_loader
(ANN001)
367-367: Missing type annotation for function argument mock_feedback_collector
(ANN001)
372-372: Trailing comma missing
Add trailing comma
(COM812)
376-376: Missing return type annotation for public function test_fine_tune_model_success
Add return type annotation: None
(ANN201)
376-376: Missing type annotation for function argument learning_system
(ANN001)
393-393: Missing return type annotation for public function test_fine_tune_model_failure
Add return type annotation: None
(ANN201)
393-393: Missing type annotation for function argument learning_system
(ANN001)
403-403: Missing return type annotation for public function test_fine_tune_model_concurrent_training_prevention
Add return type annotation: None
(ANN201)
403-403: Missing type annotation for function argument learning_system
(ANN001)
411-411: Missing return type annotation for public function test_fine_tune_model_updates_statistics
Add return type annotation: None
(ANN201)
411-411: Missing type annotation for function argument learning_system
(ANN001)
422-422: Missing return type annotation for public function test_evaluate_model_performance_success
Add return type annotation: None
(ANN201)
422-422: Missing type annotation for function argument learning_system
(ANN001)
432-432: Missing return type annotation for public function test_evaluate_model_performance_failure
Add return type annotation: None
(ANN201)
432-432: Missing type annotation for function argument learning_system
(ANN001)
442-442: Missing return type annotation for public function test_calculate_learning_metrics_improvement
Add return type annotation: None
(ANN201)
442-442: Missing type annotation for function argument learning_system
(ANN001)
452-452: Missing return type annotation for public function test_calculate_learning_metrics_degradation
Add return type annotation: None
(ANN201)
452-452: Missing type annotation for function argument learning_system
(ANN001)
462-462: Missing return type annotation for public function test_calculate_learning_metrics_missing_keys
Add return type annotation: None
(ANN201)
462-462: Missing type annotation for function argument learning_system
(ANN001)
472-472: Missing return type annotation for public function test_simulate_long_training_success
Add return type annotation: None
(ANN201)
472-472: Missing type annotation for function argument learning_system
(ANN001)
483-483: Missing return type annotation for public function mock_model
(ANN201)
488-488: Missing return type annotation for public function mock_data_loader
(ANN201)
493-493: Missing return type annotation for public function mock_feedback_collector
(ANN201)
497-497: datetime.datetime.now() called without a tz argument
(DTZ005)
498-498: datetime.datetime.now() called without a tz argument
(DTZ005)
499-499: datetime.datetime.now() called without a tz argument
(DTZ005)
500-500: datetime.datetime.now() called without a tz argument
(DTZ005)
501-501: datetime.datetime.now() called without a tz argument
(DTZ005)
501-501: Trailing comma missing
Add trailing comma
(COM812)
506-506: Missing return type annotation for public function learning_system
(ANN201)
506-506: Missing type annotation for function argument mock_model
(ANN001)
506-506: Missing type annotation for function argument mock_data_loader
(ANN001)
506-506: Missing type annotation for function argument mock_feedback_collector
(ANN001)
511-511: Trailing comma missing
Add trailing comma
(COM812)
515-515: Missing return type annotation for public function sample_feedback_data
(ANN201)
518-518: datetime.datetime.now() called without a tz argument
(DTZ005)
519-519: datetime.datetime.now() called without a tz argument
(DTZ005)
520-520: datetime.datetime.now() called without a tz argument
(DTZ005)
521-521: datetime.datetime.now() called without a tz argument
(DTZ005)
522-522: datetime.datetime.now() called without a tz argument
(DTZ005)
522-522: Trailing comma missing
Add trailing comma
(COM812)
525-525: Missing return type annotation for public function test_collect_feedback_success
Add return type annotation: None
(ANN201)
525-525: Missing type annotation for function argument learning_system
(ANN001)
535-535: Missing return type annotation for public function test_collect_feedback_empty_results
Add return type annotation: None
(ANN201)
535-535: Missing type annotation for function argument learning_system
(ANN001)
544-544: Missing return type annotation for public function test_filter_high_quality_feedback_default_threshold
Add return type annotation: None
(ANN201)
544-544: Missing type annotation for function argument learning_system
(ANN001)
544-544: Missing type annotation for function argument sample_feedback_data
(ANN001)
551-551: Missing return type annotation for public function test_filter_high_quality_feedback_custom_threshold
Add return type annotation: None
(ANN201)
551-551: Missing type annotation for function argument learning_system
(ANN001)
551-551: Missing type annotation for function argument sample_feedback_data
(ANN001)
558-558: Missing return type annotation for public function test_filter_high_quality_feedback_high_threshold
Add return type annotation: None
(ANN201)
558-558: Missing type annotation for function argument learning_system
(ANN001)
558-558: Missing type annotation for function argument sample_feedback_data
(ANN001)
564-564: Missing return type annotation for public function test_filter_high_quality_feedback_invalid_threshold
Add return type annotation: None
(ANN201)
564-564: Missing type annotation for function argument learning_system
(ANN001)
564-564: Missing type annotation for function argument sample_feedback_data
(ANN001)
569-569: Missing return type annotation for public function test_filter_high_quality_feedback_negative_threshold
Add return type annotation: None
(ANN201)
569-569: Missing type annotation for function argument learning_system
(ANN001)
569-569: Missing type annotation for function argument sample_feedback_data
(ANN001)
574-574: Missing return type annotation for public function test_filter_high_quality_feedback_missing_rating
Add return type annotation: None
(ANN201)
574-574: Missing type annotation for function argument learning_system
(ANN001)
578-578: Trailing comma missing
Add trailing comma
(COM812)
586-586: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
593-593: Missing return type annotation for public function test_filter_high_quality_feedback_various_thresholds
Add return type annotation: None
(ANN201)
593-593: Missing type annotation for function argument learning_system
(ANN001)
593-593: Missing type annotation for function argument sample_feedback_data
(ANN001)
594-594: Missing type annotation for function argument min_rating
(ANN001)
594-594: Missing type annotation for function argument expected_count
(ANN001)
606-606: Missing return type annotation for public function mock_model
(ANN201)
612-612: Trailing comma missing
Add trailing comma
(COM812)
617-617: Missing return type annotation for public function mock_data_loader
(ANN201)
621-621: Trailing comma missing
Add trailing comma
(COM812)
626-626: Missing return type annotation for public function mock_feedback_collector
(ANN201)
632-632: Trailing comma missing
Add trailing comma
(COM812)
637-637: Missing return type annotation for public function learning_system
(ANN201)
637-637: Missing type annotation for function argument mock_model
(ANN001)
637-637: Missing type annotation for function argument mock_data_loader
(ANN001)
637-637: Missing type annotation for function argument mock_feedback_collector
(ANN001)
642-642: Trailing comma missing
Add trailing comma
(COM812)
646-646: Missing return type annotation for public function test_continuous_learning_cycle_success
Add return type annotation: None
(ANN201)
646-646: Missing type annotation for function argument learning_system
(ANN001)
659-659: Missing return type annotation for public function test_continuous_learning_cycle_no_feedback
Add return type annotation: None
(ANN201)
659-659: Missing type annotation for function argument learning_system
(ANN001)
669-669: Missing return type annotation for public function test_continuous_learning_cycle_no_high_quality_feedback
Add return type annotation: None
(ANN201)
669-669: Missing type annotation for function argument learning_system
(ANN001)
673-673: Trailing comma missing
Add trailing comma
(COM812)
682-682: Missing return type annotation for public function test_continuous_learning_cycle_training_failure
Add return type annotation: None
(ANN201)
682-682: Missing type annotation for function argument learning_system
(ANN001)
690-690: Missing return type annotation for public function test_continuous_learning_cycle_evaluation_failure
Add return type annotation: None
(ANN201)
690-690: Missing type annotation for function argument learning_system
(ANN001)
702-702: Missing return type annotation for public function mock_model
(ANN201)
710-710: Missing return type annotation for public function mock_data_loader
(ANN201)
715-715: Missing return type annotation for public function mock_feedback_collector
(ANN201)
720-720: Missing return type annotation for public function learning_system
(ANN201)
720-720: Missing type annotation for function argument mock_model
(ANN001)
720-720: Missing type annotation for function argument mock_data_loader
(ANN001)
720-720: Missing type annotation for function argument mock_feedback_collector
(ANN001)
725-725: Trailing comma missing
Add trailing comma
(COM812)
728-728: Missing return type annotation for public function test_save_model_checkpoint_success
Add return type annotation: None
(ANN201)
728-728: Missing type annotation for function argument learning_system
(ANN001)
730-730: Probable insecure usage of temporary file or directory: "/tmp/test_checkpoint.pkl"
(S108)
736-736: Missing return type annotation for public function test_load_model_checkpoint_success
Add return type annotation: None
(ANN201)
736-736: Missing type annotation for function argument learning_system
(ANN001)
748-748: Missing return type annotation for public function test_load_model_checkpoint_file_not_found
Add return type annotation: None
(ANN201)
748-748: Missing type annotation for function argument learning_system
(ANN001)
750-750: Probable insecure usage of temporary file or directory: "/tmp/nonexistent_checkpoint.pkl"
(S108)
755-755: Missing return type annotation for public function test_save_checkpoint_with_various_paths
Add return type annotation: None
(ANN201)
755-755: Missing type annotation for function argument learning_system
(ANN001)
758-758: Probable insecure usage of temporary file or directory: "/tmp/checkpoint1.pkl"
(S108)
761-761: Trailing comma missing
Add trailing comma
(COM812)
773-773: Missing return type annotation for public function mock_model
(ANN201)
778-778: Missing return type annotation for public function mock_data_loader
(ANN201)
783-783: Missing return type annotation for public function mock_feedback_collector
(ANN201)
788-788: Missing return type annotation for public function learning_system
(ANN201)
788-788: Missing type annotation for function argument mock_model
(ANN001)
788-788: Missing type annotation for function argument mock_data_loader
(ANN001)
788-788: Missing type annotation for function argument mock_feedback_collector
(ANN001)
793-793: Trailing comma missing
Add trailing comma
(COM812)
796-796: Missing return type annotation for public function test_get_system_statistics_initial_state
Add return type annotation: None
(ANN201)
796-796: Missing type annotation for function argument learning_system
(ANN001)
807-807: Missing return type annotation for public function test_get_system_statistics_after_updates
Add return type annotation: None
(ANN201)
807-807: Missing type annotation for function argument learning_system
(ANN001)
814-814: datetime.datetime.now() called without a tz argument
(DTZ005)
826-826: Missing return type annotation for public function test_reset_learning_history
Add return type annotation: None
(ANN201)
826-826: Missing type annotation for function argument learning_system
(ANN001)
832-832: datetime.datetime.now() called without a tz argument
(DTZ005)
842-842: Missing return type annotation for public function test_memory_management
Add return type annotation: None
(ANN201)
842-842: Missing type annotation for function argument learning_system
(ANN001)
857-857: Missing return type annotation for public function mock_model
(ANN201)
862-862: Missing return type annotation for public function mock_data_loader
(ANN201)
867-867: Missing return type annotation for public function mock_feedback_collector
(ANN201)
872-872: Missing return type annotation for public function learning_system
(ANN201)
872-872: Missing type annotation for function argument mock_model
(ANN001)
872-872: Missing type annotation for function argument mock_data_loader
(ANN001)
872-872: Missing type annotation for function argument mock_feedback_collector
(ANN001)
877-877: Trailing comma missing
Add trailing comma
(COM812)
880-880: Missing return type annotation for public function test_validate_configuration_valid_config
Add return type annotation: None
(ANN201)
880-880: Missing type annotation for function argument learning_system
(ANN001)
885-885: Trailing comma missing
Add trailing comma
(COM812)
891-891: Missing return type annotation for public function test_validate_configuration_missing_learning_rate
Add return type annotation: None
(ANN201)
891-891: Missing type annotation for function argument learning_system
(ANN001)
895-895: Trailing comma missing
Add trailing comma
(COM812)
901-901: Missing return type annotation for public function test_validate_configuration_missing_batch_size
Add return type annotation: None
(ANN201)
901-901: Missing type annotation for function argument learning_system
(ANN001)
905-905: Trailing comma missing
Add trailing comma
(COM812)
911-911: Missing return type annotation for public function test_validate_configuration_missing_max_epochs
Add return type annotation: None
(ANN201)
911-911: Missing type annotation for function argument learning_system
(ANN001)
915-915: Trailing comma missing
Add trailing comma
(COM812)
921-921: Missing return type annotation for public function test_validate_configuration_negative_learning_rate
Add return type annotation: None
(ANN201)
921-921: Missing type annotation for function argument learning_system
(ANN001)
926-926: Trailing comma missing
Add trailing comma
(COM812)
932-932: Missing return type annotation for public function test_validate_configuration_zero_batch_size
Add return type annotation: None
(ANN201)
932-932: Missing type annotation for function argument learning_system
(ANN001)
937-937: Trailing comma missing
Add trailing comma
(COM812)
943-943: Missing return type annotation for public function test_validate_configuration_negative_max_epochs
Add return type annotation: None
(ANN201)
943-943: Missing type annotation for function argument learning_system
(ANN001)
948-948: Trailing comma missing
Add trailing comma
(COM812)
954-954: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
961-961: Missing return type annotation for public function test_validate_configuration_various_values
Add return type annotation: None
(ANN201)
961-961: Missing type annotation for function argument learning_system
(ANN001)
961-961: Missing type annotation for function argument config
(ANN001)
961-961: Missing type annotation for function argument expected
(ANN001)
971-971: Missing return type annotation for public function mock_model
(ANN201)
979-979: Missing return type annotation for public function mock_data_loader
(ANN201)
983-983: Trailing comma missing
Add trailing comma
(COM812)
988-988: Missing return type annotation for public function mock_feedback_collector
(ANN201)
993-993: Missing return type annotation for public function learning_system
(ANN201)
993-993: Missing type annotation for function argument mock_model
(ANN001)
993-993: Missing type annotation for function argument mock_data_loader
(ANN001)
993-993: Missing type annotation for function argument mock_feedback_collector
(ANN001)
998-998: Trailing comma missing
Add trailing comma
(COM812)
1001-1001: Missing return type annotation for public function test_thread_safety_statistics_access
Add return type annotation: None
(ANN201)
1001-1001: Missing type annotation for function argument learning_system
(ANN001)
1006-1006: Missing return type annotation for private function worker
Add return type annotation: None
(ANN202)
1012-1012: Do not catch blind exception: Exception
(BLE001)
1032-1032: Missing return type annotation for public function test_training_lock_mechanism
Add return type annotation: None
(ANN201)
1032-1032: Missing type annotation for function argument learning_system
(ANN001)
1047-1047: Missing return type annotation for public function test_concurrent_statistics_updates
Add return type annotation: None
(ANN201)
1047-1047: Missing type annotation for function argument learning_system
(ANN001)
1049-1049: Missing return type annotation for private function update_worker
Add return type annotation: None
(ANN202)
1050-1050: Loop control variable i not used within loop body
Rename unused i to _i
(B007)
1072-1072: Missing return type annotation for public function mock_model
(ANN201)
1077-1077: Missing return type annotation for public function mock_data_loader
(ANN201)
1082-1082: Missing return type annotation for public function mock_feedback_collector
(ANN201)
1087-1087: Missing return type annotation for public function learning_system
(ANN201)
1087-1087: Missing type annotation for function argument mock_model
(ANN001)
1087-1087: Missing type annotation for function argument mock_data_loader
(ANN001)
1087-1087: Missing type annotation for function argument mock_feedback_collector
(ANN001)
1092-1092: Trailing comma missing
Add trailing comma
(COM812)
1095-1095: Missing return type annotation for public function test_edge_case_very_large_input
Add return type annotation: None
(ANN201)
1095-1095: Missing type annotation for function argument learning_system
(ANN001)
1105-1105: Missing return type annotation for public function test_edge_case_empty_strings
Add return type annotation: None
(ANN201)
1105-1105: Missing type annotation for function argument learning_system
(ANN001)
1110-1110: Trailing comma missing
Add trailing comma
(COM812)
1116-1116: Missing return type annotation for public function test_edge_case_none_values
Add return type annotation: None
(ANN201)
1116-1116: Missing type annotation for function argument learning_system
(ANN001)
1120-1120: Trailing comma missing
Add trailing comma
(COM812)
1126-1126: Missing return type annotation for public function test_edge_case_extreme_ratings
Add return type annotation: None
(ANN201)
1126-1126: Missing type annotation for function argument learning_system
(ANN001)
1131-1131: Trailing comma missing
Add trailing comma
(COM812)
1138-1138: Missing return type annotation for public function test_edge_case_unicode_and_emoji_handling
Add return type annotation: None
(ANN201)
1138-1138: Missing type annotation for function argument learning_system
(ANN001)
1144-1144: Trailing comma missing
Add trailing comma
(COM812)
1151-1151: Missing return type annotation for public function test_edge_case_very_small_batch_size
Add return type annotation: None
(ANN201)
1151-1151: Missing type annotation for function argument learning_system
(ANN001)
1162-1162: Missing return type annotation for public function test_edge_case_batch_size_larger_than_data
Add return type annotation: None
(ANN201)
1162-1162: Missing type annotation for function argument learning_system
(ANN001)
1173-1173: Missing return type annotation for public function test_error_count_incrementation
Add return type annotation: None
(ANN201)
1173-1173: Missing type annotation for function argument learning_system
(ANN001)
1178-1181: Use contextlib.suppress(Exception) instead of try-except-pass
Replace with contextlib.suppress(Exception)
(SIM105)
1180-1181: try-except-pass detected, consider logging the exception
(S110)
1180-1180: Do not catch blind exception: Exception
(BLE001)
1191-1191: Missing return type annotation for public function test_end_to_end_learning_pipeline
Add return type annotation: None
(ANN201)
1196-1196: Missing return type annotation for public function test_real_model_fine_tuning
Add return type annotation: None
(ANN201)
1201-1201: Missing return type annotation for public function test_database_persistence
Add return type annotation: None
(ANN201)
1210-1210: Missing return type annotation for public function test_large_dataset_processing
Add return type annotation: None
(ANN201)
1215-1215: Missing return type annotation for public function test_memory_usage_under_load
Add return type annotation: None
(ANN201)
1220-1220: Missing return type annotation for public function test_concurrent_training_performance
Add return type annotation: None
(ANN201)
1226-1226: Use list instead of List for type annotation
Replace with list
(UP006)
1226-1226: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
1234-1234: Undefined name Tuple
(F821)
1234-1234: Use list instead of List for type annotation
Replace with list
(UP006)
1234-1234: Use dict instead of Dict for type annotation
Replace with dict
(UP006)
1242-1242: datetime.datetime.now() called without a tz argument
(DTZ005)
1242-1242: Trailing comma missing
Add trailing comma
(COM812)
1254-1254: Missing return type annotation for public function pytest_configure
Add return type annotation: None
(ANN201)
1254-1254: Missing type annotation for function argument config
(ANN001)
🪛 Pylint (3.3.7)
run_comprehensive_tests.py
[convention] 15-15: Trailing whitespace
(C0303)
[convention] 19-19: Trailing whitespace
(C0303)
[convention] 24-24: Trailing whitespace
(C0303)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 47-47: Trailing whitespace
(C0303)
[convention] 58-58: Final newline missing
(C0304)
[warning] 18-23: 'subprocess.run' used without explicitly defining the value for 'check'.
(W1510)
[warning] 34-39: 'subprocess.run' used without explicitly defining the value for 'check'.
(W1510)
[refactor] 50-55: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[warning] 9-9: Unused import time
(W0611)
test_github_workflows.py
[convention] 17-17: Trailing whitespace
(C0303)
[convention] 117-117: Trailing whitespace
(C0303)
[convention] 136-136: Trailing whitespace
(C0303)
[convention] 145-145: Trailing whitespace
(C0303)
[convention] 158-158: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 175-175: Trailing whitespace
(C0303)
[convention] 181-181: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 196-196: Trailing whitespace
(C0303)
[convention] 209-209: Trailing whitespace
(C0303)
[convention] 213-213: Trailing whitespace
(C0303)
[convention] 221-221: Trailing whitespace
(C0303)
[convention] 235-235: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 248-248: Trailing whitespace
(C0303)
[convention] 256-256: Trailing whitespace
(C0303)
[convention] 268-268: Trailing whitespace
(C0303)
[convention] 271-271: Trailing whitespace
(C0303)
[convention] 289-289: Trailing whitespace
(C0303)
[convention] 293-293: Trailing whitespace
(C0303)
[convention] 301-301: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 319-319: Trailing whitespace
(C0303)
[convention] 329-329: Trailing whitespace
(C0303)
[convention] 334-334: Trailing whitespace
(C0303)
[convention] 338-338: Trailing whitespace
(C0303)
[convention] 349-349: Trailing whitespace
(C0303)
[convention] 373-373: Trailing whitespace
(C0303)
[convention] 380-380: Trailing whitespace
(C0303)
[convention] 386-386: Trailing whitespace
(C0303)
[convention] 393-393: Trailing whitespace
(C0303)
[convention] 399-399: Trailing whitespace
(C0303)
[convention] 406-406: Trailing whitespace
(C0303)
[convention] 412-412: Trailing whitespace
(C0303)
[convention] 418-418: Trailing whitespace
(C0303)
[convention] 434-434: Trailing whitespace
(C0303)
[convention] 443-443: Trailing whitespace
(C0303)
[convention] 455-455: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 478-478: Trailing whitespace
(C0303)
[convention] 482-482: Trailing whitespace
(C0303)
[convention] 495-495: Trailing whitespace
(C0303)
[convention] 502-502: Trailing whitespace
(C0303)
[convention] 506-506: Trailing whitespace
(C0303)
[convention] 511-511: Trailing whitespace
(C0303)
[convention] 519-519: Trailing whitespace
(C0303)
[convention] 527-527: Trailing whitespace
(C0303)
[convention] 530-530: Trailing whitespace
(C0303)
[convention] 532-532: Trailing whitespace
(C0303)
[convention] 541-541: Trailing whitespace
(C0303)
[convention] 546-546: Trailing whitespace
(C0303)
[convention] 551-551: Trailing whitespace
(C0303)
[convention] 558-558: Trailing whitespace
(C0303)
[convention] 566-566: Trailing whitespace
(C0303)
[convention] 575-575: Trailing whitespace
(C0303)
[convention] 585-585: Trailing whitespace
(C0303)
[convention] 592-592: Trailing whitespace
(C0303)
[convention] 600-600: Trailing whitespace
(C0303)
[convention] 603-603: Trailing whitespace
(C0303)
[convention] 617-617: Trailing whitespace
(C0303)
[convention] 624-624: Trailing whitespace
(C0303)
[convention] 632-632: Trailing whitespace
(C0303)
[convention] 673-673: Trailing whitespace
(C0303)
[convention] 681-681: Trailing whitespace
(C0303)
[convention] 690-690: Trailing whitespace
(C0303)
[convention] 697-697: Trailing whitespace
(C0303)
[convention] 740-740: Trailing whitespace
(C0303)
[convention] 785-785: Trailing whitespace
(C0303)
[convention] 793-793: Final newline missing
(C0304)
[warning] 205-205: Unused argument 'step_type'
(W0613)
[warning] 257-257: Unused variable 'job_name'
(W0612)
[warning] 273-273: Unused variable 'job_name'
(W0612)
[warning] 313-313: Using open without explicitly specifying an encoding
(W1514)
[warning] 556-556: Catching too general exception Exception
(W0718)
[convention] 587-587: Import outside toplevel (time)
(C0415)
[convention] 599-599: Import outside toplevel (sys)
(C0415)
[warning] 599-599: Unused import sys
(W0611)
[convention] 7-7: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 9-9: standard import "os" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 10-10: standard import "unittest.mock.Mock" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 11-11: standard import "pathlib.Path" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 12-12: standard import "typing.Dict" should be placed before third party imports "pytest", "yaml"
(C0411)
[warning] 7-7: Unused import json
(W0611)
[warning] 9-9: Unused import os
(W0611)
[warning] 10-10: Unused Mock imported from unittest.mock
(W0611)
[warning] 10-10: Unused mock_open imported from unittest.mock
(W0611)
[warning] 12-12: Unused Dict imported from typing
(W0611)
[warning] 12-12: Unused List imported from typing
(W0611)
[warning] 12-12: Unused Any imported from typing
(W0611)
test_config_files.py
[convention] 14-14: Trailing whitespace
(C0303)
[convention] 20-20: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 80-80: Trailing whitespace
(C0303)
[convention] 86-86: Trailing whitespace
(C0303)
[convention] 89-89: Trailing whitespace
(C0303)
[convention] 94-94: Trailing whitespace
(C0303)
[convention] 100-100: Trailing whitespace
(C0303)
[convention] 104-104: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 113-113: Trailing whitespace
(C0303)
[convention] 115-115: Trailing whitespace
(C0303)
[convention] 121-121: Trailing whitespace
(C0303)
[convention] 124-124: Trailing whitespace
(C0303)
[convention] 127-127: Trailing whitespace
(C0303)
[convention] 131-131: Trailing whitespace
(C0303)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 146-146: Trailing whitespace
(C0303)
[convention] 150-150: Trailing whitespace
(C0303)
[convention] 153-153: Trailing whitespace
(C0303)
[convention] 164-164: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 177-177: Trailing whitespace
(C0303)
[convention] 183-183: Trailing whitespace
(C0303)
[convention] 187-187: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 207-207: Trailing whitespace
(C0303)
[convention] 210-210: Trailing whitespace
(C0303)
[convention] 215-215: Trailing whitespace
(C0303)
[convention] 221-221: Trailing whitespace
(C0303)
[convention] 224-224: Trailing whitespace
(C0303)
[convention] 230-230: Trailing whitespace
(C0303)
[convention] 236-236: Trailing whitespace
(C0303)
[convention] 239-239: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 249-249: Trailing whitespace
(C0303)
[convention] 252-252: Trailing whitespace
(C0303)
[convention] 255-255: Trailing whitespace
(C0303)
[convention] 258-258: Trailing whitespace
(C0303)
[convention] 264-264: Trailing whitespace
(C0303)
[convention] 267-267: Trailing whitespace
(C0303)
[convention] 270-270: Trailing whitespace
(C0303)
[convention] 273-273: Trailing whitespace
(C0303)
[convention] 282-282: Trailing whitespace
(C0303)
[convention] 286-286: Trailing whitespace
(C0303)
[convention] 289-289: Trailing whitespace
(C0303)
[convention] 296-296: Trailing whitespace
(C0303)
[convention] 300-300: Trailing whitespace
(C0303)
[convention] 304-304: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 313-313: Trailing whitespace
(C0303)
[convention] 321-321: Trailing whitespace
(C0303)
[convention] 332-332: Trailing whitespace
(C0303)
[convention] 337-337: Trailing whitespace
(C0303)
[convention] 341-341: Trailing whitespace
(C0303)
[convention] 345-345: Trailing whitespace
(C0303)
[convention] 349-349: Trailing whitespace
(C0303)
[convention] 352-352: Trailing whitespace
(C0303)
[convention] 356-356: Trailing whitespace
(C0303)
[convention] 360-360: Trailing whitespace
(C0303)
[convention] 362-362: Trailing whitespace
(C0303)
[convention] 367-367: Trailing whitespace
(C0303)
[convention] 370-370: Trailing whitespace
(C0303)
[convention] 373-373: Trailing whitespace
(C0303)
[convention] 376-376: Trailing whitespace
(C0303)
[convention] 380-380: Trailing whitespace
(C0303)
[convention] 383-383: Trailing whitespace
(C0303)
[convention] 386-386: Line too long (105/100)
(C0301)
[convention] 390-390: Trailing whitespace
(C0303)
[convention] 398-398: Trailing whitespace
(C0303)
[convention] 402-402: Trailing whitespace
(C0303)
[convention] 406-406: Trailing whitespace
(C0303)
[convention] 409-409: Trailing whitespace
(C0303)
[convention] 412-412: Trailing whitespace
(C0303)
[convention] 414-414: Trailing whitespace
(C0303)
[convention] 417-417: Trailing whitespace
(C0303)
[convention] 423-423: Trailing whitespace
(C0303)
[convention] 429-429: Trailing whitespace
(C0303)
[convention] 436-436: Trailing whitespace
(C0303)
[convention] 441-441: Trailing whitespace
(C0303)
[convention] 445-445: Unnecessary parens after 'not' keyword
(C0325)
[convention] 446-446: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 464-464: Trailing whitespace
(C0303)
[convention] 481-481: Trailing whitespace
(C0303)
[convention] 488-488: Trailing whitespace
(C0303)
[convention] 493-493: Trailing whitespace
(C0303)
[convention] 497-497: Trailing whitespace
(C0303)
[convention] 500-500: Trailing whitespace
(C0303)
[convention] 508-508: Trailing whitespace
(C0303)
[convention] 510-510: Trailing whitespace
(C0303)
[convention] 513-513: Trailing whitespace
(C0303)
[convention] 516-516: Trailing whitespace
(C0303)
[convention] 523-523: Final newline missing
(C0304)
[convention] 1-1: Missing module docstring
(C0114)
[warning] 84-84: Using open without explicitly specifying an encoding
(W1514)
[warning] 87-87: Using open without explicitly specifying an encoding
(W1514)
[warning] 98-98: Using open without explicitly specifying an encoding
(W1514)
[warning] 102-102: Using open without explicitly specifying an encoding
(W1514)
[warning] 108-108: Using open without explicitly specifying an encoding
(W1514)
[warning] 111-111: Using open without explicitly specifying an encoding
(W1514)
[warning] 122-122: Using open without explicitly specifying an encoding
(W1514)
[warning] 125-125: Using open without explicitly specifying an encoding
(W1514)
[warning] 148-148: Using open without explicitly specifying an encoding
(W1514)
[warning] 151-151: Using open without explicitly specifying an encoding
(W1514)
[warning] 168-168: Using open without explicitly specifying an encoding
(W1514)
[warning] 171-171: Using open without explicitly specifying an encoding
(W1514)
[warning] 181-181: Using open without explicitly specifying an encoding
(W1514)
[warning] 185-185: Using open without explicitly specifying an encoding
(W1514)
[warning] 205-205: Using open without explicitly specifying an encoding
(W1514)
[warning] 208-208: Using open without explicitly specifying an encoding
(W1514)
[warning] 219-219: Using open without explicitly specifying an encoding
(W1514)
[warning] 222-222: Using open without explicitly specifying an encoding
(W1514)
[warning] 234-234: Using open without explicitly specifying an encoding
(W1514)
[warning] 247-247: Using open without explicitly specifying an encoding
(W1514)
[warning] 262-262: Using open without explicitly specifying an encoding
(W1514)
[warning] 284-284: Using open without explicitly specifying an encoding
(W1514)
[warning] 302-302: Using open without explicitly specifying an encoding
(W1514)
[warning] 308-308: Using open without explicitly specifying an encoding
(W1514)
[warning] 316-316: Using open without explicitly specifying an encoding
(W1514)
[warning] 323-323: Redefining name 'mock_open' from outer scope (line 7)
(W0621)
[warning] 326-326: Using open without explicitly specifying an encoding
(W1514)
[warning] 323-323: Unused argument 'mock_open'
(W0613)
[warning] 339-339: Using open without explicitly specifying an encoding
(W1514)
[warning] 343-343: Using open without explicitly specifying an encoding
(W1514)
[warning] 343-343: Using open without explicitly specifying an encoding
(W1514)
[warning] 350-350: Using open without explicitly specifying an encoding
(W1514)
[warning] 354-354: Using open without explicitly specifying an encoding
(W1514)
[warning] 354-354: Using open without explicitly specifying an encoding
(W1514)
[warning] 358-358: Using open without explicitly specifying an encoding
(W1514)
[warning] 371-371: Using open without explicitly specifying an encoding
(W1514)
[warning] 374-374: Using open without explicitly specifying an encoding
(W1514)
[warning] 378-378: Using open without explicitly specifying an encoding
(W1514)
[warning] 381-381: Using open without explicitly specifying an encoding
(W1514)
[warning] 404-404: Using open without explicitly specifying an encoding
(W1514)
[convention] 407-407: Import outside toplevel (time)
(C0415)
[warning] 410-410: Using open without explicitly specifying an encoding
(W1514)
[warning] 421-421: Using open without explicitly specifying an encoding
(W1514)
[warning] 427-427: Using open without explicitly specifying an encoding
(W1514)
[convention] 454-454: Import outside toplevel (re)
(C0415)
[convention] 473-473: Import outside toplevel (re)
(C0415)
[convention] 491-491: Import outside toplevel (threading)
(C0415)
[convention] 492-492: Import outside toplevel (time)
(C0415)
[warning] 495-495: Using open without explicitly specifying an encoding
(W1514)
[warning] 506-506: Catching too general exception Exception
(W0718)
[warning] 503-503: Using open without explicitly specifying an encoding
(W1514)
[warning] 492-492: Unused import time
(W0611)
[refactor] 486-486: Too few public methods (1/2)
(R0903)
[convention] 2-2: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 4-4: standard import "tempfile" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 5-5: standard import "os" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 6-6: standard import "pathlib.Path" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 7-7: standard import "unittest.mock.patch" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 8-8: standard import "configparser" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 9-9: standard import "io.StringIO" should be placed before third party imports "pytest", "yaml"
(C0411)
[warning] 7-7: Unused mock_open imported from unittest.mock
(W0611)
[warning] 7-7: Unused MagicMock imported from unittest.mock
(W0611)
[warning] 9-9: Unused StringIO imported from io
(W0611)
test_utils_helpers.py
[convention] 33-33: Trailing whitespace
(C0303)
[convention] 39-39: Trailing whitespace
(C0303)
[convention] 45-45: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 71-71: Trailing whitespace
(C0303)
[convention] 78-78: Trailing whitespace
(C0303)
[convention] 85-85: Trailing whitespace
(C0303)
[convention] 91-91: Trailing whitespace
(C0303)
[convention] 99-99: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 118-118: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[convention] 132-132: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 148-148: Trailing whitespace
(C0303)
[convention] 153-153: Trailing whitespace
(C0303)
[convention] 156-156: Trailing whitespace
(C0303)
[convention] 160-160: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 175-175: Trailing whitespace
(C0303)
[convention] 178-178: Trailing whitespace
(C0303)
[convention] 186-186: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 204-204: Trailing whitespace
(C0303)
[convention] 211-211: Trailing whitespace
(C0303)
[convention] 228-228: Trailing whitespace
(C0303)
[convention] 234-234: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 249-249: Trailing whitespace
(C0303)
[convention] 253-253: Trailing whitespace
(C0303)
[convention] 259-259: Trailing whitespace
(C0303)
[convention] 263-263: Trailing whitespace
(C0303)
[convention] 269-269: Trailing whitespace
(C0303)
[convention] 273-273: Trailing whitespace
(C0303)
[convention] 279-279: Trailing whitespace
(C0303)
[convention] 287-287: Trailing whitespace
(C0303)
[convention] 293-293: Trailing whitespace
(C0303)
[convention] 299-299: Trailing whitespace
(C0303)
[convention] 305-305: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 316-316: Trailing whitespace
(C0303)
[convention] 326-326: Trailing whitespace
(C0303)
[convention] 334-334: Trailing whitespace
(C0303)
[convention] 342-342: Trailing whitespace
(C0303)
[convention] 354-354: Trailing whitespace
(C0303)
[convention] 359-359: Trailing whitespace
(C0303)
[convention] 366-366: Trailing whitespace
(C0303)
[convention] 368-368: Trailing whitespace
(C0303)
[convention] 375-375: Trailing whitespace
(C0303)
[convention] 382-382: Trailing whitespace
(C0303)
[convention] 389-389: Trailing whitespace
(C0303)
[convention] 396-396: Trailing whitespace
(C0303)
[convention] 403-403: Trailing whitespace
(C0303)
[convention] 408-408: Trailing whitespace
(C0303)
[convention] 419-419: Trailing whitespace
(C0303)
[convention] 425-425: Trailing whitespace
(C0303)
[convention] 431-431: Trailing whitespace
(C0303)
[convention] 437-437: Trailing whitespace
(C0303)
[convention] 444-444: Trailing whitespace
(C0303)
[convention] 449-449: Trailing whitespace
(C0303)
[convention] 456-456: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 465-465: Trailing whitespace
(C0303)
[convention] 470-470: Trailing whitespace
(C0303)
[convention] 476-476: Trailing whitespace
(C0303)
[convention] 480-480: Trailing whitespace
(C0303)
[convention] 484-484: Trailing whitespace
(C0303)
[convention] 487-487: Trailing whitespace
(C0303)
[convention] 498-498: Trailing whitespace
(C0303)
[convention] 501-501: Trailing whitespace
(C0303)
[convention] 504-504: Trailing whitespace
(C0303)
[convention] 507-507: Trailing whitespace
(C0303)
[convention] 511-511: Trailing whitespace
(C0303)
[convention] 523-523: Trailing whitespace
(C0303)
[convention] 530-530: Trailing whitespace
(C0303)
[convention] 533-533: Trailing whitespace
(C0303)
[convention] 540-540: Trailing whitespace
(C0303)
[convention] 549-549: Trailing whitespace
(C0303)
[convention] 554-554: Trailing whitespace
(C0303)
[convention] 563-563: Trailing whitespace
(C0303)
[convention] 568-568: Trailing whitespace
(C0303)
[convention] 586-586: Trailing whitespace
(C0303)
[convention] 593-593: Trailing whitespace
(C0303)
[convention] 596-596: Trailing whitespace
(C0303)
[convention] 602-602: Trailing whitespace
(C0303)
[convention] 605-605: Trailing whitespace
(C0303)
[convention] 608-608: Trailing whitespace
(C0303)
[convention] 612-612: Trailing whitespace
(C0303)
[convention] 617-617: Trailing whitespace
(C0303)
[convention] 626-626: Trailing whitespace
(C0303)
[convention] 629-629: Trailing whitespace
(C0303)
[convention] 640-640: Trailing whitespace
(C0303)
[convention] 645-645: Trailing whitespace
(C0303)
[convention] 652-652: Trailing whitespace
(C0303)
[convention] 657-657: Trailing whitespace
(C0303)
[convention] 663-663: Trailing whitespace
(C0303)
[convention] 667-667: Trailing whitespace
(C0303)
[convention] 672-672: Trailing whitespace
(C0303)
[convention] 676-676: Trailing whitespace
(C0303)
[convention] 682-682: Trailing whitespace
(C0303)
[convention] 685-685: Trailing whitespace
(C0303)
[convention] 690-690: Trailing whitespace
(C0303)
[convention] 694-694: Trailing whitespace
(C0303)
[convention] 699-699: Trailing whitespace
(C0303)
[convention] 708-708: Trailing whitespace
(C0303)
[convention] 713-713: Trailing whitespace
(C0303)
[convention] 716-716: Trailing whitespace
(C0303)
[convention] 718-718: Trailing whitespace
(C0303)
[convention] 725-725: Trailing whitespace
(C0303)
[convention] 729-729: Trailing whitespace
(C0303)
[convention] 734-734: Trailing whitespace
(C0303)
[convention] 740-740: Trailing whitespace
(C0303)
[convention] 743-743: Trailing whitespace
(C0303)
[convention] 748-748: Trailing whitespace
(C0303)
[convention] 753-753: Trailing whitespace
(C0303)
[convention] 763-763: Trailing whitespace
(C0303)
[convention] 766-766: Trailing whitespace
(C0303)
[convention] 770-770: Trailing whitespace
(C0303)
[convention] 773-773: Trailing whitespace
(C0303)
[convention] 779-779: Trailing whitespace
(C0303)
[convention] 781-781: Trailing whitespace
(C0303)
[convention] 784-784: Trailing whitespace
(C0303)
[convention] 794-794: Trailing whitespace
(C0303)
[convention] 818-818: Trailing whitespace
(C0303)
[convention] 820-820: Trailing whitespace
(C0303)
[convention] 831-831: Trailing whitespace
(C0303)
[convention] 834-834: Trailing whitespace
(C0303)
[convention] 845-845: Trailing whitespace
(C0303)
[convention] 847-847: Trailing whitespace
(C0303)
[convention] 854-854: Trailing whitespace
(C0303)
[convention] 856-856: Trailing whitespace
(C0303)
[convention] 860-860: Trailing whitespace
(C0303)
[convention] 864-864: Trailing whitespace
(C0303)
[convention] 874-874: Trailing whitespace
(C0303)
[convention] 887-887: Trailing whitespace
(C0303)
[convention] 892-892: Trailing whitespace
(C0303)
[convention] 895-895: Trailing whitespace
(C0303)
[convention] 902-902: Trailing whitespace
(C0303)
[convention] 907-907: Trailing whitespace
(C0303)
[convention] 912-912: Trailing whitespace
(C0303)
[convention] 919-919: Trailing whitespace
(C0303)
[convention] 926-926: Trailing whitespace
(C0303)
[convention] 930-930: Trailing whitespace
(C0303)
[convention] 936-936: Trailing whitespace
(C0303)
[convention] 951-951: Trailing whitespace
(C0303)
[convention] 960-960: Trailing whitespace
(C0303)
[convention] 969-969: Trailing whitespace
(C0303)
[convention] 980-980: Trailing whitespace
(C0303)
[convention] 993-993: Trailing whitespace
(C0303)
[convention] 995-995: Trailing whitespace
(C0303)
[convention] 1000-1000: Trailing whitespace
(C0303)
[convention] 1005-1005: Trailing whitespace
(C0303)
[convention] 1007-1007: Trailing whitespace
(C0303)
[convention] 1011-1011: Trailing whitespace
(C0303)
[convention] 1026-1026: Trailing whitespace
(C0303)
[convention] 1028-1028: Trailing whitespace
(C0303)
[convention] 1033-1033: Trailing whitespace
(C0303)
[convention] 1038-1038: Trailing whitespace
(C0303)
[convention] 1042-1042: Trailing whitespace
(C0303)
[convention] 1044-1044: Trailing whitespace
(C0303)
[convention] 1048-1048: Trailing whitespace
(C0303)
[convention] 1057-1057: Trailing whitespace
(C0303)
[convention] 1062-1062: Trailing whitespace
(C0303)
[convention] 1067-1067: Trailing whitespace
(C0303)
[convention] 1070-1070: Trailing whitespace
(C0303)
[convention] 1075-1075: Trailing whitespace
(C0303)
[convention] 1080-1080: Trailing whitespace
(C0303)
[convention] 1082-1082: Trailing whitespace
(C0303)
[convention] 1086-1086: Trailing whitespace
(C0303)
[convention] 1090-1090: Trailing whitespace
(C0303)
[convention] 1095-1095: Trailing whitespace
(C0303)
[convention] 1098-1098: Trailing whitespace
(C0303)
[convention] 1100-1100: Trailing whitespace
(C0303)
[convention] 1106-1106: Trailing whitespace
(C0303)
[convention] 1110-1110: Trailing whitespace
(C0303)
[convention] 1117-1117: Trailing whitespace
(C0303)
[convention] 1121-1121: Trailing whitespace
(C0303)
[convention] 1125-1125: Trailing whitespace
(C0303)
[convention] 1133-1133: Trailing whitespace
(C0303)
[convention] 1144-1144: Trailing whitespace
(C0303)
[convention] 1157-1157: Trailing whitespace
(C0303)
[convention] 1165-1165: Trailing whitespace
(C0303)
[convention] 1172-1172: Trailing whitespace
(C0303)
[convention] 1179-1179: Trailing whitespace
(C0303)
[convention] 1187-1187: Trailing whitespace
(C0303)
[convention] 1201-1201: Trailing whitespace
(C0303)
[convention] 1210-1210: Trailing whitespace
(C0303)
[convention] 1215-1215: Trailing whitespace
(C0303)
[convention] 1220-1220: Trailing whitespace
(C0303)
[convention] 1224-1224: Trailing whitespace
(C0303)
[convention] 1228-1228: Trailing whitespace
(C0303)
[convention] 1232-1232: Trailing whitespace
(C0303)
[convention] 1235-1235: Trailing whitespace
(C0303)
[convention] 1242-1242: Trailing whitespace
(C0303)
[convention] 1247-1247: Trailing whitespace
(C0303)
[convention] 1253-1253: Trailing whitespace
(C0303)
[convention] 1256-1256: Trailing whitespace
(C0303)
[convention] 1262-1262: Trailing whitespace
(C0303)
[convention] 1270-1270: Trailing whitespace
(C0303)
[convention] 1283-1283: Trailing whitespace
(C0303)
[convention] 1286-1286: Trailing whitespace
(C0303)
[convention] 1293-1293: Trailing whitespace
(C0303)
[convention] 1297-1297: Trailing whitespace
(C0303)
[convention] 1306-1306: Trailing whitespace
(C0303)
[convention] 1308-1308: Trailing whitespace
(C0303)
[convention] 1314-1314: Trailing whitespace
(C0303)
[convention] 1317-1317: Trailing whitespace
(C0303)
[convention] 1320-1320: Trailing whitespace
(C0303)
[convention] 1330-1330: Trailing whitespace
(C0303)
[convention] 1334-1334: Trailing whitespace
(C0303)
[convention] 1336-1336: Trailing whitespace
(C0303)
[convention] 1339-1339: Trailing whitespace
(C0303)
[convention] 1344-1344: Trailing whitespace
(C0303)
[convention] 1355-1355: Trailing whitespace
(C0303)
[convention] 1361-1361: Trailing whitespace
(C0303)
[convention] 1364-1364: Trailing whitespace
(C0303)
[convention] 1375-1375: Trailing whitespace
(C0303)
[convention] 1381-1381: Trailing whitespace
(C0303)
[convention] 1383-1383: Trailing whitespace
(C0303)
[convention] 1386-1386: Trailing whitespace
(C0303)
[convention] 1393-1393: Trailing whitespace
(C0303)
[convention] 1397-1397: Trailing whitespace
(C0303)
[convention] 1402-1402: Trailing whitespace
(C0303)
[convention] 1409-1409: Trailing whitespace
(C0303)
[convention] 1418-1418: Trailing whitespace
(C0303)
[convention] 1420-1420: Trailing whitespace
(C0303)
[convention] 1425-1425: Trailing whitespace
(C0303)
[convention] 1430-1430: Trailing whitespace
(C0303)
[convention] 1435-1435: Trailing whitespace
(C0303)
[convention] 1440-1440: Trailing whitespace
(C0303)
[convention] 1-1: Too many lines in module (1451/1000)
(C0302)
[convention] 17-28: Import "from utils.helpers import safe_json_parse, safe_json_dumps, generate_hash, retry_with_backoff, flatten_dict, ensure_directory_exists, sanitize_filename, merge_dicts, chunk_list, format_duration" should be placed at the top of the module
(C0413)
[convention] 94-94: Import outside toplevel (datetime.datetime)
(C0415)
[convention] 238-238: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[convention] 358-358: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[warning] 528-528: Unused variable 'i'
(W0612)
[convention] 599-599: Missing class docstring
(C0115)
[refactor] 599-599: Too few public methods (1/2)
(R0903)
[convention] 615-615: Import outside toplevel (decimal.Decimal)
(C0415)
[convention] 616-616: Import outside toplevel (uuid)
(C0415)
[warning] 641-641: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 641-641: Reimport 'time' (imported line 10)
(W0404)
[convention] 641-641: Import outside toplevel (time)
(C0415)
[warning] 769-769: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 769-769: Reimport 'time' (imported line 10)
(W0404)
[convention] 769-769: Import outside toplevel (time)
(C0415)
[warning] 771-771: Unused variable 'start_time'
(W0612)
[warning] 838-843: Duplicate key True in dictionary
(W0109)
[error] 868-868: Unexpected keyword argument 'separator' in function call
(E1123)
[warning] 888-888: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 888-888: Reimport 'time' (imported line 10)
(W0404)
[convention] 888-888: Import outside toplevel (time)
(C0415)
[warning] 906-906: Redefining name 'tempfile' from outer scope (line 9)
(W0621)
[convention] 905-905: Import outside toplevel (threading)
(C0415)
[warning] 906-906: Reimport 'tempfile' (imported line 9)
(W0404)
[convention] 906-906: Import outside toplevel (tempfile)
(C0415)
[warning] 917-917: Catching too general exception Exception
(W0718)
[convention] 975-975: Use expected.rsplit('.', maxsplit=1)[-1] instead
(C0207)
[warning] 1063-1063: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 1063-1063: Reimport 'time' (imported line 10)
(W0404)
[convention] 1063-1063: Import outside toplevel (time)
(C0415)
[warning] 1280-1280: Catching too general exception Exception
(W0718)
[warning] 1275-1275: Cell variable chunk defined in loop
(W0640)
[warning] 1296-1296: Redefining name 'tempfile' from outer scope (line 9)
(W0621)
[warning] 1296-1296: Reimport 'tempfile' (imported line 9)
(W0404)
[convention] 1296-1296: Import outside toplevel (tempfile)
(C0415)
[warning] 1346-1346: Using open without explicitly specifying an encoding
(W1514)
[convention] 1359-1359: Import outside toplevel (threading)
(C0415)
[convention] 1360-1360: Import outside toplevel (random)
(C0415)
[warning] 1384-1384: Catching too general exception Exception
(W0718)
[warning] 1419-1419: Redefining name 'time' from outer scope (line 10)
(W0621)
[error] 1414-1414: Using variable 'time' before assignment
(E0601)
[warning] 1419-1419: Reimport 'time' (imported line 10)
(W0404)
[convention] 1419-1419: Import outside toplevel (time)
(C0415)
[error] 1449-1449: Module 'pytest' has no 'config' member; maybe 'Config'?
(E1101)
[convention] 8-8: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 9-9: standard import "tempfile" should be placed before third party import "pytest"
(C0411)
[convention] 10-10: standard import "time" should be placed before third party import "pytest"
(C0411)
[convention] 11-11: standard import "pathlib.Path" should be placed before third party import "pytest"
(C0411)
[convention] 12-12: standard import "unittest.mock.patch" should be placed before third party import "pytest"
(C0411)
[convention] 14-14: standard import "sys" should be placed before third party import "pytest"
(C0411)
test_llm_continuous_learning_system.py
[convention] 46-46: Line too long (114/100)
(C0301)
[convention] 67-67: Line too long (111/100)
(C0301)
[convention] 68-68: Line too long (111/100)
(C0301)
[convention] 69-69: Line too long (110/100)
(C0301)
[convention] 82-82: Line too long (114/100)
(C0301)
[convention] 89-89: Trailing whitespace
(C0303)
[convention] 102-102: Line too long (123/100)
(C0301)
[convention] 112-112: Trailing whitespace
(C0303)
[convention] 126-126: Line too long (122/100)
(C0301)
[convention] 136-136: Line too long (119/100)
(C0301)
[convention] 146-146: Line too long (119/100)
(C0301)
[convention] 162-162: Line too long (118/100)
(C0301)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 218-218: Trailing whitespace
(C0303)
[convention] 220-220: Trailing whitespace
(C0303)
[convention] 227-227: Trailing whitespace
(C0303)
[convention] 237-237: Trailing whitespace
(C0303)
[convention] 244-244: Trailing whitespace
(C0303)
[convention] 251-251: Trailing whitespace
(C0303)
[convention] 258-258: Trailing whitespace
(C0303)
[convention] 265-265: Trailing whitespace
(C0303)
[convention] 272-272: Trailing whitespace
(C0303)
[convention] 280-280: Trailing whitespace
(C0303)
[convention] 287-287: Trailing whitespace
(C0303)
[convention] 298-298: Trailing whitespace
(C0303)
[convention] 307-307: Trailing whitespace
(C0303)
[convention] 309-309: Trailing whitespace
(C0303)
[convention] 319-319: Trailing whitespace
(C0303)
[convention] 321-321: Trailing whitespace
(C0303)
[convention] 333-333: Trailing whitespace
(C0303)
[convention] 335-335: Trailing whitespace
(C0303)
[convention] 348-348: Line too long (114/100)
(C0301)
[convention] 380-380: Trailing whitespace
(C0303)
[convention] 382-382: Trailing whitespace
(C0303)
[convention] 396-396: Trailing whitespace
(C0303)
[convention] 399-399: Trailing whitespace
(C0303)
[convention] 406-406: Trailing whitespace
(C0303)
[convention] 415-415: Trailing whitespace
(C0303)
[convention] 417-417: Trailing whitespace
(C0303)
[convention] 426-426: Trailing whitespace
(C0303)
[convention] 428-428: Trailing whitespace
(C0303)
[convention] 436-436: Trailing whitespace
(C0303)
[convention] 439-439: Trailing whitespace
(C0303)
[convention] 446-446: Trailing whitespace
(C0303)
[convention] 448-448: Trailing whitespace
(C0303)
[convention] 456-456: Trailing whitespace
(C0303)
[convention] 458-458: Trailing whitespace
(C0303)
[convention] 466-466: Trailing whitespace
(C0303)
[convention] 468-468: Trailing whitespace
(C0303)
[convention] 475-475: Trailing whitespace
(C0303)
[convention] 497-497: Line too long (111/100)
(C0301)
[convention] 498-498: Line too long (111/100)
(C0301)
[convention] 499-499: Line too long (111/100)
(C0301)
[convention] 500-500: Line too long (111/100)
(C0301)
[convention] 501-501: Line too long (110/100)
(C0301)
[convention] 518-518: Line too long (125/100)
(C0301)
[convention] 519-519: Line too long (129/100)
(C0301)
[convention] 520-520: Line too long (141/100)
(C0301)
[convention] 521-521: Line too long (126/100)
(C0301)
[convention] 522-522: Line too long (139/100)
(C0301)
[convention] 528-528: Trailing whitespace
(C0303)
[convention] 530-530: Trailing whitespace
(C0303)
[convention] 538-538: Trailing whitespace
(C0303)
[convention] 540-540: Trailing whitespace
(C0303)
[convention] 544-544: Line too long (105/100)
(C0301)
[convention] 547-547: Trailing whitespace
(C0303)
[convention] 551-551: Line too long (104/100)
(C0301)
[convention] 554-554: Trailing whitespace
(C0303)
[convention] 558-558: Line too long (102/100)
(C0301)
[convention] 561-561: Trailing whitespace
(C0303)
[convention] 564-564: Line too long (105/100)
(C0301)
[convention] 569-569: Line too long (106/100)
(C0301)
[convention] 580-580: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 593-593: Trailing whitespace
(C0303)
[convention] 593-593: Line too long (105/100)
(C0301)
[convention] 596-596: Line too long (106/100)
(C0301)
[convention] 597-597: Trailing whitespace
(C0303)
[convention] 649-649: Trailing whitespace
(C0303)
[convention] 662-662: Trailing whitespace
(C0303)
[convention] 664-664: Trailing whitespace
(C0303)
[convention] 675-675: Trailing whitespace
(C0303)
[convention] 677-677: Trailing whitespace
(C0303)
[convention] 685-685: Trailing whitespace
(C0303)
[convention] 693-693: Trailing whitespace
(C0303)
[convention] 731-731: Trailing whitespace
(C0303)
[convention] 733-733: Trailing whitespace
(C0303)
[convention] 741-741: Trailing whitespace
(C0303)
[convention] 751-751: Trailing whitespace
(C0303)
[convention] 752-752: Line too long (102/100)
(C0301)
[convention] 763-763: Trailing whitespace
(C0303)
[convention] 799-799: Trailing whitespace
(C0303)
[convention] 816-816: Trailing whitespace
(C0303)
[convention] 818-818: Trailing whitespace
(C0303)
[convention] 833-833: Trailing whitespace
(C0303)
[convention] 835-835: Trailing whitespace
(C0303)
[convention] 848-848: Trailing whitespace
(C0303)
[convention] 887-887: Trailing whitespace
(C0303)
[convention] 897-897: Trailing whitespace
(C0303)
[convention] 907-907: Trailing whitespace
(C0303)
[convention] 917-917: Trailing whitespace
(C0303)
[convention] 928-928: Trailing whitespace
(C0303)
[convention] 939-939: Trailing whitespace
(C0303)
[convention] 950-950: Trailing whitespace
(C0303)
[convention] 1005-1005: Trailing whitespace
(C0303)
[convention] 1014-1014: Trailing whitespace
(C0303)
[convention] 1016-1016: Trailing whitespace
(C0303)
[convention] 1019-1019: Trailing whitespace
(C0303)
[convention] 1022-1022: Trailing whitespace
(C0303)
[convention] 1025-1025: Trailing whitespace
(C0303)
[convention] 1036-1036: Trailing whitespace
(C0303)
[convention] 1039-1039: Trailing whitespace
(C0303)
[convention] 1043-1043: Trailing whitespace
(C0303)
[convention] 1053-1053: Trailing whitespace
(C0303)
[convention] 1055-1055: Trailing whitespace
(C0303)
[convention] 1058-1058: Trailing whitespace
(C0303)
[convention] 1061-1061: Trailing whitespace
(C0303)
[convention] 1099-1099: Trailing whitespace
(C0303)
[convention] 1101-1101: Trailing whitespace
(C0303)
[convention] 1112-1112: Trailing whitespace
(C0303)
[convention] 1122-1122: Trailing whitespace
(C0303)
[convention] 1133-1133: Trailing whitespace
(C0303)
[convention] 1146-1146: Trailing whitespace
(C0303)
[convention] 1156-1156: Trailing whitespace
(C0303)
[convention] 1158-1158: Trailing whitespace
(C0303)
[convention] 1167-1167: Trailing whitespace
(C0303)
[convention] 1169-1169: Trailing whitespace
(C0303)
[convention] 1177-1177: Trailing whitespace
(C0303)
[convention] 1182-1182: Trailing whitespace
(C0303)
[convention] 1234-1234: Line too long (107/100)
(C0301)
[convention] 1259-1259: Final newline missing
(C0304)
[convention] 1-1: Too many lines in module (1259/1000)
(C0302)
[warning] 100-100: Access to a protected member _is_training of a client class
(W0212)
[refactor] 162-162: Too many arguments (7/5)
(R0913)
[refactor] 162-162: Too many positional arguments (7/5)
(R0917)
[warning] 389-389: Access to a protected member _is_training of a client class
(W0212)
[warning] 400-400: Access to a protected member _is_training of a client class
(W0212)
[warning] 405-405: Access to a protected member _is_training of a client class
(W0212)
[warning] 815-815: Access to a protected member _is_training of a client class
(W0212)
[warning] 1012-1012: Catching too general exception Exception
(W0718)
[warning] 1050-1050: Unused variable 'i'
(W0612)
[warning] 1180-1180: Catching too general exception Exception
(W0718)
[error] 1234-1234: Undefined variable 'Tuple'
(E0602)
[convention] 19-19: standard import "asyncio" should be placed before third party import "pytest"
(C0411)
[convention] 20-20: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 21-21: standard import "threading" should be placed before third party import "pytest"
(C0411)
[convention] 22-22: standard import "time" should be placed before third party import "pytest"
(C0411)
[convention] 23-23: standard import "tempfile" should be placed before third party import "pytest"
(C0411)
[convention] 24-24: standard import "os" should be placed before third party import "pytest"
(C0411)
[convention] 25-25: standard import "unittest.mock.Mock" should be placed before third party import "pytest"
(C0411)
[convention] 26-26: standard import "datetime.datetime" should be placed before third party import "pytest"
(C0411)
[convention] 27-27: standard import "typing.List" should be placed before third party import "pytest"
(C0411)
[warning] 20-20: Unused import json
(W0611)
[warning] 25-25: Unused patch imported from unittest.mock
(W0611)
[warning] 25-25: Unused MagicMock imported from unittest.mock
(W0611)
[warning] 25-25: Unused call imported from unittest.mock
(W0611)
🔇 Additional comments (3)
pytest.ini (1)
1-5: Configuration looks good!The pytest configuration properly defines a custom marker for slow tests and enforces strict marker usage, which helps maintain test organization and prevents typos in marker names.
test_github_workflows.py (1)
629-790: Excellent edge case coverage!The edge case tests are comprehensive and cover important scenarios including Unicode support, empty workflows, malformed YAML, deeply nested structures, and all GitHub workflow trigger types. This thorough testing helps ensure robustness.
test_llm_continuous_learning_system.py (1)
1-16: Well-structured and comprehensive test suite!The test suite provides excellent coverage of the LLMContinuousLearningSystem with proper organization into focused test classes, good use of fixtures, and thorough testing of edge cases.
| class TestGitHubWorkflowSecurity: | ||
| """Test suite for GitHub workflow security validations.""" | ||
|
|
||
| @pytest.fixture | ||
| def insecure_workflow_yaml(self): | ||
| """Workflow with potential security issues.""" | ||
| return """ | ||
| name: Insecure Workflow | ||
| on: | ||
| pull_request_target: # Potentially dangerous | ||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v2 # Outdated version | ||
| - name: Run untrusted code | ||
| run: | | ||
| curl -s ${{ github.event.pull_request.head.repo.clone_url }} | bash | ||
| - name: Use secret in command | ||
| run: echo "Secret: ${{ secrets.API_KEY }}" | ||
| """ | ||
|
|
||
| def test_detect_pull_request_target_trigger(self, insecure_workflow_yaml): | ||
| """Test detection of potentially dangerous pull_request_target trigger.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| # This trigger can be dangerous as it runs with write permissions | ||
| assert 'pull_request_target' in parsed['on'] | ||
|
|
||
| def test_detect_outdated_actions(self, insecure_workflow_yaml): | ||
| """Test detection of outdated action versions.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| checkout_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'uses' in step and 'checkout' in step['uses']: | ||
| checkout_step = step | ||
| break | ||
|
|
||
| assert checkout_step is not None | ||
| assert '@v2' in checkout_step['uses'] # Outdated version | ||
|
|
||
| def test_detect_secret_exposure(self, insecure_workflow_yaml): | ||
| """Test detection of potential secret exposure.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| dangerous_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'run' in step and 'secrets.' in step['run']: | ||
| dangerous_step = step | ||
| break | ||
|
|
||
| assert dangerous_step is not None | ||
| assert '${{ secrets.' in dangerous_step['run'] | ||
|
|
||
| def test_detect_code_injection_risk(self, insecure_workflow_yaml): | ||
| """Test detection of potential code injection vulnerabilities.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| risky_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'run' in step and 'github.event' in step['run'] and 'bash' in step['run']: | ||
| risky_step = step | ||
| break | ||
|
|
||
| assert risky_step is not None | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Excellent security test coverage!
The security tests effectively cover critical vulnerabilities like pull_request_target usage, outdated actions, secret exposure, and code injection risks. Just add type annotations for consistency.
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 349-349: blank line contains whitespace
(W293)
[warning] 373-373: blank line contains whitespace
(W293)
[warning] 380-380: blank line contains whitespace
(W293)
[warning] 386-386: blank line contains whitespace
(W293)
[warning] 393-393: blank line contains whitespace
(W293)
[warning] 399-399: blank line contains whitespace
(W293)
[warning] 406-406: blank line contains whitespace
(W293)
[warning] 412-412: blank line contains whitespace
(W293)
🪛 Ruff (0.11.9)
351-351: Missing return type annotation for public function insecure_workflow_yaml
Add return type annotation: str
(ANN201)
370-370: Missing return type annotation for public function test_detect_pull_request_target_trigger
Add return type annotation: None
(ANN201)
370-370: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
377-377: Missing return type annotation for public function test_detect_outdated_actions
Add return type annotation: None
(ANN201)
377-377: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
390-390: Missing return type annotation for public function test_detect_secret_exposure
Add return type annotation: None
(ANN201)
390-390: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
403-403: Missing return type annotation for public function test_detect_code_injection_risk
Add return type annotation: None
(ANN201)
403-403: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
🪛 Pylint (3.3.7)
[convention] 349-349: Trailing whitespace
(C0303)
[convention] 373-373: Trailing whitespace
(C0303)
[convention] 380-380: Trailing whitespace
(C0303)
[convention] 386-386: Trailing whitespace
(C0303)
[convention] 393-393: Trailing whitespace
(C0303)
[convention] 399-399: Trailing whitespace
(C0303)
[convention] 406-406: Trailing whitespace
(C0303)
[convention] 412-412: Trailing whitespace
(C0303)
🤖 Prompt for AI Agents
In test_github_workflows.py from lines 347 to 414, the security test methods
lack type annotations for their parameters and return types. Add appropriate
type annotations to all test methods and fixtures, such as specifying the return
type of the insecure_workflow_yaml fixture as str and annotating the test
methods with the pytest fixture parameter types and return type None. This will
improve code consistency and clarity.
| # Test parsing performance | ||
| import time | ||
| start_time = time.time() | ||
| yaml_content = yaml.dump(large_workflow) | ||
| parsed = yaml.safe_load(yaml_content) | ||
| end_time = time.time() | ||
|
|
||
| assert parsed['name'] == 'Large Workflow' | ||
| assert len(parsed['jobs']) == 50 | ||
| assert (end_time - start_time) < 1.0 # Should complete within 1 second |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Move time import to module level
Imports should be at the module level, not inside functions.
Add import time at the top of the file with other imports, then remove line 587.
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 592-592: blank line contains whitespace
(W293)
🪛 Pylint (3.3.7)
[convention] 592-592: Trailing whitespace
(C0303)
[convention] 587-587: Import outside toplevel (time)
(C0415)
🤖 Prompt for AI Agents
In test_github_workflows.py around lines 586 to 595, the import statement for
the time module is inside the function, which is not best practice. Move the
import time statement to the top of the file with the other imports and remove
the import time line at line 587 inside the function.
| """ | ||
| Comprehensive unit tests for GitHub workflow functionality. | ||
| Testing framework: pytest with fixtures, mocks, and parametrized tests. | ||
| """ | ||
|
|
||
| import pytest | ||
| import json | ||
| import yaml | ||
| import os | ||
| from unittest.mock import Mock, patch, mock_open | ||
| from pathlib import Path | ||
| from typing import Dict, List, Any | ||
|
|
||
|
|
||
| class TestGitHubWorkflowParser: | ||
| """Test suite for GitHub workflow parsing functionality.""" | ||
|
|
||
| @pytest.fixture | ||
| def sample_workflow_yaml(self): | ||
| """Sample GitHub workflow YAML content for testing.""" | ||
| return """ | ||
| name: CI | ||
| on: | ||
| push: | ||
| branches: [main, develop] | ||
| pull_request: | ||
| branches: [main] | ||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.9' | ||
| - name: Install dependencies | ||
| run: pip install -r requirements.txt | ||
| - name: Run tests | ||
| run: pytest | ||
| """ | ||
|
|
||
| @pytest.fixture | ||
| def invalid_workflow_yaml(self): | ||
| """Invalid YAML content for testing error handling.""" | ||
| return """ | ||
| name: Invalid Workflow | ||
| on: | ||
| push: | ||
| branches: [main | ||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - invalid_syntax | ||
| """ | ||
|
|
||
| @pytest.fixture | ||
| def complex_workflow_yaml(self): | ||
| """Complex workflow with multiple jobs and conditions.""" | ||
| return """ | ||
| name: Complex CI/CD | ||
| on: | ||
| push: | ||
| branches: [main] | ||
| tags: ['v*'] | ||
| schedule: | ||
| - cron: '0 2 * * 0' | ||
| env: | ||
| GLOBAL_VAR: global_value | ||
| jobs: | ||
| lint: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| lint-status: ${{ steps.lint.outputs.status }} | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - name: Lint code | ||
| id: lint | ||
| run: flake8 . | ||
| test: | ||
| runs-on: ${{ matrix.os }} | ||
| needs: lint | ||
| strategy: | ||
| matrix: | ||
| os: [ubuntu-latest, windows-latest, macos-latest] | ||
| python-version: ['3.8', '3.9', '3.10'] | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - name: Setup Python ${{ matrix.python-version }} | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
| - name: Run tests | ||
| run: pytest --cov | ||
| deploy: | ||
| runs-on: ubuntu-latest | ||
| needs: [lint, test] | ||
| if: github.ref == 'refs/heads/main' | ||
| environment: production | ||
| steps: | ||
| - name: Deploy | ||
| run: echo "Deploying to production" | ||
| """ | ||
|
|
||
| @pytest.fixture | ||
| def mock_workflow_file(self, tmp_path, sample_workflow_yaml): | ||
| """Create a temporary workflow file for testing.""" | ||
| workflow_file = tmp_path / ".github" / "workflows" / "ci.yml" | ||
| workflow_file.parent.mkdir(parents=True, exist_ok=True) | ||
| workflow_file.write_text(sample_workflow_yaml) | ||
| return workflow_file | ||
|
|
||
| def test_parse_valid_workflow_yaml(self, sample_workflow_yaml): | ||
| """Test parsing of valid workflow YAML.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
|
|
||
| assert parsed['name'] == 'CI' | ||
| assert 'push' in parsed['on'] | ||
| assert 'pull_request' in parsed['on'] | ||
| assert 'test' in parsed['jobs'] | ||
| assert parsed['jobs']['test']['runs-on'] == 'ubuntu-latest' | ||
| assert len(parsed['jobs']['test']['steps']) == 4 | ||
|
|
||
| def test_parse_invalid_workflow_yaml(self, invalid_workflow_yaml): | ||
| """Test handling of invalid YAML syntax.""" | ||
| with pytest.raises(yaml.YAMLError): | ||
| yaml.safe_load(invalid_workflow_yaml) | ||
|
|
||
| def test_workflow_validation_missing_required_fields(self): | ||
| """Test validation of workflows missing required fields.""" | ||
| incomplete_workflow = { | ||
| 'name': 'Incomplete Workflow' | ||
| # Missing 'on' and 'jobs' fields | ||
| } | ||
|
|
||
| # Test that required fields are validated | ||
| assert 'on' not in incomplete_workflow | ||
| assert 'jobs' not in incomplete_workflow | ||
|
|
||
| def test_workflow_job_validation(self, sample_workflow_yaml): | ||
| """Test validation of job configuration.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
| job = parsed['jobs']['test'] | ||
|
|
||
| assert 'runs-on' in job | ||
| assert 'steps' in job | ||
| assert isinstance(job['steps'], list) | ||
| assert all('uses' in step or 'run' in step or 'name' in step for step in job['steps']) | ||
|
|
||
| @pytest.mark.parametrize("trigger_event,expected_branches", [ | ||
| ('push', ['main', 'develop']), | ||
| ('pull_request', ['main']), | ||
| ]) | ||
| def test_workflow_triggers(self, sample_workflow_yaml, trigger_event, expected_branches): | ||
| """Test workflow trigger configurations.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
|
|
||
| assert trigger_event in parsed['on'] | ||
| if 'branches' in parsed['on'][trigger_event]: | ||
| assert parsed['on'][trigger_event]['branches'] == expected_branches | ||
|
|
||
| def test_complex_workflow_structure(self, complex_workflow_yaml): | ||
| """Test parsing of complex workflow with multiple jobs and dependencies.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| # Test basic structure | ||
| assert parsed['name'] == 'Complex CI/CD' | ||
| assert len(parsed['jobs']) == 3 | ||
|
|
||
| # Test job dependencies | ||
| assert 'needs' in parsed['jobs']['test'] | ||
| assert parsed['jobs']['test']['needs'] == 'lint' | ||
| assert parsed['jobs']['deploy']['needs'] == ['lint', 'test'] | ||
|
|
||
| # Test matrix strategy | ||
| assert 'strategy' in parsed['jobs']['test'] | ||
| matrix = parsed['jobs']['test']['strategy']['matrix'] | ||
| assert len(matrix['os']) == 3 | ||
| assert len(matrix['python-version']) == 3 | ||
|
|
||
| # Test conditional execution | ||
| assert 'if' in parsed['jobs']['deploy'] | ||
| assert 'environment' in parsed['jobs']['deploy'] | ||
|
|
||
| def test_workflow_environment_variables(self, complex_workflow_yaml): | ||
| """Test handling of environment variables in workflows.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| assert 'env' in parsed | ||
| assert parsed['env']['GLOBAL_VAR'] == 'global_value' | ||
|
|
||
| def test_workflow_outputs(self, complex_workflow_yaml): | ||
| """Test job outputs configuration.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| lint_job = parsed['jobs']['lint'] | ||
| assert 'outputs' in lint_job | ||
| assert 'lint-status' in lint_job['outputs'] | ||
|
|
||
| @pytest.mark.parametrize("step_type,required_field", [ | ||
| ('action', 'uses'), | ||
| ('script', 'run'), | ||
| ]) | ||
| def test_workflow_step_types(self, sample_workflow_yaml, step_type, required_field): | ||
| """Test different types of workflow steps.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
| steps = parsed['jobs']['test']['steps'] | ||
|
|
||
| # Find steps of the specified type | ||
| matching_steps = [step for step in steps if required_field in step] | ||
| assert len(matching_steps) > 0 | ||
|
|
||
| for step in matching_steps: | ||
| assert required_field in step | ||
| assert isinstance(step[required_field], str) | ||
|
|
||
|
|
||
| class TestGitHubWorkflowValidator: | ||
| """Test suite for GitHub workflow validation functionality.""" | ||
|
|
||
| @pytest.fixture | ||
| def validator_config(self): | ||
| """Configuration for workflow validator.""" | ||
| return { | ||
| 'required_fields': ['name', 'on', 'jobs'], | ||
| 'allowed_runners': ['ubuntu-latest', 'windows-latest', 'macos-latest'], | ||
| 'max_jobs': 10, | ||
| 'max_steps_per_job': 20 | ||
| } | ||
|
|
||
| def test_validate_workflow_structure_valid(self, sample_workflow_yaml, validator_config): | ||
| """Test validation of valid workflow structure.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
|
|
||
| # Check required fields | ||
| for field in validator_config['required_fields']: | ||
| assert field in parsed | ||
|
|
||
| def test_validate_workflow_structure_missing_fields(self, validator_config): | ||
| """Test validation fails for missing required fields.""" | ||
| invalid_workflow = {'name': 'Test'} | ||
|
|
||
| missing_fields = [] | ||
| for field in validator_config['required_fields']: | ||
| if field not in invalid_workflow: | ||
| missing_fields.append(field) | ||
|
|
||
| assert len(missing_fields) > 0 | ||
| assert 'on' in missing_fields | ||
| assert 'jobs' in missing_fields | ||
|
|
||
| def test_validate_runner_allowed(self, sample_workflow_yaml, validator_config): | ||
| """Test validation of allowed runners.""" | ||
| parsed = yaml.safe_load(sample_workflow_yaml) | ||
|
|
||
| for job_name, job_config in parsed['jobs'].items(): | ||
| if 'runs-on' in job_config: | ||
| runner = job_config['runs-on'] | ||
| if isinstance(runner, str): | ||
| # For matrix strategies, runner might be a template | ||
| if not runner.startswith('${{'): | ||
| assert runner in validator_config['allowed_runners'] | ||
|
|
||
| def test_validate_job_limits(self, complex_workflow_yaml, validator_config): | ||
| """Test validation of job and step limits.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| # Test job count limit | ||
| assert len(parsed['jobs']) <= validator_config['max_jobs'] | ||
|
|
||
| # Test steps per job limit | ||
| for job_name, job_config in parsed['jobs'].items(): | ||
| if 'steps' in job_config: | ||
| assert len(job_config['steps']) <= validator_config['max_steps_per_job'] | ||
|
|
||
| @pytest.mark.parametrize("invalid_runner", [ | ||
| 'invalid-runner', | ||
| 'custom-runner-not-allowed', | ||
| 'ubuntu-18.04', # Deprecated | ||
| ]) | ||
| def test_validate_runner_not_allowed(self, invalid_runner, validator_config): | ||
| """Test validation rejects invalid runners.""" | ||
| assert invalid_runner not in validator_config['allowed_runners'] | ||
|
|
||
|
|
||
| class TestGitHubWorkflowFileOperations: | ||
| """Test suite for GitHub workflow file operations.""" | ||
|
|
||
| def test_read_workflow_file(self, mock_workflow_file): | ||
| """Test reading workflow file from filesystem.""" | ||
| content = mock_workflow_file.read_text() | ||
|
|
||
| assert 'name: CI' in content | ||
| assert 'on:' in content | ||
| assert 'jobs:' in content | ||
|
|
||
| def test_read_nonexistent_workflow_file(self, tmp_path): | ||
| """Test handling of nonexistent workflow files.""" | ||
| nonexistent_file = tmp_path / "nonexistent.yml" | ||
|
|
||
| assert not nonexistent_file.exists() | ||
| with pytest.raises(FileNotFoundError): | ||
| nonexistent_file.read_text() | ||
|
|
||
| @patch('pathlib.Path.read_text') | ||
| def test_read_workflow_file_permission_error(self, mock_read_text): | ||
| """Test handling of permission errors when reading files.""" | ||
| mock_read_text.side_effect = PermissionError("Permission denied") | ||
|
|
||
| workflow_file = Path("test.yml") | ||
| with pytest.raises(PermissionError): | ||
| workflow_file.read_text() | ||
|
|
||
| def test_write_workflow_file(self, tmp_path, sample_workflow_yaml): | ||
| """Test writing workflow file to filesystem.""" | ||
| output_file = tmp_path / "output.yml" | ||
| output_file.write_text(sample_workflow_yaml) | ||
|
|
||
| assert output_file.exists() | ||
| content = output_file.read_text() | ||
| assert content == sample_workflow_yaml | ||
|
|
||
| def test_discover_workflow_files(self, tmp_path): | ||
| """Test discovery of workflow files in directory structure.""" | ||
| # Create multiple workflow files | ||
| workflows_dir = tmp_path / ".github" / "workflows" | ||
| workflows_dir.mkdir(parents=True) | ||
|
|
||
| (workflows_dir / "ci.yml").write_text("name: CI") | ||
| (workflows_dir / "cd.yml").write_text("name: CD") | ||
| (workflows_dir / "test.yaml").write_text("name: Test") | ||
| (workflows_dir / "README.md").write_text("Not a workflow") | ||
|
|
||
| # Find workflow files | ||
| workflow_files = list(workflows_dir.glob("*.yml")) + list(workflows_dir.glob("*.yaml")) | ||
| workflow_files = [f for f in workflow_files if f.suffix in ['.yml', '.yaml']] | ||
|
|
||
| assert len(workflow_files) == 3 | ||
| workflow_names = [f.name for f in workflow_files] | ||
| assert "ci.yml" in workflow_names | ||
| assert "cd.yml" in workflow_names | ||
| assert "test.yaml" in workflow_names | ||
| assert "README.md" not in workflow_names | ||
|
|
||
|
|
||
| class TestGitHubWorkflowSecurity: | ||
| """Test suite for GitHub workflow security validations.""" | ||
|
|
||
| @pytest.fixture | ||
| def insecure_workflow_yaml(self): | ||
| """Workflow with potential security issues.""" | ||
| return """ | ||
| name: Insecure Workflow | ||
| on: | ||
| pull_request_target: # Potentially dangerous | ||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v2 # Outdated version | ||
| - name: Run untrusted code | ||
| run: | | ||
| curl -s ${{ github.event.pull_request.head.repo.clone_url }} | bash | ||
| - name: Use secret in command | ||
| run: echo "Secret: ${{ secrets.API_KEY }}" | ||
| """ | ||
|
|
||
| def test_detect_pull_request_target_trigger(self, insecure_workflow_yaml): | ||
| """Test detection of potentially dangerous pull_request_target trigger.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| # This trigger can be dangerous as it runs with write permissions | ||
| assert 'pull_request_target' in parsed['on'] | ||
|
|
||
| def test_detect_outdated_actions(self, insecure_workflow_yaml): | ||
| """Test detection of outdated action versions.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| checkout_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'uses' in step and 'checkout' in step['uses']: | ||
| checkout_step = step | ||
| break | ||
|
|
||
| assert checkout_step is not None | ||
| assert '@v2' in checkout_step['uses'] # Outdated version | ||
|
|
||
| def test_detect_secret_exposure(self, insecure_workflow_yaml): | ||
| """Test detection of potential secret exposure.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| dangerous_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'run' in step and 'secrets.' in step['run']: | ||
| dangerous_step = step | ||
| break | ||
|
|
||
| assert dangerous_step is not None | ||
| assert '${{ secrets.' in dangerous_step['run'] | ||
|
|
||
| def test_detect_code_injection_risk(self, insecure_workflow_yaml): | ||
| """Test detection of potential code injection vulnerabilities.""" | ||
| parsed = yaml.safe_load(insecure_workflow_yaml) | ||
|
|
||
| risky_step = None | ||
| for step in parsed['jobs']['test']['steps']: | ||
| if 'run' in step and 'github.event' in step['run'] and 'bash' in step['run']: | ||
| risky_step = step | ||
| break | ||
|
|
||
| assert risky_step is not None | ||
|
|
||
|
|
||
| class TestGitHubWorkflowUtilities: | ||
| """Test suite for GitHub workflow utility functions.""" | ||
|
|
||
| @pytest.mark.parametrize("workflow_name,expected_filename", [ | ||
| ("CI", "ci.yml"), | ||
| ("Build and Deploy", "build-and-deploy.yml"), | ||
| ("Test_Matrix", "test-matrix.yml"), | ||
| ("PR Validation", "pr-validation.yml"), | ||
| ]) | ||
| def test_generate_workflow_filename(self, workflow_name, expected_filename): | ||
| """Test generation of workflow filenames from names.""" | ||
| # Simple implementation of filename generation | ||
| filename = workflow_name.lower().replace(' ', '-').replace('_', '-') + '.yml' | ||
| assert filename == expected_filename | ||
|
|
||
| def test_extract_workflow_metadata(self, complex_workflow_yaml): | ||
| """Test extraction of workflow metadata.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| metadata = { | ||
| 'name': parsed.get('name'), | ||
| 'triggers': list(parsed.get('on', {}).keys()), | ||
| 'job_count': len(parsed.get('jobs', {})), | ||
| 'has_matrix': any('strategy' in job for job in parsed.get('jobs', {}).values()), | ||
| 'has_conditions': any('if' in job for job in parsed.get('jobs', {}).values()), | ||
| 'has_environment': any('environment' in job for job in parsed.get('jobs', {}).values()) | ||
| } | ||
|
|
||
| assert metadata['name'] == 'Complex CI/CD' | ||
| assert 'push' in metadata['triggers'] | ||
| assert 'schedule' in metadata['triggers'] | ||
| assert metadata['job_count'] == 3 | ||
| assert metadata['has_matrix'] is True | ||
| assert metadata['has_conditions'] is True | ||
| assert metadata['has_environment'] is True | ||
|
|
||
| def test_workflow_dependency_graph(self, complex_workflow_yaml): | ||
| """Test creation of job dependency graph.""" | ||
| parsed = yaml.safe_load(complex_workflow_yaml) | ||
|
|
||
| dependencies = {} | ||
| for job_name, job_config in parsed['jobs'].items(): | ||
| needs = job_config.get('needs', []) | ||
| if isinstance(needs, str): | ||
| needs = [needs] | ||
| dependencies[job_name] = needs | ||
|
|
||
| assert dependencies['lint'] == [] | ||
| assert dependencies['test'] == ['lint'] | ||
| assert set(dependencies['deploy']) == {'lint', 'test'} | ||
|
|
||
| @pytest.mark.parametrize("cron_expression,is_valid", [ | ||
| ("0 2 * * 0", True), # Every Sunday at 2 AM | ||
| ("0 0 * * *", True), # Daily at midnight | ||
| ("*/15 * * * *", True), # Every 15 minutes | ||
| ("invalid cron", False), # Invalid expression | ||
| ("60 25 * * *", False), # Invalid time values | ||
| ]) | ||
| def test_validate_cron_expressions(self, cron_expression, is_valid): | ||
| """Test validation of cron expressions in schedule triggers.""" | ||
| # Basic cron validation (simplified) | ||
| parts = cron_expression.split() | ||
|
|
||
| if len(parts) != 5: | ||
| assert not is_valid | ||
| return | ||
|
|
||
| # Check for obviously invalid patterns | ||
| if "invalid" in cron_expression: | ||
| assert not is_valid | ||
| elif "60" in parts[0] or "25" in parts[1]: # Invalid minute/hour | ||
| assert not is_valid | ||
| else: | ||
| assert is_valid | ||
|
|
||
|
|
||
| # Integration tests | ||
| class TestGitHubWorkflowIntegration: | ||
| """Integration tests for complete workflow processing.""" | ||
|
|
||
| def test_end_to_end_workflow_processing(self, tmp_path, sample_workflow_yaml): | ||
| """Test complete workflow processing from file to validation.""" | ||
| # Setup | ||
| workflow_file = tmp_path / ".github" / "workflows" / "test.yml" | ||
| workflow_file.parent.mkdir(parents=True) | ||
| workflow_file.write_text(sample_workflow_yaml) | ||
|
|
||
| # Process workflow | ||
| content = workflow_file.read_text() | ||
| parsed = yaml.safe_load(content) | ||
|
|
||
| # Validate structure | ||
| assert parsed['name'] == 'CI' | ||
| assert 'jobs' in parsed | ||
| assert 'test' in parsed['jobs'] | ||
|
|
||
| # Extract metadata | ||
| metadata = { | ||
| 'file_path': str(workflow_file), | ||
| 'name': parsed['name'], | ||
| 'job_count': len(parsed['jobs']), | ||
| 'step_count': sum(len(job.get('steps', [])) for job in parsed['jobs'].values()) | ||
| } | ||
|
|
||
| assert metadata['job_count'] == 1 | ||
| assert metadata['step_count'] == 4 | ||
|
|
||
| @patch('yaml.safe_load') | ||
| def test_workflow_processing_with_yaml_error(self, mock_yaml_load, tmp_path): | ||
| """Test handling of YAML parsing errors in workflow processing.""" | ||
| mock_yaml_load.side_effect = yaml.YAMLError("Invalid YAML") | ||
|
|
||
| workflow_file = tmp_path / "invalid.yml" | ||
| workflow_file.write_text("invalid: yaml: content") | ||
|
|
||
| content = workflow_file.read_text() | ||
|
|
||
| with pytest.raises(yaml.YAMLError): | ||
| yaml.safe_load(content) | ||
|
|
||
| def test_batch_workflow_validation(self, tmp_path): | ||
| """Test validation of multiple workflow files.""" | ||
| # Create multiple workflow files | ||
| workflows_dir = tmp_path / ".github" / "workflows" | ||
| workflows_dir.mkdir(parents=True) | ||
|
|
||
| workflows = [ | ||
| ("valid.yml", "name: Valid\non: push\njobs:\n test:\n runs-on: ubuntu-latest"), | ||
| ("invalid.yml", "name: Invalid\n# Missing required fields"), | ||
| ] | ||
|
|
||
| results = {} | ||
| for filename, content in workflows: | ||
| file_path = workflows_dir / filename | ||
| file_path.write_text(content) | ||
|
|
||
| try: | ||
| parsed = yaml.safe_load(content) | ||
| has_required_fields = all(field in parsed for field in ['name', 'on', 'jobs']) | ||
| results[filename] = {'valid': has_required_fields, 'error': None} | ||
| except Exception as e: | ||
| results[filename] = {'valid': False, 'error': str(e)} | ||
|
|
||
| assert results['valid.yml']['valid'] is True | ||
| assert results['invalid.yml']['valid'] is False | ||
|
|
||
|
|
||
| # Performance tests | ||
| class TestGitHubWorkflowPerformance: | ||
| """Performance tests for workflow processing.""" | ||
|
|
||
| def test_large_workflow_parsing_performance(self): | ||
| """Test performance with large workflow files.""" | ||
| # Generate a large workflow | ||
| large_workflow = { | ||
| 'name': 'Large Workflow', | ||
| 'on': ['push', 'pull_request'], | ||
| 'jobs': {} | ||
| } | ||
|
|
||
| # Add many jobs | ||
| for i in range(50): | ||
| large_workflow['jobs'][f'job_{i}'] = { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'steps': [ | ||
| {'uses': 'actions/checkout@v3'}, | ||
| {'run': f'echo "Job {i}"'} | ||
| ] | ||
| } | ||
|
|
||
| # Test parsing performance | ||
| import time | ||
| start_time = time.time() | ||
| yaml_content = yaml.dump(large_workflow) | ||
| parsed = yaml.safe_load(yaml_content) | ||
| end_time = time.time() | ||
|
|
||
| assert parsed['name'] == 'Large Workflow' | ||
| assert len(parsed['jobs']) == 50 | ||
| assert (end_time - start_time) < 1.0 # Should complete within 1 second | ||
|
|
||
| def test_memory_usage_with_multiple_workflows(self, tmp_path): | ||
| """Test memory usage when processing multiple workflows.""" | ||
| import sys | ||
|
|
||
| workflows_dir = tmp_path / ".github" / "workflows" | ||
| workflows_dir.mkdir(parents=True) | ||
|
|
||
| # Create multiple workflow files | ||
| for i in range(10): | ||
| workflow_content = f""" | ||
| name: Workflow {i} | ||
| on: push | ||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - run: echo "Workflow {i}" | ||
| """ | ||
| (workflows_dir / f"workflow_{i}.yml").write_text(workflow_content) | ||
|
|
||
| # Process all workflows | ||
| parsed_workflows = [] | ||
| for workflow_file in workflows_dir.glob("*.yml"): | ||
| content = workflow_file.read_text() | ||
| parsed = yaml.safe_load(content) | ||
| parsed_workflows.append(parsed) | ||
|
|
||
| assert len(parsed_workflows) == 10 | ||
| # Memory usage test would need additional tooling in real scenario | ||
|
|
||
|
|
||
| # Edge case tests | ||
| class TestGitHubWorkflowEdgeCases: | ||
| """Test suite for edge cases and unusual scenarios.""" | ||
|
|
||
| @pytest.fixture | ||
| def edge_case_workflows(self): | ||
| """Various edge case workflow configurations.""" | ||
| return { | ||
| 'empty_workflow': {}, | ||
| 'minimal_workflow': { | ||
| 'name': 'Minimal', | ||
| 'on': 'push', | ||
| 'jobs': { | ||
| 'test': { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'steps': [{'run': 'echo "test"'}] | ||
| } | ||
| } | ||
| }, | ||
| 'workflow_with_unicode': { | ||
| 'name': 'Unicode Test 🚀', | ||
| 'on': 'push', | ||
| 'jobs': { | ||
| 'test': { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'steps': [{'run': 'echo "Testing unicode: 你好世界"'}] | ||
| } | ||
| } | ||
| }, | ||
| 'workflow_with_long_strings': { | ||
| 'name': 'A' * 1000, # Very long name | ||
| 'on': 'push', | ||
| 'jobs': { | ||
| 'test': { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'steps': [{'run': 'B' * 5000}] # Very long command | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def test_empty_workflow_handling(self, edge_case_workflows): | ||
| """Test handling of completely empty workflows.""" | ||
| empty_workflow = edge_case_workflows['empty_workflow'] | ||
|
|
||
| # Should handle empty workflows gracefully | ||
| assert isinstance(empty_workflow, dict) | ||
| assert len(empty_workflow) == 0 | ||
|
|
||
| def test_minimal_workflow_validation(self, edge_case_workflows): | ||
| """Test validation of minimal but valid workflows.""" | ||
| minimal = edge_case_workflows['minimal_workflow'] | ||
|
|
||
| assert 'name' in minimal | ||
| assert 'on' in minimal | ||
| assert 'jobs' in minimal | ||
| assert len(minimal['jobs']) == 1 | ||
|
|
||
| def test_unicode_support_in_workflows(self, edge_case_workflows): | ||
| """Test support for Unicode characters in workflows.""" | ||
| unicode_workflow = edge_case_workflows['workflow_with_unicode'] | ||
|
|
||
| assert '🚀' in unicode_workflow['name'] | ||
| assert '你好世界' in unicode_workflow['jobs']['test']['steps'][0]['run'] | ||
|
|
||
| def test_large_string_handling(self, edge_case_workflows): | ||
| """Test handling of very large strings in workflows.""" | ||
| long_workflow = edge_case_workflows['workflow_with_long_strings'] | ||
|
|
||
| assert len(long_workflow['name']) == 1000 | ||
| assert len(long_workflow['jobs']['test']['steps'][0]['run']) == 5000 | ||
|
|
||
| @pytest.mark.parametrize("invalid_yaml", [ | ||
| "name: Test\nsteps:\n - invalid: [\n", # Unclosed bracket | ||
| "name: Test\n\ttabs_and_spaces: mixed", # Mixed indentation | ||
| "name: Test\n'unmatched quote", # Unmatched quote | ||
| "name: Test\n@invalid_yaml_character", # Invalid character | ||
| ]) | ||
| def test_malformed_yaml_handling(self, invalid_yaml): | ||
| """Test handling of various malformed YAML inputs.""" | ||
| with pytest.raises(yaml.YAMLError): | ||
| yaml.safe_load(invalid_yaml) | ||
|
|
||
| def test_deeply_nested_workflow_structure(self): | ||
| """Test handling of deeply nested workflow structures.""" | ||
| nested_workflow = { | ||
| 'name': 'Nested Test', | ||
| 'on': { | ||
| 'push': { | ||
| 'branches': ['main'], | ||
| 'paths': ['src/**', 'tests/**'] | ||
| }, | ||
| 'pull_request': { | ||
| 'types': ['opened', 'synchronize'], | ||
| 'branches': ['main', 'develop'] | ||
| } | ||
| }, | ||
| 'jobs': { | ||
| 'test': { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'strategy': { | ||
| 'matrix': { | ||
| 'include': [ | ||
| {'os': 'ubuntu-latest', 'python': '3.8', 'extra': 'test1'}, | ||
| {'os': 'windows-latest', 'python': '3.9', 'extra': 'test2'} | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # Test that deeply nested structures are parsed correctly | ||
| assert nested_workflow['on']['push']['branches'] == ['main'] | ||
| assert len(nested_workflow['jobs']['test']['strategy']['matrix']['include']) == 2 | ||
|
|
||
| def test_workflow_with_all_trigger_types(self): | ||
| """Test workflow with every possible trigger type.""" | ||
| all_triggers_workflow = { | ||
| 'name': 'All Triggers', | ||
| 'on': { | ||
| 'push': {'branches': ['main']}, | ||
| 'pull_request': {'branches': ['main']}, | ||
| 'pull_request_target': {'branches': ['main']}, | ||
| 'schedule': [{'cron': '0 0 * * *'}], | ||
| 'workflow_dispatch': {'inputs': {'environment': {'type': 'string'}}}, | ||
| 'workflow_call': {'inputs': {'version': {'type': 'string'}}}, | ||
| 'repository_dispatch': {'types': ['custom-event']}, | ||
| 'release': {'types': ['published']}, | ||
| 'issues': {'types': ['opened']}, | ||
| 'issue_comment': {'types': ['created']}, | ||
| 'watch': {'types': ['started']}, | ||
| 'fork': {}, | ||
| 'create': {}, | ||
| 'delete': {}, | ||
| 'gollum': {}, | ||
| 'milestone': {'types': ['created']}, | ||
| 'project': {'types': ['created']}, | ||
| 'project_card': {'types': ['created']}, | ||
| 'project_column': {'types': ['created']}, | ||
| 'public': {}, | ||
| 'status': {}, | ||
| 'check_run': {'types': ['created']}, | ||
| 'check_suite': {'types': ['completed']}, | ||
| 'deployment': {}, | ||
| 'deployment_status': {}, | ||
| 'page_build': {}, | ||
| 'registry_package': {'types': ['published']} | ||
| }, | ||
| 'jobs': { | ||
| 'test': { | ||
| 'runs-on': 'ubuntu-latest', | ||
| 'steps': [{'run': 'echo "All triggers test"'}] | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # Verify all trigger types are present | ||
| assert len(all_triggers_workflow['on']) > 20 | ||
| assert 'workflow_dispatch' in all_triggers_workflow['on'] | ||
| assert 'workflow_call' in all_triggers_workflow['on'] | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| pytest.main([__file__, "-v", "--tb=short"]) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove trailing whitespace throughout the file
There are numerous lines with trailing whitespace throughout the file (lines 17, 117, 136, 145, 158, 166, 170, 175, 181, 189, 196, 209, 213, 221, 235, 243, 248, 256, 268, 271, 289, 293, 301, 310, 319, 329, 334, 338, 349, 373, 380, 386, 393, 399, 406, 412, 418, 434, 443, 455, 462, 478, 482, 495, 502, 506, 511, 519, 527, 530, 532, 541, 546, 551, 558, 566, 575, 585, 592, 600, 603, 617, 624, 632, 673, 681, 690, 697, 740, 785).
Configure your editor to automatically strip trailing whitespace on save, or use a pre-commit hook.
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 7-7: 'json' imported but unused
(F401)
[error] 9-9: 'os' imported but unused
(F401)
[error] 10-10: 'unittest.mock.Mock' imported but unused
(F401)
[error] 10-10: 'unittest.mock.mock_open' imported but unused
(F401)
[error] 12-12: 'typing.Dict' imported but unused
(F401)
[error] 12-12: 'typing.List' imported but unused
(F401)
[error] 12-12: 'typing.Any' imported but unused
(F401)
[warning] 17-17: blank line contains whitespace
(W293)
[warning] 117-117: blank line contains whitespace
(W293)
[warning] 136-136: blank line contains whitespace
(W293)
[warning] 145-145: blank line contains whitespace
(W293)
[warning] 158-158: blank line contains whitespace
(W293)
[warning] 166-166: blank line contains whitespace
(W293)
[warning] 170-170: blank line contains whitespace
(W293)
[warning] 175-175: blank line contains whitespace
(W293)
[warning] 181-181: blank line contains whitespace
(W293)
[warning] 189-189: blank line contains whitespace
(W293)
[warning] 196-196: blank line contains whitespace
(W293)
[warning] 209-209: blank line contains whitespace
(W293)
[warning] 213-213: blank line contains whitespace
(W293)
[warning] 221-221: blank line contains whitespace
(W293)
[warning] 235-235: blank line contains whitespace
(W293)
[warning] 243-243: blank line contains whitespace
(W293)
[warning] 248-248: blank line contains whitespace
(W293)
[warning] 256-256: blank line contains whitespace
(W293)
[warning] 268-268: blank line contains whitespace
(W293)
[warning] 271-271: blank line contains whitespace
(W293)
[warning] 289-289: blank line contains whitespace
(W293)
[warning] 293-293: blank line contains whitespace
(W293)
[warning] 301-301: blank line contains whitespace
(W293)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 319-319: blank line contains whitespace
(W293)
[warning] 329-329: blank line contains whitespace
(W293)
[warning] 334-334: blank line contains whitespace
(W293)
[warning] 338-338: blank line contains whitespace
(W293)
[warning] 349-349: blank line contains whitespace
(W293)
[warning] 373-373: blank line contains whitespace
(W293)
[warning] 380-380: blank line contains whitespace
(W293)
[warning] 386-386: blank line contains whitespace
(W293)
[warning] 393-393: blank line contains whitespace
(W293)
[warning] 399-399: blank line contains whitespace
(W293)
[warning] 406-406: blank line contains whitespace
(W293)
[warning] 412-412: blank line contains whitespace
(W293)
[warning] 418-418: blank line contains whitespace
(W293)
[warning] 434-434: blank line contains whitespace
(W293)
[warning] 443-443: blank line contains whitespace
(W293)
[warning] 455-455: blank line contains whitespace
(W293)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 478-478: blank line contains whitespace
(W293)
[warning] 482-482: blank line contains whitespace
(W293)
[warning] 495-495: blank line contains whitespace
(W293)
[warning] 502-502: blank line contains whitespace
(W293)
[warning] 506-506: blank line contains whitespace
(W293)
[warning] 511-511: blank line contains whitespace
(W293)
[warning] 519-519: blank line contains whitespace
(W293)
[warning] 527-527: blank line contains whitespace
(W293)
[warning] 530-530: blank line contains whitespace
(W293)
[warning] 532-532: blank line contains whitespace
(W293)
[warning] 541-541: blank line contains whitespace
(W293)
[warning] 546-546: blank line contains whitespace
(W293)
[warning] 551-551: blank line contains whitespace
(W293)
[warning] 558-558: blank line contains whitespace
(W293)
[warning] 566-566: blank line contains whitespace
(W293)
[warning] 575-575: blank line contains whitespace
(W293)
[warning] 585-585: blank line contains whitespace
(W293)
[warning] 592-592: blank line contains whitespace
(W293)
[error] 599-599: 'sys' imported but unused
(F401)
[warning] 600-600: blank line contains whitespace
(W293)
[warning] 603-603: blank line contains whitespace
(W293)
[warning] 617-617: blank line contains whitespace
(W293)
[warning] 624-624: blank line contains whitespace
(W293)
[warning] 632-632: blank line contains whitespace
(W293)
[warning] 673-673: blank line contains whitespace
(W293)
[warning] 681-681: blank line contains whitespace
(W293)
[warning] 690-690: blank line contains whitespace
(W293)
[warning] 697-697: blank line contains whitespace
(W293)
[warning] 740-740: blank line contains whitespace
(W293)
[warning] 785-785: blank line contains whitespace
(W293)
[warning] 793-793: no newline at end of file
(W292)
🪛 Ruff (0.11.9)
7-7: json imported but unused
Remove unused import: json
(F401)
9-9: os imported but unused
Remove unused import: os
(F401)
10-10: unittest.mock.Mock imported but unused
Remove unused import
(F401)
10-10: unittest.mock.mock_open imported but unused
Remove unused import
(F401)
12-12: typing.Dict is deprecated, use dict instead
(UP035)
12-12: typing.List is deprecated, use list instead
(UP035)
12-12: typing.Dict imported but unused
Remove unused import
(F401)
12-12: typing.List imported but unused
Remove unused import
(F401)
12-12: typing.Any imported but unused
Remove unused import
(F401)
19-19: Missing return type annotation for public function sample_workflow_yaml
Add return type annotation: str
(ANN201)
44-44: Missing return type annotation for public function invalid_workflow_yaml
Add return type annotation: str
(ANN201)
59-59: Missing return type annotation for public function complex_workflow_yaml
Add return type annotation: str
(ANN201)
107-107: Missing return type annotation for public function mock_workflow_file
(ANN201)
107-107: Missing type annotation for function argument tmp_path
(ANN001)
107-107: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
114-114: Missing return type annotation for public function test_parse_valid_workflow_yaml
Add return type annotation: None
(ANN201)
114-114: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
125-125: Missing return type annotation for public function test_parse_invalid_workflow_yaml
Add return type annotation: None
(ANN201)
125-125: Missing type annotation for function argument invalid_workflow_yaml
(ANN001)
130-130: Missing return type annotation for public function test_workflow_validation_missing_required_fields
Add return type annotation: None
(ANN201)
133-133: Trailing comma missing
Add trailing comma
(COM812)
141-141: Missing return type annotation for public function test_workflow_job_validation
Add return type annotation: None
(ANN201)
141-141: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
151-151: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
155-155: Missing return type annotation for public function test_workflow_triggers
Add return type annotation: None
(ANN201)
155-155: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
155-155: Missing type annotation for function argument trigger_event
(ANN001)
155-155: Missing type annotation for function argument expected_branches
(ANN001)
163-163: Missing return type annotation for public function test_complex_workflow_structure
Add return type annotation: None
(ANN201)
163-163: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
186-186: Missing return type annotation for public function test_workflow_environment_variables
Add return type annotation: None
(ANN201)
186-186: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
193-193: Missing return type annotation for public function test_workflow_outputs
Add return type annotation: None
(ANN201)
193-193: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
201-201: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
205-205: Missing return type annotation for public function test_workflow_step_types
Add return type annotation: None
(ANN201)
205-205: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
205-205: Missing type annotation for function argument step_type
(ANN001)
205-205: Unused method argument: step_type
(ARG002)
205-205: Missing type annotation for function argument required_field
(ANN001)
223-223: Missing return type annotation for public function validator_config
(ANN201)
229-229: Trailing comma missing
Add trailing comma
(COM812)
232-232: Missing return type annotation for public function test_validate_workflow_structure_valid
Add return type annotation: None
(ANN201)
232-232: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
232-232: Missing type annotation for function argument validator_config
(ANN001)
240-240: Missing return type annotation for public function test_validate_workflow_structure_missing_fields
Add return type annotation: None
(ANN201)
240-240: Missing type annotation for function argument validator_config
(ANN001)
253-253: Missing return type annotation for public function test_validate_runner_allowed
Add return type annotation: None
(ANN201)
253-253: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
253-253: Missing type annotation for function argument validator_config
(ANN001)
257-257: Loop control variable job_name not used within loop body
Rename unused job_name to _job_name
(B007)
260-262: Use a single if statement instead of nested if statements
(SIM102)
265-265: Missing return type annotation for public function test_validate_job_limits
Add return type annotation: None
(ANN201)
265-265: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
265-265: Missing type annotation for function argument validator_config
(ANN001)
273-273: Loop control variable job_name not used within loop body
Rename unused job_name to _job_name
(B007)
282-282: Missing return type annotation for public function test_validate_runner_not_allowed
Add return type annotation: None
(ANN201)
282-282: Missing type annotation for function argument invalid_runner
(ANN001)
282-282: Missing type annotation for function argument validator_config
(ANN001)
290-290: Missing return type annotation for public function test_read_workflow_file
Add return type annotation: None
(ANN201)
290-290: Missing type annotation for function argument mock_workflow_file
(ANN001)
298-298: Missing return type annotation for public function test_read_nonexistent_workflow_file
Add return type annotation: None
(ANN201)
298-298: Missing type annotation for function argument tmp_path
(ANN001)
307-307: Missing return type annotation for public function test_read_workflow_file_permission_error
Add return type annotation: None
(ANN201)
307-307: Missing type annotation for function argument mock_read_text
(ANN001)
315-315: Missing return type annotation for public function test_write_workflow_file
Add return type annotation: None
(ANN201)
315-315: Missing type annotation for function argument tmp_path
(ANN001)
315-315: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
324-324: Missing return type annotation for public function test_discover_workflow_files
Add return type annotation: None
(ANN201)
324-324: Missing type annotation for function argument tmp_path
(ANN001)
351-351: Missing return type annotation for public function insecure_workflow_yaml
Add return type annotation: str
(ANN201)
370-370: Missing return type annotation for public function test_detect_pull_request_target_trigger
Add return type annotation: None
(ANN201)
370-370: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
377-377: Missing return type annotation for public function test_detect_outdated_actions
Add return type annotation: None
(ANN201)
377-377: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
390-390: Missing return type annotation for public function test_detect_secret_exposure
Add return type annotation: None
(ANN201)
390-390: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
403-403: Missing return type annotation for public function test_detect_code_injection_risk
Add return type annotation: None
(ANN201)
403-403: Missing type annotation for function argument insecure_workflow_yaml
(ANN001)
419-419: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
425-425: Missing return type annotation for public function test_generate_workflow_filename
Add return type annotation: None
(ANN201)
425-425: Missing type annotation for function argument workflow_name
(ANN001)
425-425: Missing type annotation for function argument expected_filename
(ANN001)
431-431: Missing return type annotation for public function test_extract_workflow_metadata
Add return type annotation: None
(ANN201)
431-431: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
441-441: Trailing comma missing
Add trailing comma
(COM812)
452-452: Missing return type annotation for public function test_workflow_dependency_graph
Add return type annotation: None
(ANN201)
452-452: Missing type annotation for function argument complex_workflow_yaml
(ANN001)
467-467: Wrong type passed to first argument of pytest.mark.parametrize; expected tuple
Use a tuple for the first argument
(PT006)
474-474: Missing return type annotation for public function test_validate_cron_expressions
Add return type annotation: None
(ANN201)
474-474: Missing type annotation for function argument cron_expression
(ANN001)
474-474: Missing type annotation for function argument is_valid
(ANN001)
484-487: Combine if branches using logical or operator
Combine if branches
(SIM114)
496-496: Missing return type annotation for public function test_end_to_end_workflow_processing
Add return type annotation: None
(ANN201)
496-496: Missing type annotation for function argument tmp_path
(ANN001)
496-496: Missing type annotation for function argument sample_workflow_yaml
(ANN001)
517-517: Trailing comma missing
Add trailing comma
(COM812)
524-524: Missing return type annotation for public function test_workflow_processing_with_yaml_error
Add return type annotation: None
(ANN201)
524-524: Missing type annotation for function argument mock_yaml_load
(ANN001)
524-524: Missing type annotation for function argument tmp_path
(ANN001)
536-536: Missing return type annotation for public function test_batch_workflow_validation
Add return type annotation: None
(ANN201)
536-536: Missing type annotation for function argument tmp_path
(ANN001)
556-556: Do not catch blind exception: Exception
(BLE001)
567-567: Missing return type annotation for public function test_large_workflow_parsing_performance
Add return type annotation: None
(ANN201)
573-573: Trailing comma missing
Add trailing comma
(COM812)
582-582: Trailing comma missing
Add trailing comma
(COM812)
583-583: Trailing comma missing
Add trailing comma
(COM812)
597-597: Missing return type annotation for public function test_memory_usage_with_multiple_workflows
Add return type annotation: None
(ANN201)
597-597: Missing type annotation for function argument tmp_path
(ANN001)
599-599: sys imported but unused
Remove unused import: sys
(F401)
634-634: Missing return type annotation for public function edge_case_workflows
(ANN201)
644-644: Trailing comma missing
Add trailing comma
(COM812)
645-645: Trailing comma missing
Add trailing comma
(COM812)
646-646: Trailing comma missing
Add trailing comma
(COM812)
654-654: Trailing comma missing
Add trailing comma
(COM812)
655-655: Trailing comma missing
Add trailing comma
(COM812)
656-656: Trailing comma missing
Add trailing comma
(COM812)
664-664: Trailing comma missing
Add trailing comma
(COM812)
665-665: Trailing comma missing
Add trailing comma
(COM812)
666-666: Trailing comma missing
Add trailing comma
(COM812)
667-667: Trailing comma missing
Add trailing comma
(COM812)
670-670: Missing return type annotation for public function test_empty_workflow_handling
Add return type annotation: None
(ANN201)
670-670: Missing type annotation for function argument edge_case_workflows
(ANN001)
678-678: Missing return type annotation for public function test_minimal_workflow_validation
Add return type annotation: None
(ANN201)
678-678: Missing type annotation for function argument edge_case_workflows
(ANN001)
687-687: Missing return type annotation for public function test_unicode_support_in_workflows
Add return type annotation: None
(ANN201)
687-687: Missing type annotation for function argument edge_case_workflows
(ANN001)
694-694: Missing return type annotation for public function test_large_string_handling
Add return type annotation: None
(ANN201)
694-694: Missing type annotation for function argument edge_case_workflows
(ANN001)
707-707: Missing return type annotation for public function test_malformed_yaml_handling
Add return type annotation: None
(ANN201)
707-707: Missing type annotation for function argument invalid_yaml
(ANN001)
712-712: Missing return type annotation for public function test_deeply_nested_workflow_structure
Add return type annotation: None
(ANN201)
719-719: Trailing comma missing
Add trailing comma
(COM812)
723-723: Trailing comma missing
Add trailing comma
(COM812)
724-724: Trailing comma missing
Add trailing comma
(COM812)
733-733: Trailing comma missing
Add trailing comma
(COM812)
734-734: Trailing comma missing
Add trailing comma
(COM812)
735-735: Trailing comma missing
Add trailing comma
(COM812)
736-736: Trailing comma missing
Add trailing comma
(COM812)
737-737: Trailing comma missing
Add trailing comma
(COM812)
738-738: Trailing comma missing
Add trailing comma
(COM812)
745-745: Missing return type annotation for public function test_workflow_with_all_trigger_types
Add return type annotation: None
(ANN201)
776-776: Trailing comma missing
Add trailing comma
(COM812)
781-781: Trailing comma missing
Add trailing comma
(COM812)
782-782: Trailing comma missing
Add trailing comma
(COM812)
783-783: Trailing comma missing
Add trailing comma
(COM812)
🪛 Pylint (3.3.7)
[convention] 17-17: Trailing whitespace
(C0303)
[convention] 117-117: Trailing whitespace
(C0303)
[convention] 136-136: Trailing whitespace
(C0303)
[convention] 145-145: Trailing whitespace
(C0303)
[convention] 158-158: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 175-175: Trailing whitespace
(C0303)
[convention] 181-181: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 196-196: Trailing whitespace
(C0303)
[convention] 209-209: Trailing whitespace
(C0303)
[convention] 213-213: Trailing whitespace
(C0303)
[convention] 221-221: Trailing whitespace
(C0303)
[convention] 235-235: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 248-248: Trailing whitespace
(C0303)
[convention] 256-256: Trailing whitespace
(C0303)
[convention] 268-268: Trailing whitespace
(C0303)
[convention] 271-271: Trailing whitespace
(C0303)
[convention] 289-289: Trailing whitespace
(C0303)
[convention] 293-293: Trailing whitespace
(C0303)
[convention] 301-301: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 319-319: Trailing whitespace
(C0303)
[convention] 329-329: Trailing whitespace
(C0303)
[convention] 334-334: Trailing whitespace
(C0303)
[convention] 338-338: Trailing whitespace
(C0303)
[convention] 349-349: Trailing whitespace
(C0303)
[convention] 373-373: Trailing whitespace
(C0303)
[convention] 380-380: Trailing whitespace
(C0303)
[convention] 386-386: Trailing whitespace
(C0303)
[convention] 393-393: Trailing whitespace
(C0303)
[convention] 399-399: Trailing whitespace
(C0303)
[convention] 406-406: Trailing whitespace
(C0303)
[convention] 412-412: Trailing whitespace
(C0303)
[convention] 418-418: Trailing whitespace
(C0303)
[convention] 434-434: Trailing whitespace
(C0303)
[convention] 443-443: Trailing whitespace
(C0303)
[convention] 455-455: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 478-478: Trailing whitespace
(C0303)
[convention] 482-482: Trailing whitespace
(C0303)
[convention] 495-495: Trailing whitespace
(C0303)
[convention] 502-502: Trailing whitespace
(C0303)
[convention] 506-506: Trailing whitespace
(C0303)
[convention] 511-511: Trailing whitespace
(C0303)
[convention] 519-519: Trailing whitespace
(C0303)
[convention] 527-527: Trailing whitespace
(C0303)
[convention] 530-530: Trailing whitespace
(C0303)
[convention] 532-532: Trailing whitespace
(C0303)
[convention] 541-541: Trailing whitespace
(C0303)
[convention] 546-546: Trailing whitespace
(C0303)
[convention] 551-551: Trailing whitespace
(C0303)
[convention] 558-558: Trailing whitespace
(C0303)
[convention] 566-566: Trailing whitespace
(C0303)
[convention] 575-575: Trailing whitespace
(C0303)
[convention] 585-585: Trailing whitespace
(C0303)
[convention] 592-592: Trailing whitespace
(C0303)
[convention] 600-600: Trailing whitespace
(C0303)
[convention] 603-603: Trailing whitespace
(C0303)
[convention] 617-617: Trailing whitespace
(C0303)
[convention] 624-624: Trailing whitespace
(C0303)
[convention] 632-632: Trailing whitespace
(C0303)
[convention] 673-673: Trailing whitespace
(C0303)
[convention] 681-681: Trailing whitespace
(C0303)
[convention] 690-690: Trailing whitespace
(C0303)
[convention] 697-697: Trailing whitespace
(C0303)
[convention] 740-740: Trailing whitespace
(C0303)
[convention] 785-785: Trailing whitespace
(C0303)
[convention] 793-793: Final newline missing
(C0304)
[warning] 205-205: Unused argument 'step_type'
(W0613)
[warning] 257-257: Unused variable 'job_name'
(W0612)
[warning] 273-273: Unused variable 'job_name'
(W0612)
[warning] 313-313: Using open without explicitly specifying an encoding
(W1514)
[warning] 556-556: Catching too general exception Exception
(W0718)
[convention] 587-587: Import outside toplevel (time)
(C0415)
[convention] 599-599: Import outside toplevel (sys)
(C0415)
[warning] 599-599: Unused import sys
(W0611)
[convention] 7-7: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 9-9: standard import "os" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 10-10: standard import "unittest.mock.Mock" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 11-11: standard import "pathlib.Path" should be placed before third party imports "pytest", "yaml"
(C0411)
[convention] 12-12: standard import "typing.Dict" should be placed before third party imports "pytest", "yaml"
(C0411)
[warning] 7-7: Unused import json
(W0611)
[warning] 9-9: Unused import os
(W0611)
[warning] 10-10: Unused Mock imported from unittest.mock
(W0611)
[warning] 10-10: Unused mock_open imported from unittest.mock
(W0611)
[warning] 12-12: Unused Dict imported from typing
(W0611)
[warning] 12-12: Unused List imported from typing
(W0611)
[warning] 12-12: Unused Any imported from typing
(W0611)
🤖 Prompt for AI Agents
In test_github_workflows.py across the entire file (lines 1 to 793), there are
multiple instances of trailing whitespace on many lines. Remove all trailing
whitespace characters at the end of these lines to clean up the file. Configure
your editor or use a pre-commit hook to automatically strip trailing whitespace
on save to prevent this issue in the future.
| for job_name, job_config in parsed['jobs'].items(): | ||
| if 'steps' in job_config: | ||
| assert len(job_config['steps']) <= validator_config['max_steps_per_job'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix unused loop variable
-for job_name, job_config in parsed['jobs'].items():
+for _job_name, job_config in parsed['jobs'].items():📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for job_name, job_config in parsed['jobs'].items(): | |
| if 'steps' in job_config: | |
| assert len(job_config['steps']) <= validator_config['max_steps_per_job'] | |
| for _job_name, job_config in parsed['jobs'].items(): | |
| if 'steps' in job_config: | |
| assert len(job_config['steps']) <= validator_config['max_steps_per_job'] |
🧰 Tools
🪛 Ruff (0.11.9)
273-273: Loop control variable job_name not used within loop body
Rename unused job_name to _job_name
(B007)
🪛 Pylint (3.3.7)
[warning] 273-273: Unused variable 'job_name'
(W0612)
🤖 Prompt for AI Agents
In test_github_workflows.py around lines 273 to 275, the loop variable job_name
is declared but not used, causing an unused variable issue. To fix this, replace
job_name with an underscore (_) to indicate the variable is intentionally
unused, keeping the loop functional and clean.
| if __name__ == "__main__": | ||
| pytest.main([__file__, "-v", "--tb=short"]) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Add newline at end of file
Files should end with a newline character.
if __name__ == "__main__":
- pytest.main([__file__, "-v", "--tb=short"])
+ pytest.main([__file__, "-v", "--tb=short"])
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v", "--tb=short"]) | |
| if __name__ == "__main__": | |
| pytest.main([__file__, "-v", "--tb=short"]) | |
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 793-793: no newline at end of file
(W292)
🪛 Pylint (3.3.7)
[convention] 793-793: Final newline missing
(C0304)
🤖 Prompt for AI Agents
In test_github_workflows.py at lines 792 to 793, the file is missing a newline
character at the end. Add a single newline character after the last line to
ensure the file ends with a newline.
| def test_permission_denied_error(self, temp_config_dir): | ||
| """Test handling of permission denied errors.""" | ||
| config_file = temp_config_dir / "restricted.json" | ||
| with open(config_file, 'w') as f: | ||
| json.dump({"key": "value"}, f) | ||
|
|
||
| # Make file unreadable | ||
| os.chmod(config_file, 0o000) | ||
|
|
||
| try: | ||
| with pytest.raises(PermissionError): | ||
| with open(config_file, 'r') as f: | ||
| json.load(f) | ||
| finally: | ||
| # Restore permissions for cleanup | ||
| os.chmod(config_file, 0o644) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve the permission denied test reliability.
The permission test may fail on some systems and needs better error handling.
Apply this diff to improve the test:
- def test_permission_denied_error(self, temp_config_dir):
+ def test_permission_denied_error(self, temp_config_dir: Path) -> None:
"""Test handling of permission denied errors."""
config_file = temp_config_dir / "restricted.json"
- with open(config_file, 'w') as f:
+ with open(config_file, 'w', encoding='utf-8') as f:
json.dump({"key": "value"}, f)
-
+
# Make file unreadable
os.chmod(config_file, 0o000)
-
+
try:
- with pytest.raises(PermissionError):
- with open(config_file, 'r') as f:
+ with pytest.raises((PermissionError, OSError)):
+ with open(config_file, 'r', encoding='utf-8') as f:
json.load(f)
finally:
# Restore permissions for cleanup
os.chmod(config_file, 0o644)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def test_permission_denied_error(self, temp_config_dir): | |
| """Test handling of permission denied errors.""" | |
| config_file = temp_config_dir / "restricted.json" | |
| with open(config_file, 'w') as f: | |
| json.dump({"key": "value"}, f) | |
| # Make file unreadable | |
| os.chmod(config_file, 0o000) | |
| try: | |
| with pytest.raises(PermissionError): | |
| with open(config_file, 'r') as f: | |
| json.load(f) | |
| finally: | |
| # Restore permissions for cleanup | |
| os.chmod(config_file, 0o644) | |
| def test_permission_denied_error(self, temp_config_dir: Path) -> None: | |
| """Test handling of permission denied errors.""" | |
| config_file = temp_config_dir / "restricted.json" | |
| with open(config_file, 'w', encoding='utf-8') as f: | |
| json.dump({"key": "value"}, f) | |
| # Make file unreadable | |
| os.chmod(config_file, 0o000) | |
| try: | |
| with pytest.raises((PermissionError, OSError)): | |
| with open(config_file, 'r', encoding='utf-8') as f: | |
| json.load(f) | |
| finally: | |
| # Restore permissions for cleanup | |
| os.chmod(config_file, 0o644) |
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 313-313: blank line contains whitespace
(W293)
[warning] 321-321: blank line contains whitespace
(W293)
🪛 Ruff (0.11.9)
305-305: Missing return type annotation for public function test_permission_denied_error
Add return type annotation: None
(ANN201)
305-305: Missing type annotation for function argument temp_config_dir
(ANN001)
315-316: Use a single with statement with multiple contexts instead of nested with statements
(SIM117)
316-316: Unnecessary mode argument
Remove mode argument
(UP015)
🪛 Pylint (3.3.7)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 313-313: Trailing whitespace
(C0303)
[convention] 321-321: Trailing whitespace
(C0303)
[warning] 308-308: Using open without explicitly specifying an encoding
(W1514)
[warning] 316-316: Using open without explicitly specifying an encoding
(W1514)
🤖 Prompt for AI Agents
In test_config_files.py around lines 305 to 321, the test for permission denied
errors can be unreliable on some systems due to direct file permission changes.
To fix this, modify the test to mock the open function or use a more controlled
way to simulate permission errors, ensuring consistent triggering of
PermissionError. Also, add error handling to safely restore file permissions in
the finally block to avoid test failures during cleanup.
| class TestConfigFileValidation: | ||
| """Test suite for validating configuration files.""" | ||
|
|
||
| @pytest.fixture | ||
| def temp_config_dir(self): | ||
| """Create a temporary directory for test config files.""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| yield Path(temp_dir) | ||
|
|
||
| @pytest.fixture | ||
| def sample_json_config(self): | ||
| """Sample JSON configuration for testing.""" | ||
| return { | ||
| "database": { | ||
| "host": "localhost", | ||
| "port": 5432, | ||
| "name": "testdb" | ||
| }, | ||
| "api": { | ||
| "base_url": "https://api.example.com", | ||
| "timeout": 30, | ||
| "retries": 3 | ||
| }, | ||
| "logging": { | ||
| "level": "INFO", | ||
| "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | ||
| } | ||
| } | ||
|
|
||
| @pytest.fixture | ||
| def sample_yaml_config(self): | ||
| """Sample YAML configuration for testing.""" | ||
| return """ | ||
| database: | ||
| host: localhost | ||
| port: 5432 | ||
| name: testdb | ||
| api: | ||
| base_url: https://api.example.com | ||
| timeout: 30 | ||
| retries: 3 | ||
| logging: | ||
| level: INFO | ||
| format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | ||
| """ | ||
|
|
||
| @pytest.fixture | ||
| def sample_ini_config(self): | ||
| """Sample INI configuration for testing.""" | ||
| return """ | ||
| [database] | ||
| host = localhost | ||
| port = 5432 | ||
| name = testdb | ||
|
|
||
| [api] | ||
| base_url = https://api.example.com | ||
| timeout = 30 | ||
| retries = 3 | ||
|
|
||
| [logging] | ||
| level = INFO | ||
| format = %%(asctime)s - %%(name)s - %%(levelname)s - %%(message)s | ||
| """ | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add type annotations and fix formatting issues.
The fixture definitions need type annotations and have trailing whitespace issues throughout.
Apply this diff to add type annotations and fix formatting:
+from typing import Any, Dict, Generator
+
class TestConfigFileValidation:
"""Test suite for validating configuration files."""
-
+
@pytest.fixture
- def temp_config_dir(self):
+ def temp_config_dir(self) -> Generator[Path, None, None]:
"""Create a temporary directory for test config files."""
with tempfile.TemporaryDirectory() as temp_dir:
yield Path(temp_dir)
-
+
@pytest.fixture
- def sample_json_config(self):
+ def sample_json_config(self) -> Dict[str, Any]:
"""Sample JSON configuration for testing."""
return {
"database": {
"host": "localhost",
"port": 5432,
- "name": "testdb"
+ "name": "testdb",
},
"api": {
"base_url": "https://api.example.com",
"timeout": 30,
- "retries": 3
+ "retries": 3,
},
"logging": {
"level": "INFO",
- "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
- }
+ "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
+ },
}
-
+
@pytest.fixture
- def sample_yaml_config(self):
+ def sample_yaml_config(self) -> str:
"""Sample YAML configuration for testing."""
return """
database:
@@ -53,7 +56,7 @@
level: INFO
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
"""
-
+
@pytest.fixture
- def sample_ini_config(self):
+ def sample_ini_config(self) -> str:
"""Sample INI configuration for testing."""📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| class TestConfigFileValidation: | |
| """Test suite for validating configuration files.""" | |
| @pytest.fixture | |
| def temp_config_dir(self): | |
| """Create a temporary directory for test config files.""" | |
| with tempfile.TemporaryDirectory() as temp_dir: | |
| yield Path(temp_dir) | |
| @pytest.fixture | |
| def sample_json_config(self): | |
| """Sample JSON configuration for testing.""" | |
| return { | |
| "database": { | |
| "host": "localhost", | |
| "port": 5432, | |
| "name": "testdb" | |
| }, | |
| "api": { | |
| "base_url": "https://api.example.com", | |
| "timeout": 30, | |
| "retries": 3 | |
| }, | |
| "logging": { | |
| "level": "INFO", | |
| "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| } | |
| } | |
| @pytest.fixture | |
| def sample_yaml_config(self): | |
| """Sample YAML configuration for testing.""" | |
| return """ | |
| database: | |
| host: localhost | |
| port: 5432 | |
| name: testdb | |
| api: | |
| base_url: https://api.example.com | |
| timeout: 30 | |
| retries: 3 | |
| logging: | |
| level: INFO | |
| format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| """ | |
| @pytest.fixture | |
| def sample_ini_config(self): | |
| """Sample INI configuration for testing.""" | |
| return """ | |
| [database] | |
| host = localhost | |
| port = 5432 | |
| name = testdb | |
| [api] | |
| base_url = https://api.example.com | |
| timeout = 30 | |
| retries = 3 | |
| [logging] | |
| level = INFO | |
| format = %%(asctime)s - %%(name)s - %%(levelname)s - %%(message)s | |
| """ | |
| from typing import Any, Dict, Generator | |
| class TestConfigFileValidation: | |
| """Test suite for validating configuration files.""" | |
| @pytest.fixture | |
| def temp_config_dir(self) -> Generator[Path, None, None]: | |
| """Create a temporary directory for test config files.""" | |
| with tempfile.TemporaryDirectory() as temp_dir: | |
| yield Path(temp_dir) | |
| @pytest.fixture | |
| def sample_json_config(self) -> Dict[str, Any]: | |
| """Sample JSON configuration for testing.""" | |
| return { | |
| "database": { | |
| "host": "localhost", | |
| "port": 5432, | |
| "name": "testdb", | |
| }, | |
| "api": { | |
| "base_url": "https://api.example.com", | |
| "timeout": 30, | |
| "retries": 3, | |
| }, | |
| "logging": { | |
| "level": "INFO", | |
| "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s", | |
| }, | |
| } | |
| @pytest.fixture | |
| def sample_yaml_config(self) -> str: | |
| """Sample YAML configuration for testing.""" | |
| return """ | |
| database: | |
| host: localhost | |
| port: 5432 | |
| name: testdb | |
| api: | |
| base_url: https://api.example.com | |
| timeout: 30 | |
| retries: 3 | |
| logging: | |
| level: INFO | |
| format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| """ | |
| @pytest.fixture | |
| def sample_ini_config(self) -> str: | |
| """Sample INI configuration for testing.""" | |
| return """ | |
| [database] | |
| host = localhost | |
| port = 5432 | |
| name = testdb | |
| [api] | |
| base_url = https://api.example.com | |
| timeout = 30 | |
| retries = 3 | |
| [logging] | |
| level = INFO | |
| format = %%(asctime)s - %%(name)s - %%(levelname)s - %%(message)s | |
| """ |
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 14-14: blank line contains whitespace
(W293)
[warning] 20-20: blank line contains whitespace
(W293)
[warning] 40-40: blank line contains whitespace
(W293)
[warning] 57-57: blank line contains whitespace
(W293)
[warning] 66-66: blank line contains whitespace
(W293)
[warning] 71-71: blank line contains whitespace
(W293)
🪛 Ruff (0.11.9)
16-16: Missing return type annotation for public function temp_config_dir
(ANN201)
22-22: Missing return type annotation for public function sample_json_config
(ANN201)
28-28: Trailing comma missing
Add trailing comma
(COM812)
33-33: Trailing comma missing
Add trailing comma
(COM812)
37-37: Trailing comma missing
Add trailing comma
(COM812)
38-38: Trailing comma missing
Add trailing comma
(COM812)
42-42: Missing return type annotation for public function sample_yaml_config
Add return type annotation: str
(ANN201)
59-59: Missing return type annotation for public function sample_ini_config
Add return type annotation: str
(ANN201)
🪛 Pylint (3.3.7)
[convention] 14-14: Trailing whitespace
(C0303)
[convention] 20-20: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
🤖 Prompt for AI Agents
In test_config_files.py between lines 12 and 76, add appropriate type
annotations to all pytest fixture methods, specifying their return types such as
Path for temp_config_dir and str or dict for the config fixtures. Also, remove
any trailing whitespace from the fixture method bodies and their returned
strings to fix formatting issues. Ensure consistent indentation and clean
formatting throughout the fixture definitions.
| @pytest.mark.parametrize("url", [ | ||
| "http://example.com", | ||
| "https://api.example.com", | ||
| "https://api.example.com:8080/v1" | ||
| ]) | ||
| def test_valid_urls(self, url): | ||
| """Test validation of valid URLs.""" | ||
| import re | ||
| url_pattern = re.compile( | ||
| r'^https?://' # http:// or https:// | ||
| r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | ||
| r'localhost|' # localhost... | ||
| r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | ||
| r'(?::\d+)?' # optional port | ||
| r'(?:/?|[/?]\S+)$', re.IGNORECASE) | ||
|
|
||
| assert url_pattern.match(url) is not None | ||
|
|
||
| @pytest.mark.parametrize("url", [ | ||
| "not-a-url", | ||
| "ftp://example.com", | ||
| "http://", | ||
| "https://" | ||
| ]) | ||
| def test_invalid_urls(self, url): | ||
| """Test validation of invalid URLs.""" | ||
| import re | ||
| url_pattern = re.compile( | ||
| r'^https?://' # http:// or https:// | ||
| r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | ||
| r'localhost|' # localhost... | ||
| r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | ||
| r'(?::\d+)?' # optional port | ||
| r'(?:/?|[/?]\S+)$', re.IGNORECASE) | ||
|
|
||
| assert url_pattern.match(url) is None | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Extract URL validation pattern to a class constant.
The repeated URL regex pattern should be extracted to avoid duplication and improve maintainability.
class TestConfigFileValidationRules:
"""Test validation rules for configuration files."""
-
+
+ URL_PATTERN = re.compile(
+ r'^https?://' # http:// or https://
+ r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
+ r'localhost|' # localhost...
+ r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
+ r'(?::\d+)?' # optional port
+ r'(?:/?|[/?]\S+)$', re.IGNORECASE)
+
@pytest.mark.parametrize("url", [
"http://example.com",
"https://api.example.com",
- "https://api.example.com:8080/v1"
+ "https://api.example.com:8080/v1",
])
- def test_valid_urls(self, url):
+ def test_valid_urls(self, url: str) -> None:
"""Test validation of valid URLs."""
- import re
- url_pattern = re.compile(
- r'^https?://' # http:// or https://
- r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain...
- r'localhost|' # localhost...
- r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
- r'(?::\d+)?' # optional port
- r'(?:/?|[/?]\S+)$', re.IGNORECASE)
-
- assert url_pattern.match(url) is not None
+ assert self.URL_PATTERN.match(url) is not NoneAdd import re to the top-level imports and apply similar changes to test_invalid_urls.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @pytest.mark.parametrize("url", [ | |
| "http://example.com", | |
| "https://api.example.com", | |
| "https://api.example.com:8080/v1" | |
| ]) | |
| def test_valid_urls(self, url): | |
| """Test validation of valid URLs.""" | |
| import re | |
| url_pattern = re.compile( | |
| r'^https?://' # http:// or https:// | |
| r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | |
| r'localhost|' # localhost... | |
| r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | |
| r'(?::\d+)?' # optional port | |
| r'(?:/?|[/?]\S+)$', re.IGNORECASE) | |
| assert url_pattern.match(url) is not None | |
| @pytest.mark.parametrize("url", [ | |
| "not-a-url", | |
| "ftp://example.com", | |
| "http://", | |
| "https://" | |
| ]) | |
| def test_invalid_urls(self, url): | |
| """Test validation of invalid URLs.""" | |
| import re | |
| url_pattern = re.compile( | |
| r'^https?://' # http:// or https:// | |
| r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | |
| r'localhost|' # localhost... | |
| r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | |
| r'(?::\d+)?' # optional port | |
| r'(?:/?|[/?]\S+)$', re.IGNORECASE) | |
| assert url_pattern.match(url) is None | |
| class TestConfigFileValidationRules: | |
| """Test validation rules for configuration files.""" | |
| + URL_PATTERN = re.compile( | |
| + r'^https?://' # http:// or https:// | |
| + r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | |
| + r'localhost|' # localhost... | |
| + r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | |
| + r'(?::\d+)?' # optional port | |
| + r'(?:/?|[/?]\S+)$', re.IGNORECASE) | |
| @pytest.mark.parametrize("url", [ | |
| "http://example.com", | |
| "https://api.example.com", | |
| - "https://api.example.com:8080/v1" | |
| + "https://api.example.com:8080/v1", | |
| ]) | |
| - def test_valid_urls(self, url): | |
| + def test_valid_urls(self, url: str) -> None: | |
| """Test validation of valid URLs.""" | |
| - import re | |
| - url_pattern = re.compile( | |
| - r'^https?://' # http:// or https:// | |
| - r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | |
| - r'localhost|' # localhost... | |
| - r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | |
| - r'(?::\d+)?' # optional port | |
| - r'(?:/?|[/?]\S+)$', re.IGNORECASE) | |
| - | |
| - assert url_pattern.match(url) is not None | |
| + assert self.URL_PATTERN.match(url) is not None | |
| @pytest.mark.parametrize("url", [ | |
| "not-a-url", | |
| "ftp://example.com", | |
| "http://", | |
| "https://" | |
| ]) | |
| def test_invalid_urls(self, url): | |
| """Test validation of invalid URLs.""" | |
| import re | |
| url_pattern = re.compile( | |
| r'^https?://' # http:// or https:// | |
| r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' # domain... | |
| r'localhost|' # localhost... | |
| r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip | |
| r'(?::\d+)?' # optional port | |
| r'(?:/?|[/?]\S+)$', re.IGNORECASE) | |
| assert url_pattern.match(url) is None |
🧰 Tools
🪛 Flake8 (7.2.0)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 464-464: blank line contains whitespace
(W293)
[warning] 481-481: blank line contains whitespace
(W293)
🪛 Ruff (0.11.9)
450-450: Trailing comma missing
Add trailing comma
(COM812)
452-452: Missing return type annotation for public function test_valid_urls
Add return type annotation: None
(ANN201)
452-452: Missing type annotation for function argument url
(ANN001)
469-469: Trailing comma missing
Add trailing comma
(COM812)
471-471: Missing return type annotation for public function test_invalid_urls
Add return type annotation: None
(ANN201)
471-471: Missing type annotation for function argument url
(ANN001)
🪛 Pylint (3.3.7)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 464-464: Trailing whitespace
(C0303)
[convention] 481-481: Trailing whitespace
(C0303)
[convention] 454-454: Import outside toplevel (re)
(C0415)
[convention] 473-473: Import outside toplevel (re)
(C0415)
🤖 Prompt for AI Agents
In test_config_files.py around lines 447 to 483, the URL regex pattern is
duplicated in both test_valid_urls and test_invalid_urls functions. Extract this
regex pattern into a class-level constant or module-level constant to avoid
repetition. Move the import re statement to the top of the file with other
imports. Then update both test functions to use this constant for URL validation
instead of defining the regex inline.
| #!/usr/bin/env python3 | ||
| """ | ||
| Test suite for utils/helpers.py | ||
| Tests all utility helper functions with comprehensive coverage | ||
| """ | ||
|
|
||
| import pytest | ||
| import json | ||
| import tempfile | ||
| import time | ||
| from pathlib import Path | ||
| from unittest.mock import patch | ||
|
|
||
| import sys | ||
| sys.path.append(str(Path(__file__).parent)) | ||
|
|
||
| from utils.helpers import ( | ||
| safe_json_parse, | ||
| safe_json_dumps, | ||
| generate_hash, | ||
| retry_with_backoff, | ||
| flatten_dict, | ||
| ensure_directory_exists, | ||
| sanitize_filename, | ||
| merge_dicts, | ||
| chunk_list, | ||
| format_duration | ||
| ) | ||
|
|
||
|
|
||
| class TestSafeJsonParse: | ||
| """Test safe_json_parse function""" | ||
|
|
||
| def test_valid_json_string(self): | ||
| """Test parsing valid JSON string""" | ||
| json_str = '{"key": "value", "number": 42}' | ||
| result = safe_json_parse(json_str) | ||
| assert result == {"key": "value", "number": 42} | ||
|
|
||
| def test_valid_json_array(self): | ||
| """Test parsing valid JSON array""" | ||
| json_str = '[1, 2, 3, "test"]' | ||
| result = safe_json_parse(json_str) | ||
| assert result == [1, 2, 3, "test"] | ||
|
|
||
| def test_invalid_json_string(self): | ||
| """Test parsing invalid JSON string""" | ||
| json_str = '{"key": "value",}' # Trailing comma | ||
| result = safe_json_parse(json_str) | ||
| assert result is None | ||
|
|
||
| def test_completely_malformed_json(self): | ||
| """Test parsing completely malformed JSON""" | ||
| json_str = 'not json at all' | ||
| result = safe_json_parse(json_str) | ||
| assert result is None | ||
|
|
||
| def test_none_input(self): | ||
| """Test parsing None input""" | ||
| result = safe_json_parse(None) | ||
| assert result is None | ||
|
|
||
| def test_empty_string(self): | ||
| """Test parsing empty string""" | ||
| result = safe_json_parse("") | ||
| assert result is None | ||
|
|
||
|
|
||
| class TestSafeJsonDumps: | ||
| """Test safe_json_dumps function""" | ||
|
|
||
| def test_valid_dict(self): | ||
| """Test serializing valid dictionary""" | ||
| data = {"key": "value", "number": 42} | ||
| result = safe_json_dumps(data) | ||
| assert '"key": "value"' in result | ||
| assert '"number": 42' in result | ||
|
|
||
| def test_valid_list(self): | ||
| """Test serializing valid list""" | ||
| data = [1, 2, 3, "test"] | ||
| result = safe_json_dumps(data) | ||
| expected = json.dumps(data, indent=2, default=str) | ||
| assert result == expected | ||
|
|
||
| def test_custom_indent(self): | ||
| """Test serializing with custom indentation""" | ||
| data = {"nested": {"key": "value"}} | ||
| result = safe_json_dumps(data, indent=4) | ||
| assert result.count(" ") > result.count("\n") # More spaces due to indent=4 | ||
|
|
||
| def test_complex_object_with_datetime(self): | ||
| """Test serializing complex object with datetime (uses default=str)""" | ||
| from datetime import datetime | ||
| data = {"timestamp": datetime.now(), "value": 42} | ||
| result = safe_json_dumps(data) | ||
| assert result != "" # Should not fail due to default=str | ||
| assert "timestamp" in result | ||
|
|
||
| def test_circular_reference(self): | ||
| """Test serializing object with circular reference""" | ||
| data = {} | ||
| data["self"] = data # Circular reference | ||
| result = safe_json_dumps(data) | ||
| assert result == "" # Should return empty string on failure | ||
|
|
||
|
|
||
| class TestGenerateHash: | ||
| """Test generate_hash function""" | ||
|
|
||
| def test_string_input(self): | ||
| """Test hashing string input""" | ||
| text = "test string" | ||
| result = generate_hash(text) | ||
| assert len(result) == 64 # SHA256 hex string length | ||
| assert isinstance(result, str) | ||
| assert all(c in '0123456789abcdef' for c in result) | ||
|
|
||
| def test_bytes_input(self): | ||
| """Test hashing bytes input""" | ||
| data = b"test bytes" | ||
| result = generate_hash(data) | ||
| assert len(result) == 64 | ||
| assert isinstance(result, str) | ||
|
|
||
| def test_consistent_hashing(self): | ||
| """Test that same input produces same hash""" | ||
| text = "consistent test" | ||
| hash1 = generate_hash(text) | ||
| hash2 = generate_hash(text) | ||
| assert hash1 == hash2 | ||
|
|
||
| def test_different_inputs_different_hashes(self): | ||
| """Test that different inputs produce different hashes""" | ||
| hash1 = generate_hash("input1") | ||
| hash2 = generate_hash("input2") | ||
| assert hash1 != hash2 | ||
|
|
||
| def test_empty_string(self): | ||
| """Test hashing empty string""" | ||
| result = generate_hash("") | ||
| assert len(result) == 64 | ||
| assert result != generate_hash("not empty") | ||
|
|
||
|
|
||
| class TestRetryWithBackoff: | ||
| """Test retry_with_backoff function""" | ||
|
|
||
| def test_successful_function(self): | ||
| """Test function that succeeds on first try""" | ||
| def success_func(): | ||
| return "success" | ||
|
|
||
| result = retry_with_backoff(success_func) | ||
| assert result == "success" | ||
|
|
||
| def test_function_succeeds_after_retries(self): | ||
| """Test function that succeeds after failures""" | ||
| attempts = [] | ||
|
|
||
| def eventually_succeeds(): | ||
| attempts.append(1) | ||
| if len(attempts) < 3: | ||
| raise ValueError("Not yet") | ||
| return "finally succeeded" | ||
|
|
||
| result = retry_with_backoff(eventually_succeeds, max_retries=3) | ||
| assert result == "finally succeeded" | ||
| assert len(attempts) == 3 | ||
|
|
||
| def test_function_fails_all_retries(self): | ||
| """Test function that fails all retry attempts""" | ||
| def always_fails(): | ||
| raise ValueError("Always fails") | ||
|
|
||
| with pytest.raises(ValueError, match="Always fails"): | ||
| retry_with_backoff(always_fails, max_retries=2) | ||
|
|
||
| @patch('time.sleep') | ||
| def test_backoff_timing(self, mock_sleep): | ||
| """Test exponential backoff timing""" | ||
| def fails_twice(): | ||
| if mock_sleep.call_count < 2: | ||
| raise ValueError("Fail") | ||
| return "success" | ||
|
|
||
| result = retry_with_backoff(fails_twice, max_retries=3, base_delay=1.0) | ||
| assert result == "success" | ||
|
|
||
| # Check exponential backoff: 1s, 2s | ||
| expected_delays = [1.0, 2.0] | ||
| actual_delays = [call[0][0] for call in mock_sleep.call_args_list] | ||
| assert actual_delays == expected_delays | ||
|
|
||
|
|
||
| class TestFlattenDict: | ||
| """Test flatten_dict function""" | ||
|
|
||
| def test_simple_dict(self): | ||
| """Test flattening simple dictionary""" | ||
| data = {"a": 1, "b": 2} | ||
| result = flatten_dict(data) | ||
| assert result == {"a": 1, "b": 2} | ||
|
|
||
| def test_nested_dict(self): | ||
| """Test flattening nested dictionary""" | ||
| data = {"a": {"b": {"c": 1}}, "d": 2} | ||
| result = flatten_dict(data) | ||
| expected = {"a.b.c": 1, "d": 2} | ||
| assert result == expected | ||
|
|
||
| def test_mixed_nested_dict(self): | ||
| """Test flattening mixed nested dictionary""" | ||
| data = { | ||
| "user": {"name": "John", "address": {"city": "NYC", "zip": "10001"}}, | ||
| "age": 30, | ||
| "active": True | ||
| } | ||
| result = flatten_dict(data) | ||
| expected = { | ||
| "user.name": "John", | ||
| "user.address.city": "NYC", | ||
| "user.address.zip": "10001", | ||
| "age": 30, | ||
| "active": True | ||
| } | ||
| assert result == expected | ||
|
|
||
| def test_with_prefix(self): | ||
| """Test flattening with custom prefix""" | ||
| data = {"a": {"b": 1}} | ||
| result = flatten_dict(data, prefix="root") | ||
| assert result == {"root.a.b": 1} | ||
|
|
||
| def test_empty_dict(self): | ||
| """Test flattening empty dictionary""" | ||
| result = flatten_dict({}) | ||
| assert result == {} | ||
|
|
||
|
|
||
| class TestEnsureDirectoryExists: | ||
| """Test ensure_directory_exists function""" | ||
|
|
||
| def test_create_new_directory(self): | ||
| """Test creating new directory""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| new_dir = Path(temp_dir) / "new_directory" | ||
| result = ensure_directory_exists(new_dir) | ||
|
|
||
| assert result.exists() | ||
| assert result.is_dir() | ||
| assert result == new_dir | ||
|
|
||
| def test_existing_directory(self): | ||
| """Test with existing directory""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| existing_dir = Path(temp_dir) | ||
| result = ensure_directory_exists(existing_dir) | ||
|
|
||
| assert result.exists() | ||
| assert result.is_dir() | ||
| assert result == existing_dir | ||
|
|
||
| def test_nested_directory_creation(self): | ||
| """Test creating nested directories""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| nested_dir = Path(temp_dir) / "level1" / "level2" / "level3" | ||
| result = ensure_directory_exists(nested_dir) | ||
|
|
||
| assert result.exists() | ||
| assert result.is_dir() | ||
| assert result == nested_dir | ||
|
|
||
| def test_string_path_input(self): | ||
| """Test with string path input""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| new_dir_str = f"{temp_dir}/string_path" | ||
| result = ensure_directory_exists(new_dir_str) | ||
|
|
||
| assert result.exists() | ||
| assert result.is_dir() | ||
| assert str(result) == new_dir_str | ||
|
|
||
|
|
||
| class TestSanitizeFilename: | ||
| """Test sanitize_filename function""" | ||
|
|
||
| def test_valid_filename(self): | ||
| """Test already valid filename""" | ||
| filename = "valid_filename.txt" | ||
| result = sanitize_filename(filename) | ||
| assert result == filename | ||
|
|
||
| def test_invalid_characters(self): | ||
| """Test filename with invalid characters""" | ||
| filename = 'file<>:"/\\|?*name.txt' | ||
| result = sanitize_filename(filename) | ||
| assert result == "file_________name.txt" | ||
|
|
||
| def test_leading_trailing_spaces_dots(self): | ||
| """Test filename with leading/trailing spaces and dots""" | ||
| filename = " ...filename... " | ||
| result = sanitize_filename(filename) | ||
| assert result == "filename" | ||
|
|
||
| def test_empty_filename(self): | ||
| """Test empty filename""" | ||
| result = sanitize_filename("") | ||
| assert result == "unnamed" | ||
|
|
||
| def test_only_invalid_characters(self): | ||
| """Test filename with only invalid characters""" | ||
| filename = "<>?*|" | ||
| result = sanitize_filename(filename) | ||
| assert result == "unnamed" | ||
|
|
||
| def test_spaces_and_dots_only(self): | ||
| """Test filename with only spaces and dots""" | ||
| filename = " ... " | ||
| result = sanitize_filename(filename) | ||
| assert result == "unnamed" | ||
|
|
||
|
|
||
| class TestMergeDicts: | ||
| """Test merge_dicts function""" | ||
|
|
||
| def test_simple_merge(self): | ||
| """Test merging simple dictionaries""" | ||
| dict1 = {"a": 1, "b": 2} | ||
| dict2 = {"c": 3, "d": 4} | ||
| result = merge_dicts(dict1, dict2) | ||
| expected = {"a": 1, "b": 2, "c": 3, "d": 4} | ||
| assert result == expected | ||
|
|
||
| def test_overlapping_keys(self): | ||
| """Test merging with overlapping keys""" | ||
| dict1 = {"a": 1, "b": 2} | ||
| dict2 = {"b": 3, "c": 4} | ||
| result = merge_dicts(dict1, dict2) | ||
| expected = {"a": 1, "b": 3, "c": 4} # dict2 takes precedence | ||
| assert result == expected | ||
|
|
||
| def test_nested_dict_merge(self): | ||
| """Test deep merging nested dictionaries""" | ||
| dict1 = {"user": {"name": "John", "age": 30}, "active": True} | ||
| dict2 = {"user": {"city": "NYC", "age": 31}, "role": "admin"} | ||
| result = merge_dicts(dict1, dict2) | ||
| expected = { | ||
| "user": {"name": "John", "age": 31, "city": "NYC"}, | ||
| "active": True, | ||
| "role": "admin" | ||
| } | ||
| assert result == expected | ||
|
|
||
| def test_empty_dicts(self): | ||
| """Test merging empty dictionaries""" | ||
| result = merge_dicts({}, {}) | ||
| assert result == {} | ||
|
|
||
| def test_original_dicts_unchanged(self): | ||
| """Test that original dictionaries are not modified""" | ||
| dict1 = {"a": 1} | ||
| dict2 = {"b": 2} | ||
| original_dict1 = dict1.copy() | ||
| original_dict2 = dict2.copy() | ||
|
|
||
| merge_dicts(dict1, dict2) | ||
|
|
||
| assert dict1 == original_dict1 | ||
| assert dict2 == original_dict2 | ||
|
|
||
|
|
||
| class TestChunkList: | ||
| """Test chunk_list function""" | ||
|
|
||
| def test_even_chunks(self): | ||
| """Test chunking list into even chunks""" | ||
| data = [1, 2, 3, 4, 5, 6] | ||
| result = chunk_list(data, 2) | ||
| expected = [[1, 2], [3, 4], [5, 6]] | ||
| assert result == expected | ||
|
|
||
| def test_uneven_chunks(self): | ||
| """Test chunking list with remainder""" | ||
| data = [1, 2, 3, 4, 5] | ||
| result = chunk_list(data, 2) | ||
| expected = [[1, 2], [3, 4], [5]] | ||
| assert result == expected | ||
|
|
||
| def test_chunk_size_larger_than_list(self): | ||
| """Test chunk size larger than list length""" | ||
| data = [1, 2, 3] | ||
| result = chunk_list(data, 5) | ||
| expected = [[1, 2, 3]] | ||
| assert result == expected | ||
|
|
||
| def test_chunk_size_one(self): | ||
| """Test chunk size of 1""" | ||
| data = [1, 2, 3] | ||
| result = chunk_list(data, 1) | ||
| expected = [[1], [2], [3]] | ||
| assert result == expected | ||
|
|
||
| def test_empty_list(self): | ||
| """Test chunking empty list""" | ||
| result = chunk_list([], 2) | ||
| assert result == [] | ||
|
|
||
| def test_mixed_data_types(self): | ||
| """Test chunking list with mixed data types""" | ||
| data = [1, "two", 3.0, True, None] | ||
| result = chunk_list(data, 2) | ||
| expected = [[1, "two"], [3.0, True], [None]] | ||
| assert result == expected | ||
|
|
||
|
|
||
| class TestFormatDuration: | ||
| """Test format_duration function""" | ||
|
|
||
| def test_seconds_format(self): | ||
| """Test formatting duration in seconds""" | ||
| assert format_duration(5.5) == "5.50s" | ||
| assert format_duration(30.25) == "30.25s" | ||
| assert format_duration(59.99) == "59.99s" | ||
|
|
||
| def test_minutes_format(self): | ||
| """Test formatting duration in minutes""" | ||
| assert format_duration(60) == "1.0m" | ||
| assert format_duration(90) == "1.5m" | ||
| assert format_duration(3599) == "60.0m" | ||
|
|
||
| def test_hours_format(self): | ||
| """Test formatting duration in hours""" | ||
| assert format_duration(3600) == "1.0h" | ||
| assert format_duration(5400) == "1.5h" | ||
| assert format_duration(7200) == "2.0h" | ||
|
|
||
| def test_edge_cases(self): | ||
| """Test edge cases for duration formatting""" | ||
| assert format_duration(0) == "0.00s" | ||
| assert format_duration(0.01) == "0.01s" | ||
| assert format_duration(59.99) == "59.99s" | ||
| assert format_duration(60.001) == "1.0m" | ||
|
|
||
| def test_large_durations(self): | ||
| """Test very large duration values""" | ||
| one_day = 24 * 3600 | ||
| assert format_duration(one_day) == "24.0h" | ||
|
|
||
| one_week = 7 * 24 * 3600 | ||
| assert format_duration(one_week) == "168.0h" | ||
|
|
||
|
|
||
| class TestHelpersIntegration: | ||
| """Integration tests combining multiple helper functions""" | ||
|
|
||
| def test_json_and_hash_integration(self): | ||
| """Test combining JSON serialization with hashing""" | ||
| data = {"user": "test", "timestamp": "2023-01-01"} | ||
| json_str = safe_json_dumps(data) | ||
| hash_value = generate_hash(json_str) | ||
|
|
||
| assert json_str != "" | ||
| assert len(hash_value) == 64 | ||
|
|
||
| # Same data should produce same hash | ||
| same_json = safe_json_dumps(data) | ||
| same_hash = generate_hash(same_json) | ||
| assert hash_value == same_hash | ||
|
|
||
| def test_file_operations_integration(self): | ||
| """Test combining file operations""" | ||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| # Create directory structure | ||
| nested_dir = ensure_directory_exists(f"{temp_dir}/nested/path") | ||
|
|
||
| # Sanitize and create filename | ||
| unsafe_filename = "test<>file.txt" | ||
| safe_filename = sanitize_filename(unsafe_filename) | ||
|
|
||
| # Create file path | ||
| file_path = nested_dir / safe_filename | ||
| file_path.write_text("test content") | ||
|
|
||
| assert file_path.exists() | ||
| assert safe_filename == "test__file.txt" | ||
|
|
||
| def test_data_processing_pipeline(self): | ||
| """Test a complete data processing pipeline""" | ||
| # Start with nested data | ||
| data = { | ||
| "users": { | ||
| "john": {"age": 30, "city": "NYC"}, | ||
| "jane": {"age": 25, "city": "LA"} | ||
| }, | ||
| "settings": {"theme": "dark", "notifications": True} | ||
| } | ||
|
|
||
| # Flatten the structure | ||
| flat_data = flatten_dict(data) | ||
|
|
||
| # Serialize to JSON | ||
| json_str = safe_json_dumps(flat_data) | ||
|
|
||
| # Parse it back | ||
| parsed_data = safe_json_parse(json_str) | ||
|
|
||
| # Chunk the keys for processing | ||
| keys = list(parsed_data.keys()) | ||
| key_chunks = chunk_list(keys, 2) | ||
|
|
||
| assert len(flat_data) == 6 # All nested keys flattened | ||
| assert parsed_data == flat_data # Round-trip successful | ||
| assert len(key_chunks) == 3 # 6 keys chunked by 2 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| pytest.main([__file__, "-v"]) | ||
|
|
||
| # Additional Enhanced Test Classes for Comprehensive Coverage | ||
| class TestSafeJsonParseAdvanced: | ||
| """Advanced edge cases and stress tests for safe_json_parse""" | ||
|
|
||
| def test_deeply_nested_json_performance(self): | ||
| """Test parsing very deeply nested JSON structures""" | ||
| # Create deeply nested structure | ||
| nested_data = "value" | ||
| for i in range(100): | ||
| nested_data = {"level": nested_data} | ||
|
|
||
| json_str = json.dumps(nested_data) | ||
| result = safe_json_parse(json_str) | ||
|
|
||
| # Navigate to verify correct parsing | ||
| current = result | ||
| for i in range(100): | ||
| assert "level" in current | ||
| current = current["level"] | ||
| assert current == "value" | ||
|
|
||
| def test_unicode_and_escape_sequences(self): | ||
| """Test parsing JSON with various unicode and escape sequences""" | ||
| test_cases = [ | ||
| r'{"unicode": "\u0048\u0065\u006C\u006C\u006F"}', # "Hello" in unicode | ||
| r'{"escaped": "line1\nline2\ttab"}', # Newlines and tabs | ||
| r'{"quotes": "He said \"Hello\""}', # Escaped quotes | ||
| '{"emoji": "🚀 \ud83c\udf1f"}', # Mixed emoji encoding | ||
| ] | ||
|
|
||
| for json_str in test_cases: | ||
| result = safe_json_parse(json_str) | ||
| assert result is not None | ||
| assert isinstance(result, dict) | ||
|
|
||
| def test_json_with_large_numbers(self): | ||
| """Test parsing JSON with very large numbers""" | ||
| large_numbers = [ | ||
| '{"big_int": 9223372036854775807}', # Max 64-bit signed int | ||
| '{"big_float": 1.7976931348623157e+308}', # Near max float | ||
| '{"small_float": 2.2250738585072014e-308}', # Near min positive float | ||
| '{"scientific": 1.23e100}', # Scientific notation | ||
| ] | ||
|
|
||
| for json_str in large_numbers: | ||
| result = safe_json_parse(json_str) | ||
| assert result is not None | ||
| assert isinstance(result, dict) | ||
|
|
||
| @pytest.mark.parametrize("malformed_json", [ | ||
| '{"key": }', # Missing value | ||
| '{"key": "value",}', # Trailing comma | ||
| '{key: "value"}', # Unquoted key | ||
| "{'key': 'value'}", # Single quotes | ||
| '{"key": "value"', # Missing closing brace | ||
| '{"key": undefined}', # JavaScript undefined | ||
| '{"key": /*comment*/ "value"}', # Comment in JSON | ||
| ]) | ||
| def test_malformed_json_variations(self, malformed_json): | ||
| """Test various malformed JSON inputs""" | ||
| result = safe_json_parse(malformed_json) | ||
| assert result is None | ||
|
|
||
|
|
||
| class TestSafeJsonDumpsAdvanced: | ||
| """Advanced tests for safe_json_dumps with complex scenarios""" | ||
|
|
||
| def test_circular_reference_detection(self): | ||
| """Test detection and handling of circular references""" | ||
| # Create circular reference | ||
| obj_a = {"name": "A"} | ||
| obj_b = {"name": "B", "ref": obj_a} | ||
| obj_a["ref"] = obj_b | ||
|
|
||
| result = safe_json_dumps(obj_a) | ||
| assert result == "" # Should return empty string due to circular reference | ||
|
|
||
| def test_custom_objects_with_str_method(self): | ||
| """Test serialization of custom objects with __str__ method""" | ||
| class CustomObject: | ||
| def __init__(self, value): | ||
| self.value = value | ||
|
|
||
| def __str__(self): | ||
| return f"CustomObject(value={self.value})" | ||
|
|
||
| data = {"custom": CustomObject(42), "normal": "value"} | ||
| result = safe_json_dumps(data) | ||
|
|
||
| assert result != "" | ||
| assert "CustomObject" in result | ||
| assert "42" in result | ||
|
|
||
| def test_mixed_data_types_edge_cases(self): | ||
| """Test serialization with edge case data types""" | ||
| from decimal import Decimal | ||
| import uuid | ||
|
|
||
| data = { | ||
| "decimal": Decimal("123.456"), | ||
| "uuid": uuid.uuid4(), | ||
| "complex": complex(1, 2), | ||
| "frozenset": frozenset([1, 2, 3]), | ||
| "bytes": b"hello world", | ||
| "range": range(5), | ||
| } | ||
|
|
||
| result = safe_json_dumps(data) | ||
| assert result != "" # Should handle all types via default=str | ||
|
|
||
| def test_performance_large_object(self): | ||
| """Test performance with large objects""" | ||
| large_data = { | ||
| f"key_{i}": { | ||
| "value": i, | ||
| "data": "x" * 1000, # 1KB per entry | ||
| "nested": {"sub_key": f"sub_value_{i}"} | ||
| } | ||
| for i in range(1000) # ~1MB total | ||
| } | ||
|
|
||
| import time | ||
| start_time = time.time() | ||
| result = safe_json_dumps(large_data) | ||
| end_time = time.time() | ||
|
|
||
| assert result != "" | ||
| assert end_time - start_time < 5.0 # Should complete within 5 seconds | ||
|
|
||
|
|
||
| class TestGenerateHashAdvanced: | ||
| """Advanced hash generation tests""" | ||
|
|
||
| def test_hash_distribution(self): | ||
| """Test hash distribution to ensure no obvious patterns""" | ||
| inputs = [f"test_{i}" for i in range(1000)] | ||
| hashes = [generate_hash(inp) for inp in inputs] | ||
|
|
||
| # Check that hashes are well distributed | ||
| first_chars = [h[0] for h in hashes] | ||
| char_counts = {} | ||
| for char in first_chars: | ||
| char_counts[char] = char_counts.get(char, 0) + 1 | ||
|
|
||
| # No single character should dominate (rough distribution check) | ||
| max_count = max(char_counts.values()) | ||
| assert max_count < len(hashes) * 0.2 # No more than 20% should start with same char | ||
|
|
||
| def test_avalanche_effect(self): | ||
| """Test avalanche effect - small input changes cause large hash changes""" | ||
| base_string = "test_string_for_avalanche" | ||
| base_hash = generate_hash(base_string) | ||
|
|
||
| # Change one character | ||
| modified_string = base_string[:-1] + 'X' | ||
| modified_hash = generate_hash(modified_string) | ||
|
|
||
| # Count different bits (simplified check) | ||
| base_int = int(base_hash, 16) | ||
| modified_int = int(modified_hash, 16) | ||
| xor_result = base_int ^ modified_int | ||
| different_bits = bin(xor_result).count('1') | ||
|
|
||
| # Should have significant bit differences (roughly 50% for good hash) | ||
| assert different_bits > 50 # Out of 256 bits, expect substantial difference | ||
|
|
||
| def test_hash_consistency_across_runs(self): | ||
| """Test that hash function is deterministic across multiple runs""" | ||
| test_string = "consistency_test_string" | ||
| hashes = [generate_hash(test_string) for _ in range(10)] | ||
|
|
||
| # All hashes should be identical | ||
| assert len(set(hashes)) == 1 | ||
| assert all(h == hashes[0] for h in hashes) | ||
|
|
||
| def test_empty_and_whitespace_inputs(self): | ||
| """Test hashing of empty and whitespace-only inputs""" | ||
| test_cases = ["", " ", "\t", "\n", " ", "\t\n "] | ||
| hashes = [generate_hash(case) for case in test_cases] | ||
|
|
||
| # All should produce valid hashes | ||
| assert all(len(h) == 64 for h in hashes) | ||
| # All should be different (even whitespace variations) | ||
| assert len(set(hashes)) == len(hashes) | ||
|
|
||
|
|
||
| class TestRetryWithBackoffAdvanced: | ||
| """Advanced retry mechanism tests""" | ||
|
|
||
| def test_retry_with_different_exception_types(self): | ||
| """Test retry behavior with mixed exception types""" | ||
| exceptions_to_raise = [ | ||
| ConnectionError("Connection failed"), | ||
| TimeoutError("Request timed out"), | ||
| ValueError("Invalid value"), | ||
| ] | ||
|
|
||
| call_count = [0] | ||
|
|
||
| def failing_function(): | ||
| if call_count[0] < len(exceptions_to_raise): | ||
| exc = exceptions_to_raise[call_count[0]] | ||
| call_count[0] += 1 | ||
| raise exc | ||
| return "success" | ||
|
|
||
| result = retry_with_backoff(failing_function, max_retries=5) | ||
| assert result == "success" | ||
| assert call_count[0] == len(exceptions_to_raise) | ||
|
|
||
| @patch('time.sleep') | ||
| def test_exponential_backoff_progression(self, mock_sleep): | ||
| """Test that backoff follows exponential progression""" | ||
| call_count = [0] | ||
|
|
||
| def always_fails(): | ||
| call_count[0] += 1 | ||
| if call_count[0] <= 4: # Fail first 4 times | ||
| raise RuntimeError("Temporary failure") | ||
| return "success" | ||
|
|
||
| result = retry_with_backoff(always_fails, max_retries=5, base_delay=1.0) | ||
| assert result == "success" | ||
|
|
||
| # Check exponential progression: 1, 2, 4, 8 | ||
| expected_delays = [1.0, 2.0, 4.0, 8.0] | ||
| actual_delays = [call[0][0] for call in mock_sleep.call_args_list] | ||
| assert actual_delays == expected_delays | ||
|
|
||
| def test_retry_with_return_values(self): | ||
| """Test retry with functions returning different values""" | ||
| return_values = [None, False, 0, "", "success"] | ||
| call_count = [0] | ||
|
|
||
| def function_with_varying_returns(): | ||
| if call_count[0] < len(return_values) - 1: | ||
| value = return_values[call_count[0]] | ||
| call_count[0] += 1 | ||
| if value is None: | ||
| raise ValueError("None result") | ||
| return value | ||
| call_count[0] += 1 | ||
| return return_values[-1] | ||
|
|
||
| result = retry_with_backoff(function_with_varying_returns, max_retries=3) | ||
| assert result == "success" | ||
|
|
||
| def test_retry_timeout_simulation(self): | ||
| """Test retry with simulated timeout scenarios""" | ||
| import time | ||
|
|
||
| start_time = time.time() | ||
| call_times = [] | ||
|
|
||
| def time_tracking_function(): | ||
| call_times.append(time.time()) | ||
| if len(call_times) < 3: | ||
| raise TimeoutError("Simulated timeout") | ||
| return "completed" | ||
|
|
||
| result = retry_with_backoff(time_tracking_function, max_retries=3, base_delay=0.1) | ||
|
|
||
| assert result == "completed" | ||
| assert len(call_times) == 3 | ||
|
|
||
| # Verify timing progression | ||
| for i in range(1, len(call_times)): | ||
| time_diff = call_times[i] - call_times[i-1] | ||
| expected_min_delay = 0.1 * (2 ** (i-1)) | ||
| assert time_diff >= expected_min_delay * 0.9 # Allow 10% tolerance | ||
|
|
||
|
|
||
| class TestFlattenDictAdvanced: | ||
| """Advanced dictionary flattening tests""" | ||
|
|
||
| def test_flatten_with_complex_nested_structures(self): | ||
| """Test flattening complex nested structures with mixed types""" | ||
| complex_data = { | ||
| "api": { | ||
| "v1": { | ||
| "endpoints": ["users", "posts", "comments"], | ||
| "auth": {"required": True, "methods": ["jwt", "oauth"]}, | ||
| "rate_limits": {"per_hour": 1000, "burst": 10} | ||
| }, | ||
| "v2": { | ||
| "endpoints": ["users", "posts"], | ||
| "auth": {"required": True, "methods": ["jwt"]}, | ||
| "features": {"pagination": True, "filtering": True} | ||
| } | ||
| }, | ||
| "database": { | ||
| "primary": {"host": "db1.local", "port": 5432}, | ||
| "replicas": [ | ||
| {"host": "db2.local", "port": 5432}, | ||
| {"host": "db3.local", "port": 5432} | ||
| ] | ||
| } | ||
| } | ||
|
|
||
| result = flatten_dict(complex_data) | ||
|
|
||
| # Verify specific flattened keys exist | ||
| expected_keys = [ | ||
| "api.v1.endpoints", | ||
| "api.v1.auth.required", | ||
| "api.v1.auth.methods", | ||
| "api.v1.rate_limits.per_hour", | ||
| "api.v2.features.pagination", | ||
| "database.primary.host", | ||
| "database.replicas" | ||
| ] | ||
|
|
||
| for key in expected_keys: | ||
| assert key in result | ||
|
|
||
| def test_flatten_with_numeric_and_boolean_keys(self): | ||
| """Test flattening with non-string keys""" | ||
| data = { | ||
| "config": { | ||
| 1: "first_item", | ||
| 2: {"nested": "second_nested"}, | ||
| True: "boolean_key", | ||
| False: {"deep": "boolean_nested"} | ||
| } | ||
| } | ||
|
|
||
| result = flatten_dict(data) | ||
|
|
||
| expected_flattened = { | ||
| "config.1": "first_item", | ||
| "config.2.nested": "second_nested", | ||
| "config.True": "boolean_key", | ||
| "config.False.deep": "boolean_nested" | ||
| } | ||
|
|
||
| assert result == expected_flattened | ||
|
|
||
| def test_flatten_with_custom_separator(self): | ||
| """Test flattening with custom separator (if supported)""" | ||
| data = {"a": {"b": {"c": "value"}}} | ||
|
|
||
| # Test with default separator | ||
| result_dot = flatten_dict(data) | ||
| assert result_dot == {"a.b.c": "value"} | ||
|
|
||
| # If function supports custom separator, test it | ||
| # Note: This might not be supported by the current implementation | ||
| try: | ||
| result_underscore = flatten_dict(data, separator="_") | ||
| if result_underscore != result_dot: # If separator was actually used | ||
| assert result_underscore == {"a_b_c": "value"} | ||
| except TypeError: | ||
| # Function doesn't support custom separator - that's fine | ||
| pass | ||
|
|
||
| def test_flatten_performance_large_dict(self): | ||
| """Test flattening performance with large dictionary""" | ||
| # Create large nested dictionary | ||
| large_dict = {} | ||
| for i in range(100): | ||
| large_dict[f"section_{i}"] = { | ||
| f"subsection_{j}": { | ||
| f"item_{k}": f"value_{i}_{j}_{k}" | ||
| for k in range(10) | ||
| } | ||
| for j in range(10) | ||
| } | ||
|
|
||
| import time | ||
| start_time = time.time() | ||
| result = flatten_dict(large_dict) | ||
| end_time = time.time() | ||
|
|
||
| # Should complete reasonably quickly | ||
| assert end_time - start_time < 1.0 | ||
|
|
||
| # Should have 100 * 10 * 10 = 10,000 flattened keys | ||
| assert len(result) == 10000 | ||
|
|
||
|
|
||
| class TestFileOperationsAdvanced: | ||
| """Advanced tests for file operation helpers""" | ||
|
|
||
| def test_ensure_directory_concurrent_creation(self): | ||
| """Test concurrent directory creation""" | ||
| import threading | ||
| import tempfile | ||
|
|
||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| target_dir = Path(temp_dir) / "concurrent_test" | ||
| results = [] | ||
| errors = [] | ||
|
|
||
| def create_directory(thread_id): | ||
| try: | ||
| result = ensure_directory_exists(target_dir) | ||
| results.append((thread_id, result)) | ||
| except Exception as e: | ||
| errors.append((thread_id, e)) | ||
|
|
||
| # Create multiple threads trying to create same directory | ||
| threads = [] | ||
| for i in range(10): | ||
| thread = threading.Thread(target=create_directory, args=(i,)) | ||
| threads.append(thread) | ||
| thread.start() | ||
|
|
||
| # Wait for all threads | ||
| for thread in threads: | ||
| thread.join() | ||
|
|
||
| # All should succeed without errors | ||
| assert len(errors) == 0 | ||
| assert len(results) == 10 | ||
| assert target_dir.exists() | ||
| assert target_dir.is_dir() | ||
|
|
||
| def test_sanitize_filename_edge_cases(self): | ||
| """Test filename sanitization with edge cases""" | ||
| edge_cases = [ | ||
| ("", "unnamed"), # Empty string | ||
| (".", "unnamed"), # Just dot | ||
| ("..", "unnamed"), # Double dot | ||
| ("...", "unnamed"), # Triple dot | ||
| (" ", "unnamed"), # Only spaces | ||
| ("___", "unnamed"), # Only underscores after sanitization | ||
| ("CON", "CON"), # Windows reserved name (may vary by implementation) | ||
| ("file" + "x" * 300, None), # Very long filename | ||
| ("file\x00name.txt", "file_name.txt"), # Null character | ||
| ("file\r\nname.txt", "file__name.txt"), # Newline characters | ||
| ] | ||
|
|
||
| for input_name, expected in edge_cases: | ||
| result = sanitize_filename(input_name) | ||
| if expected is not None: | ||
| assert result == expected | ||
| else: | ||
| # For very long filenames, just check it's not too long | ||
| assert len(result) <= 255 | ||
| assert result != "" | ||
|
|
||
| def test_sanitize_filename_preserves_extensions(self): | ||
| """Test that filename sanitization preserves valid extensions""" | ||
| test_cases = [ | ||
| ("file<>.txt", "file__.txt"), | ||
| ("document?.pdf", "document_.pdf"), | ||
| ("image|photo.jpg", "image_photo.jpg"), | ||
| ("data*file.csv", "data_file.csv"), | ||
| ] | ||
|
|
||
| for input_name, expected in test_cases: | ||
| result = sanitize_filename(input_name) | ||
| assert result == expected | ||
| # Verify extension is preserved | ||
| if "." in expected: | ||
| assert result.split(".")[-1] == expected.split(".")[-1] | ||
|
|
||
|
|
||
| class TestMergeDictsAdvanced: | ||
| """Advanced dictionary merging tests""" | ||
|
|
||
| def test_merge_with_conflicting_types(self): | ||
| """Test merging when same keys have different types""" | ||
| dict1 = { | ||
| "value": "string", | ||
| "config": {"setting": "old"}, | ||
| "list_item": [1, 2, 3] | ||
| } | ||
| dict2 = { | ||
| "value": 42, # String -> int | ||
| "config": "new_config", # Dict -> string | ||
| "list_item": {"new": "format"} # List -> dict | ||
| } | ||
|
|
||
| result = merge_dicts(dict1, dict2) | ||
|
|
||
| # dict2 values should take precedence | ||
| assert result["value"] == 42 | ||
| assert result["config"] == "new_config" | ||
| assert result["list_item"] == {"new": "format"} | ||
|
|
||
| def test_merge_very_deep_nesting(self): | ||
| """Test merging with very deep nesting""" | ||
| dict1 = {"a": {"b": {"c": {"d": {"e": {"f": "deep1"}}}}}} | ||
| dict2 = {"a": {"b": {"c": {"d": {"e": {"g": "deep2"}}}}}} | ||
|
|
||
| result = merge_dicts(dict1, dict2) | ||
|
|
||
| # Both deep values should be present | ||
| assert result["a"]["b"]["c"]["d"]["e"]["f"] == "deep1" | ||
| assert result["a"]["b"]["c"]["d"]["e"]["g"] == "deep2" | ||
|
|
||
| def test_merge_with_none_and_empty_values(self): | ||
| """Test merging with None and empty values""" | ||
| dict1 = { | ||
| "null_value": None, | ||
| "empty_dict": {}, | ||
| "empty_list": [], | ||
| "normal": "value1" | ||
| } | ||
| dict2 = { | ||
| "null_value": "not_null", | ||
| "empty_dict": {"filled": True}, | ||
| "empty_list": ["item"], | ||
| "normal": "value2" | ||
| } | ||
|
|
||
| result = merge_dicts(dict1, dict2) | ||
|
|
||
| assert result["null_value"] == "not_null" | ||
| assert result["empty_dict"] == {"filled": True} | ||
| assert result["empty_list"] == ["item"] | ||
| assert result["normal"] == "value2" | ||
|
|
||
| def test_merge_preserves_original_dicts(self): | ||
| """Test that merge operation doesn't modify original dictionaries""" | ||
| dict1 = {"shared": {"a": 1}, "unique1": "value1"} | ||
| dict2 = {"shared": {"b": 2}, "unique2": "value2"} | ||
|
|
||
| # Store original states | ||
| original_dict1 = {"shared": {"a": 1}, "unique1": "value1"} | ||
| original_dict2 = {"shared": {"b": 2}, "unique2": "value2"} | ||
|
|
||
| result = merge_dicts(dict1, dict2) | ||
|
|
||
| # Originals should be unchanged | ||
| assert dict1 == original_dict1 | ||
| assert dict2 == original_dict2 | ||
|
|
||
| # Result should have merged content | ||
| assert result["shared"] == {"a": 1, "b": 2} | ||
| assert result["unique1"] == "value1" | ||
| assert result["unique2"] == "value2" | ||
|
|
||
|
|
||
| class TestChunkListAdvanced: | ||
| """Advanced list chunking tests""" | ||
|
|
||
| def test_chunk_with_large_lists(self): | ||
| """Test chunking very large lists""" | ||
| large_list = list(range(100000)) # 100k items | ||
| chunk_size = 1000 | ||
|
|
||
| import time | ||
| start_time = time.time() | ||
| result = chunk_list(large_list, chunk_size) | ||
| end_time = time.time() | ||
|
|
||
| # Should complete quickly | ||
| assert end_time - start_time < 1.0 | ||
|
|
||
| # Verify correct chunking | ||
| assert len(result) == 100 # 100k / 1k = 100 chunks | ||
| assert all(len(chunk) == chunk_size for chunk in result[:-1]) # All but last chunk | ||
| assert len(result[-1]) <= chunk_size # Last chunk may be smaller | ||
|
|
||
| def test_chunk_memory_efficiency(self): | ||
| """Test that chunking doesn't create excessive memory overhead""" | ||
| # Create list with large objects | ||
| large_objects = [{"data": "x" * 1000, "id": i} for i in range(1000)] | ||
|
|
||
| result = chunk_list(large_objects, 100) | ||
|
|
||
| # Verify structure | ||
| assert len(result) == 10 | ||
| assert all(len(chunk) == 100 for chunk in result) | ||
|
|
||
| # Verify objects are the same instances (not copied) | ||
| assert result[0][0] is large_objects[0] | ||
| assert result[5][50] is large_objects[550] | ||
|
|
||
| def test_chunk_with_various_data_types(self): | ||
| """Test chunking lists with various data types""" | ||
| mixed_list = [ | ||
| "string", 42, 3.14, True, None, | ||
| [1, 2, 3], {"key": "value"}, | ||
| lambda x: x, set([1, 2, 3]) | ||
| ] | ||
|
|
||
| result = chunk_list(mixed_list, 3) | ||
|
|
||
| # Verify chunking preserves all types | ||
| assert len(result) == 3 # 9 items / 3 = 3 chunks | ||
| assert len(result[0]) == 3 | ||
| assert len(result[1]) == 3 | ||
| assert len(result[2]) == 3 | ||
|
|
||
| # Verify types are preserved | ||
| flattened = [item for chunk in result for item in chunk] | ||
| assert flattened == mixed_list | ||
|
|
||
| def test_chunk_edge_cases_comprehensive(self): | ||
| """Test comprehensive edge cases for chunking""" | ||
| # Test with chunk size equal to list length | ||
| data = [1, 2, 3, 4, 5] | ||
| result = chunk_list(data, 5) | ||
| assert result == [[1, 2, 3, 4, 5]] | ||
|
|
||
| # Test with chunk size larger than list | ||
| result = chunk_list(data, 10) | ||
| assert result == [[1, 2, 3, 4, 5]] | ||
|
|
||
| # Test with single item chunks | ||
| result = chunk_list(data, 1) | ||
| assert result == [[1], [2], [3], [4], [5]] | ||
|
|
||
| # Test with empty list | ||
| result = chunk_list([], 5) | ||
| assert result == [] | ||
|
|
||
|
|
||
| class TestFormatDurationAdvanced: | ||
| """Advanced duration formatting tests""" | ||
|
|
||
| def test_duration_precision_requirements(self): | ||
| """Test duration formatting meets precision requirements""" | ||
| test_cases = [ | ||
| (0.001, "0.00s"), # Very small duration | ||
| (0.999, "1.00s"), # Just under 1 second | ||
| (59.999, "60.00s"), # Just under 1 minute | ||
| (60.001, "1.0m"), # Just over 1 minute | ||
| (3599.999, "60.0m"), # Just under 1 hour | ||
| (3600.001, "1.0h"), # Just over 1 hour | ||
| ] | ||
|
|
||
| for duration, expected in test_cases: | ||
| result = format_duration(duration) | ||
| # Allow some variation in implementation | ||
| if expected.endswith("s"): | ||
| assert result.endswith("s") | ||
| assert abs(float(result[:-1]) - float(expected[:-1])) < 0.01 | ||
| elif expected.endswith("m"): | ||
| assert result.endswith("m") | ||
| assert abs(float(result[:-1]) - float(expected[:-1])) < 0.1 | ||
| elif expected.endswith("h"): | ||
| assert result.endswith("h") | ||
| assert abs(float(result[:-1]) - float(expected[:-1])) < 0.1 | ||
|
|
||
| def test_duration_format_consistency(self): | ||
| """Test duration format consistency across ranges""" | ||
| # Test seconds range | ||
| for i in range(60): | ||
| result = format_duration(i) | ||
| assert result.endswith("s") | ||
| assert float(result[:-1]) == i | ||
|
|
||
| # Test minutes range | ||
| for i in range(1, 60): | ||
| duration = i * 60 | ||
| result = format_duration(duration) | ||
| assert result.endswith("m") | ||
| assert float(result[:-1]) == i | ||
|
|
||
| # Test hours range | ||
| for i in range(1, 24): | ||
| duration = i * 3600 | ||
| result = format_duration(duration) | ||
| assert result.endswith("h") | ||
| assert float(result[:-1]) == i | ||
|
|
||
| def test_duration_extreme_values(self): | ||
| """Test duration formatting with extreme values""" | ||
| extreme_cases = [ | ||
| 1e-10, # Very tiny duration | ||
| 1e10, # Very large duration (over 300 years) | ||
| float('inf'), # Infinity | ||
| ] | ||
|
|
||
| for duration in extreme_cases: | ||
| try: | ||
| result = format_duration(duration) | ||
| assert isinstance(result, str) | ||
| assert len(result) > 0 | ||
| assert any(unit in result for unit in ["s", "m", "h"]) | ||
| except (ValueError, OverflowError): | ||
| # Acceptable to raise exception for extreme values | ||
| pass | ||
|
|
||
|
|
||
| class TestIntegrationAndWorkflows: | ||
| """Integration tests simulating real-world workflows""" | ||
|
|
||
| def test_configuration_management_workflow(self): | ||
| """Test complete configuration management workflow""" | ||
| # Simulate loading configuration from multiple sources | ||
| base_config = { | ||
| "app": {"name": "MyApp", "version": "1.0"}, | ||
| "database": {"host": "localhost", "port": 5432}, | ||
| "features": {"auth": True, "logging": {"level": "INFO"}} | ||
| } | ||
|
|
||
| user_config = { | ||
| "database": {"host": "prod.db.com", "ssl": True}, | ||
| "features": {"logging": {"level": "DEBUG", "file": "app.log"}} | ||
| } | ||
|
|
||
| env_config = { | ||
| "database": {"password": "secret"}, | ||
| "features": {"rate_limiting": True} | ||
| } | ||
|
|
||
| # Merge configurations | ||
| merged_config = merge_dicts(base_config, user_config) | ||
| final_config = merge_dicts(merged_config, env_config) | ||
|
|
||
| # Serialize for storage | ||
| config_json = safe_json_dumps(final_config) | ||
| assert config_json != "" | ||
|
|
||
| # Create hash for versioning | ||
| config_hash = generate_hash(config_json) | ||
| assert len(config_hash) == 64 | ||
|
|
||
| # Flatten for environment variable export | ||
| flat_config = flatten_dict(final_config) | ||
|
|
||
| # Verify expected merged values | ||
| assert final_config["database"]["host"] == "prod.db.com" | ||
| assert final_config["database"]["ssl"] is True | ||
| assert final_config["database"]["password"] == "secret" | ||
| assert final_config["features"]["logging"]["level"] == "DEBUG" | ||
| assert final_config["features"]["rate_limiting"] is True | ||
|
|
||
| # Verify flattened structure | ||
| assert "database.host" in flat_config | ||
| assert "features.logging.level" in flat_config | ||
| assert flat_config["features.logging.level"] == "DEBUG" | ||
|
|
||
| def test_data_processing_pipeline_with_retry(self): | ||
| """Test data processing pipeline with retry mechanisms""" | ||
| # Simulate processing data in chunks with potential failures | ||
| raw_data = [{"id": i, "value": f"item_{i}"} for i in range(100)] | ||
| chunks = chunk_list(raw_data, 10) | ||
|
|
||
| processed_results = [] | ||
| failure_count = [0] | ||
|
|
||
| def process_chunk_with_failure(chunk): | ||
| # Simulate intermittent failures | ||
| failure_count[0] += 1 | ||
| if failure_count[0] % 3 == 0: # Fail every 3rd attempt | ||
| raise ConnectionError("Simulated processing failure") | ||
|
|
||
| # Process chunk | ||
| processed = { | ||
| "chunk_id": generate_hash(safe_json_dumps(chunk))[:8], | ||
| "items": len(chunk), | ||
| "data": chunk | ||
| } | ||
| return processed | ||
|
|
||
| # Process each chunk with retry | ||
| for chunk in chunks: | ||
| try: | ||
| result = retry_with_backoff( | ||
| lambda: process_chunk_with_failure(chunk), | ||
| max_retries=3, | ||
| base_delay=0.1 | ||
| ) | ||
| processed_results.append(result) | ||
| except Exception as e: | ||
| # Log failure and continue (in real scenario) | ||
| print(f"Failed to process chunk after retries: {e}") | ||
|
|
||
| # Verify processing completed for most chunks | ||
| assert len(processed_results) >= 8 # At least 80% success rate | ||
|
|
||
| # Verify each result has expected structure | ||
| for result in processed_results: | ||
| assert "chunk_id" in result | ||
| assert len(result["chunk_id"]) == 8 | ||
| assert result["items"] == 10 | ||
| assert len(result["data"]) == 10 | ||
|
|
||
| def test_file_management_workflow(self): | ||
| """Test file management workflow with sanitization and directory creation""" | ||
| import tempfile | ||
|
|
||
| with tempfile.TemporaryDirectory() as temp_dir: | ||
| # Simulate organizing files from various sources | ||
| file_specs = [ | ||
| {"name": "report<2023>.pdf", "category": "reports", "subcategory": "annual"}, | ||
| {"name": "data|backup.csv", "category": "data", "subcategory": "backups"}, | ||
| {"name": "config?.yaml", "category": "config", "subcategory": "environments"}, | ||
| {"name": " .hidden_file ", "category": "misc", "subcategory": "temp"}, | ||
| ] | ||
|
|
||
| organized_files = [] | ||
|
|
||
| for spec in file_specs: | ||
| # Create directory structure | ||
| category_dir = ensure_directory_exists( | ||
| Path(temp_dir) / spec["category"] / spec["subcategory"] | ||
| ) | ||
|
|
||
| # Sanitize filename | ||
| safe_name = sanitize_filename(spec["name"]) | ||
|
|
||
| # Create file path | ||
| file_path = category_dir / safe_name | ||
|
|
||
| # Simulate file creation with metadata | ||
| file_metadata = { | ||
| "original_name": spec["name"], | ||
| "safe_name": safe_name, | ||
| "category": spec["category"], | ||
| "subcategory": spec["subcategory"], | ||
| "path": str(file_path), | ||
| "created": time.time() | ||
| } | ||
|
|
||
| # Write metadata as JSON | ||
| metadata_json = safe_json_dumps(file_metadata) | ||
| file_path.write_text(metadata_json) | ||
|
|
||
| organized_files.append(file_metadata) | ||
|
|
||
| # Verify all files were created successfully | ||
| assert len(organized_files) == 4 | ||
|
|
||
| for file_info in organized_files: | ||
| file_path = Path(file_info["path"]) | ||
| assert file_path.exists() | ||
| assert file_path.is_file() | ||
|
|
||
| # Verify content can be read back | ||
| content = file_path.read_text() | ||
| parsed_metadata = safe_json_parse(content) | ||
| assert parsed_metadata is not None | ||
| assert parsed_metadata["original_name"] == file_info["original_name"] | ||
|
|
||
|
|
||
| # Performance and stress testing | ||
| class TestPerformanceAndStress: | ||
| """Performance and stress tests for all utility functions""" | ||
|
|
||
| @pytest.mark.slow | ||
| def test_concurrent_mixed_operations(self): | ||
| """Test concurrent execution of mixed utility operations""" | ||
| import threading | ||
| import random | ||
|
|
||
| results = [] | ||
| errors = [] | ||
|
|
||
| def worker_thread(thread_id): | ||
| try: | ||
| # Perform random mix of operations | ||
| operations = [ | ||
| lambda: safe_json_dumps({"thread": thread_id, "data": list(range(100))}), | ||
| lambda: generate_hash(f"thread_{thread_id}_data"), | ||
| lambda: flatten_dict({"thread": thread_id, "nested": {"value": thread_id}}), | ||
| lambda: chunk_list(list(range(50)), 10), | ||
| lambda: format_duration(thread_id * 10.5), | ||
| ] | ||
|
|
||
| thread_results = [] | ||
| for _ in range(10): # 10 operations per thread | ||
| op = random.choice(operations) | ||
| result = op() | ||
| thread_results.append(result) | ||
|
|
||
| results.append((thread_id, thread_results)) | ||
|
|
||
| except Exception as e: | ||
| errors.append((thread_id, str(e))) | ||
|
|
||
| # Run 20 concurrent threads | ||
| threads = [] | ||
| for i in range(20): | ||
| thread = threading.Thread(target=worker_thread, args=(i,)) | ||
| threads.append(thread) | ||
| thread.start() | ||
|
|
||
| # Wait for completion | ||
| for thread in threads: | ||
| thread.join() | ||
|
|
||
| # Verify results | ||
| assert len(errors) == 0, f"Errors occurred: {errors}" | ||
| assert len(results) == 20 | ||
| assert all(len(thread_results) == 10 for _, thread_results in results) | ||
|
|
||
| @pytest.mark.slow | ||
| def test_memory_usage_large_operations(self): | ||
| """Test memory usage with large data operations""" | ||
| # Test with large data structures | ||
| large_nested_dict = {} | ||
| current_level = large_nested_dict | ||
|
|
||
| # Create 50 levels of nesting with data at each level | ||
| for i in range(50): | ||
| current_level[f"level_{i}"] = { | ||
| "data": [f"item_{j}" for j in range(100)], # 100 items per level | ||
| "metadata": {"level": i, "timestamp": time.time()}, | ||
| "next": {} | ||
| } | ||
| current_level = current_level[f"level_{i}"]["next"] | ||
|
|
||
| import time | ||
|
|
||
| # Test JSON serialization performance | ||
| start_time = time.time() | ||
| json_result = safe_json_dumps(large_nested_dict) | ||
| json_time = time.time() - start_time | ||
|
|
||
| # Test flattening performance | ||
| start_time = time.time() | ||
| flattened = flatten_dict(large_nested_dict) | ||
| flatten_time = time.time() - start_time | ||
|
|
||
| # Test hash generation performance | ||
| start_time = time.time() | ||
| hash_result = generate_hash(json_result) | ||
| hash_time = time.time() - start_time | ||
|
|
||
| # Verify operations completed | ||
| assert json_result != "" | ||
| assert len(flattened) > 100 # Should have many flattened keys | ||
| assert len(hash_result) == 64 | ||
|
|
||
| # Performance should be reasonable (adjust thresholds as needed) | ||
| assert json_time < 10.0, f"JSON serialization too slow: {json_time}s" | ||
| assert flatten_time < 10.0, f"Flattening too slow: {flatten_time}s" | ||
| assert hash_time < 5.0, f"Hashing too slow: {hash_time}s" | ||
|
|
||
|
|
||
| # Add marker for slow tests | ||
| pytest.mark.slow = pytest.mark.skipif( | ||
| not pytest.config.getoption("--run-slow", default=False), | ||
| reason="Slow tests skipped unless --run-slow option provided" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
🛠️ Refactor suggestion
Consider splitting this large test file
The file has 1451 lines, which exceeds typical readability limits. Consider splitting it into multiple focused test files:
test_json_helpers.py- JSON parsing/dumping teststest_file_helpers.py- File system operation teststest_data_helpers.py- Dictionary, list, and data manipulation teststest_retry_helpers.py- Retry mechanism teststest_integration.py- Integration and performance tests
Would you like me to help reorganize this into smaller, more focused test modules?
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 17-17: module level import not at top of file
(E402)
[warning] 33-33: blank line contains whitespace
(W293)
[warning] 39-39: blank line contains whitespace
(W293)
[warning] 45-45: blank line contains whitespace
(W293)
[warning] 51-51: blank line contains whitespace
(W293)
[warning] 57-57: blank line contains whitespace
(W293)
[warning] 62-62: blank line contains whitespace
(W293)
[warning] 71-71: blank line contains whitespace
(W293)
[warning] 78-78: blank line contains whitespace
(W293)
[warning] 85-85: blank line contains whitespace
(W293)
[warning] 91-91: blank line contains whitespace
(W293)
[warning] 99-99: blank line contains whitespace
(W293)
[warning] 110-110: blank line contains whitespace
(W293)
[warning] 118-118: blank line contains whitespace
(W293)
[warning] 125-125: blank line contains whitespace
(W293)
[warning] 132-132: blank line contains whitespace
(W293)
[warning] 138-138: blank line contains whitespace
(W293)
[warning] 148-148: blank line contains whitespace
(W293)
[warning] 153-153: blank line contains whitespace
(W293)
[warning] 156-156: blank line contains whitespace
(W293)
[warning] 160-160: blank line contains whitespace
(W293)
[warning] 166-166: blank line contains whitespace
(W293)
[warning] 170-170: blank line contains whitespace
(W293)
[warning] 175-175: blank line contains whitespace
(W293)
[warning] 178-178: blank line contains whitespace
(W293)
[warning] 186-186: blank line contains whitespace
(W293)
[warning] 189-189: blank line contains whitespace
(W293)
[warning] 198-198: blank line contains whitespace
(W293)
[warning] 204-204: blank line contains whitespace
(W293)
[warning] 211-211: blank line contains whitespace
(W293)
[warning] 228-228: blank line contains whitespace
(W293)
[warning] 234-234: blank line contains whitespace
(W293)
[warning] 243-243: blank line contains whitespace
(W293)
[warning] 249-249: blank line contains whitespace
(W293)
[warning] 253-253: blank line contains whitespace
(W293)
[warning] 259-259: blank line contains whitespace
(W293)
[warning] 263-263: blank line contains whitespace
(W293)
[warning] 269-269: blank line contains whitespace
(W293)
[warning] 273-273: blank line contains whitespace
(W293)
[warning] 279-279: blank line contains whitespace
(W293)
[warning] 287-287: blank line contains whitespace
(W293)
[warning] 293-293: blank line contains whitespace
(W293)
[warning] 299-299: blank line contains whitespace
(W293)
[warning] 305-305: blank line contains whitespace
(W293)
[warning] 310-310: blank line contains whitespace
(W293)
[warning] 316-316: blank line contains whitespace
(W293)
[warning] 326-326: blank line contains whitespace
(W293)
[warning] 334-334: blank line contains whitespace
(W293)
[warning] 342-342: blank line contains whitespace
(W293)
[warning] 354-354: blank line contains whitespace
(W293)
[warning] 359-359: blank line contains whitespace
(W293)
[warning] 366-366: blank line contains whitespace
(W293)
[warning] 368-368: blank line contains whitespace
(W293)
[warning] 375-375: blank line contains whitespace
(W293)
[warning] 382-382: blank line contains whitespace
(W293)
[warning] 389-389: blank line contains whitespace
(W293)
[warning] 396-396: blank line contains whitespace
(W293)
[warning] 403-403: blank line contains whitespace
(W293)
[warning] 408-408: blank line contains whitespace
(W293)
[warning] 419-419: blank line contains whitespace
(W293)
[warning] 425-425: blank line contains whitespace
(W293)
[warning] 431-431: blank line contains whitespace
(W293)
[warning] 437-437: blank line contains whitespace
(W293)
[warning] 444-444: blank line contains whitespace
(W293)
[warning] 449-449: blank line contains whitespace
(W293)
[warning] 456-456: blank line contains whitespace
(W293)
[warning] 462-462: blank line contains whitespace
(W293)
[warning] 465-465: blank line contains whitespace
(W293)
[warning] 470-470: blank line contains whitespace
(W293)
[warning] 476-476: blank line contains whitespace
(W293)
[warning] 480-480: blank line contains whitespace
(W293)
[warning] 484-484: blank line contains whitespace
(W293)
[warning] 487-487: blank line contains whitespace
(W293)
[warning] 498-498: blank line contains whitespace
(W293)
[warning] 501-501: blank line contains whitespace
(W293)
[warning] 504-504: blank line contains whitespace
(W293)
[warning] 507-507: blank line contains whitespace
(W293)
[warning] 511-511: blank line contains whitespace
(W293)
[error] 521-521: expected 2 blank lines, found 1
(E302)
[warning] 523-523: blank line contains whitespace
(W293)
[warning] 530-530: blank line contains whitespace
(W293)
[warning] 533-533: blank line contains whitespace
(W293)
[warning] 540-540: blank line contains whitespace
(W293)
[warning] 549-549: blank line contains whitespace
(W293)
[warning] 554-554: blank line contains whitespace
(W293)
[error] 559-559: at least two spaces before inline comment
(E261)
[error] 560-560: at least two spaces before inline comment
(E261)
[warning] 563-563: blank line contains whitespace
(W293)
[warning] 568-568: blank line contains whitespace
(W293)
[warning] 586-586: blank line contains whitespace
(W293)
[warning] 593-593: blank line contains whitespace
(W293)
[warning] 596-596: blank line contains whitespace
(W293)
[warning] 602-602: blank line contains whitespace
(W293)
[warning] 605-605: blank line contains whitespace
(W293)
[warning] 608-608: blank line contains whitespace
(W293)
[warning] 612-612: blank line contains whitespace
(W293)
[warning] 617-617: blank line contains whitespace
(W293)
[warning] 626-626: blank line contains whitespace
(W293)
[warning] 629-629: blank line contains whitespace
(W293)
[warning] 640-640: blank line contains whitespace
(W293)
[warning] 645-645: blank line contains whitespace
(W293)
[warning] 652-652: blank line contains whitespace
(W293)
[warning] 657-657: blank line contains whitespace
(W293)
[warning] 663-663: blank line contains whitespace
(W293)
[warning] 667-667: blank line contains whitespace
(W293)
[warning] 672-672: blank line contains whitespace
(W293)
[warning] 676-676: blank line contains whitespace
(W293)
[warning] 682-682: blank line contains whitespace
(W293)
[warning] 685-685: blank line contains whitespace
(W293)
[warning] 690-690: blank line contains whitespace
(W293)
[warning] 694-694: blank line contains whitespace
(W293)
[warning] 699-699: blank line contains whitespace
(W293)
[warning] 708-708: blank line contains whitespace
(W293)
[warning] 713-713: trailing whitespace
(W291)
[warning] 716-716: blank line contains whitespace
(W293)
[warning] 718-718: blank line contains whitespace
(W293)
[warning] 725-725: blank line contains whitespace
(W293)
[warning] 729-729: blank line contains whitespace
(W293)
[warning] 734-734: blank line contains whitespace
(W293)
[warning] 740-740: blank line contains whitespace
(W293)
[warning] 743-743: blank line contains whitespace
(W293)
[warning] 748-748: blank line contains whitespace
(W293)
[warning] 753-753: blank line contains whitespace
(W293)
[warning] 763-763: blank line contains whitespace
(W293)
[warning] 766-766: blank line contains whitespace
(W293)
[warning] 770-770: blank line contains whitespace
(W293)
[error] 771-771: local variable 'start_time' is assigned to but never used
(F841)
[warning] 773-773: blank line contains whitespace
(W293)
[warning] 779-779: blank line contains whitespace
(W293)
[warning] 781-781: blank line contains whitespace
(W293)
[warning] 784-784: blank line contains whitespace
(W293)
[warning] 794-794: blank line contains whitespace
(W293)
[warning] 818-818: blank line contains whitespace
(W293)
[warning] 820-820: blank line contains whitespace
(W293)
[warning] 831-831: blank line contains whitespace
(W293)
[warning] 834-834: blank line contains whitespace
(W293)
[error] 839-839: dictionary key 1 repeated with different values
(F601)
[error] 841-841: dictionary key 1 repeated with different values
(F601)
[warning] 845-845: blank line contains whitespace
(W293)
[warning] 847-847: blank line contains whitespace
(W293)
[warning] 850-850: trailing whitespace
(W291)
[warning] 854-854: blank line contains whitespace
(W293)
[warning] 856-856: blank line contains whitespace
(W293)
[warning] 860-860: blank line contains whitespace
(W293)
[warning] 864-864: blank line contains whitespace
(W293)
[warning] 874-874: blank line contains whitespace
(W293)
[warning] 887-887: blank line contains whitespace
(W293)
[warning] 892-892: blank line contains whitespace
(W293)
[warning] 895-895: blank line contains whitespace
(W293)
[warning] 902-902: blank line contains whitespace
(W293)
[warning] 907-907: blank line contains whitespace
(W293)
[warning] 912-912: blank line contains whitespace
(W293)
[warning] 919-919: blank line contains whitespace
(W293)
[warning] 926-926: blank line contains whitespace
(W293)
[warning] 930-930: blank line contains whitespace
(W293)
[warning] 936-936: blank line contains whitespace
(W293)
[error] 949-949: at least two spaces before inline comment
(E261)
[warning] 951-951: blank line contains whitespace
(W293)
[warning] 960-960: blank line contains whitespace
(W293)
[warning] 969-969: blank line contains whitespace
(W293)
[warning] 980-980: blank line contains whitespace
(W293)
[warning] 990-990: trailing whitespace
(W291)
[warning] 993-993: blank line contains whitespace
(W293)
[warning] 995-995: blank line contains whitespace
(W293)
[warning] 1000-1000: blank line contains whitespace
(W293)
[warning] 1005-1005: blank line contains whitespace
(W293)
[warning] 1007-1007: blank line contains whitespace
(W293)
[warning] 1011-1011: blank line contains whitespace
(W293)
[warning] 1026-1026: blank line contains whitespace
(W293)
[warning] 1028-1028: blank line contains whitespace
(W293)
[warning] 1033-1033: blank line contains whitespace
(W293)
[warning] 1038-1038: blank line contains whitespace
(W293)
[warning] 1042-1042: blank line contains whitespace
(W293)
[warning] 1044-1044: blank line contains whitespace
(W293)
[warning] 1048-1048: blank line contains whitespace
(W293)
[warning] 1057-1057: blank line contains whitespace
(W293)
[warning] 1062-1062: blank line contains whitespace
(W293)
[warning] 1067-1067: blank line contains whitespace
(W293)
[warning] 1070-1070: blank line contains whitespace
(W293)
[warning] 1075-1075: blank line contains whitespace
(W293)
[warning] 1080-1080: blank line contains whitespace
(W293)
[warning] 1082-1082: blank line contains whitespace
(W293)
[warning] 1086-1086: blank line contains whitespace
(W293)
[warning] 1090-1090: blank line contains whitespace
(W293)
[warning] 1094-1094: trailing whitespace
(W291)
[warning] 1095-1095: trailing whitespace
(W291)
[warning] 1098-1098: blank line contains whitespace
(W293)
[warning] 1100-1100: blank line contains whitespace
(W293)
[warning] 1106-1106: blank line contains whitespace
(W293)
[warning] 1110-1110: blank line contains whitespace
(W293)
[warning] 1117-1117: blank line contains whitespace
(W293)
[warning] 1121-1121: blank line contains whitespace
(W293)
[warning] 1125-1125: blank line contains whitespace
(W293)
[warning] 1133-1133: blank line contains whitespace
(W293)
[warning] 1144-1144: blank line contains whitespace
(W293)
[warning] 1157-1157: blank line contains whitespace
(W293)
[warning] 1165-1165: blank line contains whitespace
(W293)
[warning] 1172-1172: blank line contains whitespace
(W293)
[warning] 1179-1179: blank line contains whitespace
(W293)
[warning] 1187-1187: blank line contains whitespace
(W293)
[warning] 1201-1201: blank line contains whitespace
(W293)
[warning] 1210-1210: blank line contains whitespace
(W293)
[warning] 1215-1215: blank line contains whitespace
(W293)
[warning] 1220-1220: blank line contains whitespace
(W293)
[warning] 1224-1224: blank line contains whitespace
(W293)
[warning] 1228-1228: blank line contains whitespace
(W293)
[warning] 1232-1232: blank line contains whitespace
(W293)
[warning] 1235-1235: blank line contains whitespace
(W293)
[warning] 1242-1242: blank line contains whitespace
(W293)
[warning] 1247-1247: blank line contains whitespace
(W293)
[warning] 1253-1253: blank line contains whitespace
(W293)
[warning] 1256-1256: blank line contains whitespace
(W293)
[warning] 1262-1262: blank line contains whitespace
(W293)
[warning] 1270-1270: blank line contains whitespace
(W293)
[warning] 1283-1283: blank line contains whitespace
(W293)
[warning] 1286-1286: blank line contains whitespace
(W293)
[warning] 1293-1293: blank line contains whitespace
(W293)
[warning] 1297-1297: blank line contains whitespace
(W293)
[warning] 1306-1306: blank line contains whitespace
(W293)
[warning] 1308-1308: blank line contains whitespace
(W293)
[warning] 1314-1314: blank line contains whitespace
(W293)
[warning] 1317-1317: blank line contains whitespace
(W293)
[warning] 1320-1320: blank line contains whitespace
(W293)
[warning] 1330-1330: blank line contains whitespace
(W293)
[warning] 1334-1334: blank line contains whitespace
(W293)
[warning] 1336-1336: blank line contains whitespace
(W293)
[warning] 1339-1339: blank line contains whitespace
(W293)
[warning] 1344-1344: blank line contains whitespace
(W293)
[warning] 1355-1355: blank line contains whitespace
(W293)
[warning] 1361-1361: blank line contains whitespace
(W293)
[warning] 1364-1364: blank line contains whitespace
(W293)
[warning] 1375-1375: blank line contains whitespace
(W293)
[warning] 1381-1381: blank line contains whitespace
(W293)
[warning] 1383-1383: blank line contains whitespace
(W293)
[warning] 1386-1386: blank line contains whitespace
(W293)
[warning] 1393-1393: blank line contains whitespace
(W293)
[warning] 1397-1397: blank line contains whitespace
(W293)
[warning] 1402-1402: blank line contains whitespace
(W293)
[warning] 1409-1409: blank line contains whitespace
(W293)
[warning] 1418-1418: blank line contains whitespace
(W293)
[warning] 1420-1420: blank line contains whitespace
(W293)
[warning] 1425-1425: blank line contains whitespace
(W293)
[warning] 1430-1430: blank line contains whitespace
(W293)
[warning] 1435-1435: blank line contains whitespace
(W293)
[warning] 1440-1440: blank line contains whitespace
(W293)
🪛 Ruff (0.11.9)
1-1: Shebang is present but file is not executable
(EXE001)
27-27: Trailing comma missing
Add trailing comma
(COM812)
34-34: Missing return type annotation for public function test_valid_json_string
Add return type annotation: None
(ANN201)
40-40: Missing return type annotation for public function test_valid_json_array
Add return type annotation: None
(ANN201)
46-46: Missing return type annotation for public function test_invalid_json_string
Add return type annotation: None
(ANN201)
52-52: Missing return type annotation for public function test_completely_malformed_json
Add return type annotation: None
(ANN201)
58-58: Missing return type annotation for public function test_none_input
Add return type annotation: None
(ANN201)
63-63: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
72-72: Missing return type annotation for public function test_valid_dict
Add return type annotation: None
(ANN201)
79-79: Missing return type annotation for public function test_valid_list
Add return type annotation: None
(ANN201)
86-86: Missing return type annotation for public function test_custom_indent
Add return type annotation: None
(ANN201)
92-92: Missing return type annotation for public function test_complex_object_with_datetime
Add return type annotation: None
(ANN201)
95-95: datetime.datetime.now() called without a tz argument
(DTZ005)
100-100: Missing return type annotation for public function test_circular_reference
Add return type annotation: None
(ANN201)
111-111: Missing return type annotation for public function test_string_input
Add return type annotation: None
(ANN201)
119-119: Missing return type annotation for public function test_bytes_input
Add return type annotation: None
(ANN201)
126-126: Missing return type annotation for public function test_consistent_hashing
Add return type annotation: None
(ANN201)
133-133: Missing return type annotation for public function test_different_inputs_different_hashes
Add return type annotation: None
(ANN201)
139-139: Missing return type annotation for public function test_empty_string
Add return type annotation: None
(ANN201)
149-149: Missing return type annotation for public function test_successful_function
Add return type annotation: None
(ANN201)
151-151: Missing return type annotation for private function success_func
Add return type annotation: str
(ANN202)
157-157: Missing return type annotation for public function test_function_succeeds_after_retries
Add return type annotation: None
(ANN201)
161-161: Missing return type annotation for private function eventually_succeeds
Add return type annotation: str
(ANN202)
164-164: Avoid specifying long messages outside the exception class
(TRY003)
171-171: Missing return type annotation for public function test_function_fails_all_retries
Add return type annotation: None
(ANN201)
173-173: Missing return type annotation for private function always_fails
Add return type annotation: NoReturn
(ANN202)
174-174: Avoid specifying long messages outside the exception class
(TRY003)
180-180: Missing return type annotation for public function test_backoff_timing
Add return type annotation: None
(ANN201)
180-180: Missing type annotation for function argument mock_sleep
(ANN001)
182-182: Missing return type annotation for private function fails_twice
Add return type annotation: str
(ANN202)
199-199: Missing return type annotation for public function test_simple_dict
Add return type annotation: None
(ANN201)
205-205: Missing return type annotation for public function test_nested_dict
Add return type annotation: None
(ANN201)
212-212: Missing return type annotation for public function test_mixed_nested_dict
Add return type annotation: None
(ANN201)
217-217: Trailing comma missing
Add trailing comma
(COM812)
225-225: Trailing comma missing
Add trailing comma
(COM812)
229-229: Missing return type annotation for public function test_with_prefix
Add return type annotation: None
(ANN201)
235-235: Missing return type annotation for public function test_empty_dict
Add return type annotation: None
(ANN201)
244-244: Missing return type annotation for public function test_create_new_directory
Add return type annotation: None
(ANN201)
254-254: Missing return type annotation for public function test_existing_directory
Add return type annotation: None
(ANN201)
264-264: Missing return type annotation for public function test_nested_directory_creation
Add return type annotation: None
(ANN201)
274-274: Missing return type annotation for public function test_string_path_input
Add return type annotation: None
(ANN201)
288-288: Missing return type annotation for public function test_valid_filename
Add return type annotation: None
(ANN201)
294-294: Missing return type annotation for public function test_invalid_characters
Add return type annotation: None
(ANN201)
300-300: Missing return type annotation for public function test_leading_trailing_spaces_dots
Add return type annotation: None
(ANN201)
306-306: Missing return type annotation for public function test_empty_filename
Add return type annotation: None
(ANN201)
311-311: Missing return type annotation for public function test_only_invalid_characters
Add return type annotation: None
(ANN201)
317-317: Missing return type annotation for public function test_spaces_and_dots_only
Add return type annotation: None
(ANN201)
327-327: Missing return type annotation for public function test_simple_merge
Add return type annotation: None
(ANN201)
335-335: Missing return type annotation for public function test_overlapping_keys
Add return type annotation: None
(ANN201)
343-343: Missing return type annotation for public function test_nested_dict_merge
Add return type annotation: None
(ANN201)
351-351: Trailing comma missing
Add trailing comma
(COM812)
355-355: Missing return type annotation for public function test_empty_dicts
Add return type annotation: None
(ANN201)
360-360: Missing return type annotation for public function test_original_dicts_unchanged
Add return type annotation: None
(ANN201)
376-376: Missing return type annotation for public function test_even_chunks
Add return type annotation: None
(ANN201)
383-383: Missing return type annotation for public function test_uneven_chunks
Add return type annotation: None
(ANN201)
390-390: Missing return type annotation for public function test_chunk_size_larger_than_list
Add return type annotation: None
(ANN201)
397-397: Missing return type annotation for public function test_chunk_size_one
Add return type annotation: None
(ANN201)
404-404: Missing return type annotation for public function test_empty_list
Add return type annotation: None
(ANN201)
409-409: Missing return type annotation for public function test_mixed_data_types
Add return type annotation: None
(ANN201)
420-420: Missing return type annotation for public function test_seconds_format
Add return type annotation: None
(ANN201)
426-426: Missing return type annotation for public function test_minutes_format
Add return type annotation: None
(ANN201)
432-432: Missing return type annotation for public function test_hours_format
Add return type annotation: None
(ANN201)
438-438: Missing return type annotation for public function test_edge_cases
Add return type annotation: None
(ANN201)
445-445: Missing return type annotation for public function test_large_durations
Add return type annotation: None
(ANN201)
457-457: Missing return type annotation for public function test_json_and_hash_integration
Add return type annotation: None
(ANN201)
471-471: Missing return type annotation for public function test_file_operations_integration
Add return type annotation: None
(ANN201)
488-488: Missing return type annotation for public function test_data_processing_pipeline
Add return type annotation: None
(ANN201)
494-494: Trailing comma missing
Add trailing comma
(COM812)
496-496: Trailing comma missing
Add trailing comma
(COM812)
524-524: Missing return type annotation for public function test_deeply_nested_json_performance
Add return type annotation: None
(ANN201)
528-528: Loop control variable i not used within loop body
Rename unused i to _i
(B007)
536-536: Loop control variable i not used within loop body
Rename unused i to _i
(B007)
541-541: Missing return type annotation for public function test_unicode_and_escape_sequences
Add return type annotation: None
(ANN201)
555-555: Missing return type annotation for public function test_json_with_large_numbers
Add return type annotation: None
(ANN201)
578-578: Missing return type annotation for public function test_malformed_json_variations
Add return type annotation: None
(ANN201)
578-578: Missing type annotation for function argument malformed_json
(ANN001)
587-587: Missing return type annotation for public function test_circular_reference_detection
Add return type annotation: None
(ANN201)
597-597: Missing return type annotation for public function test_custom_objects_with_str_method
Add return type annotation: None
(ANN201)
600-600: Missing return type annotation for special method __init__
Add return type annotation: None
(ANN204)
600-600: Missing type annotation for function argument value
(ANN001)
603-603: Missing return type annotation for special method __str__
Add return type annotation: str
(ANN204)
613-613: Missing return type annotation for public function test_mixed_data_types_edge_cases
Add return type annotation: None
(ANN201)
630-630: Missing return type annotation for public function test_performance_large_object
Add return type annotation: None
(ANN201)
636-636: Trailing comma missing
Add trailing comma
(COM812)
653-653: Missing return type annotation for public function test_hash_distribution
Add return type annotation: None
(ANN201)
668-668: Missing return type annotation for public function test_avalanche_effect
Add return type annotation: None
(ANN201)
686-686: Missing return type annotation for public function test_hash_consistency_across_runs
Add return type annotation: None
(ANN201)
695-695: Missing return type annotation for public function test_empty_and_whitespace_inputs
Add return type annotation: None
(ANN201)
709-709: Missing return type annotation for public function test_retry_with_different_exception_types
Add return type annotation: None
(ANN201)
719-719: Missing return type annotation for private function failing_function
Add return type annotation: str
(ANN202)
731-731: Missing return type annotation for public function test_exponential_backoff_progression
Add return type annotation: None
(ANN201)
731-731: Missing type annotation for function argument mock_sleep
(ANN001)
735-735: Missing return type annotation for private function always_fails
Add return type annotation: str
(ANN202)
738-738: Avoid specifying long messages outside the exception class
(TRY003)
749-749: Missing return type annotation for public function test_retry_with_return_values
Add return type annotation: None
(ANN201)
754-754: Missing return type annotation for private function function_with_varying_returns
(ANN202)
759-759: Avoid specifying long messages outside the exception class
(TRY003)
767-767: Missing return type annotation for public function test_retry_timeout_simulation
Add return type annotation: None
(ANN201)
771-771: Local variable start_time is assigned to but never used
Remove assignment to unused variable start_time
(F841)
774-774: Missing return type annotation for private function time_tracking_function
Add return type annotation: str
(ANN202)
777-777: Avoid specifying long messages outside the exception class
(TRY003)
795-795: Missing return type annotation for public function test_flatten_with_complex_nested_structures
Add return type annotation: None
(ANN201)
802-802: Trailing comma missing
Add trailing comma
(COM812)
807-807: Trailing comma missing
Add trailing comma
(COM812)
808-808: Trailing comma missing
Add trailing comma
(COM812)
814-814: Trailing comma missing
Add trailing comma
(COM812)
815-815: Trailing comma missing
Add trailing comma
(COM812)
816-816: Trailing comma missing
Add trailing comma
(COM812)
829-829: Trailing comma missing
Add trailing comma
(COM812)
835-835: Missing return type annotation for public function test_flatten_with_numeric_and_boolean_keys
Add return type annotation: None
(ANN201)
841-841: Dictionary key literal True repeated (True hashes to the same value as 1)
(F601)
842-842: Trailing comma missing
Add trailing comma
(COM812)
843-843: Trailing comma missing
Add trailing comma
(COM812)
852-852: Trailing comma missing
Add trailing comma
(COM812)
857-857: Missing return type annotation for public function test_flatten_with_custom_separator
Add return type annotation: None
(ANN201)
875-875: Missing return type annotation for public function test_flatten_performance_large_dict
Add return type annotation: None
(ANN201)
903-903: Missing return type annotation for public function test_ensure_directory_concurrent_creation
Add return type annotation: None
(ANN201)
913-913: Missing return type annotation for private function create_directory
Add return type annotation: None
(ANN202)
913-913: Missing type annotation for function argument thread_id
(ANN001)
917-917: Do not catch blind exception: Exception
(BLE001)
937-937: Missing return type annotation for public function test_sanitize_filename_edge_cases
Add return type annotation: None
(ANN201)
961-961: Missing return type annotation for public function test_sanitize_filename_preserves_extensions
Add return type annotation: None
(ANN201)
981-981: Missing return type annotation for public function test_merge_with_conflicting_types
Add return type annotation: None
(ANN201)
986-986: Trailing comma missing
Add trailing comma
(COM812)
991-991: Trailing comma missing
Add trailing comma
(COM812)
1001-1001: Missing return type annotation for public function test_merge_very_deep_nesting
Add return type annotation: None
(ANN201)
1012-1012: Missing return type annotation for public function test_merge_with_none_and_empty_values
Add return type annotation: None
(ANN201)
1018-1018: Trailing comma missing
Add trailing comma
(COM812)
1024-1024: Trailing comma missing
Add trailing comma
(COM812)
1034-1034: Missing return type annotation for public function test_merge_preserves_original_dicts
Add return type annotation: None
(ANN201)
1058-1058: Missing return type annotation for public function test_chunk_with_large_lists
Add return type annotation: None
(ANN201)
1076-1076: Missing return type annotation for public function test_chunk_memory_efficiency
Add return type annotation: None
(ANN201)
1091-1091: Missing return type annotation for public function test_chunk_with_various_data_types
Add return type annotation: None
(ANN201)
1096-1096: Unnecessary list literal (rewrite as a set literal)
Rewrite as a set literal
(C405)
1096-1096: Trailing comma missing
Add trailing comma
(COM812)
1111-1111: Missing return type annotation for public function test_chunk_edge_cases_comprehensive
Add return type annotation: None
(ANN201)
1134-1134: Missing return type annotation for public function test_duration_precision_requirements
Add return type annotation: None
(ANN201)
1158-1158: Missing return type annotation for public function test_duration_format_consistency
Add return type annotation: None
(ANN201)
1180-1180: Missing return type annotation for public function test_duration_extreme_values
Add return type annotation: None
(ANN201)
1202-1202: Missing return type annotation for public function test_configuration_management_workflow
Add return type annotation: None
(ANN201)
1208-1208: Trailing comma missing
Add trailing comma
(COM812)
1213-1213: Trailing comma missing
Add trailing comma
(COM812)
1218-1218: Trailing comma missing
Add trailing comma
(COM812)
1239-1239: Possible hardcoded password assigned to: "password"
(S105)
1248-1248: Missing return type annotation for public function test_data_processing_pipeline_with_retry
Add return type annotation: None
(ANN201)
1257-1257: Missing return type annotation for private function process_chunk_with_failure
(ANN202)
1257-1257: Missing type annotation for function argument chunk
(ANN001)
1261-1261: Avoid specifying long messages outside the exception class
(TRY003)
1267-1267: Trailing comma missing
Add trailing comma
(COM812)
1269-1269: Unnecessary assignment to processed before return statement
Remove unnecessary assignment
(RET504)
1275-1275: Function definition does not bind loop variable chunk
(B023)
1277-1277: Trailing comma missing
Add trailing comma
(COM812)
1280-1280: Do not catch blind exception: Exception
(BLE001)
1294-1294: Missing return type annotation for public function test_file_management_workflow
Add return type annotation: None
(ANN201)
1312-1312: Trailing comma missing
Add trailing comma
(COM812)
1328-1328: Trailing comma missing
Add trailing comma
(COM812)
1357-1357: Missing return type annotation for public function test_concurrent_mixed_operations
Add return type annotation: None
(ANN201)
1365-1365: Missing return type annotation for private function worker_thread
Add return type annotation: None
(ANN202)
1365-1365: Missing type annotation for function argument thread_id
(ANN001)
1378-1378: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
1384-1384: Do not catch blind exception: Exception
(BLE001)
1404-1404: Missing return type annotation for public function test_memory_usage_large_operations
Add return type annotation: None
(ANN201)
1414-1414: Local variable time referenced before assignment
(F823)
1415-1415: Trailing comma missing
Add trailing comma
(COM812)
1450-1450: Trailing comma missing
Add trailing comma
(COM812)
🪛 Pylint (3.3.7)
[convention] 33-33: Trailing whitespace
(C0303)
[convention] 39-39: Trailing whitespace
(C0303)
[convention] 45-45: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 71-71: Trailing whitespace
(C0303)
[convention] 78-78: Trailing whitespace
(C0303)
[convention] 85-85: Trailing whitespace
(C0303)
[convention] 91-91: Trailing whitespace
(C0303)
[convention] 99-99: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 118-118: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[convention] 132-132: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 148-148: Trailing whitespace
(C0303)
[convention] 153-153: Trailing whitespace
(C0303)
[convention] 156-156: Trailing whitespace
(C0303)
[convention] 160-160: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 170-170: Trailing whitespace
(C0303)
[convention] 175-175: Trailing whitespace
(C0303)
[convention] 178-178: Trailing whitespace
(C0303)
[convention] 186-186: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 204-204: Trailing whitespace
(C0303)
[convention] 211-211: Trailing whitespace
(C0303)
[convention] 228-228: Trailing whitespace
(C0303)
[convention] 234-234: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 249-249: Trailing whitespace
(C0303)
[convention] 253-253: Trailing whitespace
(C0303)
[convention] 259-259: Trailing whitespace
(C0303)
[convention] 263-263: Trailing whitespace
(C0303)
[convention] 269-269: Trailing whitespace
(C0303)
[convention] 273-273: Trailing whitespace
(C0303)
[convention] 279-279: Trailing whitespace
(C0303)
[convention] 287-287: Trailing whitespace
(C0303)
[convention] 293-293: Trailing whitespace
(C0303)
[convention] 299-299: Trailing whitespace
(C0303)
[convention] 305-305: Trailing whitespace
(C0303)
[convention] 310-310: Trailing whitespace
(C0303)
[convention] 316-316: Trailing whitespace
(C0303)
[convention] 326-326: Trailing whitespace
(C0303)
[convention] 334-334: Trailing whitespace
(C0303)
[convention] 342-342: Trailing whitespace
(C0303)
[convention] 354-354: Trailing whitespace
(C0303)
[convention] 359-359: Trailing whitespace
(C0303)
[convention] 366-366: Trailing whitespace
(C0303)
[convention] 368-368: Trailing whitespace
(C0303)
[convention] 375-375: Trailing whitespace
(C0303)
[convention] 382-382: Trailing whitespace
(C0303)
[convention] 389-389: Trailing whitespace
(C0303)
[convention] 396-396: Trailing whitespace
(C0303)
[convention] 403-403: Trailing whitespace
(C0303)
[convention] 408-408: Trailing whitespace
(C0303)
[convention] 419-419: Trailing whitespace
(C0303)
[convention] 425-425: Trailing whitespace
(C0303)
[convention] 431-431: Trailing whitespace
(C0303)
[convention] 437-437: Trailing whitespace
(C0303)
[convention] 444-444: Trailing whitespace
(C0303)
[convention] 449-449: Trailing whitespace
(C0303)
[convention] 456-456: Trailing whitespace
(C0303)
[convention] 462-462: Trailing whitespace
(C0303)
[convention] 465-465: Trailing whitespace
(C0303)
[convention] 470-470: Trailing whitespace
(C0303)
[convention] 476-476: Trailing whitespace
(C0303)
[convention] 480-480: Trailing whitespace
(C0303)
[convention] 484-484: Trailing whitespace
(C0303)
[convention] 487-487: Trailing whitespace
(C0303)
[convention] 498-498: Trailing whitespace
(C0303)
[convention] 501-501: Trailing whitespace
(C0303)
[convention] 504-504: Trailing whitespace
(C0303)
[convention] 507-507: Trailing whitespace
(C0303)
[convention] 511-511: Trailing whitespace
(C0303)
[convention] 523-523: Trailing whitespace
(C0303)
[convention] 530-530: Trailing whitespace
(C0303)
[convention] 533-533: Trailing whitespace
(C0303)
[convention] 540-540: Trailing whitespace
(C0303)
[convention] 549-549: Trailing whitespace
(C0303)
[convention] 554-554: Trailing whitespace
(C0303)
[convention] 563-563: Trailing whitespace
(C0303)
[convention] 568-568: Trailing whitespace
(C0303)
[convention] 586-586: Trailing whitespace
(C0303)
[convention] 593-593: Trailing whitespace
(C0303)
[convention] 596-596: Trailing whitespace
(C0303)
[convention] 602-602: Trailing whitespace
(C0303)
[convention] 605-605: Trailing whitespace
(C0303)
[convention] 608-608: Trailing whitespace
(C0303)
[convention] 612-612: Trailing whitespace
(C0303)
[convention] 617-617: Trailing whitespace
(C0303)
[convention] 626-626: Trailing whitespace
(C0303)
[convention] 629-629: Trailing whitespace
(C0303)
[convention] 640-640: Trailing whitespace
(C0303)
[convention] 645-645: Trailing whitespace
(C0303)
[convention] 652-652: Trailing whitespace
(C0303)
[convention] 657-657: Trailing whitespace
(C0303)
[convention] 663-663: Trailing whitespace
(C0303)
[convention] 667-667: Trailing whitespace
(C0303)
[convention] 672-672: Trailing whitespace
(C0303)
[convention] 676-676: Trailing whitespace
(C0303)
[convention] 682-682: Trailing whitespace
(C0303)
[convention] 685-685: Trailing whitespace
(C0303)
[convention] 690-690: Trailing whitespace
(C0303)
[convention] 694-694: Trailing whitespace
(C0303)
[convention] 699-699: Trailing whitespace
(C0303)
[convention] 708-708: Trailing whitespace
(C0303)
[convention] 713-713: Trailing whitespace
(C0303)
[convention] 716-716: Trailing whitespace
(C0303)
[convention] 718-718: Trailing whitespace
(C0303)
[convention] 725-725: Trailing whitespace
(C0303)
[convention] 729-729: Trailing whitespace
(C0303)
[convention] 734-734: Trailing whitespace
(C0303)
[convention] 740-740: Trailing whitespace
(C0303)
[convention] 743-743: Trailing whitespace
(C0303)
[convention] 748-748: Trailing whitespace
(C0303)
[convention] 753-753: Trailing whitespace
(C0303)
[convention] 763-763: Trailing whitespace
(C0303)
[convention] 766-766: Trailing whitespace
(C0303)
[convention] 770-770: Trailing whitespace
(C0303)
[convention] 773-773: Trailing whitespace
(C0303)
[convention] 779-779: Trailing whitespace
(C0303)
[convention] 781-781: Trailing whitespace
(C0303)
[convention] 784-784: Trailing whitespace
(C0303)
[convention] 794-794: Trailing whitespace
(C0303)
[convention] 818-818: Trailing whitespace
(C0303)
[convention] 820-820: Trailing whitespace
(C0303)
[convention] 831-831: Trailing whitespace
(C0303)
[convention] 834-834: Trailing whitespace
(C0303)
[convention] 845-845: Trailing whitespace
(C0303)
[convention] 847-847: Trailing whitespace
(C0303)
[convention] 854-854: Trailing whitespace
(C0303)
[convention] 856-856: Trailing whitespace
(C0303)
[convention] 860-860: Trailing whitespace
(C0303)
[convention] 864-864: Trailing whitespace
(C0303)
[convention] 874-874: Trailing whitespace
(C0303)
[convention] 887-887: Trailing whitespace
(C0303)
[convention] 892-892: Trailing whitespace
(C0303)
[convention] 895-895: Trailing whitespace
(C0303)
[convention] 902-902: Trailing whitespace
(C0303)
[convention] 907-907: Trailing whitespace
(C0303)
[convention] 912-912: Trailing whitespace
(C0303)
[convention] 919-919: Trailing whitespace
(C0303)
[convention] 926-926: Trailing whitespace
(C0303)
[convention] 930-930: Trailing whitespace
(C0303)
[convention] 936-936: Trailing whitespace
(C0303)
[convention] 951-951: Trailing whitespace
(C0303)
[convention] 960-960: Trailing whitespace
(C0303)
[convention] 969-969: Trailing whitespace
(C0303)
[convention] 980-980: Trailing whitespace
(C0303)
[convention] 993-993: Trailing whitespace
(C0303)
[convention] 995-995: Trailing whitespace
(C0303)
[convention] 1000-1000: Trailing whitespace
(C0303)
[convention] 1005-1005: Trailing whitespace
(C0303)
[convention] 1007-1007: Trailing whitespace
(C0303)
[convention] 1011-1011: Trailing whitespace
(C0303)
[convention] 1026-1026: Trailing whitespace
(C0303)
[convention] 1028-1028: Trailing whitespace
(C0303)
[convention] 1033-1033: Trailing whitespace
(C0303)
[convention] 1038-1038: Trailing whitespace
(C0303)
[convention] 1042-1042: Trailing whitespace
(C0303)
[convention] 1044-1044: Trailing whitespace
(C0303)
[convention] 1048-1048: Trailing whitespace
(C0303)
[convention] 1057-1057: Trailing whitespace
(C0303)
[convention] 1062-1062: Trailing whitespace
(C0303)
[convention] 1067-1067: Trailing whitespace
(C0303)
[convention] 1070-1070: Trailing whitespace
(C0303)
[convention] 1075-1075: Trailing whitespace
(C0303)
[convention] 1080-1080: Trailing whitespace
(C0303)
[convention] 1082-1082: Trailing whitespace
(C0303)
[convention] 1086-1086: Trailing whitespace
(C0303)
[convention] 1090-1090: Trailing whitespace
(C0303)
[convention] 1095-1095: Trailing whitespace
(C0303)
[convention] 1098-1098: Trailing whitespace
(C0303)
[convention] 1100-1100: Trailing whitespace
(C0303)
[convention] 1106-1106: Trailing whitespace
(C0303)
[convention] 1110-1110: Trailing whitespace
(C0303)
[convention] 1117-1117: Trailing whitespace
(C0303)
[convention] 1121-1121: Trailing whitespace
(C0303)
[convention] 1125-1125: Trailing whitespace
(C0303)
[convention] 1133-1133: Trailing whitespace
(C0303)
[convention] 1144-1144: Trailing whitespace
(C0303)
[convention] 1157-1157: Trailing whitespace
(C0303)
[convention] 1165-1165: Trailing whitespace
(C0303)
[convention] 1172-1172: Trailing whitespace
(C0303)
[convention] 1179-1179: Trailing whitespace
(C0303)
[convention] 1187-1187: Trailing whitespace
(C0303)
[convention] 1201-1201: Trailing whitespace
(C0303)
[convention] 1210-1210: Trailing whitespace
(C0303)
[convention] 1215-1215: Trailing whitespace
(C0303)
[convention] 1220-1220: Trailing whitespace
(C0303)
[convention] 1224-1224: Trailing whitespace
(C0303)
[convention] 1228-1228: Trailing whitespace
(C0303)
[convention] 1232-1232: Trailing whitespace
(C0303)
[convention] 1235-1235: Trailing whitespace
(C0303)
[convention] 1242-1242: Trailing whitespace
(C0303)
[convention] 1247-1247: Trailing whitespace
(C0303)
[convention] 1253-1253: Trailing whitespace
(C0303)
[convention] 1256-1256: Trailing whitespace
(C0303)
[convention] 1262-1262: Trailing whitespace
(C0303)
[convention] 1270-1270: Trailing whitespace
(C0303)
[convention] 1283-1283: Trailing whitespace
(C0303)
[convention] 1286-1286: Trailing whitespace
(C0303)
[convention] 1293-1293: Trailing whitespace
(C0303)
[convention] 1297-1297: Trailing whitespace
(C0303)
[convention] 1306-1306: Trailing whitespace
(C0303)
[convention] 1308-1308: Trailing whitespace
(C0303)
[convention] 1314-1314: Trailing whitespace
(C0303)
[convention] 1317-1317: Trailing whitespace
(C0303)
[convention] 1320-1320: Trailing whitespace
(C0303)
[convention] 1330-1330: Trailing whitespace
(C0303)
[convention] 1334-1334: Trailing whitespace
(C0303)
[convention] 1336-1336: Trailing whitespace
(C0303)
[convention] 1339-1339: Trailing whitespace
(C0303)
[convention] 1344-1344: Trailing whitespace
(C0303)
[convention] 1355-1355: Trailing whitespace
(C0303)
[convention] 1361-1361: Trailing whitespace
(C0303)
[convention] 1364-1364: Trailing whitespace
(C0303)
[convention] 1375-1375: Trailing whitespace
(C0303)
[convention] 1381-1381: Trailing whitespace
(C0303)
[convention] 1383-1383: Trailing whitespace
(C0303)
[convention] 1386-1386: Trailing whitespace
(C0303)
[convention] 1393-1393: Trailing whitespace
(C0303)
[convention] 1397-1397: Trailing whitespace
(C0303)
[convention] 1402-1402: Trailing whitespace
(C0303)
[convention] 1409-1409: Trailing whitespace
(C0303)
[convention] 1418-1418: Trailing whitespace
(C0303)
[convention] 1420-1420: Trailing whitespace
(C0303)
[convention] 1425-1425: Trailing whitespace
(C0303)
[convention] 1430-1430: Trailing whitespace
(C0303)
[convention] 1435-1435: Trailing whitespace
(C0303)
[convention] 1440-1440: Trailing whitespace
(C0303)
[convention] 1-1: Too many lines in module (1451/1000)
(C0302)
[convention] 17-28: Import "from utils.helpers import safe_json_parse, safe_json_dumps, generate_hash, retry_with_backoff, flatten_dict, ensure_directory_exists, sanitize_filename, merge_dicts, chunk_list, format_duration" should be placed at the top of the module
(C0413)
[convention] 94-94: Import outside toplevel (datetime.datetime)
(C0415)
[convention] 238-238: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[convention] 358-358: "result == {}" can be simplified to "not result", if it is strictly a sequence, as an empty dict is falsey
(C1803)
[warning] 528-528: Unused variable 'i'
(W0612)
[convention] 599-599: Missing class docstring
(C0115)
[refactor] 599-599: Too few public methods (1/2)
(R0903)
[convention] 615-615: Import outside toplevel (decimal.Decimal)
(C0415)
[convention] 616-616: Import outside toplevel (uuid)
(C0415)
[warning] 641-641: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 641-641: Reimport 'time' (imported line 10)
(W0404)
[convention] 641-641: Import outside toplevel (time)
(C0415)
[warning] 769-769: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 769-769: Reimport 'time' (imported line 10)
(W0404)
[convention] 769-769: Import outside toplevel (time)
(C0415)
[warning] 771-771: Unused variable 'start_time'
(W0612)
[warning] 838-843: Duplicate key True in dictionary
(W0109)
[error] 868-868: Unexpected keyword argument 'separator' in function call
(E1123)
[warning] 888-888: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 888-888: Reimport 'time' (imported line 10)
(W0404)
[convention] 888-888: Import outside toplevel (time)
(C0415)
[warning] 906-906: Redefining name 'tempfile' from outer scope (line 9)
(W0621)
[convention] 905-905: Import outside toplevel (threading)
(C0415)
[warning] 906-906: Reimport 'tempfile' (imported line 9)
(W0404)
[convention] 906-906: Import outside toplevel (tempfile)
(C0415)
[warning] 917-917: Catching too general exception Exception
(W0718)
[convention] 975-975: Use expected.rsplit('.', maxsplit=1)[-1] instead
(C0207)
[warning] 1063-1063: Redefining name 'time' from outer scope (line 10)
(W0621)
[warning] 1063-1063: Reimport 'time' (imported line 10)
(W0404)
[convention] 1063-1063: Import outside toplevel (time)
(C0415)
[warning] 1280-1280: Catching too general exception Exception
(W0718)
[warning] 1275-1275: Cell variable chunk defined in loop
(W0640)
[warning] 1296-1296: Redefining name 'tempfile' from outer scope (line 9)
(W0621)
[warning] 1296-1296: Reimport 'tempfile' (imported line 9)
(W0404)
[convention] 1296-1296: Import outside toplevel (tempfile)
(C0415)
[warning] 1346-1346: Using open without explicitly specifying an encoding
(W1514)
[convention] 1359-1359: Import outside toplevel (threading)
(C0415)
[convention] 1360-1360: Import outside toplevel (random)
(C0415)
[warning] 1384-1384: Catching too general exception Exception
(W0718)
[warning] 1419-1419: Redefining name 'time' from outer scope (line 10)
(W0621)
[error] 1414-1414: Using variable 'time' before assignment
(E0601)
[warning] 1419-1419: Reimport 'time' (imported line 10)
(W0404)
[convention] 1419-1419: Import outside toplevel (time)
(C0415)
[error] 1449-1449: Module 'pytest' has no 'config' member; maybe 'Config'?
(E1101)
[convention] 8-8: standard import "json" should be placed before third party import "pytest"
(C0411)
[convention] 9-9: standard import "tempfile" should be placed before third party import "pytest"
(C0411)
[convention] 10-10: standard import "time" should be placed before third party import "pytest"
(C0411)
[convention] 11-11: standard import "pathlib.Path" should be placed before third party import "pytest"
(C0411)
[convention] 12-12: standard import "unittest.mock.patch" should be placed before third party import "pytest"
(C0411)
[convention] 14-14: standard import "sys" should be placed before third party import "pytest"
(C0411)
🤖 Prompt for AI Agents
In test_utils_helpers.py spanning lines 1 to 1451, the test file is excessively
large and impacts readability and maintainability. To fix this, split the file
into multiple smaller, focused test modules such as test_json_helpers.py for
JSON-related tests, test_file_helpers.py for file system operations,
test_data_helpers.py for data manipulation tests, test_retry_helpers.py for
retry mechanism tests, and test_integration.py for integration and performance
tests. Move the relevant test classes and functions into these new files
accordingly, ensuring imports and test execution remain correct.
| pytest.mark.slow = pytest.mark.skipif( | ||
| not pytest.config.getoption("--run-slow", default=False), | ||
| reason="Slow tests skipped unless --run-slow option provided" | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix pytest marker implementation
pytest.config doesn't exist in modern pytest versions. Use pytest.mark.skipif with an environment variable or command-line option instead.
Replace with a proper implementation:
-# Add marker for slow tests
-pytest.mark.slow = pytest.mark.skipif(
- not pytest.config.getoption("--run-slow", default=False),
- reason="Slow tests skipped unless --run-slow option provided"
-)
+# Define slow marker - configure in pytest.ini or conftest.py
+# Usage: pytest -m "not slow" to skip slow tests
+# or: pytest -m slow to run only slow testsConfigure the marker properly in pytest.ini:
[tool:pytest]
markers =
slow: marks tests as slow (deselect with '-m "not slow"')🧰 Tools
🪛 Ruff (0.11.9)
1450-1450: Trailing comma missing
Add trailing comma
(COM812)
🪛 Pylint (3.3.7)
[error] 1449-1449: Module 'pytest' has no 'config' member; maybe 'Config'?
(E1101)
🤖 Prompt for AI Agents
In test_utils_helpers.py around lines 1448 to 1451, the current use of
pytest.config to check for the --run-slow option is outdated and invalid in
modern pytest versions. Replace this by using pytest's command line options or
environment variables properly. Define the slow marker in pytest.ini under
[tool:pytest] with "slow: marks tests as slow (deselect with '-m \"not
slow\"')". Then, update the skipif condition to check for the presence of the
environment variable or command line option using pytest's recommended approach,
such as accessing pytest's config via a fixture or using pytest_addoption hook
to add the --run-slow option and conditionally skip tests marked slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
| """Test retry with simulated timeout scenarios""" | ||
| import time | ||
|
|
||
| start_time = time.time() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused variable
The variable start_time is assigned but never used.
- start_time = time.time()
call_times = []📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| start_time = time.time() | |
| call_times = [] |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 771-771: local variable 'start_time' is assigned to but never used
(F841)
🪛 Ruff (0.11.9)
771-771: Local variable start_time is assigned to but never used
Remove assignment to unused variable start_time
(F841)
🪛 Pylint (3.3.7)
[warning] 771-771: Unused variable 'start_time'
(W0612)
🤖 Prompt for AI Agents
In test_utils_helpers.py at line 771, the variable start_time is assigned but
never used. Remove the assignment of start_time to clean up the code and avoid
unused variable warnings.
| for i in range(50): | ||
| current_level[f"level_{i}"] = { | ||
| "data": [f"item_{j}" for j in range(100)], # 100 items per level | ||
| "metadata": {"level": i, "timestamp": time.time()}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix variable shadowing issue
The local import of time on line 1419 shadows the module-level import, causing time to be referenced before assignment.
Move the time import to the top of the method or use a different approach:
def test_memory_usage_large_operations(self):
"""Test memory usage with large data operations"""
+ import time
+
# Test with large data structures
large_nested_dict = {}And remove the duplicate import on line 1419.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "metadata": {"level": i, "timestamp": time.time()}, | |
| def test_memory_usage_large_operations(self): | |
| """Test memory usage with large data operations""" | |
| + import time | |
| + | |
| # Test with large data structures | |
| large_nested_dict = {} |
🧰 Tools
🪛 Ruff (0.11.9)
1414-1414: Local variable time referenced before assignment
(F823)
🪛 Pylint (3.3.7)
[error] 1414-1414: Using variable 'time' before assignment
(E0601)
🤖 Prompt for AI Agents
In test_utils_helpers.py at line 1414, the local import of the time module on
line 1419 shadows the module-level import, causing a reference before assignment
error. To fix this, remove the duplicate import of time on line 1419 and ensure
the time module is only imported once at the top of the file or at the start of
the method if necessary, avoiding any local re-imports that shadow the global
one.
| """Test flattening with non-string keys""" | ||
| data = { | ||
| "config": { | ||
| 1: "first_item", | ||
| 2: {"nested": "second_nested"}, | ||
| True: "boolean_key", | ||
| False: {"deep": "boolean_nested"} | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix duplicate dictionary keys
The dictionary has conflicting keys: 1 and True hash to the same value, as do 2 and False in Python dictionaries.
This test appears to be checking how flatten_dict handles non-string keys. Consider using string representations or different test values:
data = {
"config": {
- 1: "first_item",
- 2: {"nested": "second_nested"},
- True: "boolean_key",
- False: {"deep": "boolean_nested"}
+ "1": "first_item",
+ "2": {"nested": "second_nested"},
+ "true": "boolean_key",
+ "false": {"deep": "boolean_nested"}
}
}Or if testing numeric/boolean keys is intentional, use non-conflicting values:
data = {
"config": {
- 2: {"nested": "second_nested"},
- True: "boolean_key",
- False: {"deep": "boolean_nested"}
+ 3: {"nested": "third_nested"},
+ "bool_true": "boolean_key",
+ "bool_false": {"deep": "boolean_nested"}
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| """Test flattening with non-string keys""" | |
| data = { | |
| "config": { | |
| 1: "first_item", | |
| 2: {"nested": "second_nested"}, | |
| True: "boolean_key", | |
| False: {"deep": "boolean_nested"} | |
| } | |
| """Test flattening with non-string keys""" | |
| data = { | |
| "config": { | |
| "1": "first_item", | |
| "2": {"nested": "second_nested"}, | |
| "true": "boolean_key", | |
| "false": {"deep": "boolean_nested"} | |
| } | |
| } |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 839-839: dictionary key 1 repeated with different values
(F601)
[error] 841-841: dictionary key 1 repeated with different values
(F601)
🪛 Ruff (0.11.9)
841-841: Dictionary key literal True repeated (True hashes to the same value as 1)
(F601)
842-842: Trailing comma missing
Add trailing comma
(COM812)
843-843: Trailing comma missing
Add trailing comma
(COM812)
🪛 Pylint (3.3.7)
[warning] 838-843: Duplicate key True in dictionary
(W0109)
🤖 Prompt for AI Agents
In test_utils_helpers.py around lines 836 to 843, the dictionary used in the
test has duplicate keys because 1 and True, as well as 2 and False, hash to the
same keys in Python. To fix this, replace the boolean keys with unique
non-conflicting values or convert all keys to strings to ensure each key is
distinct. This will prevent key collisions and properly test flatten_dict with
non-string keys.
| # Additional Enhanced Test Classes for Comprehensive Coverage | ||
| class TestSafeJsonParseAdvanced: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Fix class spacing
-
-# Additional Enhanced Test Classes for Comprehensive Coverage
+
+# Additional Enhanced Test Classes for Comprehensive Coverage
class TestSafeJsonParseAdvanced:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Additional Enhanced Test Classes for Comprehensive Coverage | |
| class TestSafeJsonParseAdvanced: | |
| # … previous code … | |
| # Additional Enhanced Test Classes for Comprehensive Coverage | |
| class TestSafeJsonParseAdvanced: | |
| ... |
🧰 Tools
🪛 Flake8 (7.2.0)
[error] 521-521: expected 2 blank lines, found 1
(E302)
🤖 Prompt for AI Agents
In test_utils_helpers.py around lines 520 to 521, the class definition for
TestSafeJsonParseAdvanced lacks proper spacing. Add a blank line before the
class declaration to follow PEP8 style guidelines for class spacing.
Docstrings generation was requested by @groupthinking. * #2 (comment) The following files were modified: * `llm/continuous_learning_system.py` * `scripts/auto-improve.sh` * `utils/helpers.py` Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Updated CLAUDE.md with comprehensive project documentation and improved standards. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Pull Request
Description
Please include a summary of the change and which issue is fixed. Also include relevant motivation and context.
Fixes # (issue)
Type of change
Checklist
Screenshots (if applicable)
Additional context
Summary by CodeRabbit
New Features
Chores