Skip to content

Address even more pytest warnings, co-authored with Opus 4.6#16330

Open
AlanCoding wants to merge 3 commits intoansible:develfrom
AlanCoding:your_third_warning
Open

Address even more pytest warnings, co-authored with Opus 4.6#16330
AlanCoding wants to merge 3 commits intoansible:develfrom
AlanCoding:your_third_warning

Conversation

@AlanCoding
Copy link
Copy Markdown
Member

@AlanCoding AlanCoding commented Mar 5, 2026

SUMMARY

Fed the same prompt again, as from #16298

One before that was #16269

ISSUE TYPE
  • Bug, Docs Fix or other nominal change
COMPONENT NAME
  • API

Note

Medium Risk
Upgrades pyparsing to v3 and rewrites SmartFilter.query_from_string parsing logic, which can affect host filtering behavior and error handling. Other changes are test/warning hygiene and dependency pin updates with low functional risk.

Overview
Updates the smart host filter parser to use pyparsing v3 APIs, including a new token/operand grammar, updated exception handling, and simplified key/value extraction behavior in SmartFilter.query_from_string.

Cleans up test and CI noise by switching Grafana notification tests to timezone-aware UTC datetimes, removing several pytest deprecation-warning suppressions, and updating dependency constraints/pins (notably pyparsing and a dispatcherd version formatting fix).

Written by Cursor Bugbot for commit 50834e6. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • Tests

    • Use timezone-aware UTC datetimes in tests so ISO timestamps include UTC offset.
  • Refactor

    • Updated internal parsing implementation to follow the newer parsing library API while preserving external behavior.
  • Chores

    • Re-enabled several deprecation warnings so they are now reported.
    • Loosened parsing library version constraint and normalized lockfile pins.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 5, 2026

📝 Walkthrough

Walkthrough

Updates tests to use timezone-aware UTC datetimes, refactors internal pyparsing usage in a utility to pyparsing v3-style APIs, removes several pytest deprecation filterwarnings, and updates pyparsing and a dependency version in requirements files.

Changes

Cohort / File(s) Summary
Timezone-Aware Datetime Updates
awx/main/tests/unit/notifications/test_grafana.py
Replaced naive datetime.utcfromtimestamp(...) with aware datetime.fromtimestamp(..., tz=datetime.timezone.utc) for started/finished timestamps in tests.
Pyparsing API Refactor
awx/main/utils/filters.py
Switched imports to import pyparsing as pp and migrated parsing implementation to pyparsing v3-style APIs (pp.infix_notation/pp.infix_notationpp.infix_notation compatibility via pp.infix_notation/pp.infix_notation usage, pp.Keyword, pp.OpAssoc/pp.opAssoc style, set_parse_action, parse_string, and pp.ParseException). Key parsing logic rewritten: tokenization, operand/action binding, key/value extraction, and exception handling. Review parsing behavior and error paths.
Pytest Config
pytest.ini
Removed multiple filterwarnings = ignore::... entries that previously silenced deprecation warnings; only the index_together ignore remains. Expect newly surfaced deprecation warnings in test runs.
Requirements Updates
requirements/requirements.in, requirements/requirements.txt
Loosened pyparsing constraint (from ==2.4.7>3.0) in requirements.in and updated pyparsing in requirements.txt to 3.3.2; normalized dispatcherd[pg-notify] version formatting. Verify compatibility with pyparsing v3.3.2.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective: addressing pytest warnings through pyparsing v3 upgrade and related code changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@awx/main/utils/filters.py`:
- Around line 6-8: The module imports and uses pyparsing v3 API names
(infix_notation, OpAssoc, Opt, set_parse_action, parse_string) while the repo
pins pyparsing==2.4.7, causing ImportError; update awx/main/utils/filters.py to
import pyparsing with a compatibility shim: attempt to import the v3 symbols
(infix_notation, OpAssoc, Opt, set_parse_action, parse_string) and on
ImportError fall back to v2 equivalents (infixNotation, opAssoc, Optional,
setParseAction, parseString), then use those local names throughout (e.g., where
infix_notation/OpAssoc/Opt/set_parse_action/parse_string are referenced) so the
rest of the file (parsing logic around the filter parser) works with both
pyparsing v2 and v3.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8e9a14c9-b6ae-4481-b332-ddd9d53cb18d

📥 Commits

Reviewing files that changed from the base of the PR and between 670dfee and 8e5ba2b.

📒 Files selected for processing (3)
  • awx/main/tests/unit/notifications/test_grafana.py
  • awx/main/utils/filters.py
  • pytest.ini
💤 Files with no reviewable changes (1)
  • pytest.ini

@github-actions github-actions bot added the dependencies Pull requests that update a dependency file label Mar 5, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@requirements/requirements.in`:
- Line 53: The requirement "pyparsing>3.0" should be constrained to the v3.x
major range to avoid pulling an unreviewed v4; update the requirement spec from
"pyparsing>3.0" to a bounded spec such as "pyparsing>=3.0,<4.0" (or
"pyparsing~=3.0") in requirements.in so host query parsing code that depends on
pyparsing (awx.main.utils.filters) remains on the supported major version.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 81b35f59-e211-40a6-b2e9-0e929bff2be6

📥 Commits

Reviewing files that changed from the base of the PR and between 8e5ba2b and dedc178.

📒 Files selected for processing (2)
  • requirements/requirements.in
  • requirements/requirements.txt

@AlanCoding AlanCoding marked this pull request as draft March 6, 2026 05:01
@AlanCoding AlanCoding marked this pull request as ready for review March 12, 2026 17:10
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
awx/main/utils/filters.py (2)

317-335: Add a couple of tokenizer-focused regression cases.

The coverage in awx/main/tests/unit/utils/test_filters.py:74-94, 150-175, and 201-220 covers the common quoted/unquoted paths and precedence, but not escaped quotes or parenthesized mixed expressions through this new tokenizer. A few targeted cases there would make the pyparsing v3 swap safer.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@awx/main/utils/filters.py` around lines 317 - 335, Add targeted regression
tests exercising the new tokenizer paths: create test cases in
awx/main/tests/unit/utils/test_filters.py that feed filter strings containing
escaped quotes inside quoted tokens (e.g. a value with \" inside quotes) and
mixed parenthesized expressions combining quoted and unquoted tokens (e.g.
"(field1=value1 or field2=\"with \\\"quote\\\"\") and field3=value3") to ensure
the parser built from unquoted, quoted, token, operand, BoolOperand and
bool_expr (with BoolAnd/BoolOr) handles escapes and parentheses correctly;
assert the parsed structure or resulting boolean AST matches expected
BoolOperand/BoolAnd/BoolOr nesting and include both positive and edge cases so
the pp.QuotedString escape behavior and pp.infix_notation precedence are
covered.

268-272: Preserve the real pyparsing error and the original cause.

pp.ParseException('...') treats the string as pstr, not msg, so Line 271 does not build the error you intend. Line 336 then wraps it without chaining, which drops the underlying lookup failure during validation.

♻️ Proposed fix
-                except LookupError:
-                    raise pp.ParseException('No related field named %s' % relation)
+                except LookupError as exc:
+                    raise pp.ParseException("", 0, f"No related field named {relation}") from exc
@@
-        except (pp.ParseException, FieldDoesNotExist):
-            raise RuntimeError(u"Invalid query %s" % filter_string_raw)
+        except (pp.ParseException, FieldDoesNotExist) as exc:
+            raise RuntimeError(f"Invalid query {filter_string_raw}") from exc

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

Also applies to: 333-336

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@awx/main/utils/filters.py` around lines 268 - 272, The current code raises
pp.ParseException('No related field named ...') which passes the text as the
pstr parameter instead of the msg, and it also drops the original LookupError
cause; update both places where this pattern occurs (the get_model lookup and
the later wrap around lines referencing the same ParseException) to construct
the ParseException with an explicit msg (e.g. pp.ParseException('', 0, None,
msg='No related field named %s' % relation)) and re-raise it using exception
chaining (raise pp.ParseException(... ) from e) so the original LookupError is
preserved as the __cause__.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@awx/main/utils/filters.py`:
- Around line 317-335: Add targeted regression tests exercising the new
tokenizer paths: create test cases in awx/main/tests/unit/utils/test_filters.py
that feed filter strings containing escaped quotes inside quoted tokens (e.g. a
value with \" inside quotes) and mixed parenthesized expressions combining
quoted and unquoted tokens (e.g. "(field1=value1 or field2=\"with
\\\"quote\\\"\") and field3=value3") to ensure the parser built from unquoted,
quoted, token, operand, BoolOperand and bool_expr (with BoolAnd/BoolOr) handles
escapes and parentheses correctly; assert the parsed structure or resulting
boolean AST matches expected BoolOperand/BoolAnd/BoolOr nesting and include both
positive and edge cases so the pp.QuotedString escape behavior and
pp.infix_notation precedence are covered.
- Around line 268-272: The current code raises pp.ParseException('No related
field named ...') which passes the text as the pstr parameter instead of the
msg, and it also drops the original LookupError cause; update both places where
this pattern occurs (the get_model lookup and the later wrap around lines
referencing the same ParseException) to construct the ParseException with an
explicit msg (e.g. pp.ParseException('', 0, None, msg='No related field named
%s' % relation)) and re-raise it using exception chaining (raise
pp.ParseException(... ) from e) so the original LookupError is preserved as the
__cause__.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 624401cc-d49a-464d-8707-2fb9fe2f1036

📥 Commits

Reviewing files that changed from the base of the PR and between dedc178 and 7f324d6.

📒 Files selected for processing (5)
  • awx/main/tests/unit/notifications/test_grafana.py
  • awx/main/utils/filters.py
  • pytest.ini
  • requirements/requirements.in
  • requirements/requirements.txt
💤 Files with no reviewable changes (1)
  • pytest.ini
🚧 Files skipped from review as they are similar to previous changes (2)
  • awx/main/tests/unit/notifications/test_grafana.py
  • requirements/requirements.in

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
awx/main/utils/filters.py (1)

268-271: Consider exception chaining for better traceability.

Static analysis flags that re-raising within an except block without from can obscure the original exception context.

♻️ Suggested fix
             try:
                 model = get_model(relation)
-            except LookupError:
-                raise pp.ParseException('No related field named %s' % relation)
+            except LookupError as err:
+                raise pp.ParseException('No related field named %s' % relation) from err
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@awx/main/utils/filters.py` around lines 268 - 271, The except block catching
LookupError when calling get_model(relation) should chain the original exception
to preserve context: capture the caught exception (e.g., as e) and re-raise
pp.ParseException('No related field named %s' % relation) using "from e" so the
original LookupError is attached; update the block around get_model(relation)
accordingly to use exception chaining.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@awx/main/utils/filters.py`:
- Around line 268-271: The except block catching LookupError when calling
get_model(relation) should chain the original exception to preserve context:
capture the caught exception (e.g., as e) and re-raise pp.ParseException('No
related field named %s' % relation) using "from e" so the original LookupError
is attached; update the block around get_model(relation) accordingly to use
exception chaining.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e1befe84-068f-4b55-bda6-5d50abe48300

📥 Commits

Reviewing files that changed from the base of the PR and between 7f324d6 and 50834e6.

📒 Files selected for processing (5)
  • awx/main/tests/unit/notifications/test_grafana.py
  • awx/main/utils/filters.py
  • pytest.ini
  • requirements/requirements.in
  • requirements/requirements.txt
💤 Files with no reviewable changes (1)
  • pytest.ini
🚧 Files skipped from review as they are similar to previous changes (1)
  • awx/main/tests/unit/notifications/test_grafana.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component:api dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant