-
Notifications
You must be signed in to change notification settings - Fork 36
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
Reenable multithreading tests #850
Changes from 9 commits
3924d66
996d9b4
eefc61c
81bc73b
c66443b
d7d3ac1
ea3bed9
bae5f9f
0be3d61
8a61983
0405431
401b5d4
6f61b76
c6fd88c
e3dfa24
17ffa15
3f2334a
d4697b5
370be08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ | |||||
import errno | ||||||
import json | ||||||
import os | ||||||
import sys | ||||||
import uuid | ||||||
from collections.abc import Mapping, Sequence | ||||||
from typing import Callable, FrozenSet | ||||||
|
@@ -116,6 +117,16 @@ def json_attr_dict_validator(data): | |||||
""" | ||||||
|
||||||
|
||||||
class _IsWindows: | ||||||
"""A truthy type that is False on Windows and True otherwise.""" | ||||||
csadorf marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
def __bool__(self): | ||||||
if sys.platform.startswith("win32") or sys.platform.startswith("cygin"): | ||||||
return False | ||||||
else: | ||||||
return True | ||||||
csadorf marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
|
||||||
class JSONCollection(SyncedCollection): | ||||||
r"""A :class:`~.SyncedCollection` that synchronizes with a JSON file. | ||||||
|
||||||
|
@@ -127,11 +138,13 @@ class JSONCollection(SyncedCollection): | |||||
|
||||||
**Thread safety** | ||||||
|
||||||
The :class:`JSONCollection` is thread-safe. To make these collections safe, the | ||||||
``write_concern`` flag is ignored in multithreaded execution, and the | ||||||
write is **always** performed via a write to temporary file followed by a | ||||||
The :class:`JSONCollection` is thread-safe on Unix-like systems (not | ||||||
Windows, see the Warnings section). To make these collections safe, the | ||||||
``write_concern`` flag is ignored in multithreaded execution, and the write | ||||||
is **always** performed via a write to temporary file followed by a | ||||||
replacement of the original file. The file replacement operation uses | ||||||
:func:`os.replace`, which is guaranteed to be atomic by the Python standard. | ||||||
:func:`os.replace`, which is guaranteed to be atomic by the Python | ||||||
standard. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
|
@@ -145,10 +158,17 @@ class JSONCollection(SyncedCollection): | |||||
\*\*kwargs : | ||||||
Keyword arguments forwarded to parent constructors. | ||||||
|
||||||
Warnings | ||||||
-------- | ||||||
This class is _not_ thread safe on Windows. It relies on ``os.replace`` for | ||||||
atomic file writes, and that method can fail in multithreaded situations if | ||||||
open handles exist to the destination file withiin the same process on a | ||||||
different thread. See https://bugs.python.org/issue46003 for more | ||||||
information. | ||||||
""" | ||||||
|
||||||
_backend = __name__ # type: ignore | ||||||
_supports_threading = True | ||||||
_supports_threading = _IsWindows() # type: ignore | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I've been spending too much time in compiled languages and so I created
Then your previous two comments also become moot. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've done this for now, let me know if you decide you don't like it and we can go back. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think having a dedicated private constant for this makes sense and makes the code more readable and overall more consistent. We could reuse that variable also in the tests, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could. I wouldn't want to leak a constant like that into our public API, but that's the sort of gray area where I would be OK with importing internals into tests I suppose. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||
_validators: Sequence_t[Callable] = (require_string_key, json_format_validator) | ||||||
|
||||||
def __init__(self, filename=None, write_concern=False, *args, **kwargs): | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider this a rather drastic change in the behavior of the overall test suite. Should we consider to apply this a bit more granular, i.e., use
strict=True
where this is relevant?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, wanting to enable this was my original goal and what made me remember that these multithreaded tests had been xfailed. IMO setting this can only be a good thing because it forces us to immediately deal with changes that incidentally and unexpectedly fix a bug or change behaviors in other unexpected ways that we only catch because a test suddenly starts xpassing. The value of
strict
passed to the decorator supersedes the value in the file, so I would rather havexfail_strict=True
configured here and then manually mark withstrict=False
cases where for whatever reason we actually need to allow xfails, for instance because a test is flaky. I would prefer to force developers to jump through hoops in order to enable flaky tests.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm +1 for making the change at a global level, but I would be okay with doing it in a separate PR, or at least adding a separate changelog line to indicate this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for separate PR IMO (albeit cleaner), but +1 for dedicated changelog entry.