vsi.tools package
Subpackages
Submodules
vsi.tools.commonpath module
vsi.tools.diff module
vsi.tools.dir_util module
- class vsi.tools.dir_util.Chdir(dir, create=False, error_on_exit=False)[source]
Bases:
object
Context to change dir and guarantee you get back to your last directory
Example:
These are written in doctest format, and should illustrate how to use the function. >>> a=[1,2,3] >>> print [x + 3 for x in a] [4, 5, 6] >>> import os >>> import tempfile >>> from vsi.tools.dir_util import Chdir >>> os.chdir(os.path.abspath(os.sep)) >>> print(os.getcwd()) / >>> with Chdir(tempfile.tempdir): ... print(os.getcwd()) /tmp >>> print(os.getcwd()) /
- error_on_exit
Create Chdir object
- Parameters:
dir (str) – the directory you want to change directory to
create (str) – Optional: Create the directory if it doesn’t exist (else os error 2 will occur) Default: False
error_on_exit (bool) – When exiting the with loop, if the return directory does not exist anymore, (OSError 2), if this is true an error is thrown, else it is ignore and you are left in the new directory. Default: False
- vsi.tools.dir_util.checksum_dir(checksum, checksum_depth=2, base_dir=None)[source]
Generate checksum directory name
- Parameters:
- Returns:
The Path
- Return type:
Example
If the checksum was 1234567890abcdef, and the depth was 3, you would get 12/34/56/1234567890abcdef
Note
An optional base_dir will be prefixed
- vsi.tools.dir_util.copytree(src, dst, symlinks=False, ignore=None)[source]
Recursively copy a directory tree using copy2().
- Parameters:
src (path-like object) – The Source Tree
dst (str) – The Destination Directory may not already exist. If exception(s) occur, an Error is raised with a list of reasons. If the destination directory exists, it will be clobber by the source, including replacing entire directory trees with symlinks, if the symlinks flags is true.
symlinks (bool) – Optional. True if the symbolic links in the source tree result in symbolic links in the destination tree. False if the contents of the files pointed to by symbolic links are copied.
ignore (function) –
The optional ignore argument is a callable. If given, it is called with the src parameter, which is the directory being visited by copytree(), and names which is the list of src contents, as returned by os.listdir():
callable(src, names) -> ignored_names
Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the src directory that should not be copied.
XXX Consider this example code rather than the ultimate tool.
- vsi.tools.dir_util.find_file_in_path(fname, path=None)[source]
Find a file in any of the directories on the PATH. Like distutils.spawn.find_executable, but works for any file.
- vsi.tools.dir_util.is_dir_empty(path)[source]
Checks to see if a dir is empty. Much faster than
os.listdir
andos.walk
- vsi.tools.dir_util.is_subdir(path, base_dir, dereference_symlinks=True)[source]
Determines if the path is in the base_dir
- Parameters:
- Returns:
tuple – containing (True/False, and remainder (relative) of path)
str – Remainder, the relative different between the two paths. If on Windows and the paths are on two different drives, the entire path is returned
Note
This will NOT work with Junctions in Windows.
- vsi.tools.dir_util.mkdtemp(*args, **kwargs)[source]
Version of tempfile.mkdtemp that is r/w by uid and gid
- Parameters:
*args – Variable length argument list.
**kwargs – Arbitrary keyword arguments.
- Returns:
The Temp Directory
- Return type:
- vsi.tools.dir_util.prune_dir(directory, top_dir=None)[source]
Remove directory and ancestor directories if they are empty
- vsi.tools.dir_util.root_dir(directory)[source]
OS independent way of getting the root directory of a directory
On Windows:
C:\tmp\blah.txt -> C:\ D:\Program Files\calc.exe -> D:\
On Linux/Darwin:
/tmp/blah.txt -> /
- vsi.tools.dir_util.samefile(path1, path2, normpath=True)[source]
OS independent version of os.path.samefile
- Parameters:
- Returns:
OS independent version of the path
- Return type:
Example:
>>> os.symlink('/usr/bin', '/tmp/blah') >>> samefile('/usr', '/tmp/blah/..') False >>> samefile('/usr', '/tmp/blah/..', normpath=False) True
vsi.tools.docker_token module
vsi.tools.file_util module
- vsi.tools.file_util._path_or_temp(kwarg_key, kwarg_func=<function <lambda>>)[source]
Decorator to replace a missing kwarg (missing, empty, or
None
) that defines a path with a valid temporary path.
- vsi.tools.file_util.file_or_temp(kwarg_key, filename)[source]
Decorator to replace a missing kwarg (missing, empty, or
None
) that defines a file with a filename in a valid temporary directory.The temporary directory intended to contain the temporary file will be created on entering the decorated function, and the directory & its contents will be deleted on exiting the decorated function.
The decorated function is expected to create the file itself.
vsi.tools.iter module
- vsi.tools.iter.sub_block(data, block=3, overlap=0, subok=False)[source]
Return an array of windows into the original data array.
- Parameters:
data (numpy.ndarray) – N-dimensional array
block (int) – The block size of the final blocks. Should have length N or be a single number
overlap (float) – The amount of overlap between windows. A value of 0 has no overlap, while positive values overlap by that much, and negative values have gaps of that size.
subok (bool) – Passed to as_strided
- Returns:
numpy.ndarray – windows - N + N dimensional array where the first N dimensions are the window indexes, and the next N dimension are the data dimensions. Keep in mind, all the data is linked to the original data array. Changing values in one place changes them all.
list – remainders - An N length list of the number of elements not included in the windows: the remainder of the sub-blocks. Another function could use these values to sub_block over them too. In the 2D case, there would be 3 groups of windows, in 3D case 6 groups of windows, etc…
Example:
>> qq = np.arange(25).reshape(5,5) >> q,r = sub_block(qq, block=3, overlap=(2,1)) >> q array([[[[ 0, 1, 2], [ 5, 6, 7], [10, 11, 12]], [[ 2, 3, 4], [ 7, 8, 9], [12, 13, 14]]], [[[ 5, 6, 7], [10, 11, 12], [15, 16, 17]], [[ 7, 8, 9], [12, 13, 14], [17, 18, 19]]], [[[10, 11, 12], [15, 16, 17], [20, 21, 22]], [[12, 13, 14], [17, 18, 19], [22, 23, 24]]]])
REVIEW would be nice if this were a generator…
vsi.tools.logging_helper module
vsi.tools.mpl module
- class vsi.tools.mpl.SimpleBubblePicker(fig=None, text_function=None, x_offset=10, y_offset=15, offset_units='dots', bbox={'alpha': 0.5, 'boxstyle': 'round', 'facecolor': 'wheat'}, **kwargs)[source]
Bases:
object
Simple class to add a picker with your own text function
Currently supports plots (Line2D), scatter (PathCollection), images (AxesImage) and PatchCollection
SimpleBubblePicker
comes with a default text function that will display basic information about any point you click.
- vsi.tools.mpl.auto_fit_fontsize(text, width=None, height=None, step_size=1, min_font_size=1, max_font_size=100)[source]
Auto-fit the fontsize of a text object.
- Args:
text (matplotlib.text.Text) width (float): allowed width in data coordinates height (float): allowed height in data coordinates
- vsi.tools.mpl.imshow_chip(axes, img, origin, size, *args, **kwargs)[source]
imshow’s only a chip of an image, and draws the chip at the appropriate coordinates.
Does not support custom transforms
- Parameters:
axes (
matplotlib.axes.Axes
) – The first Axesimg (
numpy.ndarray
) – Image arrayorigin (tuple) – The origin of the chip to load, in y, x, order
size – The size of the chip to load, in y, x, order
*args – Additional parameters passed to
matplotlib.pyplot.imshow()
**kwargs – Additional keyword arguments passed to
matplotlib.pyplot.imshow()
- vsi.tools.mpl.imshow_chip_from_raster(axes, raster, origin, size, *args, **kwargs)[source]
Loads and imshow’s a chip of an image, and draws the chip at the appropriate coordinates.
Does not support custom transforms
- Parameters:
axes (
matplotlib.axes.Axes
) – The first Axesraster (
rasterio.io.DatasetReader
) – rasterio dataset objectorigin – The origin of the chip to load, in y, x, order
size – The size of the chip to load, in y, x, order
*args – Additional parameters passed to
matplotlib.pyplot.imshow()
**kwargs – Additional keyword arguments passed to
matplotlib.pyplot.imshow()
Like
Axes.sharex
/Axes.sharey
only it allows you to provide your own function instead of the 1:1 default.- Parameters:
ax1 (
matplotlib.axes.Axes
) – The first Axesax2 (
matplotlib.axes.Axes
) – The second Axesforward (Callable) – A function that takes the arguments
x0
,x1
,y0
,y1
forax1
and returns(x0, x1, y0, y1)
forax2
. ReturnNone
to indicate that no update toax2
should be performed.backward (Callable) – Same as
forward
except mapsax2
toax1
sharex (
bool
, optional) – Should the x axis be sharedsharey (
bool
, optional) – Should the y axis be shared**kwargs – Additional keyword arguments passed to
forward
andbackward
- vsi.tools.mpl.surf(z, cmap='jet', ax=None, x=None, y=None, c=None, **kwargs)[source]
Creates an equivalent “surf” plot, like in matlab
- Parameters:
z (
numpy.ndarray
) – The z datacmap – The colormap used to color based on z height. Default: jet
ax (
matplotlib.axes.Axes
) – The axes to draw on. Default: gca()x (
numpy.ndarray
, optional) – The x coordinate used to draw. Default usesnumpy.meshgrid()
y (
numpy.ndarray
, optional) – The y coordinate used to draw. Default usesnumpy.meshgrid()
c (
numpy.ndarray
, optional) – A custom array that is fed into the colormap for coloring. Default usesz
**kwargs (dict) – Additional keyword arguments passed to
mpl_toolkits.mplot3d.axes3d.Axes3D.plot_surface()
By default,
mpl_toolkits.mplot3d.axes3d.Axes3D.plot_surface()
does not draw the entire mesh, it downsamples it to 50 points instead (for efficiency). To disable downsampling, consider settingrstride
andcstride
to1
.Shading is also disabled by default
vsi.tools.mpl_zoom module
- vsi.tools.mpl_zoom.figure_with_zoom(*args, **kwargs)[source]
- Parameters:
*args – Variable length argument list.
**kwargs – Arbitrary keyword arguments.
- Returns:
The Zoomed Figure
- Return type:
- vsi.tools.mpl_zoom.zoom_factory(ax=None, base_scale=1.5)[source]
- Parameters:
ax (
matplotlib.axes
) – The Axesbase_scale (float) – The Base Scale
- Returns:
The Zoom Function
- Return type:
vsi.tools.natural_sort module
- vsi.tools.natural_sort.natural_sorted(iterable, key=None, *args, **kwargs)[source]
Return sorted list of strings according to (sub)string numerical value.
- Parameters:
- Returns:
A sorted list of strings according to (sub)string numerical value.
- Return type:
>>> natural_sorted(['f10', 'f2', 'f1']) ['f1', 'f2', 'f10']
>>> natural_sorted([('f10',2), ('f2',5), ('f1',1), ('f1a',3)], key=lambda x: x[0]) [('f1', 1), ('f1a', 3), ('f2', 5), ('f10', 2)]
vsi.tools.patch_wheel module
vsi.tools.python module
- class vsi.tools.python.ArgvContext(*args)[source]
Bases:
object
Context to temporarily change the
sys.argv
variable- Parameters:
*args (str) – Arguments to replace
sys.argv
, starting withargv[0]
- class vsi.tools.python.OptionalArgumentDecorator(*args, **kwargs)[source]
Bases:
object
Decorator for easily defining a decorator class that may take arguments
Write a decorator class as normal, that would always take arguments, and make sure they all have default values. Then decorate that decorator with this decorator and both
@decorator
and@decorator()
notations will work.See also
BasicDecorator
Simple decorator with optional arguments
- class vsi.tools.python.Try(default_ignore=<class 'Exception'>, *other_ignore)[source]
Bases:
object
Try catch helper for cases when you want to ignore certain exceptions
- Parameters:
*ignore_exceptions (Exception) – Exception classes to be ignored. Default is all.
- class vsi.tools.python._BasicArgumentDecorator[source]
Bases:
object
A basic decorator class that takes arguments
It’s best to define __init__ with a proper signature when inheriting
- class vsi.tools.python._BasicDecorator(*args, **kwargs)[source]
Bases:
object
A basic decorator class that does not take arguments
- Parameters:
fun (function) – The function that gets wrapped
- Variables:
fun (function) – The function that is being wrapped
Examples
Usage:
class MyDecorAdd1(_BasicDecorator): def __call__(self, *args, **kwargs): result = self.fun(*args, **kwargs) res @MyDecorAdd1 def fun(a, b=2): return a+b
- __call__(*args, **kwargs)[source]
Re-write this. Do need to call
super().__call__
The general idea of this class is you re-write the
__call__
method to do what you want, and callself.fun
and return the result. This can be accomplished byreturn super().__call__(*args, **kwargs)
, but more often then not, you will want the result ofself.fun
, and will callresult = self.fun(*args, **kwargs)
yourself, and thenreturn result
- fun = None
- vsi.tools.python._meta_generate_class(cls, *args, **kwargs)[source]
Determine class to use for decorators
- Parameters:
Helper function to parse the arguments from a class’s __new__ or __init__ to handle both the normal case, and when the class is being inherited by another class:
class A: def __new__(cls, *args): return super(A, cls).__new__(_meta_generate_class(A, *args)) @A class B(): pass class C(B): pass
When B is decorated by A,
A.__new__/__init__
is called with 1 argument,B
. When C inherits from B,A.__new__/__init__
is called with 3 arguments instead of one, the 3 arguments to atype()
call.This helper will run all that logic for you, and just always return the class you need.
- vsi.tools.python.args_to_kwargs(function, args=(), kwargs={})[source]
returns a single dict of all the args and kwargs
Should handle: functions, classes (their __init__), bound and unbound versions of methods, class methods, and static methods. Furthermore, if a class instance has a __call__ method, this is used.
It does not call the function.
- Parameters:
- Returns:
dict – The returned dictionary has the keywords that would be received in a real function call. Leftover args are put into the key ARGS, and leftover KWARGS are placed in the key KWARGS. While everything should behave exactly as python would, certain failure situations are not reproduced, for exampled it does not raise exception if you declare the same parameter in both //args and /*/kwargs)
On python3,
args_to_kwargs_unbound
must be used for unbound classmethods
Based on
https (//github.com/merriam/dectools/blob/master/dectools/dectools.py)
- vsi.tools.python.get_file(fid, mode='rb')[source]
Helper function to take either a filename or fid
- Parameters:
- Returns:
The opened file object
- Return type:
- vsi.tools.python.is_static_method(cls, attribute)[source]
Returns whether the attribute refers to a staticmethod or not
- vsi.tools.python.is_string_like(obj)[source]
Check whether obj behaves like a string.
Copied from numpy
- vsi.tools.python.nested_patch(obj, condition, patch, _spare_key=None)[source]
Patch strings in a nested python dict
Will patch values in mapping and iterable containers recursively. This includes (but is not limited to)
set
,list
,dict
,tuple
, etc… Only iterates through values, not keys.When the condition is met for a given key,value pair, then the patch function is used to replace the value.
- Parameters:
obj (mapping or iterable or object) – The python object to be patched. Typically a dict, but can be a list, etc… or even a normal object, but that kind of defeats the purpose
condition (function) – The condition function to decide if each value should be patched.
condition
takes two arguments,(key, value)
patch (function) – Callable that should return a patched version of the value.
patch
takes two arguments,(key, value)
- Returns:
Returns a patched version of the object. This should not be though of as a deep-copy of the original object, as unpatched values will still be the same python objects, not copies.
- Return type:
Example
patterns = ['_file', '_dir', '_path', '_files', '_dirs', '_paths'] condition = lambda key, value: isinstance(key, str) and \ any(key.endswith(pattern) for pattern in patterns) def patch_value(value, volume_map): for vol_from, vol_to in volume_map: if isinstance(value, str) and value.startswith(vol_from): return value.replace(vol_from, vol_to, 1) return value volume_map = [['/tmp', '/temp'], ['/tmp/home', '/nope'], ['/home', '/Home']] patch = lambda key, value: patch_value(value, reversed(volume_map)) z = {'test': '/tmp', 'foo_file': '/tmp', 'foo': 15, 17: 'bar', 'foo_dir': ['/tmp', '/home'], 'foo_files': 15, 'stuff': { 'this_path': '/home', 'a': { 'b': { 'c': { 'e': [{'b_path': '/home'}, {'c_dir': '/tmp'}], 'd': { 'q_path': (('/home', '/opt'), ('/tmp', '/tmp/home/foo/bar')), 'q_orig': (('/home', '/opt'), ('/tmp', '/tmp/home/foo/bar')), 'a_path': ('/home', '/opt', '/tmp', '/tmp/home/foo/bar') } } } } } } z2 = nested_patch(z, condition, patch)
- vsi.tools.python.nested_patch_inplace(obj, condition, patch, _spare_key=None)[source]
Destructive inplace version of
vsi.tools.python.nested_patch()
- vsi.tools.python.nested_update(dict_, *args, **kwargs)[source]
Updated a dictionary in a nested fashion
- vsi.tools.python.reloadModules(pattern='.*', skipPattern='^IPython')[source]
Reload modules that match pattern regular expression (string or re)
- vsi.tools.python.static(**kwargs)[source]
Decorator for easily defining static variables
- Parameters:
**kwargs – Arbitrary keyword arguments.
Example:
@static(count=0) def test(a, b): test.count += 1 print(a+b, test.count)
- vsi.tools.python.unwrap_wraps(func)[source]
Unwraps a wrapped function
Finds the originally wrapped function, using the
functools.wraps()
pattern of storing in__wrapped__
vsi.tools.redirect module
- class vsi.tools.redirect.Capture(stdout_c=1, stderr_c=2, stdout_py=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, stderr_py=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, group=True, group_outerr=True, group_out=True, group_err=True)[source]
Bases:
RedirectBase
A class to easily redirect stdout and stderr to a sting buffer
There are times in python when using “those kind of libraries” where you have to capture either stdout or stderr, and many situations are tricky. This class will help you, by using a with statement.
Example:
with Redirect() as rid: some_library.call157() print(rid.stdout)
There are 4 output pipe of concern, none of which are synced with each other (flushed together).
stdout and stderr from c (referred to as stdout_c, stderr_c) and stdout and stderr from python (referred to as stdout_py, stderr_py).
Most python functions use the python stdout/stderr, controlled by sys.stdout and sys.stderr. However c embedded calls are used the c stdout/stderr, usually fd 1 and 2. Because of this, there are 4 streams to consider
Once Redirect is done, the results are stored in
>>> self.stdout_c - Standard out output for c >>> self.stderr_c - Standard error output for c >>> self.stdout_py - Standard out output for python >>> self.stderr_py - Standard error output for python
When the streams are grouped, they both contain the same data. In the group_out and group_err case, an addition attribute is defined
>>> self.stdout - Standard out output >>> self.stderr - Standard error output
Just to make it easier
If you want a more complicated scenario, say you want stdout_c and stderr_py grouped, and stderr_c and stdout_py groups because you’ve been drinking too much. Well, this is easy to do by calling Redirect twice:
Example:
with Redirect(stdout_c=None, stderr_py=None) as rid1: with Redirect(stderr_c=None, stdout_py=None) as rid2: stuff()
Now rid1’s buffer has just stderr_c and stdout_py as one group stream and rid2 has stfout_c and stderr_py as one grouped stream
- __enter__()[source]
enter function for with statement.
Switched out stderr and stdout, and starts pipe threads
- __exit__(exc_type=None, exc_value=None, traceback=None)[source]
exit function for with statement.
Restores stdout and sterr, closes write pipe and joins with the threads
- group_err
Initialize the Redirect object
- Parameters:
stdout_c (
int
, optional) – The fd to be replace, usually 1 will work, but change it in case this is not right in your case (default: 1) None means to not redirectstderr_c (
int
, optional) – The fd to be replaced, usually 2 will work, but change it in case this is not right in your case (default: 2) None means to not redirectstdout_py (file-like object, optional) – The file object to be replaced (default: sys.stdout) None means to not redirect
stderr_py (file-like object, optional) – The file object to be replaced (default: sys.stderr) None means to not redirect
group (
bool
, optional) – Should ANY of the stream be joined together. This overrides ALL of the following group optionsgroup_outerr (
bool
, optional) – Should stdout and stderr use the a group stream or else it will have separate streams (default: True)group_out (
bool
, optional) – Should stdout_c and stdout_py use the a group stream or else it will have separate streams (default: True)group_err (
bool
, optional) – Should stderr_c and stderr_py use the a group stream or else it will have separate streams (default: True)
- class vsi.tools.redirect.FileRedirect(outputs=[])[source]
Bases:
object
Redirect a real file object to any object with .write
Some function need a REAL file object with file number and all. This class wraps a pair of pipes per output and so what everytime the pipe is written to, output.write is called.
Only supports one way communication. You can write to the file object via any valid call, and the other end of the pipe performs “readlines” and calls output.write() It would be possible to expand this to two way, but not currently needed.
Primarily used in a with expression:
>>> from StringIO import StringIO >>> s = StringIO() >>> with FileRedirect([s]) as f: >>> f.wids[0].write('hiya') >>> s.seek(0); print(s.read())
IF you call __enter__ manually, you only need to close the wids file objects, and the rest of the threads and file objects are cleaned up, of course it would be better to call __exit__ in that case.
- __exit__(exc_type=None, exc_value=None, traceback=None)[source]
Closes the write ends of the pipes, and join with monitoring threads
The read pipes are automatically closed by the monitors
- class vsi.tools.redirect.Logger(logger, lvl=20)[source]
Bases:
object
File object wrapper for logger.
Careful when using this, if the logging out goes to a stream that is redireted, you have an infinite capture loop and does not go well
Use PopenRedirect instead of Redirect in that case
- class vsi.tools.redirect.PopenRedirect(stdout=<vsi.tools.redirect.Foo object>, stderr=<vsi.tools.redirect.Bar object>)[source]
Bases:
FileRedirect
Version FileRedirect object geared towards redirecting for Popen commands
>>> from StringIO import StringIO >>> from subprocess import Popen >>> out = StringIO(); err = StringIO() >>> with PopenRedirect(out, err) as f: >>> Popen(['whoami'], stdout=f.stdout, stderr=f.stderr).wait() >>> Popen(['whoami', 'non user'], stdout=f.stdout, stderr=f.stderr).wait() >>> out.seek(0); err.seek(0) >>> print(out.read(), err.read())
- property stderr
- Returns:
Second object in wireless intrusion prevention system list.
- Return type:
- class vsi.tools.redirect.Redirect(all=None, stdout=None, stderr=None, c=None, py=None, stdout_c=None, stderr_c=None, stdout_py=None, stderr_py=None, stdout_c_fd=1, stderr_c_fd=2, stdout_py_module=<module 'sys' (built-in)>, stderr_py_module=<module 'sys' (built-in)>, stdout_py_name='stdout', stderr_py_name='stderr')[source]
Bases:
RedirectBase
FAILED EXPERIMENT! You can use this, but I don’t recommend it for anything that matters. There are too many situations where buffered output or multiple stdouts in windows cause this to not behave 100% right. Best to just not use it. PopenRedirect is good
MORE FAILURES! It looks like when extending python with C, too many cout/flushes can result in a deadlock, I’m guess the GIL does something weird
Similar to Capture class, except it redirect to file like objects
There are times in python when using “those kind of libraries” where you have to capture either stdout or stderr, and many situations are tricky. This class will help you, by using a with statement.
Example:
from StringIO import StringIO stdout = StringIO() with Redirect(stdout=stdout): some_library.call157() stdout.seek(0,0) print(stdout.read())
There are 4 output pipe of concern, none of which are synced with each other (flushed together).
stdout and stderr from c (referred to as stdout_c, stderr_c) and stdout and stderr from python (referred to as stdout_py, stderr_py).
Most python functions use the python stdout/stderr, controlled by sys.stdout and sys.stderr. However c embedded calls are used the c stdout/stderr, usually fd 1 and 2. Because of this, there are 4 streams to consider
Known bugs: In windows, after stdout_c is done being redirected, stdout buffering appears to no longer be disabled in interactive mode. What this means is typing
>>> print(123)
No longer returns 123 right away, without a
>>> sys.stdout.flush()
Why? I’m guessing os.dup2 breaks the buffered mode. The fix is to
>>> sys.stdout = os.fdopen(sys.__stdout__.fileno(), 'w', 0)
However this can only be done once or twice, and then starts failing.
Work around is to redirect stdout when calling the command. For example ‘python | find /v “”’ Mostly works.
Basically don’t do this in Windows Command line
- __enter__()[source]
enter function for with statement.
Switched out stderr and stdout, and starts pipe threads
- __exit__(exc_type=None, exc_value=None, traceback=None)[source]
exit function for with statement.
Restores stdout and stderr, closes write pipe and joins with the threads
- stderr_py_out
Create the Redirect object
- Parameters:
file_like (file-like object, optional) – File Output Argument. All File output arguments should use File like Python objects that have a .write call. Many of the arguments override the other argument for ease of use
all (
str
, optional) – Output stdout_c, stderr_c, stdout_py and stderr_py to the all file.stdout (
str
, optional) – Output stdout_c and stdout_py to the stdout file.stderr (
str
, optional) – Output stderr_c and stderr_py to the stderr file.c (
str
, optional) – Output stdout_c and stderr_c to the c file.py (
str
, optional) – Output stdout_py and stderr_py to the py file.stdout_c (
str
, optional) –stderr_c (
str
, optional) –stdout_py (file-like object, optional) –
stderr_py (file-like object, optional) – Output to each individual stream for maximum customization.
stdout_c_fd (
int
, optional) –stderr_c_fd (
int
, optional) – The default file number used for stdout (1) and stderr (2). There should be no reason to override thisstdout_py_module (module, optional) –
stderr_py_module (module, optional) –
stdout_py_name (
str
, optional) –stderr_py_name (
str
, optional) – Because of the nature of python, in order to replace and restore the python object, the module and name of attribute must be passed through, where name is a string and module and the actual module. The default is sys module and “stdout” or “stderr” (Including the quotes). Again, there should be no real reason to override these, unless you are doing some IPython/colorama redirecting, or any other library that messes with sys.stdout/sys.stderr
- class vsi.tools.redirect.StdRedirect(stdout=None, stderr=None)[source]
Bases:
object
Redirect stdout and stderr to a file object (must have a working fileno)
This is very stable and safe to use. The only caveat to remember is that C can have unflushed data in the buffer, and it will not be captured after the StdRedirect with statement. This is not vulnerable to the deadlock that the GIL can introduce with the pipe methods that need extra threads.
Primarily used in a with expression:
>>> test = open('test.txt', 'w') >>> with StdRedirect(test): ... boxm2_batch.print_db()
Supports stdout and stderr, and stderr can be set to StdRedirect. STDOUT to use the same output as stdout
- STDOUT = -1
vsi.tools.stdout_profile module
vsi.tools.subprocess_util module
vsi.tools.time_utils module
- class vsi.tools.time_utils.GenericTimer(msg, logging_func=<built-in function print>)[source]
Bases:
object
- class vsi.tools.time_utils.TaskTimer(task_name, num_tasks=1, logging_func=<built-in function print>)[source]
Bases:
object
vsi.tools.vdb module
- class vsi.tools.vdb.DbStopIfErrorGeneric(threading_support=False, *args, **kwargs)[source]
Bases:
object
With statement for local dbstop situations
- ignore_exception = False
- kwargs
- Parameters:
threading_support (bool) – Optional. Support the threading module and patch a bug preventing catching exceptions in other threads. See add_threading_excepthook for more info. Only neccesary if you want to catch exceptions not on the main thread. This is only patched after __enter__ unpatched at __exit__
*args – Variable length argument list.
**kwargs – Arbitrary keyword arguments.
All other args from db_stop_if_error()
- classmethod set_continue_exception()[source]
Continue running code after exception
- Parameters:
cls (bool) – True to continue to run code after the exception. Default: False.
After the with statement scope fails, if this is called, python will continue running as if there was no error. Can be useful, can also be dangerous. So don’t abuse it!
- class vsi.tools.vdb.PostMortemHook[source]
Bases:
object
- classmethod dbstop_if_error(interactive=False, *args, **kwargs)[source]
- Parameters:
interactive (bool) – True if interactive. False if not.
*args – Variable length argument list.
**kwargs – Arbitrary keyword arguments.
- original_excepthook = None
- class vsi.tools.vdb.RunningTrace[source]
Bases:
object
Mixin to give any bdb a running settrace
Example:
from pdb import Pdb as OldPdb from vsi.tools.vdb import RunningTrace class Pdb(OldPdb, RunningTrace): pass p = Pdb() p.set_running_trace() p.onecmd('b my_function')
- vsi.tools.vdb.add_threading_excepthook()[source]
Workaround for sys.excepthook thread bug From http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html
(https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470). Call once from __main__ before creating any threads. If using psyco, call psyco.cannotcompile(threading.Thread.run) since this replaces a new-style class method.
- Raises:
- vsi.tools.vdb.attach(pid, signal=Signals.SIGUSR1)[source]
Trigger a python pid that’s been already run set_attach
This is the second part of attaching to a python process. Once set_attach is run, on another prompt running attach will trigger the interrupt thing attaching or triggering whatever db_cmd was
- vsi.tools.vdb.break_pool_worker()[source]
Setup the ThreadPool to break when an exception occurs (so that it can be debugged)
The ThreadPool class (and the Pool class too, but not useful here) always catches any exception and raises it in the main thread. This is nice for normal behavior, but for debugging, it makes it impossible to do post mortem debugging. In order to automatically attach a post mortem debugger, the exception has to be thrown. An exception being thrown WILL BREAK the pool call, and not allow your main function to continue, however you can now attach a debugger post_mortem. Useful with dbstop_if_error
Threading has a “bug” where exceptions are also automatically caught. http://bugs.python.org/issue1230540 In order to make THIS work, call add_threading_excepthook too
Example:
>>> from multiprocessing.pool import ThreadPool >>> import vsi.tools.vdb as vdb >>> def a(b): ... print(b) ... if b==3: ... does_not_exist() >>> vdb.dbstop_if_error() >>> vdb.break_pool_worker() >>> vdb.add_threading_excepthook() >>> tp = ThreadPool(3) >>> tp.map(a, range(10))
- vsi.tools.vdb.handle_db(sig, frame, db_cmd=None, signal=Signals.SIGUSR1)[source]
signal handler part of attach/set_attach
- vsi.tools.vdb.set_attach(db_cmd=None, signal=Signals.SIGUSR1)[source]
Set up this process to be “debugger attachable”
Just like gdb can attach to a running process, if you execute this on a process, now you can “attach” to the running python using the attach command
This works pretty well, and allows you to resume the code UNLESS you are running in windows and happen to interrupt a sleep command.
vsi.tools.vdb_ipdb module
- class vsi.tools.vdb_ipdb.DbStopIfError(threading_support=False, *args, **kwargs)[source]
Bases:
DbStopIfErrorGeneric
With statement for local dbstop situations
- class vsi.tools.vdb_ipdb.Vdb(*args: Any, **kwargs: Any)[source]
Bases:
TerminalPdb
VSI Debugger, based off of IPython’s 5.x or newer debugger
- class vsi.tools.vdb_ipdb.VdbPostMortemHook[source]
Bases:
PostMortemHook
- vsi.tools.vdb_ipdb.dbstop_if_error(interactive=False)[source]
Run this to auto start the vdb debugger on an exception.
- Parameters:
interactive (
bool
, optional) – Default False. dbstop if console is interactive. You are still able to print and run commands in the debugger, just listing code declared interactively will not work. Does not appear to work in ipython. Use %debug instead. This will not help in the multithread case in ipython… ipython does too much, just don’t try that. Unless someone adds a way to override ipython’s override.
- vsi.tools.vdb_ipdb.runpdb(lines, debugger=None)[source]
Executes a list of vdb command
- Parameters:
lines (
str
orlist
ortuple
) – Collection of strings to be executed as if you were already in the debugger. Useful for setting breakpoints programatically.- Returns:
Returns the debugger object, since this can only be executed on the debugger object, you can optionally pass it in as the second argument if you want to call runpdb multiple times. If you do not, a new debugger object is created, and all the “memory” of the last debugger is lost, such as breakpoints, etc…
- Return type:
vsi.tools.vdb_rpdb module
- class vsi.tools.vdb_rpdb.DbStopIfError(threading_support=False, *args, **kwargs)[source]
Bases:
DbStopIfErrorGeneric
- class vsi.tools.vdb_rpdb.RpdbPostMortemHook[source]
Bases:
PostMortemHook
- vsi.tools.vdb_rpdb.attach(pid, ip='127.0.0.1', port=4444)[source]
NOT IMPLEMENTED! Needs a telnet client
- vsi.tools.vdb_rpdb.dbstop_if_error(interactive=False, ip='127.0.0.1', port=4444)[source]
Run this to auto start the debugger on an exception.
Optional arguments
- vsi.tools.vdb_rpdb.post_mortem(tb=None, ip='127.0.0.1', port=4444)[source]
- Parameters:
- Raises:
ValueError – Passes a valied traceback
vsi.tools.vdb_rpdb2 module
- class vsi.tools.vdb_rpdb2.CDebuggerCoreThread2(*args: Any, **kwargs: Any)[source]
Bases:
CDebuggerCoreThread
I just wanted to add some output on exception!!!
- vsi.tools.vdb_rpdb2.attach(pid, ip='127.0.0.1', password='vsi', gui=False, break_exit=False)[source]
- vsi.tools.vdb_rpdb2.dbstop_if_error(_rpdb2_pwd='vsi', fAllowUnencrypted=True, fAllowRemote=False, timeout=0, source_provider=None, fDebug=False, depth=0)[source]
Run this to auto start the debugger on an exception.
- Parameters:
_rpdb2_pwd (str) – The Remote Python Debugger Password
fAllowUnencrypted (bool) – True if unencrypted is allowed. False if not.
fAllowRemote (bool) – True if a remote is allowed. False if not. Default: False
timeout (int) – The timeout period in seconds.
source_provider (str) – The Source Provider
fDebug (bool) – The Debug Output
depth (int) – The Depth of the frame. Default: 0
I THINK rpdb2 does not use the same traceback or the frame/stack objects as pdb. So there is no way to just hand the debugger a traceback (yet). So by starting the debugger, all exceptions will be cause, and just attach to the debugger and type “analyze” to start debugging the last exception.
Of course, this means that if the debugger slows down execution, it will have to slow down all of the execution, instead of being loaded “just in time”
- vsi.tools.vdb_rpdb2.set_attach(_rpdb2_pwd='vsi', *args, **kwargs)[source]
- Parameters:
_rpdb2_pwd (str) – The Remote Python Debugger Password
*args – Variable length argument list.
**kwargs – Arbitrary keyword arguments.
- vsi.tools.vdb_rpdb2.set_trace(_rpdb2_pwd='vsi', fAllowUnencrypted=True, fAllowRemote=False, timeout=300, source_provider=None, fDebug=False, depth=1)[source]
Works, but without the other parts, it’s far from auto
- Parameters:
_rpdb2_pwd (str) – The Remote Python Debugger Password
fAllowUnencrypted (bool) – True if unencrypted is allowed. False if not.
fAllowRemote (bool) – True if a remote is allowed. False if not. Default: False
timeout (int) – The timeout period in seconds.
source_provider (str) – The Source Provider
fDebug (bool) – The Debug Output
depth (int) – The Depth of the frame. Default: 0