-
Notifications
You must be signed in to change notification settings - Fork 24
Update testing etc for Python 3.8 #75
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
Conversation
appveyor.yml
Outdated
@@ -26,6 +26,12 @@ environment: | |||
- TOXENV: py37-defaultreactor, win-py37-qt5reactor, py37-asyncioreactor | |||
PYTHON: "C:\\Python37-x64" | |||
|
|||
- TOXENV: py38-defaultreactor, win-py38-qt5reactor, py38-asyncioreactor | |||
PYTHON: "C:\\Python37" |
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.
Shouldn't this be Python38?
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.
sigh bonus, I forgot I even had this open.
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.
Oh right... I started this, noticed the failure and said "wait just a minute here... Twisted doesn't even 'support' 3.8!" So I went and thought hey, that's an easy PR... until I realized you can't PR because of Azure web config. So I walked away and gave up.
The failure on windows
That is quite strange. If I'm reading py3.8's code right, on windows ...hold up. 3.8 made ProactorEventLoop the default for windows, and that link also states:
...and Judging by a recent coverage report, Edit: I filed a ticket on Twisted's tracker |
@altendky So I wonder what the reasonable thing to do here is... one option would be to special-case py3.8 in the tests for |
pytest_twisted.py
Outdated
import asyncio | ||
|
||
selector_policy = asyncio.WindowsSelectorEventLoopPolicy() | ||
asyncio.set_event_loop_policy(selector_policy) |
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.
This is a bit extreme, don't you think? There's gotta be a nicer way of dealing with this... Come to think of it, this isn't really pytest_twisted's job at all, and it should probably not try to be clever.
Perhaps get_event_loop
, check if it's a selector event loop, then issue a warning otherwise? I think a special case to make the tests pass would be reasonable, but not something in the lib like 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.
Oh, I just realize the NotImplementedError happens when we install the reactor, so maybe just trap it and raise a contextual exception? On py3 it would just look like:
def init_asyncio_reactor():
from twisted.internet import asyncioreactor
try:
_install_reactor(
reactor_installer=asyncioreactor.install,
reactor_type=asyncioreactor.AsyncioSelectorReactor,
)
except NotImplementedError as e:
raise RuntimeError(
"Failed to install AsyncioSelectorReactor. "
"If you're on windows and python 3.8+, you might need to change "
"the event loop policy to WindowsSelectorEventLoopPolicy."
) from e
...but that's invalid syntax in py2. On py2, NotImplementedError will still show up in the traceback, so it's not too bad, and to get syntax compat six.raise_from
would work, or we could just borrow its MIT-licensed implementation as it would be kinda silly to involve six for one case. IANAL but the phrasing "all copies or substantial portions of the Software" does not seem like it would apply to 11 lines (we would still credit them accordingly anyway, of course).
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.
As long as we support py2, a six dependency seems reasonable. It's not like we need to put a restrictive version requirement on it, I would assume. I'm not totally clear why doing a thing that works in a case where it otherwise won't is particularly bad. When either twisted or asyncio address this in a new version then a version check is added here to limit the application of this. I expected to add docs notes and perhaps a warning if this was actually run. And I suppose a check to see if it's needed.
But sure, just failing is simpler and simple is good. (with a good message on how to solve it) But, it just makes everyone else implement this code themselves. So, I dunno how to balance that.
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.
It is my passionate and not-entirely-uninformed opinion that a library should not muck around with global state, except where it's either somehow scoped to the lib (say, logging.getLogger(__name__)
) or really necessary.
This situation is clearly not the former, and IMO not really the latter... the failure case is both easily detectable by pytest-twisted, and has a clear, easy (enough) to describe resolution. The burden to the end user is a matter of two lines at module scope in conftest.py
(I think? We should probably test that...), and the benefit is not needing to hunt through other probably-nonsensical errors caused by the global fiddling.
OTOH, my feeling is that the intersection between the userbases of asyncio, twisted, pytest-twisted, and windows is small as it is, and might just vanish entirely when you intersect in Python 3.8 and people who depend on ProactorEventLoop
. I wish it would be feasible to get some actual data on that 😐. Then again, the number will probably only increase.
Personal ideology and guessing aside, I still prefer the except NotImplementedError
approach over "look at versions" for a more practical reason: version detection sucks. We don't actually care what Python version we're running under for this check, only if the event loop policy will give Twisted an incompatible event loop... and that can happen on pre-3.8.
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.
Maybe the best thing to do for this PR is to not attempt to handle it in the lib at all, and just special-case the tests. We can take another look, and with a working py38 CI, do some experiments in another PR to get a clearer picture of the various ways this issue could be triggered.
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 think I'm convinced. In the meantime we see that 3.8 works otherwise. NotImplementedError
isn't very specific. :[
I'll see about special casing the tests.
Could also make it a cli option. |
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.
time for my local vm... |
I dunno... so even if I move |
pytest-twisted/testing/test_basic.py Lines 627 to 634 in 37616a6
That explains that one I guess. Hooks competing for who gets to go first, or else conftest goes first. So maybe make a function and call it from both the real conftest and in the test. Private or a utility for users to call as well? But still another layer to figure out... |
pytest_twisted.py
Outdated
def use_asyncio_selector_if_required(config): | ||
# https://twistedmatrix.com/trac/ticket/9766 | ||
|
||
if ( | ||
config.getoption("reactor", "default") == "asyncio" | ||
and sys.platform == 'win32' | ||
and sys.version_info >= (3, 8) | ||
): | ||
import asyncio | ||
|
||
selector_policy = asyncio.WindowsSelectorEventLoopPolicy() | ||
asyncio.set_event_loop_policy(selector_policy) |
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 writing up some docs on the topic too (and fixed the missing trailing newline) but it feels like there's some thing to provide users with that isn't copy/paste. But, this isn't a pytest-twisted
issue... and it could be run regardless of version. I can't decide how I feel about this.
Outdated and didn't have auto-dismiss enabled yet...
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 description provided.