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

Fix function signatures to match C APIs #132

Merged
merged 7 commits into from
Oct 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ Notable enhancements and changes are:
tools and libraries to more modern versions.
* :issue:`124` - Implemented :func:`pywincffi.kernel32.file.GetTempPath`
* :issue:`123` - Implemented :func:`pywincffi.kernel32.event.SetEvent`
* Changed ordering of arguments for the following functions as they
did not match the underlying C function signatures:

* :issue:`130` - :func:`pywincffi.kernel32.events.CreateEvent`
* :issue:`131` - :func:`pywincffi.kernel32.pipe.CreatePipe`
* :issue:`133` - :func:`pywincffi.kernel32.process.CreateProcess`

0.4.0
~~~~~
Expand Down
1 change: 0 additions & 1 deletion pywincffi/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class InputError(PyWinCFFIError):
to be sure that the input(s) being provided are what we're expecting so
we fail early and provide better error messages.


:param str name:
The name of the parameter being checked.

Expand Down
17 changes: 11 additions & 6 deletions pywincffi/kernel32/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,30 @@


def CreateEvent(
bManualReset, bInitialState, lpEventAttributes=None, lpName=None):
lpEventAttributes=None, bManualReset=True, bInitialState=False,
lpName=None):
"""
Creates or opens an named or unnamed event object.

.. seealso::

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

:param bool bManualReset:
:keyword :class:`pywincffi.wintypes.SECURITY_ATTRIBUTES` lpEventAttributes:
If not provided then, by default, the handle cannot be inherited
by a subprocess.

:keyword bool bManualReset:
If True then this function will create a manual reset
event which must be manually reset with :func:`ResetEvent`. Refer
to the msdn documentation for full information.

:param bool bInitialState:
**Default:** ``True``

:keyword bool bInitialState:
If True the initial state will be 'signaled'.

:keyword :class:`pywincffi.wintypes.SECURITY_ATTRIBUTES` lpEventAttributes:
If not provided then, by default, the handle cannot be inherited
by a subprocess.
**Default:** ``False``

:keyword str lpName:
Type is ``unicode`` on Python 2, ``str`` on Python 3.
Expand Down
10 changes: 5 additions & 5 deletions pywincffi/kernel32/pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)


def CreatePipe(nSize=0, lpPipeAttributes=None):
def CreatePipe(lpPipeAttributes=None, nSize=0):
"""
Creates an anonymous pipe and returns the read and write handles.

Expand All @@ -36,16 +36,16 @@ def CreatePipe(nSize=0, lpPipeAttributes=None):
>>> lpPipeAttributes.bInheritHandle = True
>>> reader, writer = CreatePipe(lpPipeAttributes=lpPipeAttributes)

:keyword int nSize:
The size of the buffer in bytes. Passing in 0, which is the default
will cause the system to use the default buffer size.

:keyword pywincffi.wintypes.SECURITY_ATTRIBUTES lpPipeAttributes:
The security attributes to apply to the handle. By default
``NULL`` will be passed in, meaning the handle we create
cannot be inherited. For more detailed information see the links
below.

:keyword int nSize:
The size of the buffer in bytes. Passing in 0, which is the default
will cause the system to use the default buffer size.

:return:
Returns a tuple of :class:`pywincffi.wintype.HANDLE` containing the
reader and writer ends of the pipe that was created. The user of this
Expand Down
20 changes: 13 additions & 7 deletions pywincffi/kernel32/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def CreateToolhelp32Snapshot(dwFlags, th32ProcessID):


def CreateProcess( # pylint: disable=too-many-arguments,too-many-branches
lpCommandLine, lpApplicationName=None, lpProcessAttributes=None,
lpApplicationName=None, lpCommandLine=None, lpProcessAttributes=None,
lpThreadAttributes=None, bInheritHandles=True, dwCreationFlags=None,
lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None):
"""
Expand All @@ -434,12 +434,6 @@ def CreateProcess( # pylint: disable=too-many-arguments,too-many-branches

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

:param str lpCommandLine:
The command line to be executed. The maximum length of this parameter
is 32768. If no value is provided for ``lpApplicationName`` then
the module name portion of ``lpCommandLine`` cannot exceed
``MAX_PATH``.

:keyword pywincffi.wintypes.STARTUPINFO lpStartupInfo:
See Microsoft's documentation for additional information.

Expand All @@ -448,6 +442,12 @@ def CreateProcess( # pylint: disable=too-many-arguments,too-many-branches
The STARTUPINFOEX structure is not currently supported
for this input.

:keyword str lpCommandLine:
The command line to be executed. The maximum length of this parameter
is 32768. If no value is provided for ``lpApplicationName`` then
the module name portion of ``lpCommandLine`` cannot exceed
``MAX_PATH``.

:keyword str lpApplicationName:
The name of the module or application to be executed. This can be
either the fully qualified path name or a partial name. The system
Expand Down Expand Up @@ -511,6 +511,12 @@ def CreateProcess( # pylint: disable=too-many-arguments,too-many-branches
be an instance of
:class:`pywincffi.wintypes.structures.PROCESS_INFORMATION`
"""
if lpCommandLine is None:
raise InputError(
"lpCommandLine", None,
message="lpCommandLine in call to CreateProcess() may not be "
"None.")

ffi, library = dist.load()

if len(lpCommandLine) > library.MAX_COMMAND_LINE:
Expand Down
2 changes: 1 addition & 1 deletion pywincffi/wintypes/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def wintype_to_cdata(wintype):
>>> from pywincffi.wintypes import wintype_to_cdata
>>> ffi, lib = dist.load()
>>> # Get an event HANDLE, using the wrapper: it's a Python HANDLE object.
>>> hEvent = CreateEvent(False, False)
>>> hEvent = CreateEvent(bManualReset=False, bInitialState=False)
>>> # Call ResetEvent directly without going through the wrapper:
>>> hEvent_cdata = wintype_to_cdata(hEvent)
>>> result = lib.ResetEvent(hEvent_cdata)
Expand Down
28 changes: 16 additions & 12 deletions tests/test_kernel32/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ def setUp(self):
self.skipTest("Skipped on Python 3.4, see comments.")

def test_create_event_valid_handle(self):
handle = CreateEvent(False, False)
handle = CreateEvent(bManualReset=False, bInitialState=False)
CloseHandle(handle) # will raise exception if the handle is invalid

def test_non_signaled(self):
handle = CreateEvent(False, False)
handle = CreateEvent(bManualReset=False, bInitialState=False)
self.addCleanup(CloseHandle, handle)
_, library = dist.load()
self.assertEqual(
WaitForSingleObject(handle, 0), library.WAIT_TIMEOUT)

def test_signaled(self):
handle = CreateEvent(False, True)
handle = CreateEvent(bManualReset=False, bInitialState=True)
self.addCleanup(CloseHandle, handle)
_, library = dist.load()
self.assertEqual(
Expand All @@ -61,9 +61,11 @@ def test_creating_duplicate_event_does_not_raise_error(self):
# pywincffi API ignores this error and returns the handle
# object.
name = u"pywincffi-%s" % self.random_string(5)
handle1 = CreateEvent(False, False, lpName=name)
handle1 = CreateEvent(
bManualReset=False, bInitialState=False, lpName=name)
self.addCleanup(CloseHandle, handle1)
handle2 = CreateEvent(False, False, lpName=name)
handle2 = CreateEvent(
bManualReset=False, bInitialState=False, lpName=name)
self.addCleanup(CloseHandle, handle2)

_, library = dist.load()
Expand All @@ -75,35 +77,37 @@ def raise_(*_):

with patch.object(events, "error_check", side_effect=raise_):
with self.assertRaises(WindowsAPIError):
CreateEvent(False, False)
CreateEvent(bManualReset=False, bInitialState=False)

def test_can_retrieve_named_event(self):
if sys.version_info[0:2] == (3, 4):
self.skipTest("Not compatible with Python 3.4")

_, library = dist.load()
name = u"pywincffi-%s" % self.random_string(5)
handle = CreateEvent(False, False, lpName=name)
handle = CreateEvent(
bManualReset=False, bInitialState=False, lpName=name)
self.addCleanup(CloseHandle, handle)
opened_event = OpenEvent(library.EVENT_ALL_ACCESS, True, name)
self.addCleanup(CloseHandle, opened_event)

def test_check_lpeventattributes_type(self):
with self.assertRaises(InputError):
CreateEvent(False, False, lpEventAttributes="")
CreateEvent(
bManualReset=False, bInitialState=False, lpEventAttributes="")


class TestResetEvent(TestCase):
"""
Tests for :func:`pywincffi.kernel32.ResetEvent`
"""
def test_basic_reset(self):
handle = CreateEvent(True, True)
handle = CreateEvent(bManualReset=True, bInitialState=True)
self.addCleanup(CloseHandle, handle)
ResetEvent(handle)

def test_resets_event(self):
handle = CreateEvent(True, True)
handle = CreateEvent(bManualReset=True, bInitialState=True)
self.addCleanup(CloseHandle, handle)
ResetEvent(handle)

Expand All @@ -116,15 +120,15 @@ class TestSetEvent(TestCase):
Tests for :func:`pywincffi.kernel32.SetEvent`
"""
def test_signaled(self):
handle = CreateEvent(True, False)
handle = CreateEvent(bManualReset=True, bInitialState=False)
self.addCleanup(CloseHandle, handle)
_, library = dist.load()
SetEvent(handle)
self.assertEqual(
WaitForSingleObject(handle, 0), library.WAIT_OBJECT_0)

def test_not_signaled(self):
handle = CreateEvent(True, False)
handle = CreateEvent(bManualReset=True, bInitialState=False)
self.addCleanup(CloseHandle, handle)
_, library = dist.load()
self.assertEqual(
Expand Down
2 changes: 1 addition & 1 deletion tests/test_kernel32/test_handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class TestDuplicateHandle(TestCase):
Integration tests for :func:`pywincffi.kernel32.DuplicateHandle`
"""
def test_duplication(self):
event = CreateEvent(False, False)
event = CreateEvent(bManualReset=False, bInitialState=False)
self.addCleanup(CloseHandle, event)

_, library = dist.load()
Expand Down
Loading