locomotor package

Submodules

locomotor.identify module

locomotor.identify.REDIS_METHODS = set(['append', 'blpop', 'brpop', 'brpoplpush', 'decr', 'delete', 'execute', 'exists', 'expire', 'expireat', 'get', 'getbit', 'getset', 'hdel', 'hget', 'hgetall', 'hincrby', 'hkeys', 'hlen', 'hmget', 'hmset', 'hset', 'hsetnx', 'hvals', 'incr', 'lindex', 'linsert', 'llen', 'lpop', 'lpush', 'lpushnx', 'lrange', 'lrem', 'lset', 'ltrim', 'mget', 'move', 'mset', 'msetnx', 'persist', 'publish', 'randomkey', 'rename', 'renamenx', 'rpop', 'rpoplpush', 'rpush', 'rpushx', 'sadd', 'scard', 'sdiff', 'sdiffstore', 'set', 'setbit', 'setex', 'setnx', 'setrange', 'sinter', 'sinterstore', 'sismember', 'smembers', 'smove', 'sort', 'spop', 'srandmember', 'srem', 'strlen', 'substr', 'sunion', 'sunionstore', 'ttl', 'zadd', 'zcard', 'zincrby', 'zinterstore', 'zrange', 'zrangebyscore', 'zrank', 'zrem', 'zremrangebyrank', 'zrevrange', 'zrevrangebyscore', 'zrevrank', 'zrevscore', 'zunionstore'])

Method names used when trying to identify Redis client objects

locomotor.identify.REDIS_METHOD_COUNT = 2

The minimum number of methods which must be identified as Redis calls to denote an object as corresponding to a Redis client

locomotor.identify.REDIS_METHOD_PCT = 0.8

The percentage of method calls which must match a predefined list

locomotor.identify.identify_redis_funcs(cls_or_mod)[source]

Identify functions in a class or module which use Redis

locomotor.identify.identify_redis_objs(func)[source]

Identify objects likely to be used to access Redis in the code

Module contents

locomotor.DEBUG_LOG_CHANNEL = 'locomotor-debug'

A channel used to push debug messages from Lua scripts

locomotor.FUNC_BUILTINS = ('append', 'insert', 'join', 'replace')

Function names which we assume are builtins

locomotor.LUA_HEADER = 'redis.replicate_commands()\nlocal __RETVAL = function(value, retval)\n local __RESULT = {}\n __RESULT["__value"] = value\n __RESULT["__return"] = retval\n\n return cmsgpack.pack(__RESULT)\nend\n\nlocal __TRUE = function(expr)\n local __VAL = expr\n if not __VAL or __VAL == 0 then\n return false\n end\n\n local __TYPE = type(__VAL)\n if (__TYPE == "table" or __TYPE == "string") and #__VAL == 0 then\n return false\n else\n return true\n end\nend\n\nlocal __OR = function(...)\n local __VAL = nil\n for i, v in ipairs(arg) do\n if __TRUE(v) then\n return v\n else\n __VAL = v\n end\n end\n\n return __VAL\nend\n\nlocal __AND = function(...)\n local __VAL = nil\n for i, v in ipairs(arg) do\n if not __TRUE(v) then\n return v\n else\n __VAL = v\n end\n end\n\n return __VAL\nend\n'

A header added to all generated Lua code

class locomotor.LuaBlock(lines=None)[source]

Bases: object

append(line)[source]
code
extend(block)[source]
class locomotor.LuaLine(code, node=None, indent=0, names=set([]))[source]

Bases: object

static debug(message, *args)[source]
locomotor.PACKED_TYPES = (<type 'list'>, <type 'dict'>, <type 'NoneType'>, <type 'datetime.datetime'>)

Types which should be serialized via msgpack

locomotor.PIPELINED_CODE = 'local __PIPELINE_RESULTS = {}\n\nlocal __PIPE_ADD = function(key, value)\n if __PIPELINE_RESULTS[key] == nil then\n __PIPELINE_RESULTS[key] = {}\n end\n\n table.insert(__PIPELINE_RESULTS[key], value)\n return value\nend\n\nlocal __PIPE_GET = function(key)\n local RETVAL = __PIPELINE_RESULTS[key]\n __PIPELINE_RESULTS[key] = {}\n return RETVAL\nend\n\n'

Additional functions for code which uses pipelining

class locomotor.RedisFuncFragment(taint, minlineno=None, maxlineno=None, redis_objs=None, helper=False)[source]

Bases: object

arg_conversion(arg)[source]

Returns the function used to convert this argument to Lua

convert_value(value)[source]

Convert the value to a string representation in Lua

get_constant(expr)[source]

Get the value for a constant expression

lua_code(client, args, method_self=None)[source]

Produce the lua code for this script fragment

process_Assign(node, code, indent, loops)[source]

Generate code for an assignment operation

process_Attribute(node, code, indent, loops)[source]

Generate code for an attribute access x.y

process_AugAssign(node, code, indent, loops)[source]

Generate code for agumented assignment (e.g. +=)

process_BinOp(node, code, indent, loops)[source]

Generate code for a binary operator

process_BoolOp(node, code, indent, loops)[source]

Generate code for a boolean operator

process_Break(node, code, indent, loops)[source]

Generate code for a break statement

process_Call(node, code, indent, loops)[source]

Generate code for a function call

process_Compare(node, code, indent, loops)[source]

Generate code for a comparison operation

process_Continue(node, code, indent, loops)[source]

Generate code for a continue statement

process_Dict(node, code, indent, loops)[source]

Generate code for a dictionary literal

process_Expr(node, code, indent, loops)[source]

Generate code for an expression

process_For(node, code, indent, loops)[source]

Generate code for a for loop

process_If(node, code, indent, loops)[source]

Generate code for an if statement

process_Index(node, code, indent, loops)[source]

Generate code for an index value

process_List(node, code, indent, loops)[source]

Generate code for a list constant

process_Name(node, code, indent, loops)[source]

Generate code for a simple variable name

process_Num(node, code, indent, loops)[source]

Generate code for a numberical constant

process_Pass(node, code, indent, loops)[source]

Generate code for pass

process_Print(node, code, indent, loops)[source]

Generate code for a print statement

process_Return(node, code, indent, loops)[source]

Generate code for a return statement

process_Str(node, code, indent, loops)[source]

Generate code for a string constant

process_Subscript(node, code, indent, loops)[source]

Generate code for a subscript []

process_Tuple(node, code, indent, loops)[source]

Generate code for a tuple constant

process_UnaryOp(node, code, indent, loops)[source]

Generate code for a unary operator

process_node(node, indent=0, loops=0)[source]

Generate code for a single node at a particular indentation level

register_script(*args)[source]

Register the script with the client and patch the function code

rename_expressions(expressions)[source]

Rename all expressions in a list to their appropriate names

unpack_args(args, start_arg=0, helpers=[], method_self=None)[source]

Generate code to unpack arguments with the correct name and type

class locomotor.ScriptRegistry[source]

Bases: object

SCRIPTS = {}
classmethod register_script(client, lua_code)[source]
classmethod run_script(client, script_id, args)[source]
locomotor.TAB = ' '

The string literal to use for tabs in generated Lua code

locomotor.UNPIPELINED_CODE = '\nlocal __PIPE_ADD = function(key, value) return value end\n'

A dummy function to use for code which does not involve pipelining

exception locomotor.UntranslatableCodeException(node)[source]

Bases: exceptions.Exception

Exception raised when code can’t be translated

locomotor.decode_msgpack(obj)[source]
locomotor.encode_msgpack(obj)[source]
locomotor.redis_server(method=None, redis_objs=None, minlineno=None, maxlineno=None)[source]

Create a decorator which converts a function to run on the server