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

fake_perf_counter doesnt handle 1 argument as perf_counter does #558

Open
LukasJerabek opened this issue Sep 24, 2024 · 0 comments
Open

Comments

@LukasJerabek
Copy link

LukasJerabek commented Sep 24, 2024

I am getting this using pytest error:

=============================================================================== test session starts ================================================================================
platform linux -- Python 3.8.19, pytest-8.3.3, pluggy-1.5.0
rootdir: /home/vagrant/pack/tests/integ/iadmin/modules/use_cases
plugins: anyio-4.4.0, cov-5.0.0, asyncio-0.24.0
asyncio: mode=strict, default_loop_scope=None
collected 1 item                                                                                                                                                                   

test_usecase.py E                                                                                                                                                            [100%]

====================================================================================== ERRORS ======================================================================================
___________________________________________________________________ ERROR at setup of TestProblem.test_use_case ____________________________________________________________________

cls = <class 'tests.integ.iadmin.modules.use_cases.test_usecase.TestProblem'>

    @classmethod
    def setUpClass(cls) -> None:
>       super().setUpClass()

test_usecase.py:25: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test_usecase.py:14: in setUpClass
    cls.patcher.start()
/home/vagrant/.pyenv/versions/3.8.19/lib/python3.8/unittest/mock.py:1529: in start
    result = self.__enter__()
/home/vagrant/.pyenv/versions/3.8.19/lib/python3.8/unittest/mock.py:1377: in __enter__
    self.target = self.getter()
/home/vagrant/.pyenv/versions/3.8.19/lib/python3.8/unittest/mock.py:1552: in <lambda>
    getter = lambda: _importer(target)
/home/vagrant/.pyenv/versions/3.8.19/lib/python3.8/unittest/mock.py:1224: in _importer
    thing = __import__(import_path)
usecase.py:1: in <module>
    from fontTools import subset as ftsubset
/home/vagrant/venv/pack/lib/python3.8/site-packages/fontTools/subset/__init__.py:467: in <module>
    timer = Timer(logger=logging.getLogger("fontTools.subset.timer"))
/home/vagrant/venv/pack/lib/python3.8/site-packages/fontTools/misc/loggingTools.py:292: in __init__
    self.reset(start)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <fontTools.misc.loggingTools.Timer object at 0x7fcf8f382c40>, start = None

    def reset(self, start=None):
        """Reset timer to 'start_time' or the current time."""
        if start is None:
>           self.start = self._time()
E           TypeError: fake_perf_counter() takes 0 positional arguments but 1 was given

/home/vagrant/venv/pack/lib/python3.8/site-packages/fontTools/misc/loggingTools.py:304: TypeError
============================================================================= short test summary info ==============================================================================
ERROR test_usecase.py::TestProblem::test_use_case - TypeError: fake_perf_counter() takes 0 positional arguments but 1 was given
============================================================================= 1 error in -16940665.79s =============================================================================

I was able to reproduce this in a minimal reproducer:

test_problem.py:

from datetime import datetime
import unittest
from unittest.mock import Mock, patch

from freezegun import freeze_time


@freeze_time(datetime(2024, 3, 12, 12, 30))
@patch("usecase.anyfunction", Mock())
class TestProblem(unittest.TestCase):
    def test_use_case(self):
        pass

usecase is a module and anyfunction is a function in that module, it can be anything you want, say:
usecase.py

from fontTools import subset as ftsubset

def anyfunction():
    return 5

but it has to have that import from fontTools.

and you run it with PYTHONPATH=<path_to_directory_with_your_files>/ pytest -s test_problem.py

you get the same error as above.

The problem seems to be this thing - Fonttools use timeit and in one place they do

_time = timeit.default_timer

where default_timer by default is time.perf_counter

then in a method of a class they do this, which inherently tries to add self to the perf_counter:

    def reset(self, start=None):
        """Reset timer to 'start_time' or the current time."""
        if start is None:
            self.start = self._time()

The reason I have created it here is that it was working for fonttools with original perf_counter and really when I remove the freeze_time decorator it works fine. However once freeze_time patches it with fake_perf_counter it no longer accepts the self parameter even though the original perf_counter did.

fonttools version 4.53.1
freezegun version 1.5.1
python version 3.8.19

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

1 participant