### Install Project in Developer Mode Source: https://github.com/alexmojaki/snoop/blob/master/README.md Install the project in editable mode with test dependencies using pip. This is useful for development and testing. ```bash pip install -e path/to/snoop[tests] ``` -------------------------------- ### Install Tox for Development Source: https://github.com/alexmojaki/snoop/blob/master/README.md Install the Tox testing tool using pip. Tox is used to run tests against multiple Python versions. ```console $ pip install tox ``` -------------------------------- ### Install Snoop Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.12/install_enabled.txt Use pip to install the Snoop library. This command installs Snoop and its dependencies. ```bash pip install snoop ``` -------------------------------- ### Snoop Output Example: Function Call with x=3 Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/install_enabled.txt Demonstrates Snoop's output for a call to the 'foo' function with the argument x=3. This example highlights how Snoop tracks different argument values and their corresponding return values. ```text 12:34:56.78 >>> Call to foo in File "/path/to_file.py", line 5 12:34:56.78 ...... x = 3 12:34:56.78 5 | def foo(x): 12:34:56.78 6 | return x * 2 12:34:56.78 <<< Return value from foo: 6 ``` -------------------------------- ### Multiline Context Manager Usage in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/multiline.txt Illustrates using a context manager with setup code (function calls) defined over multiple lines. ```python with context( bar(), # 1 bar(), # 2 ) ``` ```python with context( bar(), # 1 bar(), # 2 ) ``` -------------------------------- ### Set DJANGO_SETTINGS_MODULE and Setup Django Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/django_sample.txt Before importing Django modules, set the DJANGO_SETTINGS_MODULE environment variable. Then, call django.setup() to initialize Django. ```python os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.fake_django_settings' import django django.setup() ``` -------------------------------- ### Query Django ContentTypes Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/django_sample.txt After Django is set up, you can import and use Django models. This example shows how to fetch all ContentType objects. ```python from django.contrib.contenttypes.models import ContentType queryset = ContentType.objects.all() ``` -------------------------------- ### Install Snoop with Custom Watch Extras Source: https://github.com/alexmojaki/snoop/blob/master/README.md Pass a list of custom watch functions to the 'watch_extras' parameter of the 'install' function to automatically display extra information for all traced values. ```python install(watch_extras=[type_watch]) ``` -------------------------------- ### Installing snoop with Custom Columns Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This Python code demonstrates how to install the snoop debugger globally and configure it to display specific columns, such as 'time' and 'thread', in its output. This setup is useful for customizing the debugging experience. ```python import snoop snoop.install(columns='time thread') @snoop def foo(x): ``` -------------------------------- ### Multiline Context Manager Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/multiline.txt Illustrates a multiline context manager setup with function calls. The debugger shows the structure within the context. ```python with context( bar(), # 1 bar(), # 2 ``` -------------------------------- ### Python Call Trace Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/indentation.txt This example illustrates a call trace, showing the sequence of function calls and their return values. It highlights the execution path through nested functions. ```text 12:34:56.78 >>> Call to main in File "/path/to_file.py", line 5 12:34:56.78 5 | def main(): 12:34:56.78 6 | f2() 12:34:56.78 >>> Call to f2 in File "/path/to_file.py", line 9 12:34:56.78 9 | def f2(): 12:34:56.78 10 | f3() 12:34:56.78 >>> Call to f4 in File "/path/to_file.py", line 18 12:34:56.78 18 | def f4(): 12:34:56.78 19 | f5() 12:34:56.78 >>> Call to f5 in File "/path/to_file.py", line 22 12:34:56.78 22 | def f5(): 12:34:56.78 23 | pass 12:34:56.78 <<< Return value from f5: None 12:34:56.78 19 | f5() 12:34:56.78 <<< Return value from f4: None 12:34:56.78 10 | f3() 12:34:56.78 <<< Return value from f2: None 12:34:56.78 6 | f2() 12:34:56.78 <<< Return value from main: None ``` -------------------------------- ### Multiline Context Manager Usage Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.8/multiline.txt Shows how to use a context manager with arguments defined over multiple lines. This improves clarity when the context setup is extensive. ```python with context( bar(), # 1 bar(), # 2 [ x = ( ``` ```python with context( bar(), # 1 bar(), # 2 ``` ```python with context( bar(), # 1 bar(), # 2 ``` -------------------------------- ### Snoop Output Example with Qualified Names Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This is an example of the output generated by snoop, demonstrating its ability to show the qualified names of nested functions, including those defined locally. ```text 19:54:54.73 >>> Call to bar in File "/path/to/example.py", line 19 19:54:54.73 19 | def bar(): 19:54:54.73 20 | return foo() 19:54:54.73 >>> Call to my_decorator..wrapper in File "/path/to/example.py", line 8 19:54:54.73 .......... args = () 19:54:54.73 .......... kwargs = {} 19:54:54.73 .......... func = 19:54:54.73 8 | def wrapper(*args, **kwargs): 19:54:54.73 10 | return func(*args, **kwargs) 19:54:54.73 <<< Return value from my_decorator..wrapper: 3 19:54:54.73 20 | return foo() 19:54:54.73 <<< Return value from bar: 3 ``` -------------------------------- ### Return value from foo in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/threads.txt Illustrates the return value of a Python function. This example shows the result of calling the 'foo' function. ```python return 1 ``` -------------------------------- ### Set Comprehension Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/comprehensions.txt Demonstrates a basic set comprehension to create a set of numbers from a range. This is useful for concisely creating sets based on existing iterables. ```python str({x for x in list(range(100))}) ``` -------------------------------- ### Run Tests with Pytest Source: https://github.com/alexmojaki/snoop/blob/master/README.md Execute all tests in the project using pytest. Ensure pytest is installed and the project is set up correctly. ```bash pytest ``` -------------------------------- ### Install snoop with custom names Source: https://github.com/alexmojaki/snoop/blob/master/README.md Customize the names of the installed functions by passing keyword arguments where the original name is mapped to the new name. For example, 'snoop="ss"' allows decorating functions with @ss. ```python snoop.install(snoop="ss") ``` -------------------------------- ### Install snoop with builtins disabled Source: https://github.com/alexmojaki/snoop/blob/master/README.md If you prefer to import snoop normally but still want to use install() for other configuration, set builtins=False. This prevents snoop, pp, and spy from being automatically available. ```python snoop.install(builtins=False) ``` -------------------------------- ### PySnooper Output Example Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This is an example of the output generated by PySnooper when tracing function calls, showing a less detailed view of nested function calls. ```text 19:47:50.888701 call 21 def bar(): 19:47:50.888944 line 22 return foo() Starting var:.. args = () Starting var:.. kwargs = {} Starting var:.. func = 19:47:50.889062 call 8 def wrapper(*args, **kwargs): 19:47:50.889171 line 10 return func(*args, **kwargs) 19:47:50.889277 return 10 return func(*args, **kwargs) Return value:.. 3 19:47:50.889368 return 22 return foo() Return value:.. 3 ``` -------------------------------- ### Set DJANGO_SETTINGS_MODULE and Import Django Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/django_sample.txt Before importing and setting up Django, you must define the DJANGO_SETTINGS_MODULE environment variable. This snippet shows the initial setup. ```python os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.fake_django_settings' import django django.setup() ``` -------------------------------- ### Call to foo in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/threads.txt Shows a simple function call within a Python script. This example is repeated with slight variations in formatting. ```python def foo(): return 1 ``` ```python def foo(): return 1 ``` ```python def foo(): return 1 ``` -------------------------------- ### Dictionary Comprehension Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/comprehensions.txt Shows a dictionary comprehension that creates a dictionary where keys and values are the same number from a range. Use this for efficient dictionary creation. ```python str({x: x for x in list(range(100))}) ``` -------------------------------- ### Multiline Context Manager Usage in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/multiline.txt Shows how to use a context manager with arguments spread across multiple lines. This enhances readability for complex setup or teardown operations. ```python with context( bar(), # 1 bar(), # 2 ): ``` -------------------------------- ### Call to foo in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/threads.txt Shows a simple function call within a Python script. This is a basic example of function execution. ```python def foo(): return 1 ``` -------------------------------- ### Install Snoop Extension for IPython Source: https://context7.com/alexmojaki/snoop/llms.txt Configure IPython to load the snoop extension by adding this line to your IPython configuration file. ```python c.InteractiveShellApp.extensions = ['snoop'] ``` -------------------------------- ### Install snoop globally Source: https://github.com/alexmojaki/snoop/blob/master/README.md Run this code early in your project to make snoop, pp, and spy available in every file without explicit imports. This is useful for regular debugging convenience. ```python import snoop snoop.install() ``` -------------------------------- ### Snoop Output Without Prettyprinter, With Pprintpp Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/pp_custom_pformat.txt This output illustrates snoop's formatting when prettyprinter is disabled but pprintpp is enabled, showing a different datetime representation compared to the previous example. ```python 12:34:56.78 LOG: 12:34:56.78 .... d = [ 12:34:56.78 'a long key to be pretty printed prettily', 12:34:56.78 [ 12:34:56.78 'prettyprinter prints datetime with keyword arguments:', 12:34:56.78 datetime.datetime(1970, 1, 1, 0, 0, 42), 12:34:56.78 ], 12:34:56.78 ] ``` -------------------------------- ### Snoop variable representation with cheap_repr Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper Example of snoop's 'cheap_repr' output, which provides a more structured and readable representation of complex variables, including their length. ```text 21:27:28.88 .......... response = {'info': {'author': 'Ram Rachum', 'author_email': 'ram@rachum.com', 'bugtrack_url': None, 'classifiers': ['Environment :: Console', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', ..., 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Debuggers'], ...}, 'last_serial': 5421934, 'releases': {'0.0.1': [{...}, {...}], '0.0.10': [{...}, {...}], '0.0.11': [{...}, {...}], '0.0.12': [{...}, {...}], ...}, 'urls': [{'comment_text': '', 'digests': {...}, 'downloads': -1, 'filename': 'PySnooper-0.2.2-py2.py3-none-any.whl', ...}, {'comment_text': '', 'digests': {...}, 'downloads': -1, 'filename': 'PySnooper-0.2.2.tar.gz', ...}]}21:27:28.88 .......... len(response) = 4 ``` -------------------------------- ### Python List Comprehension with Zip Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.8/color.txt This example demonstrates a Python list comprehension that iterates over two ranges using `zip`. It shows the intermediate values of `x` and `y` and the final computed result. ```python [ x + y for x, y in zip(range(1000, 1020), range(2000, 2020)) ] ``` -------------------------------- ### Function Definition Trace Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/all_columns.txt This log snippet shows the definition of the 'foo' function in '/path/to_file.py' at line 8. It highlights the start of the function's code block. ```text 12:34:56.78 MainThread 123456789 all_columns.py /path/to_file.py foo main..foo 8 | def foo(): ``` -------------------------------- ### Fetching JSON data with requests Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This Python snippet demonstrates fetching JSON data from a URL using the 'requests' library. Ensure 'requests' is installed. ```python import requests response = requests.get('https://pypi.org/pypi/PySnooper/json').json() ``` -------------------------------- ### Run Specific Interpreters with Tox Source: https://github.com/alexmojaki/snoop/blob/master/README.md Use tox to run tests against specific Python interpreters. Ensure tox is installed and configured for your project. ```bash tox -e py27,py36 ``` -------------------------------- ### Snoop Output Example: Function Call with x=1 Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/install_enabled.txt Illustrates Snoop's output when tracing a call to the 'foo' function with the argument x=1. It shows the call, the argument value, the function definition lines, and the return value. ```text 12:34:56.78 >>> Call to foo in File "/path/to_file.py", line 5 12:34:56.78 ...... x = 1 12:34:56.78 5 | def foo(x): 12:34:56.78 6 | return x * 2 12:34:56.78 <<< Return value from foo: 2 ``` -------------------------------- ### Python Print with Color Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/color.txt This example demonstrates printing colored output in Python. It uses ANSI escape codes to color the text, showing how to embed color within strings. ```python pp( "x + y\n" "for x, y in zip(range(1000, 1020), range(2000, 2020))" ) ``` -------------------------------- ### Consistent Prefixes with snoop Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This example shows how snoop provides consistent, formatted prefixes for debugging output, even in multithreaded scenarios. This approach ensures all relevant information, including variable states and line numbers, is clearly associated with the correct thread. ```text 20:14:07.68 Thread-1 >>> Call to foo in File "/path/to/example.py", line 10 20:14:07.68 Thread-1 ...... x = 2 20:14:07.68 Thread-1 10 | def foo(x): 20:14:07.68 Thread-1 11 | x += 1 20:14:07.68 Thread-1 .......... x = 3 20:14:07.68 Thread-1 12 | sleep(0.1) 20:14:07.69 Thread-2 >>> Call to foo in File "/path/to/example.py", line 10 20:14:07.69 Thread-2 ...... x = 3 20:14:07.69 Thread-2 10 | def foo(x): 20:14:07.69 Thread-2 11 | x += 1 20:14:07.69 Thread-2 .......... x = 4 20:14:07.69 Thread-2 12 | sleep(0.1) 20:14:07.79 Thread-1 12 | sleep(0.1) 20:14:07.79 Thread-1 13 | try: 20:14:07.79 Thread-1 14 | return x / (x - 3) 20:14:07.79 Thread-1 !!! ZeroDivisionError: division by zero 20:14:07.79 Thread-1 15 | except: 20:14:07.79 Thread-1 16 | return x + 2 20:14:07.79 Thread-1 <<< Return value from foo: 5 20:14:07.79 Thread-2 12 | sleep(0.1) 20:14:07.79 Thread-2 13 | try: 20:14:07.79 Thread-2 14 | return x / (x - 3) 20:14:07.79 Thread-2 <<< Return value from foo: 4.0 ``` -------------------------------- ### pp.deep Exception Handling Example Source: https://github.com/alexmojaki/snoop/blob/master/README.md Demonstrates how `pp.deep` reports exceptions, showing the specific subexpression that caused the error. This aids in pinpointing the source of runtime issues within complex expressions. ```python 12:34:56.78 ................ y = 2 12:34:56.78 ............ y + 3 = 5 12:34:56.78 ........ (y + 3) / 0 = !!! ZeroDivisionError! 12:34:56.78 !!! ZeroDivisionError: division by zero ``` -------------------------------- ### Multithreaded Debugging with PySnooper Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This example demonstrates debugging a multithreaded Python script using PySnooper with thread information enabled. Observe how the output from different threads can intersperse. ```python from threading import Thread from time import sleep from pysnooper import snoop @snoop(thread_info=True) def foo(x): x += 1 sleep(0.1) try: return x / (x - 3) except: return x + 2 Thread(target=foo, args=[2]).start() Thread(target=foo, args=[3]).start() ``` -------------------------------- ### Inspect Function Return Values with Spy Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/spy.txt Spy can also log the return values of functions. This example demonstrates how spy captures the result of a function call. ```python 12:34:56.78 >>> Call to bar in File "/path/to_file.py", line 14 12:34:56.78 14 | def bar(): 12:34:56.78 15 | result = pp(4 + 6, 7 + 8) 12:34:56.78 LOG: 12:34:56.78 .... = 10 12:34:56.78 .... = 15 12:34:56.78 .......... result = (10, 15) 12:34:56.78 .......... len(result) = 2 12:34:56.78 16 | return result[0] 12:34:56.78 <<< Return value from bar: 10 ``` -------------------------------- ### Snoop: Logging Set Comprehension with Default Depth Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper This example shows how snoop logs a set comprehension. Unlike PySnooper, the `depth` argument does not affect the logging of comprehensions. ```python @snoop() def main(): return sum({x * 2 for x in range(100) if x > 50}) ``` -------------------------------- ### Trace Function Calls and Arguments with Spy Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/spy.txt Use spy to trace function calls, including arguments and return values. This example shows how spy logs the evaluation of expressions within a function. ```python 12:34:56.78 >>> Call to foo in File "/path/to_file.py", line 6 12:34:56.78 6 | def foo(): 12:34:56.78 7 | x = pp.deep(lambda: 1 + 2) 12:34:56.78 LOG: 12:34:56.78 .... = 3 12:34:56.78 .......... x = 3 12:34:56.78 8 | y = pp(3 + 4, 5 + 6)[0] 12:34:56.78 LOG: 12:34:56.78 .... = 7 12:34:56.78 .... = 11 12:34:56.78 .......... y = 7 12:34:56.78 9 | return x + y 12:34:56.78 <<< Return value from foo: 10 ``` -------------------------------- ### Main execution block Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/comprehensions.txt Represents the main execution flow of a script, calling other functions. This example shows the return value of the `main` function, which is `None` as it doesn't explicitly return anything. ```python def main(): bar() main() ``` -------------------------------- ### Initialize Django and Query ContentTypes Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/django_sample.txt This snippet demonstrates the necessary steps to initialize Django in a script and then query all ContentType objects. Ensure DJANGO_SETTINGS_MODULE is set before importing django. ```python os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.fake_django_settings' import django django.setup() from django.contrib.contenttypes.models import ContentType queryset = ContentType.objects.all() lst = [1, 2, 3] len(lst) ``` -------------------------------- ### Pretty Printing with pp Source: https://github.com/alexmojaki/snoop/blob/master/README.md Utilize the `pp` function for enhanced print debugging. It displays the source code of its arguments and pretty-prints their values using `pprint.pformat` or alternatives if installed. `pp` returns its arguments directly, allowing seamless integration into existing code. ```python from snoop import pp x = 1 y = 2 pp(pp(x + 1) + max(*pp(y + 2, y + 3))) ``` -------------------------------- ### Python Exception Call Stack Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.12/exception.txt This example shows a typical Python call stack trace when an exception occurs, indicating the sequence of function calls leading to the error. ```python 12:34:56.78 >>> Call to main in File "/path/to_file.py", line 19 12:34:56.78 19 | def main(): 12:34:56.78 20 | try: 12:34:56.78 21 | bar() 12:34:56.78 >>> Call to bar in File "/path/to_file.py", line 10 12:34:56.78 ...... _ = () 12:34:56.78 10 | def bar(*_): 12:34:56.78 11 | try: 12:34:56.78 12 | str(foo()) 12:34:56.78 >>> Call to foo in File "/path/to_file.py", line 4 12:34:56.78 4 | def foo(): 12:34:56.78 5 | raise TypeError(''' 12:34:56.78 !!! TypeError: 12:34:56.78 !!! very 12:34:56.78 !!! bad 12:34:56.78 !!! Call ended by exception 12:34:56.78 12 | str(foo()) 12:34:56.78 !!! TypeError: 12:34:56.78 !!! very 12:34:56.78 !!! bad 12:34:56.78 !!! When calling: foo() 12:34:56.78 13 | except Exception: 12:34:56.78 14 | str(1) 12:34:56.78 15 | raise 12:34:56.78 !!! Call ended by exception 12:34:56.78 21 | bar() 12:34:56.78 !!! TypeError: 12:34:56.78 !!! very 12:34:56.78 !!! bad 12:34:56.78 !!! When calling: bar() 12:34:56.78 22 | except: 12:34:56.78 23 | pass 12:34:56.78 25 | try: 12:34:56.78 26 | bob( 12:34:56.78 27 | 1, 12:34:56.78 28 | 2 12:34:56.78 26 | bob( 12:34:56.78 !!! TypeError: 'NoneType' object is not callable 12:34:56.78 !!! When calling: bob( 12:34:56.78 1, 12:34:56.78 2 12:34:56.78 ) 12:34:56.78 30 | except: 12:34:56.78 31 | pass 12:34:56.78 33 | try: 12:34:56.78 34 | (None 12:34:56.78 35 | or bob)( 12:34:56.78 36 | 1, 12:34:56.78 37 | 2 12:34:56.78 34 | (None 12:34:56.78 !!! TypeError: 'NoneType' object is not callable 12:34:56.78 !!! When calling: (None 12:34:56.78 or bob)( 12:34:56.78 1, 12:34:56.78 2 12:34:56.78 ) 12:34:56.78 39 | except: 12:34:56.78 40 | pass 12:34:56.78 42 | x = [[[2]]] 12:34:56.78 .......... len(x) = 1 12:34:56.78 44 | try: 12:34:56.78 45 | str(x[1][0][0]) 12:34:56.78 !!! IndexError: list index out of range 12:34:56.78 !!! When subscripting: x[1] 12:34:56.78 46 | except: 12:34:56.78 47 | pass 12:34:56.78 49 | try: 12:34:56.78 50 | str(x[0][1][0]) 12:34:56.78 !!! IndexError: list index out of range 12:34:56.78 !!! When subscripting: x[0][1] 12:34:56.78 51 | except: 12:34:56.78 52 | pass 12:34:56.78 54 | try: 12:34:56.78 55 | str(x[0][0][1]) 12:34:56.78 !!! IndexError: list index out of range 12:34:56.78 !!! When subscripting: x[0][0][1] 12:34:56.78 56 | except: 12:34:56.78 57 | pass 12:34:56.78 <<< Return value from main: None ``` -------------------------------- ### Nested Comprehension Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/comprehensions.txt Illustrates a nested comprehension creating a dictionary where values are sets derived from inner comprehensions. This pattern can be used for complex data structure generation. ```python str({y: {x + y for x in list(range(3))} for y in list(range(3))}) ``` -------------------------------- ### Inspect List Creation and Length in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/pp.txt Demonstrates how 'pp' can log the creation of a list using 'range' and its subsequent length. This helps in understanding list generation. ```python lst = list(range(30)) ``` -------------------------------- ### Multiline List Initialization in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/multiline.txt Demonstrates initializing a list across multiple lines. This is useful for readability with long lists. ```python x = ( [ bar(), # 1 bar(), # 2 ] ) ``` ```python x = ( [ bar(), # 1 bar(), # 2 ] ) ``` -------------------------------- ### Multiline Loop Initialization in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/multiline.txt Illustrates creating a list for a for loop across multiple lines. This improves clarity for complex loop iterables. ```python for _ in [ bar( bar(), # 1 bar(), # 2 ) ] ``` ```python for _ in [ bar() ] ``` -------------------------------- ### Multiline List Initialization Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.12/multiline.txt Demonstrates initializing a list across multiple lines. Ensure proper indentation and closing brackets. ```python x = ( [ bar(), # 1 bar(), # 2 ``` -------------------------------- ### Multiline List Initialization in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/multiline.txt Illustrates initializing a list across multiple lines using parentheses for clarity. This is useful for long lists where each element might require its own line. ```python x = ( [ bar(), # 1 bar(), # 2 ] ) ``` -------------------------------- ### Use @spy decorator with birdseye Source: https://github.com/alexmojaki/snoop/blob/master/README.md Use the @spy decorator to combine snoop with the birdseye debugger. This is roughly equivalent to using both @snoop and @eye decorators. Install birdseye separately using 'pip install birdseye'. ```python from snoop import spy # not required if you use install() @spy def foo(): ``` ```python import snoop from birdseye import eye @snoop @eye def foo(): ``` -------------------------------- ### snoop's detailed generator output Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper snoop provides granular logging for generators, clearly indicating when it starts, yields, re-enters, and returns from the generator, making it easier to follow the execution flow. ```text 23:32:37.62 >>> Call to main in File "/path/to/example.py", line 8 23:32:37.62 8 | def main(): 23:32:37.62 9 | return list(x * 2 23:32:37.62 10 | for x in [1, 2]) 23:32:37.62 >>> Start generator in File "/path/to/example.py", line 9 23:32:37.62 9 | return list(x * 2 23:32:37.62 9 | return list(x * 2 23:32:37.63 10 | for x in [1, 2]) 23:32:37.63 .......... Iterating over 23:32:37.63 .......... x = 1 23:32:37.63 <<< Yield value from : 2 23:32:37.63 >>> Re-enter generator in File "/path/to/example.py", line 10 23:32:37.63 10 | for x in [1, 2]) 23:32:37.63 9 | return list(x * 2 23:32:37.63 10 | for x in [1, 2]) 23:32:37.63 .......... Iterating over 23:32:37.63 .......... x = 2 23:32:37.63 <<< Yield value from : 4 23:32:37.63 >>> Re-enter generator in File "/path/to/example.py", line 10 23:32:37.63 10 | for x in [1, 2]) 23:32:37.63 9 | return list(x * 2 23:32:37.63 .......... Iterating over 23:32:37.63 .......... x = 2 23:32:37.63 <<< Return value from : None 23:32:37.63 10 | for x in [1, 2]) 23:32:37.63 <<< Return value from main: [2, 4] ``` -------------------------------- ### PySnooper variable representation Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper Example of how PySnooper displays a variable's representation, which can be truncated for brevity. ```text New var:....... response = {'info': {'author': 'Ram Rachum', 'author_email'...fba2080618f8666ce30327/PySnooper-0.2.2.tar.gz'}]} ``` -------------------------------- ### Python Multiplication Function Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/recursion.txt A simple function to multiply two numbers. This is used as a helper in the factorial example. ```python def mul(a, b): return a * b ``` -------------------------------- ### Trace List Creation and Manipulation in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/pp.txt Demonstrates tracing of list creation using 'range' and complex list comprehensions with 'pp.deep'. Observe how nested structures and generator expressions are evaluated. ```python lst = list(range(30)) ``` ```python pp.deep(lambda: list( list(a + b for a in [1, 2]) for b in [3, 4] )) ``` ```python list( list(a + b for a in [1, 2]) for b in [3, 4] ) + lst ``` -------------------------------- ### PP with List Initialization and Concatenation Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/pp.txt Shows how 'pp' logs the creation of a list using 'range' and its subsequent concatenation with the result of a nested list comprehension. Useful for debugging list manipulations. ```python lst = list(range(30)) pp(list( list(a + b for a in [1, 2]) for b in [3, 4] ) + lst) ``` -------------------------------- ### List Initialization and Element Access Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/variables_classes.txt Illustrates the creation of a large list using range and accessing specific elements by index. This shows standard list behavior. ```python _lst = list(range(1000)) _lst[997] = 997 _lst[998] = 998 _lst[999] = 999 ``` -------------------------------- ### Python Function Definition Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/install_enabled.txt Defines a simple Python function 'foo' that takes an argument and returns its double. This is used as an example for Snoop. ```python def foo(x): return x * 2 ``` -------------------------------- ### PP with Dictionary Creation Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/pp.txt Illustrates the 'pp' function's output when used with 'dict.fromkeys' to create a dictionary. This helps visualize the structure and content of dictionaries being generated. ```python pp(dict.fromkeys(range(30), 4)) ``` -------------------------------- ### List Initialization and Element Access Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/variables_classes.txt Demonstrates the creation of a large list using range and accessing/modifying its elements by index. ```python _lst = list(range(1000)) _lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ..., 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999] len(_lst) = 1000 _lst[997] = 997 _lst[998] = 998 _lst[999] = 999 ``` -------------------------------- ### Python Exception Handling Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/exception.txt Demonstrates catching a TypeError raised by a function call and re-raising it after some processing. Useful for understanding exception propagation. ```python def bar(*_): try: str(foo()) except Exception: str(1) raise ``` -------------------------------- ### Global configuration and builtins injection with snoop.install() Source: https://context7.com/alexmojaki/snoop/llms.txt Call `snoop.install()` once at application startup to configure a global snoop instance and inject `snoop`, `pp`, and `spy` into Python's builtins for use without imports. It supports various configurations like enabling/disabling, output redirection, custom prefixes, and custom function names. ```python import snoop # Basic: makes snoop/pp/spy available everywhere, writes to stderr snoop.install() ``` ```python # Production-safe Django example in settings.py: import snoop, os snoop.install(enabled=os.environ.get('DEBUG', 'false').lower() == 'true') ``` ```python # Write to a file, custom prefix, thread columns: snoop.install( out='debug.log', overwrite=True, # clear the file on each run prefix='>>', columns='time thread function', ) ``` ```python # Custom names to avoid conflicts: snoop.install(snoop='sn', pp='dump', spy='watch') # Now use @sn, dump(), @watch in any file ``` ```python # Route output to Python's logging instead of a stream: import logging snoop.install(out=logging.getLogger('snoop').debug, color=False) ``` ```python # After install(), no import needed in other modules: # @snoop ← just works # pp(x) ← just works ``` -------------------------------- ### Basic PP Function Call and Expression Logging Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/pp.txt Illustrates how 'pp' logs intermediate values of expressions within a function. Use this to understand the flow of simple arithmetic and function compositions. ```python def main(): x = 1 y = 2 pp(pp(x + 1) + max(*pp(y + 2, y + 3))) ``` -------------------------------- ### OrderedDict Initialization and Access Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/variables_classes.txt Shows the initialization of an OrderedDict and accessing its elements. Note that OrderedDict preserves insertion order. ```python def main(): _d = OrderedDict([('a', 1), ('b', 2), ('c', 'ignore')]) _d['a'] = 1 _d['b'] = 2 ``` -------------------------------- ### Basic variable tracing Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/with_no_args.txt snoop automatically traces the assignment and value of variables within its scope. This example shows tracing a simple variable assignment. ```python x = 1 ``` -------------------------------- ### Function Returning None Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/comprehensions.txt A function `bar` is defined and called. This example highlights that functions without an explicit return statement implicitly return `None`. ```python def bar(): pass bar() ``` -------------------------------- ### Multiline Statement Handling in snoop Source: https://github.com/alexmojaki/snoop/wiki/Comparison-to-PySnooper snoop provides context for multiline statements by showing the start of the statement, unlike PySnooper which can omit this crucial information. ```python @snoop() def main(): x = [ foo(), bar() ] ``` -------------------------------- ### Main execution block Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/comprehensions.txt A simple main function to demonstrate the execution flow and return values. ```python def bar(): pass def main(): bar() ``` -------------------------------- ### Handling TypeError in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.12/exception.txt This example shows how to catch a TypeError using an except block. The code attempts to call a non-callable object and handles the resulting exception. ```python try: bob( 1, 2 ) except: pass ``` ```python try: (None or bob)( 1, 2 ) except: pass ``` -------------------------------- ### Basic Function Call and Assertion Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/pp.txt Demonstrates a basic function call with nested calls and an assertion to verify the result. Ensure the 'pp' function is defined and accessible. ```python def main(): x = 1 y = 2 pp(pp(x + 1) + max(*pp(y + 2, y + 3))) assert pp.deep(lambda: x + 1 + max(y + 2, y + 3)) == 7 ``` -------------------------------- ### Trace Function Calls with Snoop Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.12/cellvars.txt Use snoop to trace function calls and their arguments. This example shows tracing a function `f2` called with argument 42. ```python 1 | def f2(a): 2 | def f3(a): 3 | x = 0 4 | x += 1 5 | # x is now 1 6 | def f4(_a): 7 | _y = x 8 | return 42 9 | # _y is 1 10 | return f4(a) 11 | # a is 42 12 | return f3(a) 13 | # a is 42 ``` -------------------------------- ### Python Traceback Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.11/pp_exception.txt Illustrates a typical Python traceback when an unhandled exception occurs within a function call. This is useful for debugging and understanding the call stack. ```python pp.deep(lambda: x + y + bad() + 2) return PPEvent(self, [arg], deep=True).returns ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ self.returns = self.deep_pp(call_arg.body, frame) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ return eval(code, frame.f_globals, frame.f_locals) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pp.deep(lambda: x + y + bad() + 2) ^^^^^ raise TypeError('bad') ``` -------------------------------- ### OrderedDict Initialization and Access Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/variables_classes.txt Shows the initialization of an OrderedDict and accessing its elements. Note that the representation might differ from the actual object. ```python def main(): _d = OrderedDict([('a', 1), ('b', 2), ('c', 'ignore')]) _d = OrderedDict({'a': 1, 'b': 2, 'c': 'ignore'}) len(_d) = 3 _d['a'] = 1 _d['b'] = 2 ``` -------------------------------- ### Handling IndexError in Nested Lists Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/exception.txt Illustrates catching an IndexError when accessing an element outside the bounds of a nested list. This example shows accessing x[1] which is out of bounds. ```python x = [[[2]]] try: str(x[1][0][0]) except: pass ``` -------------------------------- ### Class with Slots Initialization and Access Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/variables_classes.txt Illustrates the creation of an instance of a class that uses slots and accessing/modifying its attributes. ```python _s = WithSlots() _s = _s.x = 3 _s.y = 4 ``` -------------------------------- ### Snoop with Block Depth 3 Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.14/with_block_depth.txt Use snoop with depth=3 to trace nested function calls up to three levels deep. This example shows tracing within a 'with' block. ```python with snoop.snoop(depth=3): result1 = f2(5) ``` -------------------------------- ### Snoop Output With Prettyprinter, Without Pprintpp Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/pp_custom_pformat.txt This output shows snoop's formatting when prettyprinter is enabled but pprintpp is not, resulting in a more structured datetime representation. ```python 12:34:56.78 LOG: 12:34:56.78 .... d = [ 12:34:56.78 'a long key to be pretty printed prettily', 12:34:56.78 [ 12:34:56.78 'prettyprinter prints datetime with keyword arguments:', 12:34:56.78 datetime.datetime( 12:34:56.78 year=1970, 12:34:56.78 month=1, 12:34:56.78 day=1, 12:34:56.78 hour=0, 12:34:56.78 minute=0, 12:34:56.78 second=42 12:34:56.78 ) 12:34:56.78 ] 12:34:56.78 ] ``` -------------------------------- ### Class with Slots Initialization and Attribute Assignment Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.10/variables_classes.txt Demonstrates the creation of an instance of a class that uses slots and assigning values to its attributes. ```python _s = WithSlots() _s.x = 3 _s.y = 4 ``` -------------------------------- ### Python Boolean Short-Circuiting Example Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.8/color_without_comprehension.txt Demonstrates the 'or' operator's short-circuiting behavior. If the left operand is true, the right operand is not evaluated. In this case, 'None' is false, so 'foo()' is called. ```python (None or foo)() ``` -------------------------------- ### Inspect List Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.8/variables_classes.txt Illustrates inspecting a list, including its creation, length, and element modification. ```python _lst = list(range(1000)) _lst[997] = 997 _lst[998] = 998 _lst[999] = 999 ``` ```python _lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ..., 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999] ``` ```python len(_lst) = 1000 ``` ```python _lst[997] = 997 ``` ```python _lst[998] = 998 ``` ```python _lst[999] = 999 ``` -------------------------------- ### Python Method Call and Attribute Modification Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/method_and_prefix.txt Illustrates a method call within a Python class where an attribute is modified. This example shows the state change of `self.x` after the `square` method is executed. ```python class Baz: def square(self): foo = 7 self.x **= 2 return self ``` -------------------------------- ### Inspect Class Instance with Slots in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.13/variables_classes.txt Demonstrates inspecting an instance of a class that uses __slots__. Useful for understanding object attributes. ```python _s = ``` ```python _s.x = 3 ``` ```python _s.y = 4 ``` -------------------------------- ### Multiline Conditional Statements in Python Source: https://github.com/alexmojaki/snoop/blob/master/tests/sample_results/3.9/multiline.txt Demonstrates writing conditional logic (if, elif) with arguments or conditions spanning multiple lines. ```python if bar( bar(), # 1 bar(), # 2 ) ``` ```python elif [ bar( bar(), # 1 bar(), # 2 ) ] ``` -------------------------------- ### Install snoop with disabled effects Source: https://github.com/alexmojaki/snoop/blob/master/README.md To leave snoop functions in your codebase but disable their effects, pass enabled=False. This minimizes performance impact and suppresses output. It can be useful for automatically disabling in production environments. ```python snoop.install(enabled=False) ```