Recent revs contain work on a nifty new tracing tool: the SherlockTracer 
class in leoGlobals.py.  This is a stand-alone class: it is not a subclass 
of pdb.Pdb, and it requires no imports (it does it's own imports)

In essence, the SherlockTracer class does everything my old Sherlock 
tracing tool did, and it's a lot more flexible.  The idea is that you can 
enable and disable traces for any method or function with tracing 
arguments.  Here is the code that I am using to trace the execution of the 
Rope refactoring tool::

    sherlock = g.SherlockTracer(verbose=True,
        
patterns=['+.*','+:.*','-:.*\\lib\\.*','+:.*rope.*','-:.*leoGlobals.py',
            '-:.*worder.py','-:.*prefs.py','-:.*resources.py',])
    sherlock.run()
    try:
        << rope code to be traced >>
    finally:
        sherlock.stop()
        sherlock.print_stats(patterns=['+:.*rope.*',])

The arguments in the pattern lists determine which functions get traced or 
which stats get printed.  Each pattern starts with "+", "-", "+:" or "-:", 
followed by a regular expression.

"+x" Enables tracing (or stats) for all functions/methods whose name 
matches the regular expression x.
"-x" Disables tracing for functions/methods.
"+:x" Enables tracing for all functions in the **file** whose name matches 
x.
"-:x" Disables tracing for an entire file.

The cute part is that enabling and disabling depends on the order of 
arguments in the pattern list. Consider the arguments for the Rope trace::

    patterns=['+.*','+:.*','-:.*\\lib\\.*','+:.*rope.*','-:.*leoGlobals.py',
            '-:.*worder.py','-:.*prefs.py','-:.*resources.py',])

This enables tracing for everything, then disables tracing for all library 
modules, except for all rope modules.  Finally, it disables the tracing for 
Rope's worder, prefs and resources modules.  Btw, this is one of the best 
uses for regular expressions that I know of.

Being able to zero in on the code of interest can be a big help in studying 
other people's code.  This is a non-invasive method: no tracing code needs 
to be inserted anywhere.

Here is a snippet of a recent trace of Rope's validate call::

    .project.py:validate
    ..project.py:<lambda>
    ...project.py:get_resource
    ....project.py:_get_resource_path
    ..project.py:validate
    ...resourceobserver.py:validate
    ....project.py:_invalid
    ...resourceobserver.py:validate
    ....resourceobserver.py:__init__
    ....resourceobserver.py:_search_resource_moves
    ....resourceobserver.py:_search_resource_changes
    ....resourceobserver.py:_search_resource_creations
    ....resourceobserver.py:_perform_changes
    ...resourceobserver.py:validate
    ....resourceobserver.py:__init__
    ....resourceobserver.py:_search_resource_moves
    ....resourceobserver.py:_search_resource_changes
    ....resourceobserver.py:_search_resource_creations
    ....resourceobserver.py:_perform_changes
    ...resourceobserver.py:validate
    
The leading dots (level dots) indicate the level of nesting of the calls.  
The call to project.py:validate is the top-level call: it has only one 
level dot.  With this kind of trace it is easy to see who calls whom.

Without the verbose argument, the filenames would be omitted from the trace.

That's about it.  I'll probably be adding features to g.SherlockTracer in 
the next few days.

Edward

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/leo-editor/-/fhy-BxYKJpcJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/leo-editor?hl=en.

Reply via email to