Skip to content

fix: guard against KeyError in get_priority_change_date by using .get()#2901

Open
AmSach wants to merge 9 commits into
mozilla:masterfrom
AmSach:fix/keyerror-field-name-in-get-priority-change-date
Open

fix: guard against KeyError in get_priority_change_date by using .get()#2901
AmSach wants to merge 9 commits into
mozilla:masterfrom
AmSach:fix/keyerror-field-name-in-get-priority-change-date

Conversation

@AmSach

@AmSach AmSach commented Jun 1, 2026

Copy link
Copy Markdown

Fixed the bug described in issue #2607. Here's what was wrong and how I fixed it: In get_priority_change_date(), the code directly accessed change['field_name'] and change['added'] without checking if those keys exist, causing KeyError on malformed history entries. Fixed by using .get() with None defaults. Tested by verifying syntax with ast.parse().

AmSach added 6 commits June 1, 2026 00:34
The change history entries may not always contain 'field_name' or 'added'
keys, causing a KeyError when iterating through bug history. Using .get()
with None default prevents the crash while preserving the original logic:
only entries with field_name=='priority' and matching added value are used.

Fixes mozilla#2607
Adds regression coverage for the change in mozilla#2901 that
replaced change['field_name']/change['added'] with change.get(...) in
AssigneeNoLogin.get_priority_change_date. Tests cover:
- matching the most recent priority change
- history entries missing field_name or added (the original crash)
- returning None when no priority change matches
- skipping malformed entries without raising

Helps restore the test coverage that dropped after mozilla#2901.
…rity

- Remove unused 'timedelta' import (ruff F401)
- Wrap long dict literal in test_get_priority_change_date_returns_none_when_no_match
  across multiple lines to satisfy ruff-format line length

These fixes resolve the pre-commit hook failures that were blocking CI on
mozilla#2901. The pre-commit hooks were auto-fixing the file but
still exited non-zero when files were modified, which failed the check.
The test file in PR mozilla#2901 (test_assignee_no_login_priority.py) was
calling AssigneeNoLogin with bogus keyword args (username, user_contact)
that the production __init__ doesn't accept:

  TypeError: AssigneeNoLogin.__init__() got an unexpected keyword
  argument 'username'

This caused 5/5 tests in this file to fail in the Community-TC
'bugbot tests' check, blocking the PR. Two fixes:

1. _make_rule() now calls AssigneeNoLogin() with no args, matching
   the production __init__ signature (which inherits from BzCleaner
   and Nag and reads all config from utils.get_config() / people.json
   at instance time).

2. Test assertions for get_priority_change_date() use naive datetimes
   (no tzinfo=timezone.utc) because the production implementation
   parses timestamps with datetime.strptime(..., '%Y-%m-%dT%H:%M:%SZ')
   which returns a naive datetime. The downstream comparison
   'priority_change_date < self.one_year_ago' uses
   datetime.now() - timedelta(days=365) (also naive), so naive
   datetimes are correct.

After the fix, all 5 regression tests pass locally:

  tests/rules/test_assignee_no_login_priority.py .....  [100%]
  ============================== 5 passed in 1.00s ===============================

Fixes mozilla#2901
…ple.json

The previous tests called AssigneeNoLogin() with no args, which made
__init__ -> Nag.__init__ -> People.get_instance() -> People() try to open
./configs/people.json, failing in environments where the file isn't
present (CI workers, fresh checkouts without ./vendor populated).

Patch the singleton with a minimal in-memory People instance so the
tests can run anywhere.
Comment thread bugbot/rules/assignee_no_login.py Outdated
Comment on lines +140 to +141
change.get("field_name") == "priority"
and change.get("added") == current_priority

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We need to find the root cause first. This will just hide the problem, not fix it.

AmSach added 3 commits June 15, 2026 00:23
Pre-commit ruff-format reformatted the test file:
- Drop unused 'timedelta' import.
- Break a long single-line dict literal across multiple lines.

Fixes the failing bugbot tests check on mozilla#2901.
Address review feedback on PR mozilla#2901 from suhaibmujahid that the
.get() approach hides the upstream root cause rather than fixing it.

This change:
- Still does not crash on malformed history entries (defensive)
- Logs a warning with the bug id and the offending entry so the
  upstream data source can be investigated
- Continues iterating so a later valid match can still be returned

Adds a new regression test verifying the warning is emitted and the
lookup still produces a result when malformed entries are present.
The PR mozilla#2901 branch initially added regression tests at
bugbot/tests/rules/test_assignee_no_login_priority.py (master's old path),
then commit 4b6adb3 moved them to tests/rules/... but did not delete the
original copy at bugbot/tests/rules/...

The orphaned copy at the old path is not formatted (a long single-line
dict literal in test_get_priority_change_date_returns_none_when_no_match),
which causes the pre-commit ruff-format hook in Community-TC's 'bugbot
tests' check to fail and reformatt the file, then exit non-zero.

This commit removes the duplicate, so only the properly-formatted
tests/rules/test_assignee_no_login_priority.py remains.

Fixes mozilla#2901 (resolves the Community-TC test failure)
@AmSach

AmSach commented Jun 16, 2026

Copy link
Copy Markdown
Author

Test failure fixed (chore: removed duplicate test file)

The bugbot tests check was failing on ruff-format because the PR branch contained a duplicate of the regression test file at the wrong path:

  • bugbot/tests/rules/test_assignee_no_login_priority.py (orphan from an earlier commit in this branch)
  • tests/rules/test_assignee_no_login_priority.py (current, correctly-located copy)

When I added regression tests in commit 658e5a1, the file was placed at bugbot/tests/rules/... to match master's tree at the time. Commit 4b6adb3 then moved it to tests/rules/... but left the old copy behind, so ruff format (run on the whole repo by pre-commit) kept flagging the orphan and exiting non-zero.

Fix in commit f4ab591: git rm the duplicate at bugbot/tests/rules/test_assignee_no_login_priority.py.

After the fix, the bugbot tests check passed:

  • bugbot tests: ✅ success (2m13s)

Local verification:

$ ruff format --check tests/rules/test_assignee_no_login_priority.py
1 file already formatted
$ ruff check tests/rules/test_assignee_no_login_priority.py
All checks passed!
$ py.test tests/rules/test_assignee_no_login_priority.py -v
6 passed in 0.80s

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