Skip to content

Windows test fixes and CI with AppVeyor #1504

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

Closed
wants to merge 4 commits into from
Closed

Conversation

jtatum
Copy link

@jtatum jtatum commented May 7, 2016

I noticed in #1353 that testing for the new parser is needed on Windows. I thought I'd get that started with some CI from AppVeyor. It turned out to be a bit more complicated than that.

  • util.try_find_python2_interpreter() doesn't work well on Windows. I cheat in appveyor.yml by renaming Python 2.7's python.exe to python2.exe. I'm not sure how you could find multiple interpreters in the path on Windows since those handy version symlinks (python3, python35, etc) don't exist.
  • waiter, the parallel execution task runner, used some posix tricks to run multiple processes at once and wait for the first one to return. I replaced all that clever code with some much uglier and stupider polling that works on both Windows and saner OSes.
  • waiter also tried to open a file that was already open. On Windows, this is impossible. It's okay, though, because NamedTemporaryFile (and TemporaryFile) give you a file-like object with a file already open in binary mode. It looks like the stub generation test cases are failing with a similar issue.

This is what the tests look like on Windows: https://ci.appveyor.com/project/jtatum/mypy/build/1.0.16

Still to-do:

  • Fix failing tests on Windows. Most look like path differences (forward vs. backslash) and NamedTempFile. A couple seem a bit more mysterious.
  • Add os.replace() to typeshed

@jtatum jtatum force-pushed the appveyor branch 2 times, most recently from a57a81e to df5c18e Compare May 7, 2016 07:55
James Tatum and others added 2 commits May 7, 2016 00:58
Waiter depended on a couple of posix tricks. The first was a clever
use of os.waitpid(-1, 0) to wait for any spawned processes to return.
On Windows, this raises an exception - Windows has no concept of a
process group.

The second was the use of NamedTempFile(). On anything but Windows,
a file can be open for writing and for reading at the same time.
This trick actually isn't necessary the way NamedTempFile is used
here. It exposes a file-like object pointing to a file already opened
in binary mode. All we have to do is seek and read from it.
The only tricky bit of this is renaming python.exe to python2.exe.
This is due to util.try_find_python2_interpreter(), which may well
need work for Windows since the version symlinks don't exist on Windows.
@gvanrossum
Copy link
Member

Currently the Travis CI tests (on Linux) fail, that needs to be addressed.

I'll leave this to @ddfisher to review.

@jtatum
Copy link
Author

jtatum commented May 7, 2016

Getting a traceback in the incremental builder:

File ".\mypy\build.py", line 767, in write_cache
    os.rename(data_json_tmp, data_json)
FileExistsError: [WinError 183] Cannot create a file when that file already exists: '.mypy_cache\\3.5\\__main__.data.json'

os.rename cannot replace a file on Windows. Python 3.3 adds os.replace(), a cross-platform function, but it looks like mypy's minimum version is 3.2. There's a TODO in build.py that mentions it may not be atomic, but that's incorrect - it actually fails. Not sure how this should be fixed.

@gvanrossum
Copy link
Member

gvanrossum commented May 7, 2016 via email

Most of these fixes revolve around the path separator and the way
Windows handles files and locking. There is one bug fix in here -
build.write_cache() was using os.rename to replace a file, which
fails on Windows. I was only able to fix that for Python 3.3 and up.
@jtatum
Copy link
Author

jtatum commented May 7, 2016

I'm not sure why the type checking works on Python 3.2 after adding os.replace() to typeshed (I put it on a conditional for Python 3.3 or newer) but everything looks good now. Latest Windows build: https://ci.appveyor.com/project/jtatum/mypy/build/1.0.21

There are probably too many Python versions in the matrix - the tests are much slower and AppVeyor doesn't offer concurrency for FOSS projects.

@gvanrossum
Copy link
Member

gvanrossum commented May 7, 2016 via email

@@ -65,6 +65,8 @@ def parse_test_cases(
tcout = [] # type: List[str]
if i < len(p) and p[i].id == 'out':
tcout = p[i].data
if p[i].arg == 'pathfix':
tcout = [s.replace('/', os.path.sep) for s in tcout]
Copy link
Member

Choose a reason for hiding this comment

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

Rather than having to remember to add 'pathfix' to tests that happen to have pathnames with slashes in the expected output, maybe you could always fix the path in the text up to the first colon, skipping this completely if the line starts with whitespace or there's whitespace in the stuff before that first colon (or there is no colon)?

Copy link
Author

Choose a reason for hiding this comment

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

I considered this but was hesitant to add more magic to this code. If that's the preference, I certainly could, though. Do you suppose there are other [out] sections that might be affected by that change? Should that behavior be documented somewhere, maybe in comments in test/data.py?

Copy link
Member

Choose a reason for hiding this comment

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

The only way to be sure is to survey all [out] sections of all test files. Or at least sample a bunch of different ones (some have a different format, the test prints the repr() of some Node).

I just worry that your current approach will mean that every time a new test requires [out pathfix] it will first be committed without the pathfix and then after some time someone will report that it's broken on Windows and someone has to remember how to fix it.

@gvanrossum
Copy link
Member

gvanrossum commented May 9, 2016 via email

@gvanrossum
Copy link
Member

(I meant to say that I don't have that time right now but I will get back to this later in the week.)

@gvanrossum
Copy link
Member

So this looks fine except I still don't like the idea of having to add "pathfix" to all those tests.

Did you find a better way?

Would be nice if we could release this next week (just before PyCon).

@gvanrossum
Copy link
Member

Hey, I'm taking over this PR here: #1593. I'm closing this version. Thanks for getting it this far! I'm building on your work and acknowledging it in the commit message.

@gvanrossum gvanrossum closed this May 29, 2016
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