40 lines
1.2 KiB
Markdown
40 lines
1.2 KiB
Markdown
---
|
|
paths:
|
|
- "**/*.py"
|
|
---
|
|
|
|
# Don't use `getattr` / `hasattr` for defensive access
|
|
|
|
Over-defensive `getattr(obj, "field", default)` / `hasattr(obj, "field")` hide
|
|
errors and defeat strict type checking. If a field is always present, accessing
|
|
it defensively is confusing and masks real bugs. Prefer:
|
|
|
|
1. **`isinstance` for type narrowing** — check the type, then access fields directly:
|
|
|
|
```python
|
|
if (
|
|
isinstance(obj, (TokenizedGenerateReqInput, TokenizedEmbeddingReqInput))
|
|
and obj.mm_inputs
|
|
):
|
|
```
|
|
(see `python/sglang/srt/managers/mm_utils.py`)
|
|
|
|
2. **Always set the field (to `None` if needed), then do a `None` check** — the
|
|
field should always exist, so a `None` / non-`None` check is enough:
|
|
|
|
```python
|
|
obj.field = None # in __init__ / construction
|
|
...
|
|
if obj.field is not None:
|
|
...
|
|
```
|
|
|
|
Bad — `server_args` always has `revision`, so `getattr` is misleading and swallows
|
|
a real `AttributeError` if the field is ever renamed:
|
|
|
|
```python
|
|
revision=getattr(server_args, "revision", None), # BAD
|
|
revision=server_args.revision, # GOOD
|
|
```
|
|
(see `python/sglang/srt/managers/template_detection.py`)
|