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

bpo-29854: Print readline version information when running test suite #2618

Closed

Conversation

berkerpeksag
Copy link
Member

No description provided.

Copy link
Contributor

@nirs nirs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@vstinner
Copy link
Member

vstinner commented Jul 7, 2017

I would prefer to dump the curses version in test_readline, as done by test_tcl or test_gdb in verbose mode. When a test fails on buildbots, the test is run again in verbose mode.

@vstinner
Copy link
Member

vstinner commented Jul 7, 2017

I prefer to not make regrtest header too big.

@berkerpeksag
Copy link
Member Author

berkerpeksag commented Jul 7, 2017

Why would we want to print curses version in test_readline? Unless I'm missing something, curses doesn't have anything to do with bpo-29854.

tcl and gdb are much less common dependencies than readline. readline is probably available on all Unix platforms and I think it makes sense to easily see which version is installed on the host.

I prefer to not make regrtest header too big.

Sorry, I don't have time for this kind of bikeshedding. We don't design a production level UI for end users and it's already hard to read outputs of regrrest and Buildbot. I prefer not to spend too much time to find which version of readline installed at http://buildbot.python.org/all/builders/x86%20Tiger%203.x/builds/908/steps/test/logs/stdio Plus, that header has already prints less useful information so I don't think two additional lines would set the world on fire :)

@vstinner
Copy link
Member

vstinner commented Jul 7, 2017

Why would we want to print curses version in test_readline? Unless I'm missing something, curses doesn't have anything to do with bpo-29854.

Oh sorry, I'm always confused between readline and curses, they are the same thing for me, sorry :-)

By the way, you should mention bpo-29854 in your PR title. It helps later to get the rationale of a change ;-)

tcl and gdb are much less common dependencies than readline. readline is probably available on all Unix platforms and I think it makes sense to easily see which version is installed on the host.

Another issue with importing readline early is that importing a module has side effect, especially readline. See for example http://bugs.python.org/issue19884 and TestReadline.test_init(): this test still fails on our RHEL buildbot, so importing readline still have an annoying side effect of writing a string into stdout.

I would prefer to limit imports at regrtest startup, to make it more deterministic.

I prefer not to spend too much time to find which version of readline installed at http://buildbot.python.org/all/builders/x86%20Tiger%203.x/builds/908/steps/test/logs/stdio

Would you mind to review my PR #2619? When it will be merged, I can retrieve the libreadline version for you and put it in the issue.

@vstinner
Copy link
Member

vstinner commented Jul 7, 2017

We discuss this PR on IRC with @berkerpeksag. If imports are done are done in subprocess to prevent side effects, I'm ok to get such change merged ;-)

import readline
except ImportError:
readline = None
if readline is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line just can be an "else:" no?

rl_version_cmd = """if 1:
try:
import readline
except ImportError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use sys.exit(1) to not try to decode empty stdout in the parent process.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point!

@@ -432,6 +433,26 @@ def display_header(self):
print("== encodings: locale=%s, FS=%s"
% (locale.getpreferredencoding(False),
sys.getfilesystemencoding()))
rl_version_cmd = """if 1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may put the textwrap.dedent() directly here. But do you need "if 1:" in that case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean

rl_version_cmd = textwrap.dedent("""
...
""")

?

And, you're right, we don't need if 1:, thanks!

pass
else:
print(f"== readline version: {rl_version}")
print(f"== readline implementation: {rl_implementation}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please write both info on a single line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, what do you thing about the following format?:

== readline: 0x0602 (GNU readline)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it. Maybe just add version somewhere? "== readline: version 0x0602 (GNU readline)"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done:

== readline: version 0x0602 (GNU readline)

Thanks!

is_editline = readline.__doc__ and "libedit" in readline.__doc__
print("== readline implementation:", "editline" if is_editline else "GNU readline")
print("editline" if is_editline else "GNU readline")
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is very hard to read this code like this. The other program that you run should be indented differently from the other code.

Also the code to return the info should be in separate function, and here we can just print the values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what you're suggesting is similar to the following snippet, right?

rl_version_cmd = """
def get_rl_info():
    # all code is here
    return version, implementation
version, implementation = get_rl_info()
print(version)
print(implementation)
"""

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or:

rl_version_cmd = """
def get_rl_info():
    # all code is here
    return version, implementation
version, implementation = get_rl_info()
print("== readline: version {version} ({implementation})")
"""

Copy link
Contributor

@nirs nirs Jul 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More like:

def readline_info():
    script = """ 
import json
import readline
is_editline = readline.__doc__ and "libedit" in readline.__doc__
info = {"version": readline._READLINE_VERSION, 
        "implementation": "editline" if is_editline else "GNU readline"}
print(json.dumps(info))
"""
    c = subprocess.run([sys.executable, "-c", script],
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
    if c.returncode == 0:
        return json.loads(c.stdout.decode())

And use readline_info() in display_header(), or in any other context as needed.

@vstinner vstinner changed the title Print readline version information when running test suite bpo-29854: Print readline version information when running test suite Jul 7, 2017
@vstinner vstinner removed the trivial label Jul 7, 2017
@berkerpeksag
Copy link
Member Author

I've addressed all review comments (and hopefully I got @nirs' comment right) Thanks!

pass
import readline
except ImportError:
sys.exit(1)
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the try/else/exit, just import readline:

import readline

If import fails, we exit with exit code 1 anyway, no special code needed.

rl_output = subprocess.run([sys.executable, "-c", textwrap.dedent(rl_version_cmd)],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if rl_output.returncode == 0:
rl_version_cmd = textwrap.dedent("""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The extra indent make this much more clear, thanks!

print(f"== readline version: {rl_version}")
print(f"== readline implementation: {rl_implementation}")
def get_rl_info():
is_editline = readline.__doc__ and "libedit" in readline.__doc__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now the third place using this horrible doc check. I think we should eliminate this, now, or at least leave a todo and clean up later. Ideally we should have exactly one is_editline() function in cpython.

def get_rl_info():
is_editline = readline.__doc__ and "libedit" in readline.__doc__
return f"{readline._READLINE_VERSION:#06x}", "editline" if is_editline else "GNU readline"
rl_version, rl_implementation = get_rl_info()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should print the same values ptinted now in test_readline.setupModule

@berkerpeksag
Copy link
Member Author

Superseded by bpo-30871 and PR #3027.

@asottile
Copy link
Contributor

@berkerpeksag do you mean #3075?

@berkerpeksag
Copy link
Member Author

@asottile yes that's what I meant! :) Good catch, thanks.

@berkerpeksag berkerpeksag deleted the improve-regrtest-header branch August 15, 2017 03:57
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

Successfully merging this pull request may close these issues.

None yet

5 participants