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

Add Windows CI #62

Merged
merged 13 commits into from
Jul 28, 2017
Merged

Add Windows CI #62

merged 13 commits into from
Jul 28, 2017

Conversation

nicoddemus
Copy link
Member

@nicoddemus nicoddemus commented Jul 25, 2017

Fix #59

Also:

  • Renamed README to rst so GH renders it properly;
  • Updated classifiers;
  • Added badges.

@nicoddemus
Copy link
Member Author

Some tests are failing because I'm guessing they were not being executed on Windows yet.

I will take a look later to make them pass or skip them if not possible.

def popen_args(spec):
args = shlex.split(spec.python) if spec.python else [sys.executable]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this was a bug on Windows:

>>> import shlex
>>> shlex.split(r'X:\execnet\.env36\Scripts\python.exe')
['X:execnet.env36Scriptspython.exe']

Which of course is not a valid Python file. My quick and dirty solution at least gives a valid file:

import shlex
>>> shlex.split(r'X:\execnet\.env36\Scripts\python.exe'.replace('\\', '/'))
['X:/execnet/.env36/Scripts/python.exe']

@nicoddemus
Copy link
Member Author

flakes is not passing; given the errors and the fact that Travis does not run them as well I think it is not passing on Linux as well;

pypy is a little more tricky, I tried to debug this a little but no luck.

I can reproduce the failure with this simple script:

import execnet
from execnet.gateway import rinfo_source

def rinfo_source(channel):
    import sys
    import os
    d = dict(
        executable=sys.executable,
        version_info=sys.version_info[:5],
        platform=sys.platform,
        cwd=os.getcwd(),
        pid=os.getpid(),
    )
    channel.send(d)

gw = execnet.makegateway()
channel = gw.remote_exec(rinfo_source)
print(channel.receive())

This fails with:

Traceback (most recent call last):
  File "X:/execnet/.tmp/foo.py", line 31, in <module>
    print(channel.receive())
  File "X:\execnet\execnet\gateway_base.py", line 737, in receive
    raise self._getremoteerror() or EOFError()
EOFError

If I send a simple string (channel.send("hello")) it works, but the dictionary fails for some reason.

I used PyCharm's remote debugging and managed to get to this line on the remote:

# gateway_base.py
    def _send(self, msgcode, channelid=0, data=bytes()):
        message = Message(msgcode, channelid, data)
        try:
            message.to_io(self._io)   # << terminates here
            self._trace('sent', message)  
        except (IOError, ValueError):
            e = sys.exc_info()[1]
            self._trace('failed to send', message, e)
            # ValueError might be because the IO is already closed
            raise IOError("cannot send (already closed?)")

In the line highlighted above, the process simply terminates without any discernible message. Any pointers?

@nicoddemus
Copy link
Member Author

Played around a little bit more:


import sys
import execnet

def rinfo_source(channel):
    import sys
    import os
    d = dict(
        executable=sys.executable,
        version_info=sys.version_info[:5],
        platform=sys.platform,
        cwd=os.getcwd(),
        pid=os.getpid(),
    )
    channel.send(d)

gw = execnet.makegateway()
channel = gw.remote_exec(rinfo_source)
print 'local executable:', repr(sys.executable)
print 'local version_info:', repr(sys.version_info)
print 'remote receive:', channel.receive()
local executable: 'X:\\execnet\\.envpypy\\bin\\pypy.exe'
local version_info: (major=2, minor=7, micro=10, releaselevel='final', serial=42)
remote receive:Traceback (most recent call last):
  File "X:/execnet/.tmp/foo.py", line 20, in <module>
    print 'remote receive:', channel.receive()
  File "X:\execnet\execnet\gateway_base.py", line 737, in receive
    raise self._getremoteerror() or EOFError()
EOFError

Commenting out both executable and version_info from the remote dict makes the example work:

import sys
import execnet

def rinfo_source(channel):
    import sys
    import os
    d = dict(
        #executable=sys.executable,
        #version_info=sys.version_info[:5],
        platform=sys.platform,
        cwd=os.getcwd(),
        pid=os.getpid(),
    )
    channel.send(d)

gw = execnet.makegateway()
channel = gw.remote_exec(rinfo_source)
print 'local executable:', repr(sys.executable)
print 'local version_info:', repr(sys.version_info)
print 'remote receive:', channel.receive()
local executable: 'X:\\execnet\\.envpypy\\bin\\pypy.exe'
local version_info: (major=2, minor=7, micro=10, releaselevel='final', serial=42)
remote receive: {'platform': 'win32', 'cwd': 'X:\\execnet\\.tmp', 'pid': 16360}

Leaving either of them on the dict gives the same error.


Strangely, renaming the executable entry to something else:

import sys
import execnet

def rinfo_source(channel):
    import sys
    import os
    d = dict(
        _executable=sys.executable,
        #version_info=sys.version_info[:5],
        platform=sys.platform,
        cwd=os.getcwd(),
        pid=os.getpid(),
    )
    channel.send(d)

gw = execnet.makegateway()
channel = gw.remote_exec(rinfo_source)
print 'local executable:', repr(sys.executable)
print 'local version_info:', repr(sys.version_info)
print 'remote receive:', channel.receive()

Works:

remote receive: {'_executable': 'X:\\execnet\\.envpypy\\bin\\pypy.exe', 'platform': 'win32', 'cwd': 'X:\\execnet\\.tmp', 'pid': 16076}

Perhaps there's some bug on the marshaler which fails on PyPy with the name executable?


I tried the same trick of changing the name for version_info (and even making it a plain tuple for good measure):

import sys
import execnet

def rinfo_source(channel):
    import sys
    import os
    d = dict(
        #executable=sys.executable,
        _version_info=tuple(sys.version_info[:5]),
        platform=sys.platform,
        cwd=os.getcwd(),
        pid=os.getpid(),
    )
    channel.send(d)

gw = execnet.makegateway()
channel = gw.remote_exec(rinfo_source)
print 'local executable:', repr(sys.executable)
print 'local version_info:', repr(sys.version_info)
print 'remote receive:', channel.receive()

But in this case I still get the same error.

@RonnyPfannschmidt
Copy link
Member

for linting i wan to use a different service, imho its just bullshit to make it part of testing and run it on all platforms

@RonnyPfannschmidt
Copy link
Member

also execnet is in a shit place wrt linting, dont even try making it a ci req right now is just wasting time

@nicoddemus
Copy link
Member Author

nicoddemus commented Jul 26, 2017

also execnet is in a shit place wrt linting, dont even try making it a ci req right now is just wasting time

No problem, I tried to reproduce the environments I saw defined in tox.ini.

btw, Travis and tox are inconsistent to each other. Should we getting them in sync?

I would like to support the same versions we guarantee pytest-xdist to run, what do you think?

@nicoddemus
Copy link
Member Author

What about pypy? I won't have too much time to look deep into it, so I suppose we can create an issue for it and mark the affected tests as xfail (it is a couple of tests IIRC)

@RonnyPfannschmidt
Copy link
Member

@nicoddemus yes, we can do that bit and add pypy

@nicoddemus
Copy link
Member Author

Yay finally 😅

@RonnyPfannschmidt
Copy link
Member

Lol nice one art complex

@RonnyPfannschmidt RonnyPfannschmidt merged commit b384803 into pytest-dev:master Jul 28, 2017
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

Successfully merging this pull request may close these issues.

2 participants