Incorrectly determines mock objects are of type dict when mocking a module #697

Closed
pylint-bot opened this Issue Nov 13, 2015 · 3 comments

Comments

Projects
None yet
2 participants

Originally reported by: Anonymous


Give these two files:

sut.py:

#!python

import os

def silly_function(arg):
    return os.path.exists(arg)

and test.py:

#!python

import unittest
import mock

import sut

class SillyTest(unittest.TestCase):

    def setUp(self):
        self.os_patcher = mock.patch("sut.os")
        self.os_mock = self.os_patcher.start()

    def tearDown(self):
        self.os_patcher.stop()

    def test_mock_is_mock(self):
        self.assertIsInstance(self.os_mock, mock.MagicMock)
        self.assertNotIsInstance(self.os_mock, dict)

    def test_silly_function(self):
        self.os_mock.path.exists.return_value = "hello"
        self.assertEqual("hello", sut.silly_function("world"))

The code works fine:

#!shell

$ python -m unittest -v test
test_mock_is_mock (test.SillyTest) ... ok
test_silly_function (test.SillyTest) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

But pylint incorrectly determines that self.os_mock is of type dict:

#!shell

$ pylint -E test
************* Module test
E: 20, 8: Instance of 'dict' has no 'path' member (no-member)

The test_mock_is_mock test above shows that this is explicitly not the case.

This is using python 2.7.6


Original comment by Claudiu Popa (BitBucket: PCManticore, GitHub: @PCManticore):


I don't think there's anyway for pylint to figure out what mock is doing behind the scene in a sane way. These kind of libraries which overuses dynamic features of the language aren't well suited for a static analysis understanding.

But this might be solvable with an astroid brain plugin.

Original comment by Oliver Jeeves (BitBucket: ojeeves):


This problem only occurs when you're mocking a module. Pylint correctly finds the type of the mock if you're mocking a function, class or method.

@pylint-bot pylint-bot added the bug label Dec 9, 2015

Owner

PCManticore commented Jun 27, 2016

Closing this. I think it is not worth investing effort into something relying heavily on patching things and magic, as mock is doing it. if anyone wants to spend some effort fixing this, you might have a look at how astroid brain modules are implemented (https://github.com/PyCQA/astroid/tree/master/astroid/brain)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment