pylint icon indicating copy to clipboard operation
pylint copied to clipboard

Two tests fails with `pydantic` installed

Open mtelka opened this issue 2 years ago • 5 comments

Bug description

I'm running tests for `pylint` and I found that two of them fails when there is `pydantic 1.10.13` installed.

Configuration

No response

Command used

tox --current-env --no-provision --recreate -e py39

Pylint output

____________________ test_functional[dataclass_with_field] _____________________

self = <pylint.testutils.lint_module_test.LintModuleTest object at 0x7fffa28c29d0>

    def runTest(self) -> None:
>       self._runTest()
E       AssertionError: Wrong message(s) raised for "dataclass_with_field.py":
E
E       Expected in testdata:
E          7: import-error
E
E       Actual pylint output for this file:

pylint/testutils/lint_module_test.py:147: AssertionError
______________________ test_functional[no_name_in_module] ______________________

self = <pylint.testutils.lint_module_test.LintModuleTest object at 0x7fff9abcdca0>

    def runTest(self) -> None:
>       self._runTest()
E       AssertionError: Wrong message(s) raised for "no_name_in_module.py":
E
E       Unexpected in testdata:
E         86: no-name-in-module
E
E       Actual pylint output for this file:
E       OutputLine(symbol='no-name-in-module', lineno=5, column=0, end_lineno=5, end_column=23, object='', msg="No name 'tutu' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=6, column=0, end_lineno=6, end_column=28, object='', msg="No name 'toto' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-member', lineno=10, column=0, end_lineno=10, end_column=32, object='', msg="Module 'xml.etree.ElementTree' has no 'nonexistant_function' member", confidence='INFERENCE')
E       OutputLine(symbol='no-member', lineno=11, column=0, end_lineno=11, end_column=19, object='', msg="Module 'xml.etree.ElementTree' has no 'another' member", confidence='INFERENCE')
E       OutputLine(symbol='no-member', lineno=16, column=6, end_lineno=16, end_column=17, object='', msg="Module 'sys' has no 'stdoout' member; maybe 'stdout'?", confidence='INFERENCE')
E       OutputLine(symbol='no-name-in-module', lineno=23, column=0, end_lineno=23, end_column=34, object='', msg="No name 'compiile' in module 're'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=23, column=0, end_lineno=23, end_column=34, object='', msg="No name 'findiiter' in module 're'", confidence='UNDEFINED')
E       OutputLine(symbol='pointless-statement', lineno=26, column=0, end_lineno=26, end_column=23, object='', msg='Statement seems to have no effect', confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=34, column=4, end_lineno=34, end_column=36, object='', msg="No name 'anything' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=49, column=4, end_lineno=49, end_column=37, object='', msg="No name 'indeed_missing' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=54, column=4, end_lineno=54, end_column=27, object='', msg="No name 'emit' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=71, column=8, end_lineno=71, end_column=32, object='', msg="No name 'emit2' in module 'collections'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=76, column=0, end_lineno=76, end_column=34, object='', msg="No name 'lala' in module 'functional.n.no.no_self_argument'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=77, column=0, end_lineno=77, end_column=39, object='', msg="No name 'bla' in module 'functional.n.no.no_self_argument'", confidence='UNDEFINED')
E       OutputLine(symbol='no-name-in-module', lineno=86, column=0, end_lineno=86, end_column=30, object='', msg="No name 'BaseModel' in module 'pydantic'", confidence='UNDEFINED')

pylint/testutils/lint_module_test.py:147: AssertionError

Expected behavior

All tests pass even with pydantic installed.

Pylint version

3.0.2

OS / Environment

OpenIndiana

Additional dependencies

No response

mtelka avatar Nov 28 '23 23:11 mtelka

Same problem in astroid, see https://github.com/pylint-dev/astroid/actions/runs/7159067546/job/19491909890?pr=2340.

Since this has the potential to start blocking us, raising the priority.

jacobtylerwalls avatar Dec 10 '23 16:12 jacobtylerwalls

Hi @david-yz-liu !

Would you have a minute to recommend a course of action with the failing test in astroid that exhibits a similar issue?

  • pydantic is now one of pylint's transitive dependencies (and thus astroid's also), because we depend on isort and that depends on requirementslib, which now requires pydantic.
    def test_pydantic_field() -> None:
        """Test that pydantic.Field attributes are currently Uninferable.
    
        (Eventually, we can extend the brain to support pydantic.Field)
        """
        klass, instance = astroid.extract_node(
            """
        from pydantic import Field
        from pydantic.dataclasses import dataclass
    
        @dataclass
        class A:
            name: str = Field("hi")
    
        A.name  #@
        A().name #@
        """
        )
    
        inferred = klass.inferred()
        assert len(inferred) == 1
>       assert inferred[0] is Uninferable
E       assert <Instance of pydantic.fields.FieldInfo at 0x4532641808> is Uninferable

tests/brain/test_dataclasses.py:461: AssertionError

jacobtylerwalls avatar Dec 10 '23 17:12 jacobtylerwalls

Hi @jacobtylerwalls!

Sorry I'm in the middle of exam season so I don't have a lot of time, but off the top of my head it looks like:

  1. The original test was explicitly checking that pydantic Fields couldn't be inferred, presumably to be conservative and ensure an invalid value wasn't inferred.
  2. Somewhere along the line I'm guessing the behaviour of astroid's brain changed so that it was inferring the field attribute.
  3. But that change didn't trigger the test case failure because pydantic itself wasn't installed when the tests were run, so that result was still Uninferable. (This assumes that if pydantic isn't installed, @pydantic.dataclass decorating a class A results in Uninferable.
  4. Now that pydantic is installed, the inference is successful and so the test is failing.

I'm making some assumptions in the above, so I could be wrong! But that's where I would start. This sounds urgent so I can take a closer look in a few days, if that's helpful.

david-yz-liu avatar Dec 10 '23 18:12 david-yz-liu

Thanks, that's very helpful. Sounds like it's okay to just update the test and ensure that pydantic is either installed or the test is skipped.

In terms of urgency, I think this was just a problem because isort unintentionally pulled in a lot of dev dependencies as runtime dependencies, and I can pin astroid to the main branch of isort to unblock CI. (There was a completely unrelated second test that was failing also.)

jacobtylerwalls avatar Dec 10 '23 18:12 jacobtylerwalls

Thanks, that's very helpful. Sounds like it's okay to just update the test and ensure that pydantic is either installed or the test is skipped.

Yeah I think that's good. By the way, I think the tests are parameterized to include marshmallow-dataclass? The same issue might apply to that package as well.

david-yz-liu avatar Dec 10 '23 21:12 david-yz-liu