-
Notifications
You must be signed in to change notification settings - Fork 269
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
freeze_time class decoration causes problems with subclasses and Python 3.11.1 #485
Comments
I think this is also happening in 3.10 as well, getting an import error with Freezetime and test set up.... |
yajo
added a commit
to moduon/sale-workflow
that referenced
this issue
Oct 26, 2023
As seen in spulec/freezegun#485, when decorating a class with `@freezegun.freeze_time()`, class cleanups are not properly executed. For Odoo, this means that the cursor is not properly closed. Thus, if you happen to run a test for another module after this one that needs a Postgres-level lock that conflicts with this module's, it will fail. This change does the same, but without decorating the class. Then, the cleanups work as expected. @moduon MT-1075
yajo
added a commit
to moduon/sale-workflow
that referenced
this issue
Oct 30, 2023
As seen in spulec/freezegun#485, when decorating a class with `@freezegun.freeze_time()`, class cleanups are not properly executed. For Odoo, this means that the cursor is not properly closed. Thus, if you happen to run a test for another module after this one that needs a Postgres-level lock that conflicts with this module's, it will fail. This change does the same, but without decorating the class. Then, the cleanups work as expected. @moduon MT-1075
alan196
pushed a commit
to Jarsa/sale-workflow
that referenced
this issue
Nov 23, 2023
As seen in spulec/freezegun#485, when decorating a class with `@freezegun.freeze_time()`, class cleanups are not properly executed. For Odoo, this means that the cursor is not properly closed. Thus, if you happen to run a test for another module after this one that needs a Postgres-level lock that conflicts with this module's, it will fail. This change does the same, but without decorating the class. Then, the cleanups work as expected. @moduon MT-1075
In my case it causes really weird and impossible-to-debug Django transactional issues. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I have discovered that the way
freezegun.freeze_time
decoratesunittest.TestCase
classes causes Problems in Python 3.11.1 (yes, the micro version) if you create a subclass of a class with the decorator and you use unittest.TestCase.addClassCleanup() insetUpClass()
(as Djangos SimpleTestCase classes do, that's how I stumbled on this problem).The change in Python 3.11.1 is python/cpython#99645. While the problem only surfaces in that special combination, I do believe the right place to fix this is this library, as the freezegun decorator is what triggers this behavior.
To demonstrate the problem, let me first show a contrived example of test case classes:
Now if you run the test suite, you'll see that both test methods will always get the frozen time (as expected), but
setUpClass()
will get the base class even in the subclass. Here's the output (full class paths removed for brevity):I have checked that just removing the
freeze_time
decorator restores the expected behavior (setUpClass
receives the subclass when run for the subclass) and that this also happens if the method is defined in yet a base class (e.g. DjangosSimpleTestCase
).While certainly odd, The above class works the same way as it does in Python 3.11.1. The problem starts if you have a call to
addClassCleanup()
in your base class. python/cpython#99645 means that only those registered for the exact class are called, andsetUpClass()
for the subclass now receives the wrong class (the parent). Our sub-testcase now registers a second cleanup for the parent instead of its own class.If we add a cleanup function to the base class:
and run the test suite again, you get the following output (again trimmed the output for brevity):
Notice that the cleanup function is now called twice for the base class, but not at all for the subclass. Sure enough, if you run this with 3.11.0, you get:
... sure enough,
setUpClass()
still gets the wrong class, but it's not a problem yet, as cleanups for all base classes are called.Unfortunately I'm not quite sure how to correctly solve this issue, as I have not found a way to "correctly" decorate a class and wrap class methods so that they get the correct classes.
The text was updated successfully, but these errors were encountered: