Skip to main content

Log with 20/20 vision

Project description

Dynamic logging after the fact

Classic logging expects perfect foresight, but only hindsight is 20/20!

Usage

Install via pip, then enter a shell and define a function:

>>> def hello(a, b=2):
>>>     """docstring"""
>>>     a = 1
>>>     c = b * 2
>>>     a = b = c = a * 2 + b * c
>>>     print('output: a={} b={} c={}'.format(a, b, c))
>>>     return a, b, c

Attach a retrospect.FunctionRetrospector to it:

>>> import retrospect
>>> retro = retrospect.FunctionRetrospector(hello)

Now you can start inspecting lines in real-time:

>>> # emit at all line changes and function start/finish
>>> retro.implement(lines=True)
>>> hello(10)
((3, SetLineno, 3), {'a': 10, 'b': 2})
    ((4, SetLineno, 4), {'a': 1, 'b': 2})
    ((5, SetLineno, 5), {'a': 1, 'b': 2, 'c': 4})
    ((6, SetLineno, 6), {'a': 10, 'b': 10, 'c': 10})
    output: a=10 b=10 c=10
    ((7, SetLineno, 7), {'a': 10, 'b': 10, 'c': 10})
    ((7, RETURN_VALUE, None), {'a': 10, 'b': 10, 'c': 10})

Or a specific set of lines:

>>> # emit only at line 4
>>> retro.implement(lines=[4], boundaries=False)
>>> hello(20)
((4, SetLineno, 4), {'a': 1, 'b': 2})
output: a=10 b=10 c=10

Or only on symbol changes:

>>> # emit before/after STORE_FAST and at function start
>>> retro.implement(symbols=True, boundaries='start')
>>> hello(30)
((3, SetLineno, 3), {'a': 30, 'b': 2})
((3, STORE_FAST, 'a'), {'a': 30, 'b': 2})
((3, STORE_FAST, 'a'), {'a': 1, 'b': 2})
((4, STORE_FAST, 'c'), {'a': 1, 'b': 2})
((4, STORE_FAST, 'c'), {'a': 1, 'b': 2, 'c': 4})
((5, STORE_FAST, 'a'), {'a': 1, 'b': 2, 'c': 4})
((5, STORE_FAST, 'a'), {'a': 10, 'b': 2, 'c': 4})
((5, STORE_FAST, 'b'), {'a': 10, 'b': 2, 'c': 4})
((5, STORE_FAST, 'b'), {'a': 10, 'b': 10, 'c': 4})
((5, STORE_FAST, 'c'), {'a': 10, 'b': 10, 'c': 4})
((5, STORE_FAST, 'c'), {'a': 10, 'b': 10, 'c': 10})
output: a=10 b=10 c=10

Or specific opcodes:

>>> # emit before LOAD_CONST and RETURN_VALUE
>>> retro.implement(bytecode=['LOAD_CONST'], boundaries='finish')
>>> hello(40)
((3, LOAD_CONST, 1), {'a': 40, 'b': 2})
((4, LOAD_CONST, 2), {'a': 1, 'b': 2})
((5, LOAD_CONST, 2), {'a': 1, 'b': 2, 'c': 4})
((6, LOAD_CONST, 'output: a={} b={} c={}'), {'a': 10, 'b': 10, 'c': 10})
output: a=10 b=10 c=10
((7, RETURN_VALUE, None), {'a': 10, 'b': 10, 'c': 10})

Or return to exact original:

>>> retro.implement()
>>> hello(50)
output: a=10 b=10 c=10

Any of the above can be mixed as necessary, eg. lines=4 symbols=c

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

retrospect-0.1.3.tar.gz (8.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

retrospect-0.1.3-py2-none-any.whl (10.5 kB view details)

Uploaded Python 2

File details

Details for the file retrospect-0.1.3.tar.gz.

File metadata

  • Download URL: retrospect-0.1.3.tar.gz
  • Upload date:
  • Size: 8.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for retrospect-0.1.3.tar.gz
Algorithm Hash digest
SHA256 fb7a1d40d16f954c3ae254c963f822b8f2b1c3c4090bf6bb71a102b6ccaed36c
MD5 75972501b6f13b7791706e4203fed777
BLAKE2b-256 c5463e3e25f3cf34a79c377d2dca737001194f1d3703cccc452e6c215ccd599d

See more details on using hashes here.

File details

Details for the file retrospect-0.1.3-py2-none-any.whl.

File metadata

File hashes

Hashes for retrospect-0.1.3-py2-none-any.whl
Algorithm Hash digest
SHA256 62f6dddf1e2cd420109ec4942419199a6af74503d4fae5b924ba7416be76c5ef
MD5 2ea52c6d4b9960f7cb0ab9279efea098
BLAKE2b-256 a9919ac4458e0365f22b0994a4a9175b452055d5bf76553066ed01c2a5cfe837

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page