-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add checker for relationship backref usage (#36)
* Add checker for relationship backref usage * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix line length in relationship_backref_checker.py Refactors line lengths in `flake8_sqlalchemy/checkers/relationship_backref_checker.py` to comply with the 88 character limit. - Breaks long lines in docstrings for the `run` and `is_relationship_with_backref` methods to ensure compliance with the project's line length restriction. - Maintains readability and code structure while adhering to the `.flake8` configuration. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/miketheman/flake8-sqlalchemy/pull/36?shareId=6c56ba85-5a9f-4269-b767-acc03d66e380). * Document the SQA300 check for backref usage Adds documentation for the `SQA300` check in the README.md file. - Introduces a new section for `SQA300` to guide users on using `back_populates` instead of `backref` in SQLAlchemy relationships. - Provides examples of incorrect usage with `backref` and correct usage with `back_populates`, following the existing documentation structure for other checks. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/miketheman/flake8-sqlalchemy/pull/36?shareId=a6468ad9-2d08-40d2-9bc2-8ee40950ccfd). --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- Loading branch information
1 parent
d50f534
commit 1dda900
Showing
5 changed files
with
107 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
from .column_comment import ColumnCommentChecker | ||
from .import_alias import ImportAliasChecker | ||
from .relationship_backref_checker import RelationshipBackrefChecker | ||
|
||
__all__ = ( | ||
"ColumnCommentChecker", | ||
"ImportAliasChecker", | ||
"RelationshipBackrefChecker", | ||
) |
41 changes: 41 additions & 0 deletions
41
flake8_sqlalchemy/checkers/relationship_backref_checker.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Checker for detecting `backref` usage in SQLAlchemy relationships.""" | ||
|
||
import ast | ||
from typing import List | ||
|
||
from ..issue import Issue | ||
from ._base import Checker | ||
|
||
|
||
class SQA300(Issue): | ||
code = "SQA300" | ||
message = f"{code} Use `back_populates` instead of `backref` in relationship" | ||
|
||
|
||
class RelationshipBackrefChecker(Checker): | ||
def run(self, node: ast.Call) -> List[Issue]: | ||
""" | ||
Checks if a relationship() call uses `backref` and suggests | ||
`back_populates` instead. | ||
""" | ||
issues: List[Issue] = [] | ||
|
||
if self.is_relationship_with_backref(node): | ||
issues.append(SQA300(node.lineno, node.col_offset)) | ||
|
||
return issues | ||
|
||
@staticmethod | ||
def is_relationship_with_backref(node: ast.Call) -> bool: | ||
""" | ||
Determines if the given node represents a relationship() call with a | ||
`backref` argument. | ||
""" | ||
if RelationshipBackrefChecker.get_call_name(node) != "relationship": | ||
return False | ||
|
||
for keyword in node.keywords: | ||
if keyword.arg == "backref": | ||
return True | ||
|
||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from textwrap import dedent | ||
|
||
|
||
def test_relationship_backref_passes(helpers): | ||
sample_code = """ | ||
from sqlalchemy.orm import relationship | ||
class Parent: | ||
children = relationship("Child", back_populates="parent") | ||
class Child: | ||
parent = relationship("Parent", back_populates="children") | ||
""" | ||
assert helpers.results(dedent(sample_code)) == set() | ||
|
||
|
||
def test_relationship_backref_fails(helpers): | ||
sample_code = """ | ||
from sqlalchemy.orm import relationship | ||
class Parent: | ||
children = relationship("Child", backref="parent") | ||
class Child: | ||
parent = relationship("Parent", backref="children") | ||
""" | ||
assert helpers.results(dedent(sample_code)) == { | ||
"5:16 SQA300 Use `back_populates` instead of `backref` in relationship", | ||
"8:14 SQA300 Use `back_populates` instead of `backref` in relationship", | ||
} |