[Lint]Style: Convert vllm-ascend/compilation to ruff format (#5912)

### What this PR does / why we need it?
Convert `vllm-ascend/compilation` to ruff format.

### Does this PR introduce _any_ user-facing change?
During this migration, we encountered some **errors** in our CI and
testing environments, such as:
```
vllm_ascend/utils.py:653: in <module>
    def register_ascend_customop(vllm_config: VllmConfig | None = None):
                                              ^^^^^^^^^^^^^^^^^
E   TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'
```

**1. Root Cause Analysis:**
The project uses a common pattern to break circular dependencies:
```python
if TYPE_CHECKING:
    from vllm.config import VllmConfig
else:
    VllmConfig = None  # Placeholder assigned at runtime
```
When Python parses the function definition `def
register_ascend_customop(vllm_config: VllmConfig | None)`, it attempts
to evaluate the expression `VllmConfig | None`.
Since `VllmConfig` is assigned `None` at runtime, the expression
effectively becomes `None | None`. In Python, `None` is an instance of
`NoneType`. While the `|` operator is implemented for Type objects
(classes), it is not supported for `NoneType` instances, leading to the
`TypeError` shown above.

**2. Solution:**
To maintain the modern `|` syntax required by our new linting standards
while preserving our dependency management strategy, I have introduced:
```python
from __future__ import annotations
```
at the top of the affected files. This enables **Postponed Evaluation of
Annotations (PEP 563)**.

**3. Impact and Benefits:**
- By enabling `annotations`, Python no longer executes the `VllmConfig |
None` operation during module load. Instead, it stores the annotation as
a string literal, completely avoiding the `None | None` calculation.
- We can keep the `VllmConfig = None` placeholders. This ensures that
other modules can still import these symbols without triggering an
`ImportError`, maintaining a stable dependency graph.
- IDEs and static type checkers (MyPy/Pyright) continue to resolve the
types correctly. This allows us to use modern syntax without sacrificing
type safety or runtime stability.
- The only side effect is that `__annotations__` will now return strings
instead of type objects. Since this module does not use runtime type
enforcement or reflection, this change has zero negative impact on
existing functionality.
### How was this patch tested?

- vLLM version: v0.13.0
- vLLM main:
11b6af5280

---------

Signed-off-by: MrZ20 <2609716663@qq.com>
This commit is contained in:
SILONG ZENG
2026-01-16 20:57:46 +08:00
committed by GitHub
parent 3af91e5ac4
commit 52086394ae
16 changed files with 996 additions and 1140 deletions

View File

@@ -21,9 +21,9 @@ This module generates the service_profiling_symbols.yaml configuration file
to ~/.config/vllm_ascend/ directory.
"""
import contextlib
import tempfile
from pathlib import Path
from typing import Optional
import vllm
from vllm.logger import logger
@@ -120,7 +120,7 @@ SERVICE_PROFILING_SYMBOLS_YAML = """
def get_config_dir() -> Path:
"""
Get the vllm_ascend configuration directory path.
Returns:
Path: The path to ~/.config/vllm_ascend/ directory.
"""
@@ -129,32 +129,30 @@ def get_config_dir() -> Path:
return config_dir
def _cleanup_temp_file(tmp_path: Optional[Path]) -> None:
def _cleanup_temp_file(tmp_path: Path | None) -> None:
"""
Clean up a temporary file if it exists.
Args:
tmp_path: Path to the temporary file to clean up.
"""
if tmp_path is not None and tmp_path.exists():
try:
with contextlib.suppress(OSError):
tmp_path.unlink()
except OSError:
pass # Ignore cleanup errors
def generate_service_profiling_config() -> Optional[Path]:
def generate_service_profiling_config() -> Path | None:
"""
Generate the service_profiling_symbols.yaml configuration file
to ~/.config/vllm_ascend/ directory.
If the configuration file already exists, this function will skip
creating it and return the existing file path.
If any error occurs during file creation, it will be logged but
will not interrupt the execution. The function will return None
to indicate that the file could not be created.
Returns:
Optional[Path]: The path to the generated (or existing) configuration file.
Returns None if file creation failed.
@@ -170,9 +168,7 @@ def generate_service_profiling_config() -> Optional[Path]:
try:
config_dir.mkdir(parents=True, exist_ok=True)
except (OSError, PermissionError) as e:
logger.error(
f"Failed to create configuration directory {config_dir}: {e}",
exc_info=True)
logger.error(f"Failed to create configuration directory {config_dir}: {e}", exc_info=True)
return None
# Write the configuration file atomically using a temporary file
@@ -180,13 +176,9 @@ def generate_service_profiling_config() -> Optional[Path]:
tmp_path = None
try:
# Create a temporary file in the same directory for atomic write
with tempfile.NamedTemporaryFile(mode='w',
encoding='utf-8',
dir=config_dir,
delete=False,
suffix='.tmp',
prefix=CONFIG_FILENAME +
'.') as tmp_file:
with tempfile.NamedTemporaryFile(
mode="w", encoding="utf-8", dir=config_dir, delete=False, suffix=".tmp", prefix=CONFIG_FILENAME + "."
) as tmp_file:
tmp_file.write(SERVICE_PROFILING_SYMBOLS_YAML)
tmp_path = Path(tmp_file.name)
@@ -194,8 +186,7 @@ def generate_service_profiling_config() -> Optional[Path]:
tmp_path.replace(config_file)
return config_file
except (OSError, PermissionError) as e:
logger.error(f"Failed to write configuration file {config_file}: {e}",
exc_info=True)
logger.error(f"Failed to write configuration file {config_file}: {e}", exc_info=True)
return None
finally:
# Clean up the temporary file if it wasn't successfully replaced