Friday, May 17, 2013

pdb and gdb conditional breakpoints

Use a debugger enough and you'll eventually be in a loop looking for a certain condition. And it's too tedious to walk through all iterations of the loop to get to the one you want. Enter conditional breakpoints. In GDB you'd use something like this (borrowed from here):
(gdb) br test.cpp:2
Breakpoint 1 at 0x1234: file test.cpp, line 2.
(gdb) cond 1 i==2147483648
(gdb) run
Or this for strings:
break test2.cpp:10 if strcmp(y,"hello") == 0
In the python debugger the syntax is a little different:
b(reak) ([file:]lineno | function) [, condition]
Like this:
(Pdb) break blah.py:1, somevalue=2

Tuesday, May 14, 2013

python set a variable conditional on another variable

Tiny python snippet. If you're doing this:
if value:
  output = value
else:
  output = 'somethingelse'
Do this instead:
output = value or 'somethingelse'

Monday, May 13, 2013

Basic python chmod for windows

A basic python version of chmod for Windows using pywin32:

import ntsecuritycon
import win32security

DACL_PRESENT = 1
DACL_DEFAULT = 0

def WinChmod(filename, acl_list, user="SYSTEM"):
  """Provide chmod-like functionality for windows.

  Doco links:
    goo.gl/n7YR1
    goo.gl/rDv81
    goo.gl/hDobb

  Args:
    filename: target filename for acl
    acl_list: list of ntsecuritycon acl strings to be applied with bitwise OR.
              e.g. ["FILE_GENERIC_READ", "FILE_GENERIC_WRITE"]
    user: username string
  Raises:
    AttributeError: if a bad permission is passed
    RuntimeError: if filename doesn't exist
  """
  if not os.path.exists(filename):
    raise RuntimeError("filename %s does not exist" % filename)

  acl_bitmask = int()
  for acl in acl_list:
    acl_bitmask |= getattr(ntsecuritycon, acl)

  dacl = win32security.ACL()
  win_user, _, _ = win32security.LookupAccountName("", user)

  dacl.AddAccessAllowedAce(win32security.ACL_REVISION,
                           acl_bitmask, win_user)

  security_descriptor = win32security.GetFileSecurity(
      filename, win32security.DACL_SECURITY_INFORMATION)

  # Tell windows to set the acl and mark it as explicitly set
  security_descriptor.SetSecurityDescriptorDacl(DACL_PRESENT, dacl,
                                                DACL_DEFAULT)
  win32security.SetFileSecurity(filename,
                                win32security.DACL_SECURITY_INFORMATION,
                                security_descriptor)

Tuesday, May 7, 2013

Python: stub out windows libraries for testing on linux

Here's a quick way to stub out windows libraries when you are testing on Linux. This code creates empty modules using imp.
  import imp
  import sys

  def testMethodWithWindowsCall():
    StubOutWindowsLibs()
    import windows_utils
  
  def StubOutWindowsLibs():
    pywintypes = imp.new_module("pywintypes")
    pywintypes.error = Exception
    sys.modules["pywintypes"] = pywintypes

Monday, May 6, 2013

Google coding style guides

I didn't actually realise how important code style guides were until I saw one consistently applied with style-checking tools: it makes a big difference to code quality. If you don't have a style guide, you could do a lot worse than the google style guides, which have been open-sourced and are regularly updated as languages evolve. The python guide is here.

Chrome browser commandline switches

Chrome has a prodigious number of command line switches to control all sorts of behaviour. I recently ran into this one, which I think will be handy. From the review log:
Added the flag --host-resolver-rules=XXX in r39342.

Where XXX is a comma separated list of rules that control how hostnames are resolved.

For example:
    "MAP * 127.0.0.1" --> Forces all hostnames to be resolved to 127.0.0.1
    "MAP *.google.com proxy" --> Forces all google.com subdomains to be
                                 resolved to "proxy".
    "MAP test.com [::1]:77 --> Forces "test.com" to resolve to IPv6 loopback.
                               Will also force the port of the resulting
                               socket address to be 77.
    "MAP * baz, EXCLUDE www.google.com" --> Remaps everything to "baz",
                                            except for "www.google.com".

Friday, April 26, 2013

Crontab converts percent signs to newlines

A breadcrumb for the internet: it turns out percent (%) signs get converted to newlines inside crontabs. This is one of those things that I probably learnt in the past but forgot until it bit me: it's useful if you need to send multi-line strings as input to a command in cron. From the manpage:
The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the crontab file. Per‐cent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.
If you have unescaped %'s you will likely see errors like this:
/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file