From 6ea5d5b70db40eeb293012cccf89f69b214e7388 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:09:50 +0000 Subject: [PATCH 01/10] Initial plan From e1a4d4834553a418d87cd935fd284f33e663f3b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:20:28 +0000 Subject: [PATCH 02/10] Start creating copilot instructions file Co-authored-by: Pierre-Sassoulas <5493666+Pierre-Sassoulas@users.noreply.github.com> --- doc/user_guide/checkers/features.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/user_guide/checkers/features.rst b/doc/user_guide/checkers/features.rst index d4fb243c8d..510d95ec62 100644 --- a/doc/user_guide/checkers/features.rst +++ b/doc/user_guide/checkers/features.rst @@ -106,8 +106,8 @@ Basic checker Messages a try...finally block: the exceptions raised in the try clause will be silently swallowed instead of being re-raised. :break-in-finally (W0137): *'break' discouraged inside 'finally' clause* - Emitted when the `break` keyword is found inside a finally clause. This - will raise a SyntaxWarning starting in Python 3.14. + Emitted when the `break` keyword is found inside a finally clause. This will + raise a SyntaxWarning starting in Python 3.14. :continue-in-finally (W0136): *'continue' discouraged inside 'finally' clause* Emitted when the `continue` keyword is found inside a finally clause. This will raise a SyntaxWarning starting in Python 3.14. @@ -193,7 +193,7 @@ Basic checker Messages :missing-parentheses-for-call-in-test (W0126): *Using a conditional statement with potentially wrong function or method call due to missing parentheses* Emitted when a conditional statement (If or ternary if) seems to wrongly call a function due to missing parentheses -:comparison-of-constants (R0133): *Comparison between constants: '%s %s %s' has a constant value* +:comparison-of-constants (R0133): *Comparison between constants: "%s %s %s" has a constant value* When two literals are compared with each other the result is a constant. Using the constant directly is both easier to read and more performant. Initializing 'True' and 'False' this way is not required since Python 2.3. From 7d3a9aa8e7565bbc07aae57fc792fd121f314f66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:23:50 +0000 Subject: [PATCH 03/10] Create comprehensive copilot instructions with validated commands Co-authored-by: Pierre-Sassoulas <5493666+Pierre-Sassoulas@users.noreply.github.com> --- .github/copilot-instructions.md | 112 ++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..cf9191c081 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,112 @@ +# Pylint Development Instructions + +Always follow these instructions first and fallback to additional search and context gathering only if the information in these instructions is incomplete or found to be in error. + +## Working Effectively + +- Bootstrap and set up the development environment: + - `python --version` -- verify Python 3.10+ is available + - `pip install -e .` -- install pylint in development mode (takes ~30-60 seconds) + - `pip install coverage pytest pytest-cov pytest-xdist tox` -- install core test dependencies + +- Run basic validation: + - `pylint --help` -- verify pylint is working correctly + - `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only (takes ~20 seconds, some import errors expected) + +- Run tests: + - `pytest tests/test_check_parallel.py -v` -- run a quick test file (~2 seconds) + - `pytest tests/test_self.py -v` -- run core functionality tests (~15 seconds) + - `pytest tests/test_functional.py::test_functional --maxfail=5 -q` -- run functional tests (takes ~60 seconds, NEVER CANCEL, set timeout to 120+ seconds) + - **NEVER CANCEL:** Full test suite takes 60+ seconds. Always wait for completion. + +- Install additional development dependencies: + - `pip install pre-commit` -- for code formatting and linting + - `cd doc && pip install -r requirements.txt` -- for documentation (requires network access) + +- Build documentation: + - `cd doc && make install-dependencies` -- install doc dependencies (~10 seconds) + - `cd doc && make html` -- build documentation (~3 minutes, NEVER CANCEL, may fail without network access) + - **NEVER CANCEL:** Documentation build takes up to 3 minutes. Set timeout to 300+ seconds. + +## Validation + +- Always run pylint on your changes before committing: + - `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run + - `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and warnings + +- Run formatting and pre-commit checks: + - `pre-commit run --all-files` -- run all formatting checks (requires network for initial setup) + - **Network dependency:** pre-commit may fail in isolated environments due to hook downloads + +- **VALIDATION SCENARIOS:** Always test your changes by: + - Running pylint on a sample Python file: `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` (should find naming issues) + - Verifying pylint CLI still works: `pylint --help` and `pylint --list-msgs | head -10` + - Testing message ID functionality: `pylint --help-msg=C0103` (should show invalid-name help) + - Checking specific module: `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` (should get 10.00/10 rating) + +## Common Tasks + +### Running specific test categories: +- Functional tests: `pytest tests/test_functional.py -k "test_name" -v` +- Individual functional test: `pytest "tests/test_functional.py::test_functional[abstract_class_instantiated]" -v` (~1 second) +- Unit tests: `pytest tests/test_self.py -v` +- Quick smoke test: `pytest tests/test_func.py tests/test_check_parallel.py -v` (~2 seconds, 53 tests) + +### Understanding the codebase structure: +``` +pylint/ # Main package +├── checkers/ # All pylint checkers (rules) +├── config/ # Configuration handling +├── message/ # Message system +├── reporters/ # Output formatters +├── testutils/ # Testing utilities +└── extensions/ # Optional extensions + +tests/ # Test suite +├── functional/ # Functional test files (.py files with expected output) +├── test_*.py # Unit tests +└── data/ # Test data files + +doc/ # Documentation +├── user_guide/ # User documentation +├── development_guide/ # Developer documentation +└── additional_tools/ # Tools documentation +``` + +### Key files to know: +- `pyproject.toml` -- Main configuration (dependencies, build, tools) +- `tox.ini` -- Multi-environment testing configuration +- `.pre-commit-config.yaml` -- Code quality checks configuration +- `pylintrc` -- Pylint's own configuration +- `script/` -- Utility scripts for development + +### Creating new checkers: +- Use `python script/get_unused_message_id_category.py` to get unused message IDs (outputs next available ID) +- Look at existing checkers in `pylint/checkers/` for patterns +- Add functional tests in `tests/functional/` + +### Working with functional tests: +- Tests are in `tests/functional/` with `.py` files and corresponding `.txt` files for expected output +- Run individual functional test: `pytest tests/test_functional.py::test_functional[test_name] -v` + +## Critical Timing Information + +- **NEVER CANCEL:** All operations that show "NEVER CANCEL" may take significant time +- Functional test suite: 60 seconds (set timeout to 120+ seconds) +- Documentation build: 180 seconds (set timeout to 300+ seconds) +- Full pylint self-check: 20 seconds (set timeout to 60+ seconds) +- Individual test files: 1-15 seconds + +## Known Issues and Workarounds + +- **Network connectivity required:** Documentation build and pre-commit setup require internet access +- **Tox may fail:** In isolated environments, use direct pytest and pip commands instead of tox +- **Import errors in self-check:** Some import errors when running pylint on itself are expected (git dependencies not installed) + +## Environment Limitations + +- Some network-dependent operations may fail in isolated environments +- Use direct pip and pytest commands when tox environments fail to build +- Documentation build requires network access to fetch external inventories + +Always build and exercise your changes by running pylint on sample code to ensure functionality works correctly. \ No newline at end of file From 8cc79d53e0b2b01d86aa0853696688ade6498936 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:35:24 +0000 Subject: [PATCH 04/10] Regenerate copilot instructions from contributor guide and revert unrelated changes Co-authored-by: Pierre-Sassoulas <5493666+Pierre-Sassoulas@users.noreply.github.com> --- .github/copilot-instructions.md | 241 ++++++++++++++++++--------- doc/user_guide/checkers/features.rst | 6 +- 2 files changed, 163 insertions(+), 84 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index cf9191c081..51977131f9 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,111 +2,190 @@ Always follow these instructions first and fallback to additional search and context gathering only if the information in these instructions is incomplete or found to be in error. -## Working Effectively - -- Bootstrap and set up the development environment: - - `python --version` -- verify Python 3.10+ is available - - `pip install -e .` -- install pylint in development mode (takes ~30-60 seconds) - - `pip install coverage pytest pytest-cov pytest-xdist tox` -- install core test dependencies - -- Run basic validation: - - `pylint --help` -- verify pylint is working correctly - - `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only (takes ~20 seconds, some import errors expected) - -- Run tests: - - `pytest tests/test_check_parallel.py -v` -- run a quick test file (~2 seconds) - - `pytest tests/test_self.py -v` -- run core functionality tests (~15 seconds) - - `pytest tests/test_functional.py::test_functional --maxfail=5 -q` -- run functional tests (takes ~60 seconds, NEVER CANCEL, set timeout to 120+ seconds) - - **NEVER CANCEL:** Full test suite takes 60+ seconds. Always wait for completion. - -- Install additional development dependencies: - - `pip install pre-commit` -- for code formatting and linting - - `cd doc && pip install -r requirements.txt` -- for documentation (requires network access) - -- Build documentation: - - `cd doc && make install-dependencies` -- install doc dependencies (~10 seconds) - - `cd doc && make html` -- build documentation (~3 minutes, NEVER CANCEL, may fail without network access) - - **NEVER CANCEL:** Documentation build takes up to 3 minutes. Set timeout to 300+ seconds. - -## Validation - -- Always run pylint on your changes before committing: - - `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run - - `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and warnings - -- Run formatting and pre-commit checks: - - `pre-commit run --all-files` -- run all formatting checks (requires network for initial setup) - - **Network dependency:** pre-commit may fail in isolated environments due to hook downloads - -- **VALIDATION SCENARIOS:** Always test your changes by: - - Running pylint on a sample Python file: `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` (should find naming issues) - - Verifying pylint CLI still works: `pylint --help` and `pylint --list-msgs | head -10` - - Testing message ID functionality: `pylint --help-msg=C0103` (should show invalid-name help) - - Checking specific module: `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` (should get 10.00/10 rating) - -## Common Tasks +## Development Environment Setup + +### Basic Installation +Clone and set up pylint development environment: +- `git clone https://github.com/pylint-dev/pylint` -- clone repository +- `cd pylint` -- enter directory +- `python3 --version` -- verify Python 3.8+ is available (development requires 3.8+) +- `python3 -m venv venv` -- create virtual environment +- `source venv/bin/activate` -- activate virtual environment (Linux/Mac) +- `pip install -r requirements_test_min.txt` -- install test dependencies (~30 seconds) +- `pip install -e .` -- install pylint in editable mode (~30-60 seconds) + +### Optional Setup Steps +- `pre-commit install` -- enable pre-commit hooks for autoformatting +- `pip install pre-commit` -- install pre-commit separately if needed + +### Astroid Development (if needed) +If working on astroid changes: +- `git clone https://github.com/pylint-dev/astroid.git` -- clone astroid +- `pip install -e astroid/` -- install astroid in editable mode +- `cd astroid/ && git switch my-astroid-dev-branch` -- switch to development branch + +## Running Tests + +### Core Test Commands +- `pytest tests/test_functional.py -k test_functional` -- run functional tests (~60 seconds, NEVER CANCEL, set timeout to 120+ seconds) +- `pytest tests/` -- run all tests (several minutes, NEVER CANCEL, set timeout to 300+ seconds) +- `python3 -m pytest` -- run tests with local python +- `pytest tests/test_check_parallel.py -v` -- quick test file (~2 seconds) + +### Specific Test Types +- **Functional tests:** `pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]"` -- single functional test (~1 second) +- **Unit tests:** Located in `/tests/` directory, test specific pylint functionality +- **Configuration tests:** In `/tests/config/functional/` for testing configuration loading +- **Primer tests:** `pytest -m primer_stdlib --primer-stdlib` -- test on stdlib for crashes + +### Test with Coverage +- `pytest tests/message/ --cov=pylint.message` -- run with coverage +- `coverage html` -- generate HTML coverage report + +### Tox Usage (Optional) +- `python -m tox` -- run all tox environments +- `python -m tox -epy313` -- run Python 3.13 suite only +- `python -m tox -epylint` -- run pylint on pylint's codebase +- `python -m tox -eformatting` -- run formatting checks +- `python -m tox --recreate` -- recreate environments (recommended) +- `python -m tox -e py310 -- -k test_functional` -- run specific tests in tox + +## Documentation + +### Building Documentation +- `make -C doc/ install-dependencies` -- install doc dependencies (~10 seconds) +- `make -C doc/ html` -- build documentation (~3 minutes, NEVER CANCEL, set timeout to 300+ seconds) +- `make -C doc/ clean` -- clean build files when starting from scratch +- `tox -e docs` -- alternative way to build docs + +**Network dependency:** Documentation build requires internet access to fetch external inventories. + +## Validation and Quality Checks + +### Running Pylint on Code +- `pylint --help` -- verify pylint installation works +- `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only (~20 seconds) +- `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run +- `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and warnings + +### Pre-commit and Formatting +- `pre-commit run --all-files` -- run all formatting checks (requires network for initial setup) +- **Network dependency:** pre-commit may fail in isolated environments due to hook downloads + +### Validation Test Scenarios +Always test your changes with these validation scenarios: +- `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` -- should find naming issues +- `pylint --help` and `pylint --list-msgs | head -10` -- verify CLI functionality +- `pylint --help-msg=C0103` -- should show invalid-name help +- `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` -- should get 10.00/10 rating + +## Writing Tests + +### Functional Tests +Located in `/tests/functional/`, consists of `.py` test files with corresponding `.txt` expected output files: +- Annotate lines where messages are expected: `a, b, c = 1 # [unbalanced-tuple-unpacking]` +- Multiple messages on same line: `a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member]` +- Use offset syntax for special cases: `# +1: [singleton-comparison]` +- **Run and update:** `python tests/test_functional.py --update-functional-output -k "test_functional[test_name]"` + +### Test File Organization +- **New checkers:** Create `new_checker_message.py` in `/tests/functional/n/` +- **Extensions:** Place in `/tests/functional/ext/extension_name/` +- **Regression tests:** Place in `/tests/r/regression/` with `regression_` prefix +- **Configuration tests:** Place in `/tests/config/functional/` + +### Configuration Test Files +Create `.result.json` files with configuration differences from standard config: +```json +{ + "functional_append": { + "disable": [["a-message-to-be-added"]] + }, + "jobs": 10 +} +``` -### Running specific test categories: -- Functional tests: `pytest tests/test_functional.py -k "test_name" -v` -- Individual functional test: `pytest "tests/test_functional.py::test_functional[abstract_class_instantiated]" -v` (~1 second) -- Unit tests: `pytest tests/test_self.py -v` -- Quick smoke test: `pytest tests/test_func.py tests/test_check_parallel.py -v` (~2 seconds, 53 tests) +## Codebase Structure -### Understanding the codebase structure: ``` pylint/ # Main package -├── checkers/ # All pylint checkers (rules) -├── config/ # Configuration handling -├── message/ # Message system -├── reporters/ # Output formatters -├── testutils/ # Testing utilities -└── extensions/ # Optional extensions +├── checkers/ # All pylint checkers (rules implementation) +├── config/ # Configuration handling and parsing +├── message/ # Message system and formatting +├── reporters/ # Output formatters (text, json, etc.) +├── testutils/ # Testing utilities and helpers +└── extensions/ # Optional extensions and plugins tests/ # Test suite -├── functional/ # Functional test files (.py files with expected output) +├── functional/ # Functional test files (.py + .txt expected output) +├── config/functional/ # Configuration functional tests +├── r/regression/ # Regression tests ├── test_*.py # Unit tests -└── data/ # Test data files +└── regrtest_data/ # Test data files doc/ # Documentation ├── user_guide/ # User documentation -├── development_guide/ # Developer documentation +├── development_guide/ # Developer and contributor documentation +│ ├── contributor_guide/ # Setup, testing, contribution guidelines +│ ├── technical_reference/ # Technical implementation details +│ └── how_tos/ # Guides for custom checkers, plugins └── additional_tools/ # Tools documentation + +script/ # Development utility scripts ``` -### Key files to know: +### Key Files - `pyproject.toml` -- Main configuration (dependencies, build, tools) - `tox.ini` -- Multi-environment testing configuration -- `.pre-commit-config.yaml` -- Code quality checks configuration +- `.pre-commit-config.yaml` -- Code quality checks configuration - `pylintrc` -- Pylint's own configuration -- `script/` -- Utility scripts for development +- `requirements_test_min.txt` -- Minimal test dependencies + +## Creating New Checkers + +### Getting Started +- `python script/get_unused_message_id_category.py` -- get next available message ID +- Study existing checkers in `pylint/checkers/` for patterns +- Read technical reference documentation in `doc/development_guide/technical_reference/` +- Use `astroid.extract_node` for AST manipulation + +### Workflow +1. Create checker class in appropriate `pylint/checkers/` file +2. Add functional tests in `tests/functional/` +3. Search existing code for warning message to find where logic exists +4. Test with sample code to ensure functionality works -### Creating new checkers: -- Use `python script/get_unused_message_id_category.py` to get unused message IDs (outputs next available ID) -- Look at existing checkers in `pylint/checkers/` for patterns -- Add functional tests in `tests/functional/` +## Pull Request Guidelines -### Working with functional tests: -- Tests are in `tests/functional/` with `.py` files and corresponding `.txt` files for expected output -- Run individual functional test: `pytest tests/test_functional.py::test_functional[test_name] -v` +### Before Submitting +- Use Python 3.8+ for development (required for latest AST parser and pre-commit hooks) +- Write comprehensive commit messages relating to tracker issues +- Keep changes small and separate consensual from opinionated changes +- Add news fragment: `towncrier create .` + +### Documentation Changes +- Document non-trivial changes +- Generate docs with `tox -e docs` +- Maintainers may label issues `skip-news` if no changelog needed + +### Contribution Credits +- Add emails/names to `script/.contributors_aliases.json` if using multiple identities ## Critical Timing Information - **NEVER CANCEL:** All operations that show "NEVER CANCEL" may take significant time -- Functional test suite: 60 seconds (set timeout to 120+ seconds) -- Documentation build: 180 seconds (set timeout to 300+ seconds) -- Full pylint self-check: 20 seconds (set timeout to 60+ seconds) -- Individual test files: 1-15 seconds +- **Full test suite:** 60+ seconds (set timeout to 120+ seconds) +- **Documentation build:** 180 seconds (set timeout to 300+ seconds) +- **Functional tests:** 60 seconds (set timeout to 120+ seconds) +- **Pylint self-check:** 20 seconds (set timeout to 60+ seconds) +- **Individual test files:** 1-15 seconds +- **Installation steps:** 30-60 seconds each -## Known Issues and Workarounds +## Environment Limitations and Workarounds - **Network connectivity required:** Documentation build and pre-commit setup require internet access -- **Tox may fail:** In isolated environments, use direct pytest and pip commands instead of tox +- **Tox failures:** In isolated environments, use direct pytest and pip commands instead of tox - **Import errors in self-check:** Some import errors when running pylint on itself are expected (git dependencies not installed) +- **Build environments:** Use direct pip/pytest commands when tox environments fail to build -## Environment Limitations - -- Some network-dependent operations may fail in isolated environments -- Use direct pip and pytest commands when tox environments fail to build -- Documentation build requires network access to fetch external inventories - -Always build and exercise your changes by running pylint on sample code to ensure functionality works correctly. \ No newline at end of file +Always validate your changes by running pylint on sample code to ensure functionality works correctly. \ No newline at end of file diff --git a/doc/user_guide/checkers/features.rst b/doc/user_guide/checkers/features.rst index 510d95ec62..d4fb243c8d 100644 --- a/doc/user_guide/checkers/features.rst +++ b/doc/user_guide/checkers/features.rst @@ -106,8 +106,8 @@ Basic checker Messages a try...finally block: the exceptions raised in the try clause will be silently swallowed instead of being re-raised. :break-in-finally (W0137): *'break' discouraged inside 'finally' clause* - Emitted when the `break` keyword is found inside a finally clause. This will - raise a SyntaxWarning starting in Python 3.14. + Emitted when the `break` keyword is found inside a finally clause. This + will raise a SyntaxWarning starting in Python 3.14. :continue-in-finally (W0136): *'continue' discouraged inside 'finally' clause* Emitted when the `continue` keyword is found inside a finally clause. This will raise a SyntaxWarning starting in Python 3.14. @@ -193,7 +193,7 @@ Basic checker Messages :missing-parentheses-for-call-in-test (W0126): *Using a conditional statement with potentially wrong function or method call due to missing parentheses* Emitted when a conditional statement (If or ternary if) seems to wrongly call a function due to missing parentheses -:comparison-of-constants (R0133): *Comparison between constants: "%s %s %s" has a constant value* +:comparison-of-constants (R0133): *Comparison between constants: '%s %s %s' has a constant value* When two literals are compared with each other the result is a constant. Using the constant directly is both easier to read and more performant. Initializing 'True' and 'False' this way is not required since Python 2.3. From 0431da80f18a46f4309ce06c4316e83ebcdb8b0b Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 29 Aug 2025 10:10:10 +0200 Subject: [PATCH 05/10] Apply pre-commit --- .github/copilot-instructions.md | 108 +++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 51977131f9..252bc242ff 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,11 +1,15 @@ # Pylint Development Instructions -Always follow these instructions first and fallback to additional search and context gathering only if the information in these instructions is incomplete or found to be in error. +Always follow these instructions first and fallback to additional search and context +gathering only if the information in these instructions is incomplete or found to be in +error. ## Development Environment Setup ### Basic Installation + Clone and set up pylint development environment: + - `git clone https://github.com/pylint-dev/pylint` -- clone repository - `cd pylint` -- enter directory - `python3 --version` -- verify Python 3.8+ is available (development requires 3.8+) @@ -15,11 +19,14 @@ Clone and set up pylint development environment: - `pip install -e .` -- install pylint in editable mode (~30-60 seconds) ### Optional Setup Steps + - `pre-commit install` -- enable pre-commit hooks for autoformatting - `pip install pre-commit` -- install pre-commit separately if needed ### Astroid Development (if needed) + If working on astroid changes: + - `git clone https://github.com/pylint-dev/astroid.git` -- clone astroid - `pip install -e astroid/` -- install astroid in editable mode - `cd astroid/ && git switch my-astroid-dev-branch` -- switch to development branch @@ -27,22 +34,32 @@ If working on astroid changes: ## Running Tests ### Core Test Commands -- `pytest tests/test_functional.py -k test_functional` -- run functional tests (~60 seconds, NEVER CANCEL, set timeout to 120+ seconds) -- `pytest tests/` -- run all tests (several minutes, NEVER CANCEL, set timeout to 300+ seconds) + +- `pytest tests/test_functional.py -k test_functional` -- run functional tests (~60 + seconds, NEVER CANCEL, set timeout to 120+ seconds) +- `pytest tests/` -- run all tests (several minutes, NEVER CANCEL, set timeout to 300+ + seconds) - `python3 -m pytest` -- run tests with local python - `pytest tests/test_check_parallel.py -v` -- quick test file (~2 seconds) ### Specific Test Types -- **Functional tests:** `pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]"` -- single functional test (~1 second) + +- **Functional tests:** + `pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]"` -- single + functional test (~1 second) - **Unit tests:** Located in `/tests/` directory, test specific pylint functionality -- **Configuration tests:** In `/tests/config/functional/` for testing configuration loading -- **Primer tests:** `pytest -m primer_stdlib --primer-stdlib` -- test on stdlib for crashes +- **Configuration tests:** In `/tests/config/functional/` for testing configuration + loading +- **Primer tests:** `pytest -m primer_stdlib --primer-stdlib` -- test on stdlib for + crashes ### Test with Coverage + - `pytest tests/message/ --cov=pylint.message` -- run with coverage - `coverage html` -- generate HTML coverage report ### Tox Usage (Optional) + - `python -m tox` -- run all tox environments - `python -m tox -epy313` -- run Python 3.13 suite only - `python -m tox -epylint` -- run pylint on pylint's codebase @@ -53,55 +70,77 @@ If working on astroid changes: ## Documentation ### Building Documentation + - `make -C doc/ install-dependencies` -- install doc dependencies (~10 seconds) -- `make -C doc/ html` -- build documentation (~3 minutes, NEVER CANCEL, set timeout to 300+ seconds) +- `make -C doc/ html` -- build documentation (~3 minutes, NEVER CANCEL, set timeout to + 300+ seconds) - `make -C doc/ clean` -- clean build files when starting from scratch - `tox -e docs` -- alternative way to build docs -**Network dependency:** Documentation build requires internet access to fetch external inventories. +**Network dependency:** Documentation build requires internet access to fetch external +inventories. ## Validation and Quality Checks ### Running Pylint on Code + - `pylint --help` -- verify pylint installation works -- `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only (~20 seconds) +- `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only + (~20 seconds) - `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run -- `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and warnings +- `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and + warnings ### Pre-commit and Formatting -- `pre-commit run --all-files` -- run all formatting checks (requires network for initial setup) -- **Network dependency:** pre-commit may fail in isolated environments due to hook downloads + +- `pre-commit run --all-files` -- run all formatting checks (requires network for + initial setup) +- **Network dependency:** pre-commit may fail in isolated environments due to hook + downloads ### Validation Test Scenarios + Always test your changes with these validation scenarios: -- `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` -- should find naming issues + +- `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py` + -- should find naming issues - `pylint --help` and `pylint --list-msgs | head -10` -- verify CLI functionality - `pylint --help-msg=C0103` -- should show invalid-name help -- `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` -- should get 10.00/10 rating +- `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` -- should get 10.00/10 + rating ## Writing Tests ### Functional Tests -Located in `/tests/functional/`, consists of `.py` test files with corresponding `.txt` expected output files: -- Annotate lines where messages are expected: `a, b, c = 1 # [unbalanced-tuple-unpacking]` -- Multiple messages on same line: `a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member]` + +Located in `/tests/functional/`, consists of `.py` test files with corresponding `.txt` +expected output files: + +- Annotate lines where messages are expected: + `a, b, c = 1 # [unbalanced-tuple-unpacking]` +- Multiple messages on same line: + `a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member]` - Use offset syntax for special cases: `# +1: [singleton-comparison]` -- **Run and update:** `python tests/test_functional.py --update-functional-output -k "test_functional[test_name]"` +- **Run and update:** + `python tests/test_functional.py --update-functional-output -k "test_functional[test_name]"` ### Test File Organization + - **New checkers:** Create `new_checker_message.py` in `/tests/functional/n/` - **Extensions:** Place in `/tests/functional/ext/extension_name/` - **Regression tests:** Place in `/tests/r/regression/` with `regression_` prefix - **Configuration tests:** Place in `/tests/config/functional/` ### Configuration Test Files + Create `.result.json` files with configuration differences from standard config: + ```json { - "functional_append": { - "disable": [["a-message-to-be-added"]] - }, - "jobs": 10 + "functional_append": { + "disable": [["a-message-to-be-added"]] + }, + "jobs": 10 } ``` @@ -135,21 +174,24 @@ script/ # Development utility scripts ``` ### Key Files + - `pyproject.toml` -- Main configuration (dependencies, build, tools) - `tox.ini` -- Multi-environment testing configuration -- `.pre-commit-config.yaml` -- Code quality checks configuration +- `.pre-commit-config.yaml` -- Code quality checks configuration - `pylintrc` -- Pylint's own configuration - `requirements_test_min.txt` -- Minimal test dependencies ## Creating New Checkers ### Getting Started + - `python script/get_unused_message_id_category.py` -- get next available message ID - Study existing checkers in `pylint/checkers/` for patterns - Read technical reference documentation in `doc/development_guide/technical_reference/` - Use `astroid.extract_node` for AST manipulation ### Workflow + 1. Create checker class in appropriate `pylint/checkers/` file 2. Add functional tests in `tests/functional/` 3. Search existing code for warning message to find where logic exists @@ -158,17 +200,20 @@ script/ # Development utility scripts ## Pull Request Guidelines ### Before Submitting + - Use Python 3.8+ for development (required for latest AST parser and pre-commit hooks) - Write comprehensive commit messages relating to tracker issues - Keep changes small and separate consensual from opinionated changes - Add news fragment: `towncrier create .` ### Documentation Changes + - Document non-trivial changes - Generate docs with `tox -e docs` - Maintainers may label issues `skip-news` if no changelog needed ### Contribution Credits + - Add emails/names to `script/.contributors_aliases.json` if using multiple identities ## Critical Timing Information @@ -183,9 +228,14 @@ script/ # Development utility scripts ## Environment Limitations and Workarounds -- **Network connectivity required:** Documentation build and pre-commit setup require internet access -- **Tox failures:** In isolated environments, use direct pytest and pip commands instead of tox -- **Import errors in self-check:** Some import errors when running pylint on itself are expected (git dependencies not installed) -- **Build environments:** Use direct pip/pytest commands when tox environments fail to build - -Always validate your changes by running pylint on sample code to ensure functionality works correctly. \ No newline at end of file +- **Network connectivity required:** Documentation build and pre-commit setup require + internet access +- **Tox failures:** In isolated environments, use direct pytest and pip commands instead + of tox +- **Import errors in self-check:** Some import errors when running pylint on itself are + expected (git dependencies not installed) +- **Build environments:** Use direct pip/pytest commands when tox environments fail to + build + +Always validate your changes by running pylint on sample code to ensure functionality +works correctly. From 7836c6b61533ffe4c857dd4ffddecf606ddee6c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 Aug 2025 08:52:58 +0000 Subject: [PATCH 06/10] Add issue label guidelines for astroid-related issues Add instructions to check GitHub issue labels and only create regression tests for astroid-related issues that cannot be fixed from this repository. Co-authored-by: Pierre-Sassoulas <5493666+Pierre-Sassoulas@users.noreply.github.com> --- .github/copilot-instructions.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 252bc242ff..87ba29b56f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,6 +4,15 @@ Always follow these instructions first and fallback to additional search and con gathering only if the information in these instructions is incomplete or found to be in error. +## Issue Label Guidelines + +Before attempting to fix any issue, check the GitHub issue labels using the GitHub API: + +- If an issue is labeled with "Astroid", "Needs astroid update", "Needs astroid constraint", or "Needs astroid Brain 🧠", **ONLY** create regression tests +- Do **NOT** attempt to fix astroid-related issues as you cannot modify astroid from this repository +- For astroid-related issues, focus on creating comprehensive regression tests that reproduce the problem +- All other issues can be fixed normally following the standard development workflow + ## Development Environment Setup ### Basic Installation From b03a498ba38f58e42eca05bc0abac1ec1099c875 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 29 Aug 2025 10:15:22 +0200 Subject: [PATCH 07/10] Re-apply "Add dependency groups to pyproject.toml file" (#10523) This reverts commit d462809df4c3b78f4f656a3d5f9249708d4af61f from #10342 who itself reverted #10332 --- pyproject.toml | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d16b274573..39293df7f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,8 @@ classifiers = [ "Typing :: Typed", ] dynamic = [ "version" ] - +# All the dependencies of the project will be configured here, once pip fully supports PEP735 +# TODO: Remove all requirements.txt files and use this section instead once pip supports PEP735 dependencies = [ # Also upgrade requirements_test_min.txt. # Pinned to dev of second minor update to allow editable installs and fix primer issues, @@ -50,8 +51,10 @@ dependencies = [ "tomlkit>=0.10.1", "typing-extensions>=3.10; python_version<'3.10'", ] + optional-dependencies.spelling = [ "pyenchant~=3.2" ] optional-dependencies.testutils = [ "gitpython>3" ] + urls."Bug Tracker" = "https://github.com/pylint-dev/pylint/issues" urls."Discord Server" = "https://discord.com/invite/Egy6P8AMB5" urls."Docs: Contributor Guide" = "https://pylint.readthedocs.io/en/latest/development_guide/contributor_guide/index.html" @@ -64,6 +67,44 @@ scripts.pylint-config = "pylint:_run_pylint_config" scripts.pyreverse = "pylint:run_pyreverse" scripts.symilar = "pylint:run_symilar" +[dependency-groups] +dev = [ + "contributors-txt>=1", + "pre-commit", + "tbump~=6.11.0", +] + +test = [ + "coverage~=7.8", + "pytest-cov~=6.0", + "pytest-xdist~=3.6", + "six", + "tox>=3", + "types-setuptools==78.1.0.20250329", + { include-group = "test-min" }, +] + +docs = [ + "furo==2024.8.6", + "sphinx==8.2.3", + "sphinx-reredirects<1", + "towncrier~=24.8", +] + +# Configuration for the build system +test-min = [ + # Base test dependencies + "astroid==4.0.0a0", # Pinned to a specific version for tests + "py~=1.11.0", + "pytest~=8.3", + "pytest-benchmark~=5.1", + "pytest-timeout~=2.3", + "requests", + "setuptools; python_version>='3.12'", + "towncrier~=24.8", + "typing-extensions~=4.12", +] + [tool.setuptools.packages.find] include = [ "pylint*" ] From 5a1efed83d72ffdb1860c8ccaf4c0571a0d82078 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:09:50 +0000 Subject: [PATCH 08/10] Initial plan From f1118b39230f0c80de98324ff76551e09db76fff Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 29 Aug 2025 10:57:23 +0200 Subject: [PATCH 09/10] pre-commit --- .github/copilot-instructions.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 87ba29b56f..95454b3644 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -8,9 +8,12 @@ error. Before attempting to fix any issue, check the GitHub issue labels using the GitHub API: -- If an issue is labeled with "Astroid", "Needs astroid update", "Needs astroid constraint", or "Needs astroid Brain 🧠", **ONLY** create regression tests -- Do **NOT** attempt to fix astroid-related issues as you cannot modify astroid from this repository -- For astroid-related issues, focus on creating comprehensive regression tests that reproduce the problem +- If an issue is labeled with "Astroid", "Needs astroid update", "Needs astroid + constraint", or "Needs astroid Brain 🧠", **ONLY** create regression tests +- Do **NOT** attempt to fix astroid-related issues as you cannot modify astroid from + this repository +- For astroid-related issues, focus on creating comprehensive regression tests that + reproduce the problem - All other issues can be fixed normally following the standard development workflow ## Development Environment Setup From b95244fdf528ef5bb61e723ae6ee75a464720960 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 29 Aug 2025 11:53:07 +0200 Subject: [PATCH 10/10] pre-commit --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 95454b3644..0f9a0eead9 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -24,7 +24,6 @@ Clone and set up pylint development environment: - `git clone https://github.com/pylint-dev/pylint` -- clone repository - `cd pylint` -- enter directory -- `python3 --version` -- verify Python 3.8+ is available (development requires 3.8+) - `python3 -m venv venv` -- create virtual environment - `source venv/bin/activate` -- activate virtual environment (Linux/Mac) - `pip install -r requirements_test_min.txt` -- install test dependencies (~30 seconds) @@ -217,6 +216,7 @@ script/ # Development utility scripts - Write comprehensive commit messages relating to tracker issues - Keep changes small and separate consensual from opinionated changes - Add news fragment: `towncrier create .` +- Always launch `pre-commit run -a` before committing ### Documentation Changes