GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Cookiecutter template by tony · Pull Request #36 · vcs-python/g Conversation
|
Reviewer's Guide by SourceryThis pull request implements a cookiecutter template for generating Python projects. It includes tests using Sequence diagram for post-generation hook executionsequenceDiagram
participant User
participant Cookiecutter
participant post_gen_project.py
participant FileSystem
User->>Cookiecutter: Generate project
Cookiecutter->>post_gen_project.py: Execute post-generation hook
post_gen_project.py->>FileSystem: Check license type
alt license_type is MIT
post_gen_project.py->>FileSystem: Generate MIT license file
FileSystem-->>post_gen_project.py: License file created
else license_type is BSD-3
post_gen_project.py->>FileSystem: Generate BSD-3 license file
FileSystem-->>post_gen_project.py: License file created
else license_type is GPL-3.0
post_gen_project.py->>FileSystem: Generate GPL-3.0 license file
FileSystem-->>post_gen_project.py: License file created
else license_type is Apache-2.0
post_gen_project.py->>FileSystem: Generate Apache-2.0 license file
FileSystem-->>post_gen_project.py: License file created
else
post_gen_project.py->>User: Print unsupported license type
end
post_gen_project.py->>FileSystem: Check include_tests
alt include_tests is 'y'
post_gen_project.py->>FileSystem: Create tests directory and __init__.py
FileSystem-->>post_gen_project.py: Directory and file created
post_gen_project.py->>FileSystem: Create basic test file
FileSystem-->>post_gen_project.py: Test file created
end
post_gen_project.py->>FileSystem: Check include_docs
alt include_docs is 'y'
post_gen_project.py->>FileSystem: Create docs directory and index.md
FileSystem-->>post_gen_project.py: Directory and file created
end
post_gen_project.py->>FileSystem: Check include_github_actions
alt include_github_actions is 'y'
post_gen_project.py->>FileSystem: Create .github/workflows directory and tests.yml
FileSystem-->>post_gen_project.py: Directory and file created
end
post_gen_project.py->>User: Print success message
Cookiecutter-->>User: Project generated
Class diagram for the generated project structureclassDiagram
class Project {
+__init__.py
+__about__.py
+README.md
+pyproject.toml
+tests/
+docs/
+.github/workflows/
+LICENSE
}
class pyproject_toml {
+name
+version
+description
+requires-python
+authors
+license
+classifiers
+packages
+include
+readme
+keywords
+homepage
+urls
+scripts
+tool.uv
+dependency-groups
+build-system
+tool.mypy
+tool.ruff
+tool.pytest.ini_options
+tool.pytest-watcher
+tool.coverage.report
}
class __init__.py {
+find_repo_type()
+run()
}
class __about__.py {
+__title__
+__package_name__
+__description__
+__version__
+__author__
+__github__
+__docs__
+__tracker__
+__pypi__
+__email__
+__license__
+__copyright__
}
Project -- pyproject_toml : contains
Project -- __init__.py : contains
Project -- __about__.py : contains
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Hey @tony - I've reviewed your changes - here's some feedback:
Overall Comments:
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| assert isinstance(cmd_args, (tuple, list)) | ||
| assert isinstance(cmd, (str, bytes, pathlib.Path)) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Avoid using assert for type checking in production code.
Assertions might be disabled in optimized mode. Using explicit type checks and raising appropriate exceptions would help ensure the function behaves robustly in all environments.
| assert isinstance(cmd_args, (tuple, list)) | |
| assert isinstance(cmd, (str, bytes, pathlib.Path)) | |
| if not isinstance(cmd_args, (tuple, list)): | |
| raise TypeError("cmd_args must be a tuple or list") | |
| if not isinstance(cmd, (str, bytes, pathlib.Path)): | |
| raise TypeError("cmd must be a str, bytes, or pathlib.Path") |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if wait: | ||
| proc.wait() | ||
| else: | ||
| proc.communicate() |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
question: Clarify the behavior of the wait flag in the run() function.
Since proc.communicate() will wait for the process to finish, even when wait is False, it may be worth revisiting this logic if the intention was to allow non-blocking execution in that branch.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| def test_bake_and_run_tests(cookies: Any) -> None: | ||
| """Test running the tests in the baked project.""" | ||
| result = cookies.bake(extra_context={ | ||
| "project_name": "test_cli", | ||
| "include_tests": "y", | ||
| "project_description": "Test CLI tool for developers", | ||
| "supported_vcs": "git" # Use a single VCS to avoid format issues | ||
| }) | ||
|
|
||
| assert result.exit_code == 0 |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): More robust test execution
Instead of just checking if test_result is not None, assert on the specific expected output or exit code of the test run. This will make the test more precise and catch potential regressions.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| def test_vcspath_registry_creation(cookies: Any) -> None: | ||
| """Test proper creation of vcspath_registry for different VCS combinations.""" | ||
| # Test with git VCS supported | ||
| result = cookies.bake(extra_context={ | ||
| "project_name": "vcs_all", | ||
| "supported_vcs": "git" | ||
| }) | ||
|
|
||
| assert result.exit_code == 0 | ||
| assert result.exception is None |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): Test unsupported VCS
Add a test case where an unsupported VCS is specified in the cookiecutter options. Verify that the generated project handles this gracefully, either by raising an error or defaulting to a sensible behavior.
Suggested implementation:
assert result.exception is None # Test with unsupported VCS provided. unsupported_result = cookies.bake(extra_context={ "project_name": "vcs_unsupported", "supported_vcs": "unsupported_vcs" }) # Check if cookiecutter fails gracefully or defaults to a sensible behavior. if unsupported_result.exit_code != 0: # If it failed, ensure an exception was raised. assert unsupported_result.exception is not None else: # If it defaults, verify that a default configuration was applied. # For instance, assume it creates a file "vcspath_registry.txt" with default VCS. import os default_registry_path = os.path.join(unsupported_result.project_path, "vcspath_registry.txt") assert os.path.exists(default_registry_path)
Verify that the project code under test actually handles unsupported VCS values by either raising an error or applying default behavior. Adjust the file name or assertions (such as checking a specific file or config) according to your project's implementation.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| def test_readme_badges(cookies: Any) -> None: | ||
| """Test that README badges are correctly included/excluded.""" | ||
| # Test with all features enabled | ||
| result = cookies.bake(extra_context={ | ||
| "project_name": "full_project", | ||
| "include_docs": "y", | ||
| "include_github_actions": "y" | ||
| }) | ||
|
|
||
| assert result.exit_code == 0 |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): Test badge URLs
Instead of just checking for the presence of badge placeholders, verify that the generated README contains the correct URLs for the badges, especially for dynamic badges like code coverage and build status.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| $ {{cookiecutter.package_name}} | ||
| ``` | ||
|
|
||
| ### Developmental releases |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
question (typo): Possible typo
Should "Developmental releases" be "Development releases"?
| ### Developmental releases | |
| ### Development releases |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| year = datetime.datetime.now().year | ||
|
|
||
|
|
||
| def generate_mit_license(): |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider creating a single function to write the license file, and storing the license texts in a dictionary to avoid code duplication and improve maintainability
Consider combining the duplicated license file writing into one helper that accepts the license text. For example:
def write_license(license_text: str): with open("LICENSE", "w") as f: f.write(license_text) licenses = { "MIT": f"""MIT License Copyright (c) {year} {author} Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """, "BSD-3": f"""BSD 3-Clause License Copyright (c) {year}, {author} All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """, "GPL-3.0": f"""Copyright (C) {year} {author} This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. """, "Apache-2.0": f""" Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ Copyright {year} {author} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """, } if license_type in licenses: write_license(licenses[license_type]) else: print(f"Unsupported license type: {license_type}")
This approach centralizes license generation and minimizes code repetition while keeping functionality intact.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if "{{cookiecutter.include_tests}}" == "y": | ||
| if not os.path.exists("tests"): | ||
| os.makedirs("tests") | ||
| with open("tests/__init__.py", "w") as f: | ||
| f.write("""Test package for {{cookiecutter.package_name}}.""") | ||
|
|
||
| # Create a basic test file | ||
| with open("tests/test_cli.py", "w") as f: | ||
| f.write("""#!/usr/bin/env python | ||
| \"\"\"Test CLI for {{cookiecutter.package_name}}.\"\"\" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import os | ||
| import pathlib | ||
| import subprocess | ||
| import sys | ||
|
|
||
| import pytest | ||
|
|
||
| import {{cookiecutter.package_name}} | ||
|
|
||
|
|
||
| def test_run(): | ||
| \"\"\"Test run.\"\"\" | ||
| # Test that the function doesn't error | ||
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | ||
| assert proc is None | ||
|
|
||
| # Test when G_IS_TEST is set, it returns the proc | ||
| os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] = "1" | ||
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | ||
| assert isinstance(proc, subprocess.Popen) | ||
| assert proc.returncode == 0 | ||
| del os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] | ||
| """) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Merge nested if conditions (merge-nested-ifs)
| if "{{cookiecutter.include_tests}}" == "y": | |
| if not os.path.exists("tests"): | |
| os.makedirs("tests") | |
| with open("tests/__init__.py", "w") as f: | |
| f.write("""Test package for {{cookiecutter.package_name}}.""") | |
| # Create a basic test file | |
| with open("tests/test_cli.py", "w") as f: | |
| f.write("""#!/usr/bin/env python | |
| \"\"\"Test CLI for {{cookiecutter.package_name}}.\"\"\" | |
| from __future__ import annotations | |
| import os | |
| import pathlib | |
| import subprocess | |
| import sys | |
| import pytest | |
| import {{cookiecutter.package_name}} | |
| def test_run(): | |
| \"\"\"Test run.\"\"\" | |
| # Test that the function doesn't error | |
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | |
| assert proc is None | |
| # Test when G_IS_TEST is set, it returns the proc | |
| os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] = "1" | |
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | |
| assert isinstance(proc, subprocess.Popen) | |
| assert proc.returncode == 0 | |
| del os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] | |
| """) | |
| if "{{cookiecutter.include_tests}}" == "y" and not os.path.exists("tests"): | |
| os.makedirs("tests") | |
| with open("tests/__init__.py", "w") as f: | |
| f.write("""Test package for {{cookiecutter.package_name}}.""") | |
| # Create a basic test file | |
| with open("tests/test_cli.py", "w") as f: | |
| f.write("""#!/usr/bin/env python | |
| \"\"\"Test CLI for {{cookiecutter.package_name}}.\"\"\" | |
| from __future__ import annotations | |
| import os | |
| import pathlib | |
| import subprocess | |
| import sys | |
| import pytest | |
| import {{cookiecutter.package_name}} | |
| def test_run(): | |
| \"\"\"Test run.\"\"\" | |
| # Test that the function doesn't error | |
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | |
| assert proc is None | |
| # Test when G_IS_TEST is set, it returns the proc | |
| os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] = "1" | |
| proc = {{cookiecutter.package_name}}.run(cmd="echo", cmd_args=["hello"]) | |
| assert isinstance(proc, subprocess.Popen) | |
| assert proc.returncode == 0 | |
| del os.environ["{{cookiecutter.package_name.upper()}}_IS_TEST"] | |
| """) | |
Reading deeply nested code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two if conditions can be combined using
and is an easy win.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if "{{cookiecutter.include_docs}}" == "y": | ||
| if not os.path.exists("docs"): | ||
| os.makedirs("docs") | ||
| with open("docs/index.md", "w") as f: | ||
| f.write("""# {{cookiecutter.project_name}} | ||
|
|
||
| {{cookiecutter.project_description}} | ||
|
|
||
| ## Installation | ||
|
|
||
| ```bash | ||
| pip install {{cookiecutter.package_name}} | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| {{cookiecutter.package_name}} | ||
| ``` | ||
|
|
||
| This will detect the type of repository in your current directory and run the appropriate VCS command. | ||
| """) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Merge nested if conditions (merge-nested-ifs)
| if "{{cookiecutter.include_docs}}" == "y": | |
| if not os.path.exists("docs"): | |
| os.makedirs("docs") | |
| with open("docs/index.md", "w") as f: | |
| f.write("""# {{cookiecutter.project_name}} | |
| {{cookiecutter.project_description}} | |
| ## Installation | |
| ```bash | |
| pip install {{cookiecutter.package_name}} | |
| ``` | |
| ## Usage | |
| ```bash | |
| {{cookiecutter.package_name}} | |
| ``` | |
| This will detect the type of repository in your current directory and run the appropriate VCS command. | |
| """) | |
| if "{{cookiecutter.include_docs}}" == "y" and not os.path.exists("docs"): | |
| os.makedirs("docs") | |
| with open("docs/index.md", "w") as f: | |
| f.write("""# {{cookiecutter.project_name}} | |
| {{cookiecutter.project_description}} | |
| ## Installation | |
| ```bash | |
| pip install {{cookiecutter.package_name}} | |
| ``` | |
| ## Usage | |
| ```bash | |
| {{cookiecutter.package_name}} | |
| ``` | |
| This will detect the type of repository in your current directory and run the appropriate VCS command. | |
| """) | |
Reading deeply nested code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two if conditions can be combined using
and is an easy win.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if "{{cookiecutter.include_github_actions}}" == "y": | ||
| if not os.path.exists(".github/workflows"): | ||
| os.makedirs(".github/workflows") | ||
| with open(".github/workflows/tests.yml", "w") as f: | ||
| f.write("""name: tests | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| python-version: ['3.9', '3.10', '3.11'] | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - name: Set up Python ${{ "{{" }} matrix.python-version {{ "}}" }} | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: ${{ "{{" }} matrix.python-version {{ "}}" }} | ||
| - name: Install dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install uv | ||
| uv pip install -e . | ||
| uv pip install pytest pytest-cov | ||
| - name: Test with pytest | ||
| run: | | ||
| uv pip install pytest | ||
| pytest | ||
| """) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Merge nested if conditions (merge-nested-ifs)
| if "{{cookiecutter.include_github_actions}}" == "y": | |
| if not os.path.exists(".github/workflows"): | |
| os.makedirs(".github/workflows") | |
| with open(".github/workflows/tests.yml", "w") as f: | |
| f.write("""name: tests | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.10', '3.11'] | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - name: Set up Python ${{ "{{" }} matrix.python-version {{ "}}" }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ "{{" }} matrix.python-version {{ "}}" }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install uv | |
| uv pip install -e . | |
| uv pip install pytest pytest-cov | |
| - name: Test with pytest | |
| run: | | |
| uv pip install pytest | |
| pytest | |
| """) | |
| if "{{cookiecutter.include_github_actions}}" == "y" and not os.path.exists(".github/workflows"): | |
| os.makedirs(".github/workflows") | |
| with open(".github/workflows/tests.yml", "w") as f: | |
| f.write("""name: tests | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.10', '3.11'] | |
| steps: | |
| - uses: actions/checkout@v3 | |
| - name: Set up Python ${{ "{{" }} matrix.python-version {{ "}}" }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ "{{" }} matrix.python-version {{ "}}" }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install uv | |
| uv pip install -e . | |
| uv pip install pytest pytest-cov | |
| - name: Test with pytest | |
| run: | | |
| uv pip install pytest | |
| pytest | |
| """) | |
Reading deeply nested code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two if conditions can be combined using
and is an easy win.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
53d9379 to
9949967
Compare
9949967 to
943f069
Compare
f3a49a5 to
8f6814d
Compare
8f6814d to
0ade06a
Compare
|
Automated review finding. Recorded here so it is not lost. Nothing has been pushed to this branch and no fix is applied — this is a note, not a change request. Two findings on this PR. 1. Code injection in
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.