Skip to content
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

Issue 3267: fixed wps226 location #3269

Merged
merged 2 commits into from
Feb 6, 2025
Merged

Conversation

ishonichev
Copy link
Contributor

@ishonichev ishonichev commented Jan 10, 2025

I have made things!

Checklist

  • I have double checked that there are no unrelated changes in this pull request (old patches, accidental config files, etc)
  • I have created at least one test case for the changes I have made
  • I have updated the documentation for the changes I have made
  • I have added my changes to the CHANGELOG.md

Related issues

🙏 Please, if you or your company is finding wemake-python-styleguide valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/wemake-python-styleguide. As a thank you, your profile/company logo will be added to our main README which receives hundreds of unique visitors per day.

@ishonichev ishonichev changed the title fixed wps226 location Issue 3267: fixed wps226 location Jan 10, 2025
Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! We also need a test case for that. You can probably use ._location() in any of the existing tests.

@@ -67,6 +67,11 @@ def __init__(self, *args, **kwargs) -> None:
int,
] = defaultdict(int)

self._string_constants_first_node: defaultdict[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be self._string_constants_first_node: ast.AST | None = None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain the idea, please

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need the first node, right? We don't need all nodes. So, we can only save the first node here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. And it is done so. For each string their first nodes are collected in dict.

Copy link

codecov bot commented Jan 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (11c3633) to head (4581556).
Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #3269   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          357       357           
  Lines        11703     11715   +12     
  Branches       801       802    +1     
=========================================
+ Hits         11703     11715   +12     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ishonichev ishonichev marked this pull request as draft January 10, 2025 22:22
Comment on lines 113 to 123
if ignored_types:
real_errors = [
error
for error in visitor.violations
if not isinstance(error, ignored_types)
]
else:
real_errors = visitor.violations

for violation in real_errors:
assert violation._location() != (0, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ignored_types:
real_errors = [
error
for error in visitor.violations
if not isinstance(error, ignored_types)
]
else:
real_errors = visitor.violations
for violation in real_errors:
assert violation._location() != (0, 0)
assert len(visitor.violations) == 1
violation = visitor.violations[0]
assert violation._location() == expected

Comment on lines 109 to 112
def factory(
visitor: BaseVisitor,
ignored_types: _IgnoredTypes = None,
) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def factory(
visitor: BaseVisitor,
ignored_types: _IgnoredTypes = None,
) -> None:
def factory(
visitor: BaseVisitor,
expected: tuple[int, int],
) -> None:

@@ -177,6 +178,7 @@ def test_string_overuse(
string_value.replace('"', '') or "''",
default_options.max_string_usages,
)
assert_violation_location(visitor)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert_violation_location(visitor, (X, Y))

@@ -67,6 +67,11 @@ def __init__(self, *args, **kwargs) -> None:
int,
] = defaultdict(int)

self._string_constants_first_node: defaultdict[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need the first node, right? We don't need all nodes. So, we can only save the first node here.

@ishonichev
Copy link
Contributor Author

Problem is slightly more trickier than I thought.
The reason is that OverusedStringViolation inherits from MaybeASTViolation which is ...violation without explicit node.
Also in assert_errors only for instances of ASTViolation or TokenizeViolation location is implicitly asserted (is compared with (0,0)).
For any type of violation its location isn't asserted explicitly (is compared with expected location), is it?

@ishonichev ishonichev marked this pull request as ready for review January 12, 2025 13:26
@@ -178,7 +181,7 @@ def test_string_overuse(
string_value.replace('"', '') or "''",
default_options.max_string_usages,
)
assert_violation_location(visitor)
assert_error_location(visitor, expected_location)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just create a single test with known location? Like x = 'abc' and have it as a constant? Like (1, 4)? Right now it seems too complex.

@sobolevn sobolevn mentioned this pull request Jan 15, 2025
4 tasks
Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thank you!

@sobolevn sobolevn merged commit bae29e5 into wemake-services:master Feb 6, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants