Skip to content

chore: forbid getattr and setattr in SDK - #4906

Open
neubig wants to merge 10 commits into
mainfrom
forbid-getattr-setattr
Open

chore: forbid getattr and setattr in SDK#4906
neubig wants to merge 10 commits into
mainfrom
forbid-getattr-setattr

Conversation

@neubig

@neubig neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member

HUMAN:


AGENT:
This PR was created by an AI agent (OpenHands) on behalf of the user.

Why

Prevent new dynamic getattr and setattr calls from entering the SDK while the existing migration work is tracked separately.

Summary

Issue Number

Closes #4902

How to Test

  • uv run python scripts/check_forbidden_dynamic_attributes.py /tmp/sample.py reports both forbidden calls and allows direct attribute access.
  • uv run pre-commit run --files .pre-commit-config.yaml scripts/check_forbidden_dynamic_attributes.py runs the configured hooks; the checker itself passes, while the repository's existing SDK calls are intentionally tracked by the child issues.
  • uv run ruff check scripts/check_forbidden_dynamic_attributes.py
  • uv run pycodestyle --max-line-length=88 --ignore=E203,E501,W503,E704 scripts/check_forbidden_dynamic_attributes.py

Video/Screenshots

Not applicable for this lint-only change.

Design Doc

Not applicable.

Type

  • Bug fix
  • Feature
  • Refactor
  • Breaking change
  • Docs / chore

Notes

The checker is intentionally introduced before cleanup so the remaining dynamic access is visible and can be removed in coherent follow-up PRs.


🐳 Agent Server images for this PR — GHCR package, pull/run commands, and all pushed tags (click to expand)

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python-slim amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
python amd64, arm64 nikolaik/python-nodejs:python3.13-nodejs22-slim Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:0453fe5-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-0453fe5-python \
  ghcr.io/openhands/agent-server:0453fe5-python

All tags pushed for this build

ghcr.io/openhands/agent-server:0453fe5-golang-amd64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-golang-amd64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-golang-amd64
ghcr.io/openhands/agent-server:0453fe5-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:0453fe5-golang-arm64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-golang-arm64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-golang-arm64
ghcr.io/openhands/agent-server:0453fe5-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:0453fe5-java-amd64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-java-amd64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-java-amd64
ghcr.io/openhands/agent-server:0453fe5-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:0453fe5-java-arm64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-java-arm64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-java-arm64
ghcr.io/openhands/agent-server:0453fe5-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:0453fe5-python-amd64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python-amd64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python-amd64
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-amd64
ghcr.io/openhands/agent-server:0453fe5-python-arm64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python-arm64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python-arm64
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-arm64
ghcr.io/openhands/agent-server:0453fe5-python-slim-amd64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python-slim-amd64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python-slim-amd64
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-slim-amd64
ghcr.io/openhands/agent-server:0453fe5-python-slim-arm64
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python-slim-arm64
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python-slim-arm64
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-slim-arm64
ghcr.io/openhands/agent-server:0453fe5-golang
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-golang
ghcr.io/openhands/agent-server:forbid-getattr-setattr-golang
ghcr.io/openhands/agent-server:0453fe5-golang_tag_1.21-bookworm
ghcr.io/openhands/agent-server:0453fe5-java
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-java
ghcr.io/openhands/agent-server:forbid-getattr-setattr-java
ghcr.io/openhands/agent-server:0453fe5-eclipse-temurin_tag_17-jdk
ghcr.io/openhands/agent-server:0453fe5-python-slim
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python-slim
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python-slim
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim-slim
ghcr.io/openhands/agent-server:0453fe5-python
ghcr.io/openhands/agent-server:0453fe5190dd00ad2c083ed28d2edaeaa45edf4d-python
ghcr.io/openhands/agent-server:forbid-getattr-setattr-python
ghcr.io/openhands/agent-server:0453fe5-nikolaik_s_python-nodejs_tag_python3.13-nodejs22-slim

About Multi-Architecture Support

  • Each variant tag (e.g., 0453fe5-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 0453fe5-python-amd64) are also available if needed

Add a focused pre-commit checker for getattr and setattr calls in SDK Python files.\n\nCo-authored-by: openhands <openhands@all-hands.dev>
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Python API breakage checks — ✅ PASSED

Result:PASSED

Action log

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

REST API breakage checks (OpenAPI) — ✅ PASSED

Result:PASSED

Action log

The forbidden-attributes hook introduced in this PR flagged 127 existing
getattr/setattr calls across the SDK, blocking pre-commit. Add a committed
baseline (keyed on file + call name + source-line hash) so the hook only
reports *new* violations. This lets the enforcement ship now while the
cleanup work (#4903, #4904, #4905) removes the legacy calls.

Co-authored-by: openhands <openhands@all-hands.dev>
@neubig
neubig marked this pull request as ready for review September 8, 2026 12:09
@neubig
neubig requested a review from all-hands-bot September 8, 2026 12:09
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 77d32750ebb776ba44a904454ee67850da0198e3
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/863b400d-4314-4789-bcfe-d4cf126b693f

This comment was posted by an AI agent (OpenHands).

@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 77d32750ebb776ba44a904454ee67850da0198e3
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/e66bc050-ca90-4c43-8c2a-b9a5835af472

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

🟡 Acceptable — the AST check is straightforward, but the baseline identity loses occurrence counts and therefore does not actually prevent all new calls.

The Validate PR description check is also failing because the human-only HUMAN: field still contains only its placeholder. A human author needs to fill that field before merge; I have not edited it.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM
    This only affects development enforcement, not SDK runtime behavior, but the central guardrail can silently accept newly added forbidden calls.

VERDICT:
Needs rework: Preserve occurrence counts when comparing current calls with the baseline.

KEY INSIGHT:
A baseline for repeated syntax must be a multiset, not a membership set.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

Comment thread scripts/check_forbidden_dynamic_attributes.py Outdated

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

🟡 Acceptable — the AST approach is straightforward, but the baseline comparison currently permits new forbidden calls in a common case.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM
    This is tooling-only and does not alter SDK runtime behavior, but the multiplicity bug weakens the central enforcement guarantee and can let new getattr/setattr calls merge unnoticed.

VERDICT:
Needs rework: Preserve occurrence counts when comparing current calls with the baseline.

KEY INSIGHT:
A baseline for occurrences must retain multiplicity; set membership only proves that an identical line existed somewhere in the file.

Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

Comment thread scripts/check_forbidden_dynamic_attributes.py Outdated
The baseline was loaded as a set, which deduplicates entries with the same
(file, name, hash) key. This means adding another copy of an already-baselined
call would not be detected. Switch to Counter (multiset) so occurrence counts
are preserved: a new violation is any occurrence that exceeds the baseline
count for its key.

Addresses all-hands-bot review feedback.
@neubig
neubig requested a review from all-hands-bot September 8, 2026 12:19
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: c1c13c5abb326e9c279ea63c14dc3ccbb45410df
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/9544bfab-c458-4deb-91d1-290e765ca454

This comment was posted by an AI agent (OpenHands).

When a baselined call is removed from the codebase, the baseline entry
becomes stale. Previously this was only a note; now it causes a failure,
requiring --update-baseline to permanently shrink the allowance rather
than leaving a reusable slot.

Addresses all-hands-bot review feedback.
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 0189babe735ae0d6fa908c68581870a1bf6b3477
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/dbb1129a-a461-4194-993e-04c47e9eea81

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

🟡 Acceptable — the multiset fix catches duplicate additions while the baseline is current, but stale baseline credit can still be reused after cleanup.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM
    This is development tooling only, so it does not change SDK runtime behavior. However, the enforcement can silently permit a forbidden call to be reintroduced after an existing occurrence is removed.

VERDICT:
Needs rework: Make stale baseline entries fail the check so cleanup cannot leave reusable allowance behind.

KEY INSIGHT:
A suppression baseline remains sound only if unused allowances cannot survive successful checks.

Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

Comment thread scripts/check_forbidden_dynamic_attributes.py
Covers multiset comparison (duplicate baselined lines are rejected) and
stale baseline entries (removed calls shrink the allowance). Addresses
all-hands-bot review feedback requesting regression tests.
@all-hands-bot

Copy link
Copy Markdown
Collaborator

👋 This PR needs a couple of things fixed before OpenHands can review it:

  • the PR description's HUMAN: section needs at least 20 characters describing what you tested, not just the template placeholder

Push an update once this is addressed and this check re-runs automatically.

This is an automated check - no AI was used to generate this comment.

Covers the exact sequence the reviewer described: baseline a getattr,
replace with x.y (stale failure forces refresh), reintroduce the identical
line → now correctly rejected as a new violation.
@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

Updates pushed addressing all review feedback:

  • Multiset comparison: baseline now uses collections.Counter to preserve occurrence counts — duplicating a baselined line is correctly rejected (c1c13c5)
  • Stale entries fail: removed calls cause exit 1, forcing --update-baseline to permanently shrink the allowance (0189bab)
  • Regression tests: 8 tests covering duplicate lines, stale entries, and the remove-then-reintroduce scenario (23cbafd, 1c335ef)
  • All review threads resolved

@all-hands-bot please re-review the latest commit.

@neubig
neubig requested a review from all-hands-bot September 8, 2026 12:27
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 1c335ef262eba3e1b860809044a88874d396f7bb
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/ae321002-ce4f-4478-b4d2-77aeb0df3280

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

🟡 Acceptable — stale entries now fail for modified files, but deleting a baselined file bypasses that validation entirely.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM
    This is development tooling only, but a common file-deletion path can leave reusable baseline allowances and weaken the intended guardrail.

VERDICT:
Needs rework: Ensure stale baseline validation also runs when SDK files are deleted.

KEY INSIGHT:
A baseline can only shrink reliably if validation runs against repository state, not only the existing files pre-commit passes to the hook.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

Comment thread .pre-commit-config.yaml Outdated
Top-level tests/test_*.py files are rejected by the test directory allowlist
CI check. Move the test file to tests/cross/ (where other check-script
tests live) and fix the script path (parents[1] → parents[2]).

Also fix the baseline isolation bug: BASELINE_FILE must be overridden AFTER
exec_module, not before, because the module-level assignment would clobber
the pre-set temp path and write --update-baseline output to the real file.

Co-authored-by: openhands <openhands@all-hands.dev>
@all-hands-bot

Copy link
Copy Markdown
Collaborator

Thanks for the updates. I re-reviewed latest commit b3b7393ea0bba078fead15b34c5481b80f6e61cc. The multiset fix works, stale entries for checked files now fail, and the relocated test suite passes without mutating the committed baseline. One blocking bypass remains:

Deleted files leave reusable baseline allowances (scripts/check_forbidden_dynamic_attributes.py:104-120). Stale entries are filtered to passed_files, but deleted files are not among the paths passed by pre-commit. Even a full scan of all existing SDK files therefore cannot mark entries for a deleted path as stale. If a baselined file is deleted, its allowance remains; restoring that path later with the same forbidden line can reuse the old allowance.

I reproduced the underlying behavior by baselining one file, deleting it, and calling main([]): it returned 0 while the baseline still contained the deleted file's entry. Please make missing baselined paths stale independently of passed_files (and add a deleted-file/remove-then-restore regression test), so deleting code also forces the allowance to shrink.

Verification performed:

  • uv run pytest -q tests/cross/test_check_forbidden_dynamic_attributes.py — 8 passed; committed baseline unchanged.
  • Direct deleted-file reproduction — main([]) returned 0 with a stale entry for the deleted file.

Verdict: ❌ Needs rework before approval. The current fixes close the duplicate-line and in-place removal cases, but deletion still leaves reusable baseline credit.

Generated by OpenHands AI on behalf of the user.

The pre-commit hook previously used pass_filenames: true with
always_run: false, which meant deletions of baselined SDK files
were never checked (pre-commit does not pass deleted files to hooks).

Changes:
- Set pass_filenames: false and always_run: true so the hook always
  validates the entire SDK
- Add _discover_sdk_files() to auto-enumerate SDK Python files when
  no paths are passed
- Update stale detection to flag baseline entries for files that no
  longer exist (deleted), not just files that were explicitly checked
- Add test_deleted_baselined_file_is_stale regression test

Addresses all-hands-bot review comment on .pre-commit-config.yaml.

Co-authored-by: openhands <openhands@all-hands.dev>
@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

All review feedback has been addressed in 2571ad2. All 4 review threads are resolved. Please re-review and approve.

@neubig
neubig requested a review from all-hands-bot September 8, 2026 12:39
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: 2571ad2e6dd79765768c84bed349bfefcefd8baa
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/982d50d8-8e46-4820-b886-ac16f407d756

This comment was posted by an AI agent (OpenHands).

- Collapse multi-line expressions to single-line per ruff format
- Fix _write_py return type: None -> Path
- Add assert for importlib spec None-check (pyright)
- Add type: ignore for dynamic module attribute assignment

Co-authored-by: openhands <openhands@all-hands.dev>
@all-hands-bot

Copy link
Copy Markdown
Collaborator

🤖 OpenHands is reviewing this PR.

Head commit: aadcb7b1667a5b43d3d957c33e638ca975f110e7
View the conversation: https://oss-agent-canvas.ngrok.dev/conversations/d9cfd42e-d52c-4334-bb7f-a96cf534051d

This comment was posted by an AI agent (OpenHands).

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This review was created by an AI agent (OpenHands) on behalf of the repository maintainers.

🟡 Acceptable — the deletion and stale-baseline fixes work, but multiline calls are still identified too weakly to enforce the stated invariant.

Separately, the PR description's human-only HUMAN: field still contains only the placeholder. A human author needs to fill it before the description check can pass; I have not edited it.

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM
    This is development tooling only, so it does not affect SDK runtime behavior. However, the guardrail can silently accept genuine edits to existing multiline getattr/setattr calls, weakening its central enforcement guarantee.

VERDICT:
Needs rework: Include the complete call expression in baseline identity, not only its first physical line.

KEY INSIGHT:
An AST-based baseline should identify the AST call's full source span; a first-line hash cannot distinguish multiline calls whose arguments change.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

Comment thread scripts/check_forbidden_dynamic_attributes.py Outdated
@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

Re-requesting review from @all-hands-bot after fixing pre-commit formatting and pyright type errors in commit aadcb7b. All pre-commit hooks and tests pass locally.

@neubig
neubig requested a review from all-hands-bot September 8, 2026 12:45
@all-hands-bot

Copy link
Copy Markdown
Collaborator

Thanks for the update. I re-reviewed current head aadcb7b1667a5b43d3d957c33e638ca975f110e7. The formatting and pyright fixes do not address the outstanding multiline-call blocker from the latest review.

scripts/check_forbidden_dynamic_attributes.py still hashes only lines[node.lineno - 1]. I reproduced the bypass by baselining:

value = getattr(
    old_object, "old_name"
)

and then changing it to:

value = getattr(
    new_object, "new_name"
)

The checker still returned 0, because the unchanged first line (value = getattr() is the complete baseline identity. Please hash the full AST call span (for example with ast.get_source_segment(source, node)), regenerate the baseline, and add the requested multiline regression test.

Verification performed:

  • uv run pytest -q tests/cross/test_check_forbidden_dynamic_attributes.py — 9 passed.
  • Direct multiline changed-arguments reproduction — checker returned 0 (expected 1).

Verdict: ❌ Needs rework before approval; the previously reported blocker remains reproducible on the current head.

Generated by OpenHands AI on behalf of the user.

Address bot review feedback: baseline identity now uses the complete AST
call source segment via ast.get_source_segment, not just the first
physical line. This ensures argument changes on subsequent lines of
multiline getattr/setattr calls are detected as new violations.

Also adds test_multiline_arg_change_is_caught regression test and
regenerates the baseline with the new hash algorithm.

Co-authored-by: openhands <openhands@all-hands.dev>
@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

Re-requesting review from @all-hands-bot for commit 0453fe5. All four previously flagged issues have been addressed:

  1. Multiset/Counter comparison (c1c13c5)
  2. Stale entries now fail (0189bab)
  3. Remove-then-reintroduce regression test (1c335ef)
  4. Multiline call detection via ast.get_source_segment (0453fe5)

All 10 unit tests pass, and the pre-commit hook itself passes.

@neubig
neubig requested review from all-hands-bot and removed request for all-hands-bot September 8, 2026 13:03
@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

@all-hands-bot Please re-review commit 0453fe5. All four previously flagged issues have been addressed in commits since your last review (2571ad2). All CI checks pass except 'Validate PR description' which requires a human-written note in the HUMAN section. All review threads have been resolved.

@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

Requesting re-review from @all-hands-bot on commit 0453fe5. All previously raised review threads have been addressed and resolved. Please review the latest changes.

@neubig
neubig requested review from all-hands-bot and removed request for all-hands-bot September 8, 2026 13:14

@all-hands-bot all-hands-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. The full-call source hashing addresses the multiline bypass, and the regression coverage exercises it. I also verified the targeted test suite (10 passed), the checker itself, and pre-commit on the changed files.

The remaining failing check is Validate PR description (the human-only PR metadata gate), not a code failure.

Generated by OpenHands AI on behalf of the user.

@all-hands-bot

Copy link
Copy Markdown
Collaborator

Re-review complete on 0453fe5190: approved. The full-call source hashing addresses the multiline bypass, and the new regression test covers it.

Validation performed:

  • targeted checker tests: 10 passed
  • forbidden-attribute checker: passed
  • pre-commit on changed files: passed

The remaining failing check is Validate PR description (the human-only PR metadata gate), not a code failure.

Generated by OpenHands AI on behalf of the user.

@neubig

neubig commented Sep 8, 2026

Copy link
Copy Markdown
Member Author

The only failing check is Validate PR description, which requires at least 20 visible characters in the HUMAN: section of the PR body. The PR template explicitly instructs AI agents not to edit this section, so this needs human approval. A human author needs to replace the placeholder comment between HUMAN: and AGENT: with a short note (at least 20 visible characters).

Summary of what was done:

  • All other CI checks (48/49) are green on the current head SHA 0453fe5190.
  • all-hands-bot has APPROVED the PR.
  • All 5 review threads are resolved (0 unresolved).
  • PR is mergeable (no conflicts).

The sole remaining blocker is the empty HUMAN: section, which only a human can fill in.

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.

Forbid dynamic getattr and setattr usage in the SDK

3 participants