Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trace recursively, but only my code #51

Open
guettli opened this issue Mar 14, 2022 · 9 comments
Open

Trace recursively, but only my code #51

guettli opened this issue Mar 14, 2022 · 9 comments

Comments

@guettli
Copy link

guettli commented Mar 14, 2022

Hi,

I would like to trace the http request handling of Django in my development environment.

But I am sure that the bug is in my code, not in the code of Django.

I would like to see every line of my code, excluding Django, standard library and other libraries.

I had a look at the arguments which snoop() accepts, but I think it is not possible up to now.

Would you accept a PR which implements this?

Do you have a hint how to implement this?

@alexmojaki
Copy link
Owner

Here's an example of how you can 'blacklist' folders from tracing:

import inspect
import os.path

import snoop.tracer

# Paths starting with any value in internal_directories are ignored when tracing
snoop.tracer.internal_directories += (
    # Avoid tracing anything in the standard library
    os.path.dirname(inspect.__file__),
)

@snoop(depth=5)
def foo():
    # This line would normally get traced
    source = inspect.getsource(foo)
    # Inner function to show that depth is still working
    return bar(source)

def bar(s):
    return s * 2

foo()

@guettli
Copy link
Author

guettli commented Mar 14, 2022

I think I have a special case which does not work. I start to snoop in a code which should get skipped.

Example:

# base.py

from sub.start import start

def method():
    print('here')
start(method)
# sub/start.py
import inspect
import os.path

import snoop.tracer

# Paths starting with any value in internal_directories are ignored when tracing
snoop.tracer.internal_directories += (
    # Avoid tracing anything in the standard library
    os.path.dirname(inspect.__file__),
    
    # Avoid tracing file in the sub-directory.
    os.path.dirname(__file__),
)

@snoop(depth=5)
def start(method):
    method()

output

(snoop-env) guettli@p15:~/tmp/snoop-env$ python base.py 
22:04:37.79 >>> Call to start in File "/home/guettli/tmp/snoop-env/sub/start.py", line 16
22:04:37.79 ...... method = <function method at 0x7fccc53421f0>
22:04:37.79   16 | def start(method):
22:04:37.79   17 |     method()
here
22:04:37.79 <<< Return value from start: None

I would like to see the print('here'). But it does not get traced.


Above example is just to have something which can be reproduced.

In my real use case I want to start snooping in BaseHandler.get_response() of Django.

But I don't want to trace Django, I just want to trace my code.

@yantaozhao
Copy link

yantaozhao commented Aug 27, 2022

I think there's a bug in snoop, my case is that the print('here') was traced, but "here" was not output to the console at all.
My workaround is to use print("here", file=sys.stderr) because internally snoop use stderr as output sink by default.

@alexmojaki
Copy link
Owner

Hi @yantaozhao. This sounds unrelated to the rest of this issue, you should probably open a new one.

In any case, I can't see how what you're describing could be a bug in snoop. snoop doesn't control what print does. Just because snoop is using stderr, doesn't mean that everything else has to. It sounds like the environment in which you're running your code is showing stderr but not stdout for some reason.

@rkpagadala
Copy link

@alexmojaki
How does snoop.tracer work with snoop.Config? I want multiple configurations and possibly distinct dont trace directories for each of the config.

@alexmojaki
Copy link
Owner

snoop.tracer is a module, while snoop.Config is a class. snoop.tracer.internal_directories is global. To do what you're saying, you'll need to override snoop.tracer.Tracer._is_internal_frame.

@rkpagadala
Copy link

@alexmojaki First. Thanks for the snoop and birdseye.
Second thanks for the quick response.

@ChillarAnand
Copy link

Here's an example of how you can 'blacklist' folders from tracing:

import inspect
import os.path

import snoop.tracer

# Paths starting with any value in internal_directories are ignored when tracing
snoop.tracer.internal_directories += (
    # Avoid tracing anything in the standard library
    os.path.dirname(inspect.__file__),
)

@snoop(depth=5)
def foo():
    # This line would normally get traced
    source = inspect.getsource(foo)
    # Inner function to show that depth is still working
    return bar(source)

def bar(s):
    return s * 2

foo()

Thanks for sharing a working example on blacklisting the directories.

Most of the time, users need a simple flag to blacklist python standard library as well as third party packages that are installed. If snoop can provide the flags, it would be great.

@00sapo
Copy link

00sapo commented Apr 4, 2024

Most of the time, users need a simple flag to blacklist python standard library as well as third party packages that are installed. If snoop can provide the flags, it would be great.

That's as easy as a one-liner:

from pathlib import Path
import snoop

snoop.tracer.internal_directories += tuple(
    map(str, Path(snoop.tracer.internal_directories[0]).parent.glob("*"))
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants