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

GetOverlappedResult implementation #115

Merged
merged 12 commits into from
Aug 1, 2016
Merged

Conversation

exvito
Copy link
Contributor

@exvito exvito commented Jul 26, 2016

Sharing GetOverlappedResult implementation, which is actually very simple.

I found testing a bit more complex and banged my head around it for a while.

The key issue in the simplest test case I could devise -- based on doing an overlapped WriteFile -- was the fact that when doing overlapped IO, WriteFile (and others) set the GetLastError to ERROR_IO_PENDING and the TestCase cleanups were checking and complaining about it not being 0. All seems fine after I figured it out, validated it and SetLastError to 0 afterwards.

At first I tried going for a ReadFile based test, but I think that will require some changes to the existing ReadFile implementation: the current approach does not seem to work because it is returing a bytes object which, under overlapped IO, is not available at that time... Only after the overlapped IO completes and is waited on, for example, via GetOverlappedResult. At first sight, I'm not sure of a somewhat Pythonic approach to that. :)

Submitting PR for review and maybe some discussion around this topic.

PS: Regarding Twisted, it seems that GetOverlappedResult is used in serial port code using ReadFile/WriteFile and others so the overlapped ReadFile will need thought.

PPS: The serial code in Twisted seems to depend on pyserial which, at first glance, is using ctypes to reach out to the underlying windows APIs (good, it would be a mess for Twisted if it depended on pywin32! offtopic: maybe someday pyserial can be built on top of pywincffi, who knows)

@exvito
Copy link
Contributor Author

exvito commented Jul 26, 2016

Ooops! Something strange is going on: all tests are failing the same way, in line 49 of test_overlapped.py... Given that the assertion is failing, WriteFile is returning something other than zero which, I presume, may be indicating that overlapped IO wasn't properly triggered... :/

My envirnonment is Python 2.7 on 32 bit Windows 7 and runs the test successfuly... Could you check whether it fails or passes on yours?

PS: Any other idea as to what might be the issue here? Thanks.


https://msdn.microsoft.com/en-us/library/ms683209

:param HANDLE hFile:
Copy link
Owner

Choose a reason for hiding this comment

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

Need the path to the class here so it can be linked properly in the documentation.

@opalmer
Copy link
Owner

opalmer commented Jul 27, 2016

PPS: The serial code in Twisted seems to depend on pyserial which, at first glance, is using ctypes to reach out to the underlying windows APIs (good, it would be a mess for Twisted if it depended on pywin32! offtopic: maybe someday pyserial can be built on top of pywincffi, who knows)

When I first proposed pywincffi as the thing to replace pywin32 in Twisted I asked what else might we be able to replace and pyserial/ctypes was one the list. It's not as high as the other stuff in #69 but it's probably something worth investigating later on.

My envirnonment is Python 2.7 on 32 bit Windows 7 and runs the test successfuly... Could you check whether it fails or passes on yours? PS: Any other idea as to what might be the issue here? Thanks.

Not sure and I don't have access to my Windows VM today so I'll have to check tomorrow or Thursday depending on work. It's not clear just from the test output why this could be happening so for now I don't have a better answer. If I had to guess it might a subtle timing issue of some kind and/or have something to do with the flags being passed into the functions during the tests (WriteFile for example has a few flags specifically for overlapped I/O). I'll take a look more closely when I have access to a VM again.

Other than all that, code looks pretty good. Just had a couple of small comments but I don't see anything wrong overall with style or the major parts of the implementation. Once again, thanks for the help!

@opalmer
Copy link
Owner

opalmer commented Jul 30, 2016

Sorry for the delay!

So, this passes locally for me using Python 3.4 and 3.5. I expect the same results with Python 2.7 but I need to fix something in the build first:

(pywincffi-27-32) opalmer@WIN10-DEV C:\dev\repos\pywincffi
> python setup.py build
running build
running build_py
running egg_info
writing requirements to pywincffi.egg-info\requires.txt
writing pywincffi.egg-info\PKG-INFO
writing top-level names to pywincffi.egg-info\top_level.txt
writing dependency_links to pywincffi.egg-info\dependency_links.txt
reading manifest file 'pywincffi.egg-info\SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'pywincffi.egg-info\SOURCES.txt'
running build_ext
generating cffi module 'build\\temp.win32-2.7\\Release\\_pywincffi.c'
already up-to-date
building '_pywincffi' extension
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -DUNICODE=1 -D_UNICODE=1 -Ic:\python27-x86\include -IC:\dev\virtualenv\pywincffi-27-32\PC /Tcbuild\temp.win32-2.7\Release\_pywincffi.c /Fobuild\temp.win32-2.7\Release\build\temp.win32-2.7\Release\_pywincffi.obj
_pywincffi.c
build\temp.win32-2.7\Release\_pywincffi.c(3653) : error C2065: 'INHERIT_PARENT_AFFINITY' : undeclared identifier
build\temp.win32-2.7\Release\_pywincffi.c(3654) : error C2065: 'INHERIT_PARENT_AFFINITY' : undeclared identifier
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\BIN\\cl.exe' failed with exit status 2

@opalmer
Copy link
Owner

opalmer commented Jul 30, 2016

Merged #117, your tests work fine in Python 2.7 too so I'm still not sure exactly why this fails on AppVeyor.

@opalmer opalmer closed this Jul 30, 2016
@opalmer opalmer reopened this Jul 30, 2016
@exvito
Copy link
Contributor Author

exvito commented Jul 30, 2016

(quick feedback)

Thanks for your review and comments. I've been very busy these days as I'm off for a one week vacation... Hopefully I'll be able do some improvements tomorrow morning. Otherwise I'll only be able to get back to this in about two weeks, I guess. :/

@codecov-io
Copy link

codecov-io commented Jul 31, 2016

Current coverage is 98.98% (diff: 100%)

Merging #115 into master will increase coverage by 0.01%

Powered by Codecov. Last update 1b39e7b...4842a58

@exvito
Copy link
Contributor Author

exvito commented Jul 31, 2016

Progress:

  • Updated docstrings + code as per your review.
  • Tests now passing on AppVeyor - Per MSDN docs, WriteFile can return success/failure and GetLastError() can be SUCCESS/ERROR_IO_PENDING...
  • Something is failing on one of the checks, but I'm not sure I understand it.

Any pointers?


_ = WriteFile(handle, file_contents, lpOverlapped=ovr)
error_code, _ = self.GetLastError()
self.assertIn(error_code, (lib.ERROR_IO_PENDING, 0))
Copy link
Owner

@opalmer opalmer Jul 31, 2016

Choose a reason for hiding this comment

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

Interestingly, I merged some code yesterday you could use here:

https://github.com/opalmer/pywincffi/blob/master/pywincffi/dev/testutil.py#L295

Basically, replace assertIn and SetLastError with:

self.maybe_assert_last_error(lib.ERROR_IO_PENDING)

@opalmer
Copy link
Owner

opalmer commented Jul 31, 2016

The one check is failing because you're missing some coverage in overlapped.py:

https://codecov.io/gh/opalmer/pywincffi/pull/115/compare

If possible, it would be nice to have a test which covers that code. You could probably use mock_library from testutil to replace library.GetOverlappedResult with another function that calls SetLastError internally and returns an exit code of zero. That should hit on the if statement you have under except WindowsAPIError.

@exvito
Copy link
Contributor Author

exvito commented Jul 31, 2016

Two questions before proceeding:

  • To use self.maybe_assert_last_error(lib.ERROR_IO_PENDING) I'll have to merge current master into this branch. Is that ok by you? Any other suggestion?
  • In reviewing the code around the last error_check I'm really not sure why the try/except is there... Maybe I copied it from some other function and left it alone without giving it much thought. From MSDN's docs, GetOverlappedResult should simply return NON_ZERO on success. Won't the correct implementation be simply the error_check with no try/except?

@opalmer
Copy link
Owner

opalmer commented Jul 31, 2016

To use self.maybe_assert_last_error(lib.ERROR_IO_PENDING) I'll have to merge current master into this branch. Is that ok by you? Any other suggestion?

Merging from the current master is fine.

Won't the correct implementation be simply the error_check with no try/except?

Correct yes. Sorry I should have caught this in the review...

@exvito
Copy link
Contributor Author

exvito commented Aug 1, 2016

I think this is ready for merging -- pending your review, of course.
Next would be:

PS: I'll be for a couple of weeks on vacation. :)

@opalmer
Copy link
Owner

opalmer commented Aug 1, 2016

I think this is ready for merging -- pending your review, of course.

Reviewed and I agree, merging.

Next would be:

I'll try to put some time into these if I have the time over the next couple of weeks.

PS: I'll be for a couple of weeks on vacation. :)

Enjoy your vacation and thanks again!

@opalmer opalmer merged commit 3a43d36 into opalmer:master Aug 1, 2016
opalmer added a commit that referenced this pull request Aug 1, 2016
opalmer added a commit that referenced this pull request Aug 1, 2016
@exvito exvito deleted the get-ov-result branch August 13, 2016 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants