On Monday, March 24, 2014 11:37:05 AM UTC-5, Edward K. Ream wrote: > I am using the g.SherlockTracing class to do the executing. This is, in essence, and alternate version of pdb, with many cool features.
The present Sherlock code only handles Python calls and returns, but Python's sys.settrace mechanism allows the trapping of *any* kind of Python statement. sys.settrace is a great window into the workings of Python interp--I am surprised that only a few interesting applications have been developed. sys.setttrace allows the execution of *any* code whatever, not just pdb-like code. Rather than stopping, which is *way* too slow, Sherlock runs something like full machine speed (say 10x slower). Rather than relying on human data-gathering capabilities, which is *way* too limited, Sherlock allows data gathering driving by computer code. By manipulating the present (and future) Sherlock args, the human can do what we do best, which is find patterns and meaning. There are several extensions to the Sherlock idea I would like to explore: 1. Simulating backward execution. The idea is simple: store Sherlock traces in a list instead of printing them immediately. Then, when something "interesting" happens, say the use of an object at **a particular** address/id, filter the list so that only traces pertaining to that id are shown. This allows "backward" filtering. If we simply reverse the list before printing it we show the execution "in reverse". 2. Tracing the flow of data rather than (or in addition to) tracing execution flow. Again, the idea is simple: save lists or dicts of information about objects and show/filter them to make them maximally convenient to understand. Points 1 and 2 above are intimately related, and I'll be exploring various combinations of them soon. This will be driven by real exploration of pylint. Here is the test code I am presently using to explore how pylint works:: # Test this file by running pylint --tt class aClass: def __init__ (self): self.a = 2 self.b() def b(self): return self.a.c We expect pylint to give an error. Here is the output of pylint --tt. Note that most of the opening lines were produced by print statements within Sherlock or pylint-leo.py or pylint itself, not by the enabled Sherlock patterns:: <module 'pylint.lint' from 'c:\python26\lib\site-packages\pylint-0.25.1-py2.6.egg\pylint\lint.pyc'> pylint-leo.py: c:\leo.repo\static-type-checking\test\pylint\pylint_test.py pylint-leo.py: enabling Sherlock traces patterns contained in plyint-leo.py Sherlock patterns: +PyLinter::add_message +:.*typecheck.py typecheck.py .....+<module>() typecheck.py ......+TypeChecker() typecheck.py ......-TypeChecker -> dict typecheck.py .....-<module> typecheck.py .....+register(linter=<pylint.lint.PyLinter object at 0x02AA5EF0>) typecheck.py .....-register typecheck.py ...+TypeChecker::open() typecheck.py ...-TypeChecker::open utils.py ........+PyLinter::add_message(msgid='C0111',node=<Module(pylint_test)>) utils.py ........-PyLinter::add_message utils.py .........+PyLinter::add_message(msgid='C0111',node=<Class(aClass)>) utils.py .........-PyLinter::add_message typecheck.py ........+TypeChecker::visit_assign(node=<Assign>) typecheck.py ........-TypeChecker::visit_assign typecheck.py .........+TypeChecker::visit_assattr(node=<AssAttr(a)>) typecheck.py .........-TypeChecker::visit_assattr typecheck.py .........+TypeChecker::visit_callfunc(node=<CallFunc>) typecheck.py .........-TypeChecker::visit_callfunc typecheck.py ..........+TypeChecker::visit_getattr(node=<Getattr(b)>) typecheck.py ..........-TypeChecker::visit_getattr utils.py ..........+PyLinter::add_message(msgid='C0111',node=<Function(b)>) utils.py ..........-PyLinter::add_message typecheck.py .........+TypeChecker::visit_getattr(node=<Getattr(c)>) utils.py ...........+PyLinter::add_message(msgid='E1101',node=<Getattr(c)>,args=['Instance of','int','c']) ************* Module pylint_test E1101: 9,0:aClass.b: Instance of 'int' has no 'c' member utils.py ...........-PyLinter::add_message typecheck.py .........-TypeChecker::visit_getattr typecheck.py ..........+TypeChecker::visit_getattr(node=<Getattr(a)>) typecheck.py ..........-TypeChecker::visit_getattr EKR: time: 0.12 sec, exit status: 2 Note 1: The following lines are the actual pylint error message: ************* Module pylint_test E1101: 9,0:aClass.b: Instance of 'int' has no 'c' member Note 2: The data part of this trace is produced by one of pylint's __repr__ methods, modified by me to make them more readable. For example, the <Getattr(a)> in:: TypeChecker::visit_getattr(node=<Getattr(a)> Otoh, Sherlock produces everything else, including the list of arguments to visit_getattr. (Sherlock discovers that "node" is the name of the formal argument). It's a nifty division of responsibilities. I ran the test above (with many different traces) to answer two question: 1. How the actual message gets printed (answer PyLinter.add_message) 2. The order in which nodes of the ast (abstract syntax tree) are visited in order to check the tree. The answer: the order shown by the various visit_ methods. An unanswered question: why aren't visit_ClassDef and visit_FunctionDef called? Something truly clever is going on. The part that isn't shown by this trace is the entire "inference" machinery. I'll be exploring that next. Edward -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to leo-editor+unsubscr...@googlegroups.com. To post to this group, send email to leo-editor@googlegroups.com. Visit this group at http://groups.google.com/group/leo-editor. For more options, visit https://groups.google.com/d/optout.