Skip to content

fix(npu): resolve connector classes through getattr in the factory - #567

Merged
jiangkuaixue123 merged 1 commit into
vllm-project:mainfrom
Pingzii:fix/camp2p-factory-getattr
Nov 12, 2026
Merged

jiangkuaixue123 merged 1 commit into
vllm-project:mainfrom
Pingzii:fix/camp2p-factory-getattr

Conversation

@Pingzii

@Pingzii Pingzii commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

What this fixes

camp2p resolves its public names through a package-level __getattr__ (#503). The connector factory still read the class out of the module dictionary:

connector_cls = vars(module)[class_name]

For a lazily exported class that dictionary is empty, so every CAMP2P start fails before the worker can build the connector:

File "afd_plugin/connectors/factory.py", line 40, in loader
    connector_cls = vars(module)[class_name]
KeyError: 'CAMP2pAFDConnector'

Change

Read the class with getattr, which follows the __getattr__ hook and behaves exactly as before for eagerly exported modules.

The regression case moved into tests/unit/connectors/test_p2p_connector.py with the other factory tests: it registers a temporary connector backed by a module that only answers through __getattr__, and registers into a copied _registry so the temporary entry does not outlive the test. The missing-name case was dropped; the standalone test file is gone.

Validation

  • The moved case fails with the old vars() lookup.
  • tests/unit/connectors/test_p2p_connector.py and the maintained CPU suite pass.
  • DCO, label and pre-commit pass.

@jiangkuaixue123

Copy link
Copy Markdown
Collaborator

The factory change looks good. Could we fold the lazy-export regression case into the existing factory coverage in test_p2p_connector.py and drop the new test file? One assertion captures the bug: resolving a class exposed only through module-level __getattr__ raises KeyError on the base commit and returns the class with this fix. The temporary module can define the hook directly. Please also scope the factory registration to the test so its loader is removed along with the temporary module.

I'd drop the missing-name case. The old dictionary lookup raised KeyError for that input, so asserting AttributeError introduces a new exception contract beyond the CAMP2P fix. With the regression case in the existing file, the current design-doc link still covers it.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Nov 11, 2026
@Pingzii

Pingzii commented Nov 11, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I'll move the lazy-export regression case into test_p2p_connector.py and scope both the temporary module and the factory registration to that test. I'll drop the missing-name case and keep the existing design-doc link.

@Pingzii
Pingzii force-pushed the fix/camp2p-factory-getattr branch from f7bca2e to 7e4323e Compare November 11, 2026 12:23
@github-actions github-actions Bot added the NVIDIA NVIDIA GPU, CUDA, and related changes label Nov 11, 2026
The CAMP2P package resolves its public names lazily, so the class is not in the
module dictionary and the factory's vars(module) lookup raises KeyError for
CAMP2pAFDConnector at worker start. getattr follows the package __getattr__ hook and
keeps eager modules working the same way.

The regression case lives with the other P2P factory tests and registers into a
copied registry, so the temporary entry does not outlive the test.

Signed-off-by: 宋元盟 <songyuanmeng2@huawei.com>
@Pingzii
Pingzii force-pushed the fix/camp2p-factory-getattr branch from 7e4323e to 82ef9ca Compare November 11, 2026 12:23
@Pingzii

Pingzii commented Nov 11, 2026

Copy link
Copy Markdown
Contributor Author

This restores CAMP2P startup on main. #503 turned afd_plugin.connectors.npu.camp2p into a lazy package, but the factory still read the class out of the module dictionary (vars(module)[class_name]), so every CAMP2P start failed with KeyError: 'CAMP2pAFDConnector' before the worker could build the connector.

Scope: factory.py resolves the class with getattr; the regression case now lives in tests/unit/connectors/test_p2p_connector.py and registers into a copied _registry, so the temporary entry does not outlive the test. No other production file changes.

Checks at 82ef9ca: DCO, label and pre-commit pass; MERGEABLE against main@9393311.

The test-side guards (async FFN vllm_ascend, module stand-ins, collection isolation) are in #570 and touch different files, so the two can merge in either order.

@jiangkuaixue123
jiangkuaixue123 merged commit 671a840 into vllm-project:main Nov 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation NVIDIA NVIDIA GPU, CUDA, and related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants