pylint-dev / pylint-dev/astroid

Next transformer not called if previous transformer returns `None`.

Open
#809 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
582
Forks
357
Avg merge
1d 1h
Merged PRs (30d)
23

Description

### Steps to reproduce
1. Create files:

`code_to_inspect.py`:

```python
class One:
pass

class Two:
pass
```

`plugin_foo.py`:

```python
import astroid

def transform(node):
print('plugin_foo transform()')

if node.qname().endswith('One'):
print('returning node...')
return node

print('returning None...')
return None

def register(linter):
astroid.MANAGER.register_transform(astroid.ClassDef, transform)
```

`plugin_bar.py`:

```python
import astroid

def transform(node):
print('plugin_bar transform()')
return None

def register(linter):
astroid.MANAGER.register_transform(astroid.ClassDef, transform)
```

2. Run `pylint` with plugins from above:
```bash
env PYTHONPATH=. pylint --load-plugins=plugin_foo,plugin_bar code_to_inspect.py
```

### Current behavior

The `transform()` in `plugin_bar` only gets called for class `One`, not for both classes.

E.g.:

```bash
$ env PYTHONPATH=. pylint --load-plugins=plugin_foo,plugin_bar code_to_inspect.py
plugin_foo transform()
returning node...
plugin_bar transform()
plugin_foo transform()
returning None...
************* Module code_to_inspect
...
```

### Expected behavior

The `transform()` in `plugin_bar` to always get called.

This was the behavior in Astroid/Pylint 1. E.g.:

```bash
$ pylint --version
No config file found, using default configuration
pylint 1.9.5,
astroid 1.6.6
Python 2.7.17 (default, Apr 15 2020, 17:20:14)
[GCC 7.5.0]

$ env PYTHONPATH=. pylint --load-plugins=plugin_foo,plugin_bar code_to_inspect.py
No config file found, using default configuration
plugin_foo transform()
returning node...
plugin_bar transform()
plugin_foo transform()
returning None...
plugin_bar transform()
************* Module code_to_inspect
...
```

### ``python -c "from astroid import __pkginfo__; print(__pkginfo__.version)"`` output
2.4.2

### Further info

A quick inspection of the source code suggests this may be the culprit:
https://github.com/PyCQA/astroid/blob/8a147beb9076bb5d42ff41563a9529a9076e137a/astroid/transforms.py#L45-L47
If `ret` is `None`, it's class will very often not be `cls` :)

Also, at least one of the builtin transforms (I didn't look further) and the `pylint_sqlalchemy` plugin return `None` (at least in most cases).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.