-
Notifications
You must be signed in to change notification settings - Fork 951
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
Add support for thread identifiers #87
Conversation
I notice the optional part that you need, I'll update that ASAP on this PR |
Good job. I'll be waiting for the optional part, and I also want:
|
I still say we should go for a callable prefix. Whatever system we use to keep the column width consistent in this PR, why can't we use it for a callable prefix? Then we could supply and document a utility function |
I understand, but I still think it's too hacky. |
I need to solve the padding issue |
How do you want to apply padding if we don't know the names of all thread identifiers (including those that might not exist yet, so even diving into threading.enumerate() not good enough) and therefore how much length is needed? |
The main issue come from the name of the thread to padding output. |
Guess a length that'll accommodate most thread names, and for the few that
are longer, truncate them.
…On Sat, May 4, 2019 at 1:29 AM Hervé Beraud ***@***.***> wrote:
The main issue come from the name of the thread to padding output.
We can't know by advance all threads names... I think using only thread ID
is enough.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#87 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAN3SQQ2URPB5THV4RUP7DPTS4EBANCNFSM4HKV7Y6A>
.
|
I say keep track of the padding so far and increase it as necessary, never decreasing it. A couple of bumps in the logs isn't a big problem. Use enumerate to make a good guess to start with, maybe add a couple of extra spaces initially to reduce the likelihood of bumps. Truncation risks completely misleading the user, e.g. if |
pysnooper/tracer.py
Outdated
u'{line_no:4} {source_line}'.format(**locals())) | ||
if self.threads_info: | ||
output = u'{indent}{now_string} {thread_info} {event:9} ' \ | ||
u'{line_no:4} {source_line}'.format(**locals()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Don't duplicate this logic.
- Don't needlessly compute
thread_info
.
if self.threads_info:
current_thread = threading.current_thread()
thread_info = "{ident}-{name} ".format(
ident=current_thread.ident, name=current_thread.getName())
else:
thread_info = ""
output = u'{indent}{now_string} {thread_info}{event:9} ' \
u'{line_no:4} {source_line}'.format(**locals())
tests/test_pysnooper.py
Outdated
@@ -41,6 +41,35 @@ def my_function(foo): | |||
) | |||
|
|||
|
|||
def test_threads_info(): | |||
string_io = io.StringIO() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unused. A good example of where #85 would help.
tests/utils.py
Outdated
r"""^%s(?P<indent>(?: {4})*)[0-9:.]{15} """ | ||
r"""(?P<event_name>[a-z_]*) +(?P<line_number>[0-9]*) """ | ||
r"""+(?P<source>.*)$""" % (re.escape(self.prefix,)) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stick to a single regex and make the group optional ((...)?
).
tests/utils.py
Outdated
if self.threads_info: | ||
_, _, event_name, _, source = match.groups() | ||
else: | ||
_, event_name, _, source = match.groups() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continuing from the above, groups
will have None
for the optional group if it isn't present. Although at this point using groupdict
and the group names might be better.
Agreed. I also agree about the groupdict |
Asked changes added, and padding added now. Please take a look to this POC to see sample output with padding. |
pysnooper/tracer.py
Outdated
return thread_info | ||
else: | ||
needed_spaces = " " * (self.padding - current_thread_len) | ||
return "{thread_info}{needed_spaces}".format(**locals()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try:
self.padding = max(self.padding, current_thread_len)
return thread_info.ljust(self.padding)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@4383 I agree with Alex's comments, ljust
is better.
pysnooper/tracer.py
Outdated
@@ -117,6 +119,8 @@ def __init__(self, target_code_object, write, truncate, watch=(), | |||
self.prefix = prefix | |||
self.overwrite = overwrite | |||
self._did_overwrite = False | |||
self.threads_info = threads_info | |||
self.padding = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think padding
and set_padding
sound too generic. They should indicate that they specifically apply to threads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See me next comment on padding on everything by default to keep the alignment between snooped with threads info turned on and turned off in the same output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just talking about the names. I would go for thread_info_padding
and set_thread_info_padding
pysnooper/tracer.py
Outdated
current_thread = threading.current_thread() | ||
thread_info = "{ident}-{name} ".format( | ||
ident=current_thread.ident, name=current_thread.getName()) | ||
thread_info = self.set_padding(thread_info) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't this also under the if?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To keep padding with snooped where thread info is disable.
IHMO I guess we need too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
look at the POC and sample output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once Tracer.threads_info
is true, it's not going to become false unless the user does something quite weird. But it's not impossible, especially as this library changes, so I guess this can stay.
tests/utils.py
Outdated
@@ -173,6 +173,7 @@ def __init__(self, source=None, source_regex=None, prefix=''): | |||
assert source_regex is None | |||
self.line_pattern = re.compile( | |||
r"""^%s(?P<indent>(?: {4})*)[0-9:.]{15} """ | |||
r"""(?P<threads_info>[0-9]*-[A-Za-z_]* )?""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Should be
+
, not*
. Should probably be the same for the rest of the regex as well, don't know what the reasoning was. - Need to allow for more than one space.
- Need to allow for
-
and numbers in the thread name. For me,threading.Thread().name
gives'Thread-357'
.
You also need to write a test that has multiple threads with names of different lengths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, except I'm not sure about 3. But it's a small point anyway, so I don't mind about that.
@cool-RR should the parameter name be |
I see no reason why it should be |
@4383 You're not waiting for us right? Just making sure. |
@cool-RR No don't worry I'm currently on PTO. |
I just pushed my latest changes:
I need to add the test with multi threads but I'm not convinced by the benefits to test that, I guess a better approach can be to add unit test on the padding methods and mechanism to avoid errors on it instead of testing something more bluring and general. We already test for output with threads turned on so using one or more threads doesn't change the deal... Thoughts? |
I'm sorry but I would actually avoid spending more effort on this because my PR is going to completely obsolete it and I have something else more generalised line up afterwards. |
Can you add a bit of detail?
…On Wed, May 8, 2019, 17:29 Alex Hall ***@***.***> wrote:
I'm sorry but I would actually avoid spending more effort on this because
my PR is going to completely obsolete it and I have something else more
generalised line up afterwards.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#87 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAAN3SUVYG3KWC3P3VJOEMDPULPVRANCNFSM4HKV7Y6A>
.
|
@4348 Separately, I added you now to the AUTHORS file because regardless of whether this PR makes it through, you've made a contribution. |
A test with multiple threads is essential. This test should also test for the padding increase. One test for both is enough. Regarding Alex's separate refactoring that might obsolete this PR: I can't know when I'll have time to review that, so it shouldn't block this PR. |
I've got code which lets the user specify which columns they want in the output and in what order. It handles padding for all of them. from pysnooper import snoop
@snoop(columns='time thread thread_ident file function', depth=2)
def foo(x):
y = x + 1
y += barlo(y)
z = list(range(1000))
return z
def barlo(z):
return z * 2
foo(4)
The user can also pass callables to make custom columns. Even without this, if the formatting PR goes through, then the thread info stuff has to be in the formatter, and the test will have to like |
Okay, interesting. I need to think about it. |
@alexmojaki @cool-RR you still want these changes? Not sure to understand. I don't want to spend my time on something who will finish to the trash... |
Like I said, I think you should wait for now. We may come back to it later. |
@alexmojaki Okay, let's wait with this. @4383 : Sorry for the frustration! |
Well, finally I've added the missing test (multi thread and padding test). If you don't request new changes, I think everything is done on my side... |
@4383 Since I decided against the big refactoring, I'm interested in this PR. I think it's almost ready, except one thing: Your tests don't really test that the thread reported is the right thread. That's kind of... The main thing isn't it? Modify |
If the variable lines are also supposed to be aligned, e.g:
then that has to be accounted for in the implementation as well. |
I don't think that's important enough to implement. |
@cool-RR thanks for your feedback ack! |
Oh wait I need to do some changes |
Display thread infos (identifier and name) on output to help user to track execution on apps who use threading.
done! |
Great job! I'm happy you persevered through this long PR process! |
@cool-RR My pleasure, you are welcome! :) |
Like @zzzeek as suggested these changes display thread infos (identifier and name) on output to help
user to track execution on apps who use threading.
Solve #79