Tilting at Windmills with ctypes and cygwinreg

Post on 25-Jun-2015

2.096 views 3 download

Tags:

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/cygwinreg

Transcript of Tilting at Windmills with ctypes and cygwinreg

Tilting at Windmillswith

ctypes and cygwinreg

Simon Lawsimon@akoha.com

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