Giter Site home page Giter Site logo

pysnooper's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pysnooper's Issues

"return" is misleading

The last line of the output is labeled "return" which probably refers to exiting the function, but implies a value is being returned by the function even when no return line is explicitly included in the function.

can't get values of my class variables

I was trying to inspect some variables of my class objects, and I wrote a test script, but didn't get any value of them. Does your tool support such kind of situation? or is there way I can walk around this without using 'print' function?

import pysnooper                                                                                                                                                       

class A(object):
    def __init__(self):
        self.x = 0 

    @pysnooper.snoop(variables='self.x')
    def inc(self, input):
        self.x += input



#@pysnooper.snoop(variables=('a.x'))
def number_to_bits(number):
    a = A() 
    if number:
        bits = []
        while number:
            number, remainder = divmod(number, 2)
            a.inc(number)
            a.x 
            bits.insert(0, remainder)
        return bits
    else:
        return [0] 

number_to_bits(6)

here is the result:

Starting var:.. input = 3
Starting var:.. self = <__main__.A object at 0x7f9944583e90>
17:23:31.341554 call         8     def inc(self, input):
17:23:31.341915 line         9         self.x += input
17:23:31.341989 return       9         self.x += input
Return value:.. None
Starting var:.. input = 1
Starting var:.. self = <__main__.A object at 0x7f9944583e90>
17:23:31.342112 call         8     def inc(self, input):
17:23:31.342178 line         9         self.x += input
17:23:31.342236 return       9         self.x += input
Return value:.. None
Starting var:.. input = 0
Starting var:.. self = <__main__.A object at 0x7f9944583e90>
17:23:31.342341 call         8     def inc(self, input):
17:23:31.342402 line         9         self.x += input
17:23:31.342460 return       9         self.x += input
Return value:.. None

simple for loop example fails

  @pysnooper.snoop()                                                                                                                            
  def hello():                                                                                                                                  
      for i in range(10):                                                                                                                       
          print(i)                                                                                                                              

In [10]: ---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
in
----> 1 import codecs, os;__pyfile = codecs.open('''/tmp/pybsaClo''', encoding='''utf-8''');__code = __pyfile.read().encode('''utf-8''');__pyfile$

/export/zxf/workspace/tmp/testsnoop.py in
22
23
---> 24 hello()

</home/zxf/anaconda3/lib/python3.6/site-packages/decorator.py:decorator-gen-152> in hello()

~/anaconda3/lib/python3.6/site-packages/PySnooper-0.0.11-py3.6.egg/pysnooper/pysnooper.py in decorate(function, *args, **kwargs)
70 write=write, variables=variables,
71 depth=depth, prefix=prefix):
---> 72 return function(*args, **kwargs)
73
74 return decorate

/export/zxf/workspace/tmp/testsnoop.py in hello()
15
16
---> 17 @pysnooper.snoop()
18 def hello():
19 for i in range(10):

~/anaconda3/lib/python3.6/site-packages/PySnooper-0.0.11-py3.6.egg/pysnooper/tracer.py in trace(self, frame, event, arg)
182
183 now_string = datetime_module.datetime.now().time().isoformat()
--> 184 source_line = get_source_from_frame(frame)[frame.f_lineno - 1]
185 self.write('{indent}{now_string} {event:9} '
186 '{frame.f_lineno:4} {source_line}'.format(**locals()))

IndexError: list index out of range

Feature request: Print line containing actual function name for "call" event

When the function decorator @pysnooper.snoop() is in a separate line, the "call" event will print that line instead of the one containing the actual function name. This can be seen in the example in README.md:
https://github.com/cool-RR/PySnooper/blob/master/README.md#example

While this is technically correct (for Python the function definition starts with the decorator), it would make traces easier to read if the actual function name was printed. Maybe a special case could be added for "call" events: if the source line reported by Python only contains the decorator, print the next source line instead.

Compatibility with awsebcli

There are requirement incompatibilities with the awsebcli package from amazon. I'm not sure if this has an easy fix or pysnooper really needs the specified versions of future and six:

awsebcli 3.15.0 has requirement future<0.17.0,>=0.16.0, but you'll have future 0.17.1 which is incompatible.
awsebcli 3.15.0 has requirement six<1.12.0,>=1.11.0, but you'll have six 1.12.0 which is incompatible.

Bug when outputting special characters to shell

Noticed this error while snooping on a function that handles Unicode strings, pysnooper seems unhappy about the degree symbol here:

File "weather.py", line 390, in graphic_single
'location 1': u"%dºC / %dºF" % (round(data[sol]['max_temp']),
File "/Users/userid/Library/Python/2.7/lib/python/site-packages/pysnooper/tracer.py", line 184, in trace
'{frame.f_lineno:4} {source_line}'.format(**locals()))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xba' in position 33: ordinal not in range(128)

Improve "Advanced Usage" in readme

The "Advanced Usage" section in the readme is really unclear.

We need an example of watch_explode, and separately an example of one of the special Variable classes.

Dependencies on decorator and six

Not much of an issue but just wondering if bundling external dependencies is just temporary or permanent? Isn't it kind of a bad practice to in-source external dependencies in terms of features/bug fixes/compatibility of these external modules and better come from PYPI directly?

Adding to list may not trigger modified var line

Example script:

import pysnooper

@pysnooper.snoop()
def foo():
    x = []
    for i in range(10):
        x.append(i)

foo()

Output:

13:38:44.029228 call         5 def foo():
13:38:44.029456 line         6     x = []
New var:....... x = []
13:38:44.029540 line         7     for i in range(10):
New var:....... i = 0
13:38:44.029621 line         8         x.append(i)
Modified var:.. x = [0]
13:38:44.029688 line         7     for i in range(10):
Modified var:.. i = 1
13:38:44.029751 line         8         x.append(i)
Modified var:.. x = [0, 1]
13:38:44.029816 line         7     for i in range(10):
Modified var:.. i = 2
13:38:44.029880 line         8         x.append(i)
Modified var:.. x = [0, 1, 2]
13:38:44.029948 line         7     for i in range(10):
Modified var:.. i = 3
13:38:44.030015 line         8         x.append(i)
Modified var:.. x = [0, 1, 2, 3]
13:38:44.030083 line         7     for i in range(10):
Modified var:.. i = 4
13:38:44.030150 line         8         x.append(i)
Modified var:.. x = [0, 1, 2, 3, 4]
13:38:44.030220 line         7     for i in range(10):
Modified var:.. i = 5
13:38:44.030290 line         8         x.append(i)
Modified var:.. x = [0, 1, 2, 3, 4, 5]
13:38:44.030364 line         7     for i in range(10):
Modified var:.. i = 6
13:38:44.030436 line         8         x.append(i)
Modified var:.. x = [0, 1, 2, 3, 4, 5, ...]
13:38:44.030508 line         7     for i in range(10):
Modified var:.. i = 7
13:38:44.030580 line         8         x.append(i)
13:38:44.030638 line         7     for i in range(10):
Modified var:.. i = 8
13:38:44.030712 line         8         x.append(i)
13:38:44.030770 line         7     for i in range(10):
Modified var:.. i = 9
13:38:44.030843 line         8         x.append(i)
13:38:44.030901 line         7     for i in range(10):
13:38:44.030960 return       7     for i in range(10):

Partway through x seems to stop changing and the user might be misled into thinking it has, which could be a serious problem when trying to figure out a bug. Here it's obvious but in a more complex script it may not be.

Or suppose the user is building up a list of strings to make a document and does this:

lines += doc.get_footer()

where get_footer is an abstract method and may return an empty list. The user has to debug further to know if anything changed.

add support for thread identifiers

pysnooper is amazing for the case where we are trying to see where threads are waiting on things. If I can get the thread identifier in the output as an option, that makes this great. Here's a hack that makes it work at the moment:

diff --git a/pysnooper/tracer.py b/pysnooper/tracer.py
index c4f4407..a5768f2 100644
--- a/pysnooper/tracer.py
+++ b/pysnooper/tracer.py
@@ -4,6 +4,7 @@
 import sys
 import re
 import collections
+import threading
 import datetime as datetime_module
 import itertools
 try:
@@ -226,6 +227,7 @@ class Tracer:
         ### Finished newish and modified variables. ###########################
 
         now_string = datetime_module.datetime.now().time().isoformat()
+        tid_string = threading.get_ident()
         line_no = frame.f_lineno
         source_line = get_source_from_frame(frame)[line_no - 1]
 
@@ -251,7 +253,7 @@ class Tracer:
         #                                                                     #
         ### Finished dealing with misplaced function definition. ##############
 
-        self.write('{indent}{now_string} {event:9} '
+        self.write('{indent}{now_string} {tid_string} {event:9} '
                    '{line_no:4} {source_line}'.format(**locals()))
 
         if event == 'return':

Deploy using Travis when pushing a Git tag

Instead of deploying from your local machine we should let Travis do the job of releasing new versions of this package. This has a few significant advantages:

  1. What happens at releases is better documented with an audit trail (CI jobs log).
  2. Releasing then enforces tagging on commits that are related to a release.
  3. No software needs to be installed on your local machine for pushing a new release.

See these projects for working examples: (deploy job in .travis.yml)

pysnooper/tracer.py", line 75, in get_source_from_frame raise NotImplementedError

When I ran a simple script:

import pysnooper
import numpy as np

@pysnooper.snoop()
def multi_matmul(times):
    x = np.random.rand(2,2)
    w = np.random.rand(2,2)
    
    for i in range(times):
        x = np.matmul(x,w)
    return x

multi_matmul(3)

The error happened:

Starting var:.. times = 3
Traceback (most recent call last):
  File "<tmp 1>", line 14, in <module>
    multi_matmul(3)
  File "</usr/local/lib/python3.6/dist-packages/decorator.py:decorator-gen-121>", line 2, in multi_matmul
  File "/usr/local/lib/python3.6/dist-packages/pysnooper/pysnooper.py", line 72, in decorate
    return function(*args, **kwargs)
  File "<tmp 1>", line 4, in multi_matmul
    @pysnooper.snoop()
  File "/usr/local/lib/python3.6/dist-packages/pysnooper/tracer.py", line 182, in trace
    source_line = get_source_from_frame(frame)[frame.f_lineno - 1]
  File "/usr/local/lib/python3.6/dist-packages/pysnooper/tracer.py", line 75, in get_source_from_frame
    raise NotImplementedError
NotImplementedError

Feature request: Support generators

For example:

from __future__ import print_function
import pysnooper

@pysnooper.snoop()
def fib(max_n):
    a, b = 0, 1
    while a < max_n:
        yield a
        a, b = b, a + b

def main():
    for n in fib(4):
        print(n)

if __name__ == '__main__':
    main()

Output:

$ python mytest.py 
0
1
1
2
3

Infrastructure improvement: AUTHORS bot

@bittner Here's another one you might like. I want the upkeep of the AUTHORS file to be automated, basically running:

misc/generate_authors.py > AUTHORS

It would be cool to have a bot that automatically submits pull requests whenever the AUTHORS file is different than the one generated above (i.e. we just merged a new author.) Then I could approve that pull request with a click instead of having to maintain AUTHORS manually.

Support for printing prettier with pandas.DataFrame

The DataFrame will now be printed like..

New var:....... df_results =      agentCode  ...                             ...311/02/002/E02002201...[2047 rows x 14 columns]
10:25:17.331981 line        15     df_results['agentScore'] = None
Modified var:.. df_results =      agentCode  ...  agentScore0          012  ...   002  ...        None[2047 rows x 15 columns]
10:25:17.396386 line        16     df_results['agentMag'] = None
Modified var:.. df_results =      agentCode  containCompany  ...  agentScore ....        None      None[2047 rows x 16 columns]
10:25:17.465968 line        17     df_results['customerScore'] = None
Modified var:.. df_results =      agentCode  containCompany  containName  ......     None          None[2047 rows x 17 columns]
10:25:17.538187 line        18     df_results['customerMag'] = None
Modified var:.. df_results =      agentCode  containCompany  containName  ......       None        None[2047 rows x 18 columns]
10:25:17.614447 line        19     df_results['fullScore'] = None
Modified var:.. df_results =      agentCode  containCompany  containName  ......         None      None[2047 rows x 19 columns]
10:25:17.690138 line        20     df_results['fullMag'] = None
Modified var:.. df_results =      agentCode  containCompany  containName  ......None       None    None[2047 rows x 20 columns]
10:25:17.769101 line        22     df_results[['agentScore', 'agentMag', 'customerScore', 'customerMag', 'fullScore', 'fullMag']] = df_results['sentimentScore'].apply(lambda x: pd.Series([x['agentScore'], x['agentMag'], x['customerScore'], x['customerMag'], x['fullScore'], x['fullMag']]))
Modified var:.. df_results =      agentCode  containCompany  containName  ......1        0.0   9.200000[2047 rows x 20 columns]
10:25:19.847469 line        23     return df_results
10:25:19.924770 return      23     return df_results
Return value:..      agentCode  containCompany  containName  ......1        0.0   9.200000[2047 rows x 20 columns]

Would be nice if any pretty print feature for lists/iterators...

Allow @snoop without parentheses

I think it would be good to allow:

@snoop
def foo():

Instead of requiring

@snoop()
def foo():

Any objections? I'm happy to do this.

Feature request: support recursion, including with depth argument

For example:

from __future__ import print_function
import pysnooper

@pysnooper.snoop()
def fact(n):
    if n == 1:
        return 1
    return n * fact(n - 1)

def main():
    print(fact(3))

if __name__ == '__main__':
    main()

Output:

$ python mytest2.py 
Starting var:.. n = 3
01:22:43.094346 call         4 @pysnooper.snoop()
01:22:43.095271 line         6     if n == 1:
01:22:43.095435 line         8     return n * fact(n - 1)
Starting var:.. n = 2
01:22:43.095591 call         4 @pysnooper.snoop()
01:22:43.095664 line         6     if n == 1:
01:22:43.095722 line         8     return n * fact(n - 1)
Starting var:.. n = 1
01:22:43.095830 call         4 @pysnooper.snoop()
01:22:43.095884 line         6     if n == 1:
01:22:43.095941 line         7         return 1
01:22:43.096022 return       7         return 1
01:22:43.096110 return       8     return n * fact(n - 1)
01:22:43.096175 return       8     return n * fact(n - 1)
6

When setting depth=2, it even raised an error:

Starting var:.. n = 3
01:26:47.652684 call         4 @pysnooper.snoop(depth=2)
01:26:47.653612 line         6     if n == 1:
01:26:47.653684 line         8     return n * fact(n - 1)
    Starting var:.. n = 2
Traceback (most recent call last):
  File "mytest2.py", line 14, in <module>
    main()
  File "mytest2.py", line 11, in main
    print(fact(3))
  File "</home/xiaofei/.local/lib/python2.7/site-packages/decorator.pyc:decorator-gen-2>", line 2, in fact
  File "/home/xiaofei/.local/lib/python2.7/site-packages/pysnooper/pysnooper.py", line 72, in decorate
    return function(*args, **kwargs)
  File "mytest2.py", line 8, in fact
    return n * fact(n - 1)
  File "</home/xiaofei/.local/lib/python2.7/site-packages/decorator.pyc:decorator-gen-2>", line 1, in fact
  File "/home/xiaofei/.local/lib/python2.7/site-packages/pysnooper/tracer.py", line 182, in trace
    source_line = get_source_from_frame(frame)[frame.f_lineno - 1]
  File "/home/xiaofei/.local/lib/python2.7/site-packages/pysnooper/tracer.py", line 75, in get_source_from_frame
    raise NotImplementedError
NotImplementedError

allow arbitrary callables, perhaps io / file objects, Python loggers for writers

Looking at https://github.com/cool-RR/PySnooper/blob/master/pysnooper/pysnooper.py#L13 I see our choices for "writier" are, stdout, path to a filename and something called "WritableStream" . In our case we have an application that's running under mod_wsgi, so we want to go to a logger. Since PySnooper's great talent is being able to get deep into a huge stack without any hassle, being able to send the string output anywhere is important. There are threadsafe loggers as well and things like that which follow built-in conventions like IO, or just a plain Python callable where we can plug anything we want.

Does not reliably show local variables

@pysnooper.snoop()
def go():
    test0 = 1

    test1 = {
            'test2':'val2',
            'test3':'val3'
        }

    test2 = {
        'test1': {
            'test2':'val2',
            'test3':'val3'
        }
    }

    test3 = {
        'test1': {
            'test2':'val2',
            'test3':'val3'
        },
        'test4': 'val4'
    }

    test4 = {
        'test1': {
            'test2thisisalongervariablename':'val2thisisalongervalue',
            'test3':'val3'
        },
        'test4': 'val4'
    }

results in

17:19:37.240949 call         4 @pysnooper.snoop()
17:19:37.241917 line         6     test0 = 1
New var:....... test0 = 1
17:19:37.241917 line         9             'test2':'val2',
17:19:37.241917 line        10             'test3':'val3'
New var:....... test1 = {'test2': 'val2', 'test3': 'val3'}
17:19:37.241917 line        15         'test1': {
17:19:37.241917 line        16             'test2':'val2',
17:19:37.241917 line        17             'test3':'val3'
New var:....... test2 = {'test1': {'test2': 'val2', 'test3': 'val3'}}
17:19:37.242957 line        24             'test2':'val2',
17:19:37.242957 line        25             'test3':'val3'
17:19:37.242957 line        27         'test4': 'val4'
New var:....... test3 = {'test1': {'test2': 'val2', 'test3': 'val3'}, 'test4': 'val4'}
17:19:37.242957 line        32             'test2thisisalongervariablename':'val2thisisalongervalue',
17:19:37.242957 line        33             'test3':'val3'
17:19:37.242957 line        35         'test4': 'val4'
17:19:37.242957 return      35         'test4': 'val4'

What determines not to acknowledge the assignment of test4, and is there any way to override it? This behavior basically renders this useless to me unfortunately.

[ERROR:bot] Exception in on_voice_state_update

Hello,
sorry for asking but i have some issues with the code for my MusicBot.
I wanted to learn how to create custom commands for MusicBot so i tried
creating a simple command of reply (basically the concept is if you write "hi" the bot
should reply "Hi {user.name} !" ).
Considering that i didn't know how to code with Python, i tried looking on the web
and i was close to solving the issue myself. Until this showed up:

[ERROR:bot] Exception in on_voice_state_update
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python37-32\lib\site-packages\discord\client.py", line 255, in _run_event
await coro(*args, **kwargs)
File "C:\Users\User\Server\Bot\MusicBot\musicbot\bot.py", line 2846, in on_voice_state_update
player = await self.get_player(channel)
File "C:\Users\User\Server\Bot\MusicBot\musicbot\bot.py", line 431, in get_player
'Use %ssummon to summon it to your voice channel.' % self.config.command_prefix)
musicbot.exceptions.CommandError: The bot is not in a voice channel. Use !summon to summon it to your voice channel.

Now for the bot to start normally again i should just delete the part that i wrote,
but i want this to work since i could learn how to create commands.
If someone had the same issue, please feel free to repost your situation below in the comments.
Anyway, if someone could help me that would be really helpfull.
Thanks for reading so far (i know, it's a lot).

Atlas

Testing enhancement: Test `pip install`

@bittner , this is right up your alley so if you'll feel like doing it, it'll be cool.

It'll be nice if after every release, or after every push to master, there will be separate tests that do pip install pysnooper on all platforms and run the tests. This is to rule out any errors in the installation.

show object attributes, not just local variables

Consider this code:

class Foo():
    
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = None
        
    @pysnooper.snoop()
    def myfunc(self):
        localvar = 5
        localvar += 1
        self.c = self.b + self.a

pysnooper's output when calling myfunc:

Starting var:.. self = <snooptest.Foo instance at 0x1052c5b90>
08:50:38.552499 call        16     @pysnooper.snoop()
08:50:38.553309 line        18         localvar = 5
New var:....... localvar = 5
08:50:38.553382 line        19         localvar += 1
Modified var:.. localvar = 6
08:50:38.553457 line        20         self.c = self.b + self.a
08:50:38.553560 return      20         self.c = self.b + self.a

The values of self.a, self.b, and self.c are not shown by pysnooper but are the primary purpose of this method. parameters on self should also be shown as starting values in methods decorated by pysnooper

pip install fails for missing requirements.txt

PIP install fails with missing requirements.txt file:

$ pip install pysnooper
Collecting pysnooper
  Using cached https://files.pythonhosted.org/packages/43/58/e36822363b00e3a7f15621b5b34587e171521c55bc19970cb4754ba08d18/PySnooper-0.0.10.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-blixjg7f/pysnooper/setup.py", line 16, in <module>
        install_requires=open('requirements.txt', 'r').read().split('\n'),
    FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-blixjg7f/pysnooper/
$ wget https://files.pythonhosted.org/packages/43/58/e36822363b00e3a7f15621b5b34587e171521c55bc19970cb4754ba08d18/PySnooper-0.0.10.tar.gz
...

$ tar tf PySnooper-0.0.10.tar.gz
PySnooper-0.0.10/
PySnooper-0.0.10/PKG-INFO
PySnooper-0.0.10/PySnooper.egg-info/
PySnooper-0.0.10/PySnooper.egg-info/PKG-INFO
PySnooper-0.0.10/PySnooper.egg-info/SOURCES.txt
PySnooper-0.0.10/PySnooper.egg-info/dependency_links.txt
PySnooper-0.0.10/PySnooper.egg-info/requires.txt
PySnooper-0.0.10/PySnooper.egg-info/top_level.txt
PySnooper-0.0.10/README.md
PySnooper-0.0.10/pysnooper/
PySnooper-0.0.10/pysnooper/__init__.py
PySnooper-0.0.10/pysnooper/pycompat.py
PySnooper-0.0.10/pysnooper/pysnooper.py
PySnooper-0.0.10/pysnooper/tracer.py
PySnooper-0.0.10/pysnooper/utils.py
PySnooper-0.0.10/setup.cfg
PySnooper-0.0.10/setup.py
PySnooper-0.0.10/tests/
PySnooper-0.0.10/tests/__init__.py
PySnooper-0.0.10/tests/test_pysnooper.py
PySnooper-0.0.10/tests/utils.py

Runtime error (IronPython)

I get the following runtime error with the demo code provided in the readme:

Runtime error (MissingMemberException): 'NoneType' object has no attribute 'get'
Traceback:
  line 72, in decorate, "pysnooper.py"
  line 59, in get_source_from_frame, "pysnooper\tracer.py"
  line 209, in trace, "pysnooper\tracer.py"
  line 2, in number_to_bits, "<decorator-gen-10>"
  line 20, in script

(line 20 calls the "number_to_bits" function)

Feature request: Support Jupyter notebooks and IPython

I think it can not support jupyter right now, but I hope it could be done lately.

NotImplementedError                       Traceback (most recent call last)
<ipython-input-6-48087d91d6cf> in <module>()
      5     return number
      6 
----> 7 number_to_bits(6)

<decorator-gen-164> in number_to_bits(number)

C:\ProgramData\Anaconda3\lib\site-packages\pysnooper\pysnooper.py in decorate(function, *args, **kwargs)
     70                     write=write, variables=variables,
     71                     depth=depth, prefix=prefix):
---> 72             return function(*args, **kwargs)
     73 
     74     return decorate

<ipython-input-6-48087d91d6cf> in number_to_bits(number)
      1 import pysnooper
      2 
----> 3 @pysnooper.snoop('file.log')
      4 def number_to_bits(number):
      5     return number

C:\ProgramData\Anaconda3\lib\site-packages\pysnooper\tracer.py in trace(self, frame, event, arg)
    180 
    181         now_string = datetime_module.datetime.now().time().isoformat()
--> 182         source_line = get_source_from_frame(frame)[frame.f_lineno - 1]
    183         self.write('{indent}{now_string} {event:9} '
    184                    '{frame.f_lineno:4} {source_line}'.format(**locals()))

C:\ProgramData\Anaconda3\lib\site-packages\pysnooper\tracer.py in get_source_from_frame(frame)
     73             pass
     74     if source is None:
---> 75         raise NotImplementedError
     76 
     77     # If we just read the source from a file, or if the loader did not

NotImplementedError: 

Use Tox for running tests

We should add a Tox configuration (tox.ini) to allow running all tests locally, and use tox-travis in the CI configuration to make the expansion automatic.

Here are a few examples to see how that's meant to work:

Note that this also allows to encapsulate the test requirements into tox.ini (and subsequently can make the test requirements file unnecessary 👍).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.