-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-46742: Add "-d 123" / "--trace_fd 123" option to the trace module… #31319
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
base: main
Are you sure you want to change the base?
Conversation
… to send trace logs to a different file descriptor.
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). CLA MissingOur records indicate the following people have not signed the CLA: For legal reasons we need all the people listed to sign the CLA before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
Ping...? |
Ping? |
Ok, it's been 40 days, the automated checks appear to be jammed. :-( |
If you can see a way to eliminate the "calling-fdopen-on-every-message" while keeping pytest happy, I'll gladly incorporate it. |
Ping? |
¿ƃuıԀ |
I apologize, but I don't actually know what the next step is to get this approved and merged. Can you tell me? |
@abalkin , are you available for a code review? :-) |
@serhiy-storchaka, it looks like you've done a fair bit of work on the |
Apologies for the delay, @PenelopeFudd -- the truth of the matter is that there is a sizeable PR backlog, that CPython is maintained by volunteers, and that there aren't enough maintainers to review all of the PRs that come through. The lack of response is not necessarily a comment on the merits of your PR :) (I don't know enough about the |
Fortunately, it was a straightforward change: Before this, the trace gets sent to standard output, where it swamps the program's regular output. With bash, the trace function's output is written to stderr (fd=2), with an option to write to another file descriptor by setting a reserved shell variable:
I didn't want the program's output to be swamped, and redirecting to a specified file descriptor seems to be an acceptable method. Setting a reserved variable like bash does seemed like a hack, so I made it a CLI option instead:
I was tempted to change the default behaviour to send the trace output to stderr (like bash), but there are lots of people whose trace-handling programs would stop working because of that change. |
There's only one thing about my code that I am not happy about. Initially I called I googled a fair bit, but wasn't able to find a good way to satisfy pylint. I resorted to running fdopen for every print statement. I could only justify it to myself by realizing that fdopen is not calling the operating system; it's taking an already-open file descriptor and making a file object out of it, which should be a fairly fast function. However, if you've got a better way, I'd love to implement it. |
@@ -96,6 +96,15 @@ Modifiers | |||
Directory where the report files go. The coverage report for | |||
``package.module`` is written to file :file:`{dir}/{package}/{module}.cover`. | |||
|
|||
.. cmdoption:: -d, --trace_fd |
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.
Mixing -
and _
looks weird. Either use minus, --trace-fd
(like --no-report
) or omit the separator, --tracefd
(like --listfuncs
, --trackcalls
, --coverdir
).
Also specify that the option takes an argument: --tracefd=<fd>
.
I am not sure that it is necessary to add a short option. The set of letters is limited, and -d
could be used for more popular option ("directory" or "description" or "delete").
@@ -385,14 +385,16 @@ def _find_executable_linenos(filename): | |||
return _find_lines(code, strs) | |||
|
|||
class Trace: | |||
def __init__(self, count=1, trace=1, countfuncs=0, countcallers=0, | |||
def __init__(self, count=1, trace=1, trace_fd=1, countfuncs=0, countcallers=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.
Adding a parameter before other positional parameters is a breaking change. It will break a code which calls Trace() with 3 or more positional arguments.
Add it at the end of parameters, and better make it keyword-only. 10 positional parameters is too much.
Also not that no other parameter has _
in the name, even if they are a combination of words.
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.
Ok, fixing this.
@@ -559,8 +563,9 @@ def localtrace_trace_and_count(self, frame, why, arg): | |||
if self.start_time: | |||
print('%.2f' % (_time() - self.start_time), end=' ') | |||
bname = os.path.basename(filename) | |||
print("%s(%d): %s" % (bname, lineno, | |||
linecache.getline(filename, lineno)), end='') | |||
with os.fdopen(self.trace_fd, "w", closefd=False) as trace_fp: |
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.
It uses the default encoding by default. Therefore it changes the behavior even if trace_fd=1, because the encoding of stdout can be different.
I afraid also that it can interfere with buffering user's output. Flush the standard streams before 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.
How could the code be made smarter, so that it doesn't alter the encoding of stdout?
@@ -559,8 +563,9 @@ def localtrace_trace_and_count(self, frame, why, arg): | |||
if self.start_time: | |||
print('%.2f' % (_time() - self.start_time), end=' ') |
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.
It goes to the stdout.
… to send trace logs to a different file descriptor.
Note: this does an fdopen on every write, because I could not find a way to do
self.trace_fp = os.fdopen(trace_fd,"w",closefd=False)
without triggering a warning from pytest about an unclosed file pointer (e.g. a file pointer leak). Creating an exit() function to close self.trace_fp didn't appear to work. Fortunately, os.fdopen() is not a very cpu-intensive function.https://bugs.python.org/issue46742