summaryrefslogtreecommitdiff
path: root/bps/develop.py
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-01-06 01:15:05 +0000
committerEli Collins <elic@assurancetechnologies.com>2011-01-06 01:15:05 +0000
commit1d2669f6f50d3cedc4ffd5439780b13492469bdd (patch)
treec56c9a0883aee5be78624920b85cb6e155779049 /bps/develop.py
parent0dd599bbb323387991cd8a3565ea87f36ff0892f (diff)
downloadpasslib-1d2669f6f50d3cedc4ffd5439780b13492469bdd.tar.gz
tweaked config files, moved dir to passlib
Diffstat (limited to 'bps/develop.py')
-rw-r--r--bps/develop.py357
1 files changed, 0 insertions, 357 deletions
diff --git a/bps/develop.py b/bps/develop.py
deleted file mode 100644
index f9019cf..0000000
--- a/bps/develop.py
+++ /dev/null
@@ -1,357 +0,0 @@
-"""bps.develop - useful functions for debugging and developing code
-"""
-#=========================================================
-#imports
-#=========================================================
-#core
-import inspect
-import time
-import os, sys
-import re
-import code as code_mod
-#pkg
-from bps.fs import filepath
-#local
-__all__ = [
- #console
- "dbgcon",
-
- #utils
- "trap",
- "timer",
-
- #ide
- "global_replace",
- "purge_bytecode",
-
- #tracing
- "log_imports",
-]
-
-#=========================================================
-#debugging console
-#=========================================================
-def _default_shell(local_ns, global_ns):
- "helper for dbgcon which uses default python interactive shell"
- #prepare vars
- if global_ns is None:
- global_ns = {}
- if local_ns is None:
- local_ns = {}
- filename = "<console>"
- banner = "Dropping into Python"
-
- #try to load readline
- try:
- import readline
- except ImportError:
- pass
-
- #create console object
- console = code_mod.InteractiveConsole(local_ns, filename)
-
- #patch runcode
- def runcode(code):
- try:
- eval(code, global_ns, local_ns)
- except SystemExit:
- raise
- except:
- console.showtraceback()
- else:
- if code_mod.softspace(sys.stdout, 0):
- print
- console.runcode = runcode
-
- #run the console
- console.interact(banner)
-
-#disabled this for now... integration has some glitches
-def _ipython_shell(local_ns, global_ns):
- "helper for dbgcon which runs IPython shell, or returns False if IPython not present"
- #check for IPython
- try:
- from IPython.Shell import IPShellEmbed
- except ImportError:
- global _ipython_shell
- _ipython_shell = None #disable in future
- return False
-
- #check for nested instance
- try:
- __IPYTHON__
- except NameError:
- nested = 0
- args = ['']
- else:
- print "Running nested copies of IPython."
- print "The prompts for the nested copy have been modified"
- nested = 1
- # what the embedded instance will see as sys.argv:
- args = ['-pi1','In <\\#>: ','-pi2',' .\\D.: ',
- '-po','Out<\\#>: ','-nosep']
-
- # Now create an instance of the embeddable shell. The first argument is a
- # string with options exactly as you would type them if you were starting
- # IPython at the system command line. Any parameters you want to define for
- # configuration can thus be specified here.
- ipshell = IPShellEmbed(args,
- banner = 'Dropping into IPython',
- exit_msg = 'Leaving Interpreter, back to program.')
- ipshell(local_ns=local_ns, global_ns=global_ns)
- return True
-
-def dbgcon(local_ns=None, global_ns=None, stacklevel=1):
- """opens up an embedded debugging console on stdin/stdout.
- by default, the accesses the local namespace of the calling function,
- but this can be altered via the various options.
-
- This function uses an embedded IPython shell if installed,
- else it falls back to the builtin python interpreter.
-
- .. todo::
-
- A env flag to disable IPython selection would be nice.
- A env flag to disable readline would be nice.
-
- :Parameters:
- stacklevel
- Choose what stacklevel the default namespaces should be pulled from.
- ``1`` (the default) uses the namespace of the immediate caller.
- local_ns
- Optionally overrides the local namespace that would be chosen via stacklevel.
- global_ns
- Optionally overrides the global namespace that would be chosen via stacklevel.
- """
- "run interact using caller's frame for locals"
- #TODO: make this load globals correctly!
- print "\n", "-=" * 40
- extra_keys = set() #set of extra keys we added to local_ns
- orig_ns = {} #set of values we clobbered in local_ns
- def shadow_local(key, value):
- if key in local_ns:
- orig_ns[key] = local_ns[key]
- else:
- extra_keys.add(key)
- local_ns[key] = value
- frame = inspect.currentframe(stacklevel)
- try:
- if local_ns is None:
- local_ns = frame.f_locals
- if global_ns is None:
- global_ns = frame.f_globals
- shadow_local("exit", sys.exit)
- if _ipython_shell and _ipython_shell(local_ns, global_ns):
- return
- _default_shell(local_ns, global_ns)
- finally:
- del frame
- if local_ns:
- for key in orig_ns:
- local_ns[key] = orig_ns[key]
- for key in extra_keys:
- del local_ns[key]
- print "\n", "^=" * 40
-
-#=========================================================
-#other utility funcs
-#=========================================================
-def trap(func, *args, **kwds):
- """development helper which traps and return errors.
-
- :param func:
- function to call
- :param *args:
- positional arguments for function
- :param **kwds:
- keyword arguments for function
-
- :returns:
- * ``(True,result)`` if function returns without error
- * ``(False,error)`` if function raises error
- """
- try:
- return True, func(*args, **kwds)
- except Exception, err:
- return False, err
-
-
-def dbgstack(depth=0, limit=None):
- "helper for pretty-printing the callstack"
- out = ''
- idx = depth
- frame = inspect.currentframe(1+depth)
- while frame:
- out += "(%r, %r, %r, %r),\n" % (
- depth,
- frame.f_code.co_filename,
- frame.f_code.co_name,
- frame.f_lineno)
- frame = frame.f_back
- depth += 1
- if limit and depth >= limit:
- break
- return out
-
-def timer(count, func, *args, **kwds):
- "helper func for timing a function call"
- itr = xrange(count)
- s = time.time()
- result = func(*args, **kwds)
- if count > 1:
- for c in itr:
- func(*args, **kwds)
- delta = time.time() - s
- return delta / float(count), result
-
-#=========================================================
-#global search and replace
-#=========================================================
-
-def global_replace(root_path, match_re, replace_func, guard_func=None, file_filter=None):
- """This function implements a helpful global search-and-replace for an entire project tree.
-
- For simple uses, an IDE's global search and replace tool is usually better,
- the changes that need to be made are too extensive or complicated.
- This function allows quick scripts to be written which take care of
- complicated search-and-replace operations across an entire project.
-
- :arg root_path:
- root of path to perform search & replace within
-
- :param match_re:
- regular expression (if not compiled, will be compiled with re.M flag)
- any parts of any file in tree which match this regular expression
- will be passed to the replace_func for (potential) replacement.
-
- :param replace_func:
- function to handle analysis and replacement of any matching parts of a file.
- is called with one argument, the regexp match object.
- this function should then return the desired replacement string,
- or it should return None, in which case no replacement is performed.
-
- :param guard_func:
- optional function for checking file one last time before saving it...
- passed (path, input, output)... if it returns True, file is saved, else it isn't.
-
- .. todo::
- Give an example for this function
- """
- if isinstance(match_re, (tuple, list)):
- #assume it's a (re_str, re_flags) pair
- match_re = re.compile(*match_re)
- elif isinstance(match_re, str):
- match_re = re.compile(match_re, re.M)
- if file_filter is None:
- def file_filter(name):
- return name.endswith(".py")
- ctx = [None] #helper for logging
- for root, dirs, files in os.walk(root_path):
- if '.svn' in root: continue #skip subversion dirs
- for name in files:
- if not file_filter(name):
- continue
- path = filepath(root, name)
- input = path.get()
- #replace any matches
- def replace_wrapper(match):
- output = replace_func(match)
- input = match.group()
- if output is None:
- return input
- if input != output:
- if not ctx[0]:
- if ctx[0] is False: print "\n"
- print "FILE: %r" % (path,)
- ctx[0] = True
- print " MATCH: %r" % (input,)
- print " -->: %r" % (output,)
- return output
- output = match_re.sub(replace_wrapper, input)
- if ctx[0]: ctx[0] = False
- #save result only if it changes
- if output and output != input:
- if guard_func and not guard_func(path, output, input):
- print " REJECTED"
- continue
- path.set(output)
-
-def purge_bytecode(root_path):
- """purge all pyc & pyo files from specified path"""
- for root, dirs, files in os.walk(root_path):
- if '.svn' in root: continue #skip subversion dirs
- if '.hg' in root: continue
- for name in files:
- if name[-4:] not in (".pyc", ".pyo"): continue
- path = filepath(root, name)
- print "PURGING ", path
- path.remove()
-
-#=========================================================
-#import tracker
-#=========================================================
-def log_imports(logger="sys.imports"):
- """
- this code wraps the builtin __import__ function
- with some code to log a message about every import that occurs.
-
- :param logger:
- Name of the logger to send output to.
- If ``False``, output is written straight to stderr.
- """
- depth = [0] #state for tracking import depth
- orig_import = __builtins__['__import__'] #old import hook
- import inspect,sys,os
-
- if logger:
- from logging import getLogger
- log = getLogger(logger)
- log._bps3_flag = False
- def write(msg, *args):
- if log._bps3_flag:
- #why do this? because we get a recursive import otherwise :(
- return
- msg = (". " * depth[0]) + msg
- log._bps3_flag = True
- log.info(msg, *args)
- log._bps3_flag = False
- else:
- def write(msg, *args):
- if args: msg %= args
- sys.stderr.write(" " * depth[0])
- sys.stderr.write(">>> %s\n" % (msg,))
- sys.stderr.flush()
-
- def __import__(name, globals=None, locals=None, fromlist=None, level=-1):
- fname = inspect.currentframe(1).f_code.co_filename
- for elem in sys.path:
- if fname[0:len(elem)] == elem:
- mname = fname[len(elem):]
- if mname[0] == "/":
- mname = mname[1:]
- break
- else:
- mname = fname #inspect.getmodulename(fname)
- if fromlist is not None:
- fstr = repr(fromlist)
- if len(fromlist) == 1:
- fstr = fstr[1:-2]
- else:
- fstr = fstr[1:-1]
- write("[FOR %r IMPORT %r FROM %r]", mname, fstr, name)
- else:
- write("[FOR %r IMPORT %r]", mname, name)
- depth[0] += 1
- try:
- mod = orig_import(name, globals, locals, fromlist, level)
- finally:
- depth[0] -= 1
- return mod
-
- #make sure all modules from now on use this
- __builtins__['__import__'] = __import__
- return __import__
-
-#=========================================================
-#EOF
-#=========================================================