Lightning-AI / Lightning-AI/pytorch-lightning
Loose type annotations of hparams cause Pylint basic type checker false positives
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 31.4k
- Forks
- 3.8k
- Avg merge
- 6d 7h
- Merged PRs (30d)
- 6
Description
### Bug description
Loose type annotation for `hparams` causes false positives in type checkers if hyperparameters are accessed as attributes.
I have identified the problem and will open a PR shortly.
### What version are you seeing the problem on?
v2.1
v2.0
master
### How to reproduce the bug
```python
Simple snippet:
import pytorch_lightning as pl
class TrivialModule(pl.LightningModule):
def __init__(self, arg: int = 1):
super().__init__()
self.save_hyperparameters()
def forward(self, x: T) -> T:
return x * self.hparams.arg
```
### Error messages and logs
Using VSCode, set the pylint basic type checker to "basic".
You will get the following false positive:

This is because `self.hparams` should be annotated as `AttributeDict`, rather than `Union[AttributeDict, MutableMapping]`
### Environment
Current environment
* CUDA:
- GPU:
- NVIDIA A100-PCIE-40GB
- available: True
- version: 11.8
* Lightning:
- lightning-utilities: 0.9.0
- pytorch-lightning: 2.1.1
- torch: 2.0.1
- torch-cluster: 1.6.1
- torch-geometric: 2.3.0
- torchmetrics: 0.11.4
* Packages:
- aiohttp: 3.8.4
- aiohttp-cors: 0.7.0
- aiosignal: 1.3.1
- alembic: 1.11.1
- antlr4-python3-runtime: 4.9.3
- anyio: 3.6.2
- appdirs: 1.4.4
- argcomplete: 3.0.8
- argon2-cffi: 21.3.0
- argon2-cffi-bindings: 21.2.0
- asttokens: 2.2.1
- async-timeout: 4.0.2
- attrs: 23.1.0
- awkward: 2.2.4
- awkward-cpp: 17
- backcall: 0.2.0
- backports.functools-lru-cache: 1.6.4
- beautifulsoup4: 4.12.2
- bleach: 6.0.0
- blessed: 1.20.0
- bokeh: 2.4.3
- cachetools: 5.3.1
- certifi: 2023.5.7
- cffi: 1.15.1
- cfgv: 3.4.0
- charset-normalizer: 3.1.0
- click: 8.1.3
- cloudpickle: 2.2.1
- cmaes: 0.9.1
- colorama: 0.4.6
- colorful: 0.5.5
- colorlog: 6.7.0
- comm: 0.1.3
- configparser: 6.0.0
- contourpy: 1.0.7
- coolname: 2.2.0
- coverage: 7.2.7
- cubinlinker: 0.3.0
- cuda-python: 11.8.2
- cudf: 23.6.1
- cugraph: 23.6.2
- cuml: 23.6.0
- cupy: 12.1.0
- cycler: 0.11.0
- cytoolz: 0.12.0
- dask: 2023.3.2
- dask-cuda: 23.6.0
- dask-cudf: 23.6.1
- debugpy: 1.6.7
- decorator: 5.1.1
- defusedxml: 0.7.1
- distlib: 0.3.6
- distributed: 2023.3.2.1
- distro: 1.8.0
- docker-pycreds: 0.4.0
- docstring-parser: 0.15
- entrypoints: 0.4
- exceptiongroup: 1.1.1
- executing: 1.2.0
- fastjsonschema: 2.17.1
- fastrlock: 0.8
- filelock: 3.12.0
- flit-core: 3.9.0
- fonttools: 4.39.4
- frozenlist: 1.3.3
- fsspec: 2023.6.0
- gitdb: 4.0.10
- gitpython: 3.1.31
- gmpy2: 2.1.2
- gnn-tracking: 0.0.1
- gnn-tracking-hpo: 0.1.0
- gnntrack: 0.0.1
- google-api-core: 2.11.0
- google-auth: 2.19.0
- googleapis-common-protos: 1.59.0
- gpustat: 1.1
- gql: 0.2.0
- graphql-core: 1.1
- greenlet: 2.0.2
- grpcio: 1.51.3
- hpo2: 0.1.0
- hydra-core: 1.3.2
- identify: 2.5.27
- idna: 3.4
- importlib-metadata: 6.6.0
- importlib-resources: 5.12.0
- iniconfig: 2.0.0
- ipykernel: 6.23.1
- ipython: 8.13.2
- ipython-genutils: 0.2.0
- ipywidgets: 8.0.6
- jedi: 0.18.2
- jinja2: 3.1.2
- joblib: 1.2.0
- jsonargparse: 4.22.0
- jsonschema: 4.17.3
- jupyter: 1.0.0
- jupyter-client: 8.2.0
- jupyter-console: 6.6.3
- jupyter-core: 5.3.0
- jupyter-events: 0.6.3
- jupyter-server: 2.6.0
- jupyter-server-terminals: 0.4.4
- jupyterlab-pygments: 0.2.2
- jupyterlab-widgets: 3.0.7
- jupytext: 1.15.1
- kiwisolver: 1.4.4
- lightning-utilities: 0.9.0
- llvmlite: 0.40.1
- locket: 1.0.0
- lstcondensation: 0.0.1
- lz4: 4.3.2
- mako: 1.2.4
- markdown-it-py: 3.0.0
- markupsafe: 2.1.2
- matplotlib: 3.7.1
- matplotlib-inline: 0.1.6
- mdit-py-plugins: 0.4.0
- mdmm: 0.1.3
- mdurl: 0.1.2
- mistune: 2.0.5
- mplhep: 0.3.28
- mplhep-data: 0.0.3
- mpmath: 1.3.0
- msgpack: 1.0.5
- multidict: 6.0.4
- nbclassic: 1.0.0
- nbclient: 0.8.0
- nbconvert: 7.4.0
- nbformat: 5.8.0
- nest-asyncio: 1.5.6
- networkx: 3.1
- nodeenv: 1.8.0
- notebook: 6.5.4
- notebook-shim: 0.2.3
- numba: 0.57.1
- numpy: 1.24.3
- nvidia-ml-py: 11.525.112
- nvidia-ml-py3: 7.352.0
- nvtx: 0.2.5
- object-condensation: 0.1.dev30+g1e5e4df
- ocpaper231: 0.1.0
- omegaconf: 2.3.0
- opencensus: 0.11.2
- opencensus-context: 0.1.3
- optuna: 3.1.1
- overrides: 7.3.1
- packaging: 23.1
- pandas: 1.5.3
- pandocfilters: 1.5.0
- parso: 0.8.3
- partd: 1.4.0
- pathtools: 0.1.2
- pexpect: 4.8.0
- pickleshare: 0.7.5
- pillow: 10.0.0
- pip: 23.1.2
- pipx: 1.2.0
- pkgutil-resolve-name: 1.3.10
- platformdirs: 3.5.1
- pluggy: 1.0.0
- ply: 3.11
- pooch: 1.7.0
- pre-commit: 3.3.3
- prometheus-client: 0.17.0
- promise: 2.3
- prompt-toolkit: 3.0.38
- protobuf: 3.20.0
- psutil: 5.9.5
- ptxcompiler: 0.8.1
- ptyprocess: 0.7.0
- pure-eval: 0.2.2
- py-spy: 0.3.14
- pyarrow: 11.0.0
- pyasn1: 0.5.0
- pyasn1-modules: 0.3.0
- pycparser: 2.21
- pydantic: 1.10.8
- pygments: 2.15.1
- pylibcugraph: 23.6.2
- pylibraft: 23.6.1
- pynvml: 11.4.1
- pyparsing: 3.0.9
- pyperclip: 1.8.2
- pyqt5: 5.15.7
- pyqt5-sip: 12.11.0
- pyrsistent: 0.19.3
- pysocks: 1.7.1
- pytest: 7.3.1
- pytest-cov: 4.1.0
- python-dateutil: 2.8.2
- python-json-logger: 2.0.7
- pytimeparse: 1.1.8
- pytorch-lightning: 2.1.1
- pytz: 2023.3
- pyyaml: 6.0
- pyzmq: 25.0.2
- qtconsole: 5.4.3
- qtpy: 2.3.1
- raft-dask: 23.6.1
- ranger-fm: 1.9.3
- ray: 2.4.0
- requests: 2.31.0
- rfc3339-validator: 0.1.4
- rfc3986-validator: 0.1.1
- rich: 13.4.2
- rmm: 23.6.0
- rsa: 4.9
- rt-stoppers-contrib: 1.1.2
- scienceplots: 2.1.0
- scikit-learn: 1.2.2
- scipy: 1.10.1
- seaborn: 0.12.2
- send2trash: 1.8.2
- sentry-sdk: 1.26.0
- setproctitle: 1.3.2
- setuptools: 68.0.0
- shortuuid: 1.0.11
- sip: 6.7.9
- six: 1.16.0
- smart-open: 6.3.0
- smmap: 5.0.0
- sniffio: 1.3.0
- sortedcontainers: 2.4.0
- soupsieve: 2.3.2.post1
- sqlalchemy: 2.0.15
- stack-data: 0.6.2
- subprocess32: 3.5.4
- sympy: 1.12
- tabulate: 0.9.0
- tblib: 1.7.0
- tensorboardx: 2.6
- terminado: 0.17.1
- threadpoolctl: 3.1.0
- tinycss2: 1.2.1
- toml: 0.10.2
- tomli: 2.0.1
- toolz: 0.12.0
- torch: 2.0.1
- torch-cluster: 1.6.1
- torch-geometric: 2.3.0
- torchmetrics: 0.11.4
- tornado: 6.3.2
- tqdm: 4.65.0
- trackml: 3
- traitlets: 5.9.0
- treelite: 3.2.0
- treelite-runtime: 3.2.0
- triton: 2.0.0
- typeshed-client: 2.3.0
- typing-extensions: 4.6.2
- typing-utils: 0.1.0
- ucx-py: 0.32.0
- uhi: 0.3.3
- ujson: 5.8.0
- uproot: 5.0.9
- urllib3: 2.0.3
- userpath: 1.8.0
- virtualenv: 20.21.0
- wandb: 0.15.11
- wandb-osh: 1.1.2
- watchdog: 3.0.0
- wcwidth: 0.2.6
- webencodings: 0.5.1
- websocket-client: 1.5.2
- wheel: 0.40.0
- widgetsnbextension: 4.0.7
- xonsh: 0.14.1
- yarl: 1.9.2
- zict: 3.0.0
- zipp: 3.15.0
* System:
- OS: Linux
- architecture:
- 64bit
- ELF
- processor: x86_64
- python: 3.10.11
- release: 4.18.0-477.27.1.el8_8.x86_64
- version: #1 SMP Sun Sep 24 11:46:42 EDT 2023
### More info
A workaround for the linter errors is to just access hyperparameters via the dictionary interface.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the LightningModule hparams annotation and the self.hparams access shown in the reproduction. Verify the behavior with Pylint's basic type checker using the provided snippet; done means attribute-style hyperparameter access no longer produces the reported false positive.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100