Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

importing pytest fixtures raises F401 #4046

Closed
wasim42 opened this issue Apr 20, 2023 · 7 comments
Closed

importing pytest fixtures raises F401 #4046

wasim42 opened this issue Apr 20, 2023 · 7 comments

Comments

@wasim42
Copy link

wasim42 commented Apr 20, 2023

It appears that ruff isn't handling pytest fixtures correctly.

Consider the following files (adapted from a pytest example):

fruit.py

import pytest


class Fruit:
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):
        return self.name == other.name


@pytest.fixture
def my_fruit():
    return Fruit("apple")


@pytest.fixture
def fruit_basket(my_fruit):
    return [Fruit("banana"), my_fruit]

and test_fruit.py:

from fruit import (
    my_fruit,
    fruit_basket
)

def test_my_fruit_in_basket(my_fruit, fruit_basket):
    assert my_fruit in fruit_basket

Running ruff --isolated test_fruit.py I get:

test_fruit.py:2:5: F401 [*] `fruit.my_fruit` imported but unused
test_fruit.py:3:5: F401 [*] `fruit.fruit_basket` imported but unused
test_fruit.py:6:29: F811 Redefinition of unused `my_fruit` from line 2
test_fruit.py:6:39: F811 Redefinition of unused `fruit_basket` from line 3
Found 4 errors.
[*] 2 potentially fixable with the --fix option.

I'm using ruff 0.0.262

@evanrittenhouse
Copy link
Contributor

evanrittenhouse commented Apr 20, 2023

Thanks for filing. I'll look into this!

@charliermarsh
Copy link
Member

I think this has been discussed before, but I’m on my phone and it may be hard to dig up the relevant issue.

@evanrittenhouse
Copy link
Contributor

evanrittenhouse commented Apr 20, 2023

#3295 pointed me to this. Pytest suggests avoiding importing fixtures in favor of adding them to conftest.py. In that case, I'm personally a bit torn on implementing this - on one hand, it's definitely confusing behavior since the import is in fact used, but on the other it's not recommended to do so.

I'm almost leaning towards fixing the unused import bug, but maybe implementing a separate rule centered on avoiding fixture imports? FWIW, it seems like Pylint has the same issue as the one mentioned here. The suggested solution is to simply rename the fixture file (fruit.py, in this case) to conftest.py.

@charliermarsh
Copy link
Member

Yeah, reading through the discussion, I think I agree with the conclusion that was reached in #3295: since Pytest itself recommends against this pattern, I'd rather not special-case in Ruff. (I'm not even sure how we could special-case it without introducing lots of false negatives. Best-case is that we could avoid autofixing these cases but still flag them.)

@charliermarsh
Copy link
Member

I'm going to close, given that conclusion, but always happy to continue the discussion.

@wasim42
Copy link
Author

wasim42 commented Apr 21, 2023

Thank you very much for that! I’m a novice with pytest and this was a case of me using a linter to help me muddle through, and it has 😜

@jamesbraza
Copy link
Contributor

Today, F401 autofixes wiped away my fixture imports a few times. I can think of several workarounds:

  1. Use conftest.py (which I am avoiding for reasons beyond this issue's scope)
  2. Manually insert # noqa: F401 before invoking ruff
  3. Place F401 in unfixable aspect of config

I went with option 3, marking F401 as unfixable.

lu-pl added a commit to acdh-oeaw/rdfproxy that referenced this issue Jul 26, 2024
Importing fixtures is a pytest antipattern and causes Ruff to flag F811.
See astral-sh/ruff#4046.
Defining fixtures globally in conftest.py is the idiomatic way to
remedy the problem.
lu-pl added a commit to acdh-oeaw/rdfproxy that referenced this issue Jul 26, 2024
Importing fixtures is a pytest antipattern and causes Ruff to flag F811.
See astral-sh/ruff#4046.
Defining fixtures globally in conftest.py is the idiomatic way to
remedy the problem.
lu-pl added a commit to acdh-oeaw/rdfproxy that referenced this issue Jul 29, 2024
Importing fixtures is a pytest antipattern and causes Ruff to flag F811.
See astral-sh/ruff#4046.
Defining fixtures globally in conftest.py is the idiomatic way to
remedy the problem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants