tilting at windmills with ctypes and cygwinreg
DESCRIPTION
In this presentation, I take a brisk walk through a small problem in automated browser testing, take a quick right at Windows, and dash through implementing a new Python module replacing winreg. http://pypi.python.org/pypi/cygwinregTRANSCRIPT
def introduction():
social reality game
def problem():
website
testing
clickwaitlook
clickwaitlook
clickwaitlook
slow
laborious
boring
automated testing
def test_browser():
© Andy HeatwoleCreative Commons Attribution-NonCommercial-NoDerivs 2.5.
http://blog.bluehourphoto.com/?showimage=224
getwindmill.com
one script
all browsers
from windmill.authoring import *
def setup_module(module): client = WindmillTestClient(__name__) client.click(id=u'home') client.waits.forPageLoad(timeout=u'60000') client.asserts.assertNode(id='LoginPage')
from windmill.authoring import *
def setup_module(module): client = WindmillTestClient(__name__) client.click(id=u'home') client.waits.forPageLoad(timeout=u'60000') client.asserts.assertNode(id='LoginPage')
from windmill.authoring import *
def setup_module(module): client = WindmillTestClient(__name__) client.click(id=u'home') client.waits.forPageLoad(timeout=u'60000') client.asserts.assertNode(id='LoginPage')
from windmill.authoring import *
def setup_module(module): client = WindmillTestClient(__name__) client.click(id=u'home') client.waits.forPageLoad(timeout=u'60000') client.asserts.assertNode(id='LoginPage')
semi-automated testing
def continuous_integration():
test automatically
buildbot.net
~/akoha$ make check
C:\>make check'make' is not recognized as an internal or external command, operable program or batch file.
cygwin.com
~/akoha$ make check
Traceback (most recent call last): ...ImportError: No module named _winreg
def windows_registry():
proxy settings
import _winreg
import winreg
32.3. winregWindows registry access
Platforms: Windows
32.3. winregWindows registry access
Platforms: Windows
3 choices
1
give up
2
recompile Python
3
cygwinreg
like hurting myself
def call_system_libraries():
import ctypes
foreign function interface
call functions
shared libraries
libiberty.so
libgcc.dynlib
advapi32.dll
>>> from ctypes import cdll
>>> cdll.advapi32<CDLL 'advapi32', ... at ...>
>>> cdll.advapi32.RegCloseKey<_FuncPtr object at 0x...>
>>> a = cdll.advapi32>>> RegCloseKey = a.RegCloseKey>>> RegCloseKey(0)6
no introspection
>>> RegCloseKey(0)6>>> RegCloseKey()6
return value
function arguments
from ctypes import cdllfrom ctypes import c_long, c_ulong
# WINADVAPI LONG WINAPI RegCloseKey(HKEY);RegCloseKey = cdll.advapi32.RegCloseKeyRegCloseKey.restype = c_longRegCloseKey.argtypes = [c_ulong]
from ctypes import cdllfrom ctypes import c_long, c_ulong
# WINADVAPI LONG WINAPI RegCloseKey(HKEY);RegCloseKey = cdll.advapi32.RegCloseKeyRegCloseKey.restype = c_longRegCloseKey.argtypes = [c_ulong]
from ctypes import cdllfrom ctypes import c_long, c_ulong
# WINADVAPI LONG WINAPI RegCloseKey(HKEY);RegCloseKey = cdll.advapi32.RegCloseKeyRegCloseKey.restype = c_longRegCloseKey.argtypes = [c_ulong]
from ctypes import cdllfrom ctypes import c_long, c_ulong
LONG = c_longHANDLE = c_ulong # in header files: void *HKEY = HANDLE
# WINADVAPI LONG WINAPI RegCloseKey(HKEY);RegCloseKey = cdll.advapi32.RegCloseKeyRegCloseKey.restype = LONGRegCloseKey.argtypes = [HKEY]
>>> RegCloseKey(0)6>>> RegCloseKey()Traceback (most recent call last): ...TypeError: this function takes at least 1 argument (0 given)
not Pythonic
PyHKEY.Close()
Closes the underlying Windows handle.
class PyHKEY(object): def __init__(self, hkey): self.hkey = hkey
def Close(self): if RegCloseKey(self.hkey) != 0: raise WindowsError() self.hkey = 0
class WindowsError(OSError): ...
class PyHKEY(object): def __init__(self, hkey): self.hkey = hkey
def Close(self): RegCloseKey(self.hkey) raise WindowsError() self.hkey = 0
class WindowsError(OSError): ...
class PyHKEY(object): def __init__(self, hkey): self.hkey = hkey
def Close(self): if RegCloseKey(self.hkey) != 0: raise WindowsError() self.hkey = 0
class WindowsError(OSError): ...
>>> from cygwinreg import PyHKEY>>> hkey = PyHKEY(0)>>> hkey.Close()
RegDeleteKeyW = cdll.advapi32.RegDeleteKeyWRegDeleteKeyW.restype = LONGRegDeleteKeyW.argtypes = [HKEY, LPCWSTR]
def DeleteKey(key, sub_key): from cygwinreg.w32api import RegDeleteKeyW wincall(RegDeleteKeyW(PyHKEY.make(key), sub_key))
hours later
>>> try:... import winreg... except ImportError:... import cygwinreg as winreg
def tradeoffs():
Python only
no compilation
slower
no parsing
simple
not automatic
standard
portable
good enough
def conclusion():
~/akoha$ make check
continuous integration
browser tests
pypi.python.org/pypi/cygwinreg
no compilation
no installation
no :'-(
cygwinregpypi.python.org/pypi/cygwinreg
PSF License
this presentation:Attribution-Share Alike 3.0