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

Replace optparse with argparse in suite_report.py #34

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

t00sa
Copy link
Contributor

@t00sa t00sa commented Aug 12, 2024

The only script using optparse was suite_report.py. This has been updated to use argparse and the script has been linted and its compliance with flake8 improved.

A before and after comparison of the output from suite_report.py shows no change in behaviour:

vdi> python suite_report.py -S ~/cylc-run/vn13.6_remove_optparse/runN/ -L /var/tmp
svn://fcm1/monc.xm_svn/casim/trunk appears to be the trunk, nothing to do!
svn://fcm1/jules.xm_svn/main/trunk appears to be the trunk, nothing to do!
svn://fcm1/moci.xm_svn/main/trunk appears to be the trunk, nothing to do!
svn://fcm1/um.xm_svn/mule/trunk appears to be the trunk, nothing to do!
svn://fcm1/utils.xm_svn/shumlib/trunk appears to be the trunk, nothing to do!
svn://fcm1/socrates.xm_svn/main/trunk appears to be the trunk, nothing to do!
svn://fcm1/ukca.xm_svn/main/trunk appears to be the trunk, nothing to do!
svn://fcm1/um.xm_svn/aux/trunk appears to be the trunk, nothing to do!
svn://fcm1/um.xm_svn/meta/trunk appears to be the trunk, nothing to do!
vdi> diff /var/tmp/trac.log ~/cylc-run/vn13.6_remove_optparse/runN/trac.log 
7c7
<  || Report Generated: || 2024/08/12 20:34:02 || 
---
>  || Report Generated: || 2024/08/12 13:53:01 ||
vdi> 

See also: UM ticket 7722

Remove the deprecated optparse module and replace it with an similar
implementation using argparse.
Find and fix various problems reported by pylint.
Fixes everything but a single case where the options are either an
E129 warning about having the same indentation as the next line or an
E127 warning about over-indentation - and there doesn't seem to be a
format that satisfies the checker!
@t00sa t00sa linked an issue Aug 12, 2024 that may be closed by this pull request
Enable command line argument completion for the two directory options
if/when argcomplete is available.
To keep the linter happy, most of the format() calls with f-strings.
This supposedly offers better performance and is more in keeping with
python 3.
@t00sa t00sa requested review from a team and ericaneininger and removed request for a team August 27, 2024 07:22
Copy link
Contributor

@ericaneininger ericaneininger left a comment

Choose a reason for hiding this comment

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

A couple of comments/queries in-line.

suite_report.py Show resolved Hide resolved
@@ -1274,7 +1281,7 @@ def write_lfric_testing_message(num_interactions):

if num_interactions > 0:
if num_interactions > 1:
message += ["There were {} projects ".format(num_interactions)]
message += [f"There were {num_interactions} projects "]
Copy link
Contributor

Choose a reason for hiding this comment

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

Appending a list of length one looks odd to me. Could use message.append(<msg>)
Having said that this structure is also used in the method create_approval_table(). Perhaps a pickiness too far!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suspect there was a conscious decision not to use in-place additions rather than append() to be consistent with the sections that add multiple lines to the messages list. I'm happy to leave it be for now.

I've got wider refactoring changes that replace the list with an io.StringIO instance to make it possible to use print to construct an output buffer.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I suspect, you suspect wrongly....
I suspect it's a hold over from shell programming days and then when it threw an error the brackets to make it a list of one element were added to make the error go away....

But the ancients who wrote these hieroglyphs are long gone and we'll never be able to know for sure...

@@ -1712,13 +1724,15 @@ def gen_table_element(text_list, link, bold=False):
if "working copy changes" in proj_dict:
if proj_dict["working copy changes"]:
wc_text = "YES"
# pylint: disable=consider-using-f-string
Copy link
Contributor

Choose a reason for hiding this comment

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

Having made so many the conversion to f-string format statements, there just 3 older style .format()s left. Why these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. It feels like there should be a more elegant way to format these string, but it's not immediately clear to me what it is. Perhaps they should be a property of the instance?

I'll take a look at the other pylint fstring exclusions and see if I can improve those too.

Copy link
Contributor

Choose a reason for hiding this comment

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

Happy to accept most of my comments will be addressed in the refactor ticket.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Would this be a good one to us os.path.join on instead of creating a string manually ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I would always prefer to see os.path.join() rather than a string with /s in. It's then platform safe should someone try to run on Windows.

Copy link
Collaborator

@r-sharp r-sharp left a comment

Choose a reason for hiding this comment

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

Hmmm, this looks like an also ticket....
Lets reconfigure it to use "argparse" and also do quite a lot of linting improvements...

Should it be 2 PRs 😃

Just looking at that - there were some "things were going to get back to later..." like the verbosity level which I'm amused to see are still untouched. Any chance they could be considered in the "major refactor" you mention ?

UM repository. When making changes, please ensure the changes are made in
the UM repository or they will be lost during the release process when the UM
copy is copied over.
UM repository. When making changes, please ensure the changes are
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might seem 'pedantic' - but this comment is no longer true is it ?
The file has been moved from the UM repos, to the SimSys_Scripts one, and hopefully removed from all the repos it was in before. (this possibly needs checking)

So rather than change the line length (which I assume was done by black or similar, hence no-one noticing it was out of date) Could we remove this comment completely ?

"""

# pylint: disable=too-many-lines
Copy link
Collaborator

Choose a reason for hiding this comment

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

I notice that quite a few directives for pylint have been added.
Should we either - have them all in one block at the top ?
Or - Always enable and disable the ones we want around the specific block causing us issues.
Or - both...

@@ -330,7 +344,13 @@ def _parse_string(
return value


class SuiteReport(object):
# pylint: disable=too-many-instance-attributes
Copy link
Collaborator

Choose a reason for hiding this comment

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

AS in comment further up - do these need "deactivating" at the relevant point ? e.g. the bottom of this class ?

@@ -1274,7 +1281,7 @@ def write_lfric_testing_message(num_interactions):

if num_interactions > 0:
if num_interactions > 1:
message += ["There were {} projects ".format(num_interactions)]
message += [f"There were {num_interactions} projects "]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I suspect, you suspect wrongly....
I suspect it's a hold over from shell programming days and then when it threw an error the brackets to make it a list of one element were added to make the error go away....

But the ancients who wrote these hieroglyphs are long gone and we'll never be able to know for sure...

@@ -1355,6 +1367,8 @@ def generate_task_table(
if not empty and indicates how many tasks of the relevant types have
been hidden"""

status_counts = status_counts or defaultdict(int)
Copy link
Collaborator

Choose a reason for hiding this comment

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

How/Why is doing this here better than giving status_counts the default value of defaultdict(int) in the argument list - they seem to be identical to me....

except KeyError:
pass
trac_log.append(
# pylint: disable=consider-using-f-string
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmmmmm, .... Yum !
What about breaking it into 2 lines...
bg_colour = BACKGROUND_COLOURS[self.primary_project.lower()]
trac_log.append(
f"{{{{{{#!div style='background : {bg_colour}'"

I appreciate it's just the same thing another way, but it should (hopefully) dispose of 2 linter directives...

trac_log.append(
" || Cylc-Review: || {0:s}/{1:s}/{2:s}/?suite={3:s} || ".format(
" || Cylc-Review: || {0:s}/{1:s}/{2:s}/?suite={3:s} || "
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another where it might be useful to split out into multiple 'steps'
use os.path.join() to join all the parts together into a string which you assign to "sodding_path", and then use an f-string with {sodding_path} in it.

# on a JULES rose-stem suite as JULES has no 'need' of the two
# compare variables and to prevent the warning their absence
# would produce from occuring unnecessarily in JULES they have
# been added to rose-suite.conf for now
Copy link
Collaborator

Choose a reason for hiding this comment

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

In general - are these not dead yet ? does the UM trac.log still report on compare wallclock and compare output tests ?

@@ -2009,17 +2029,19 @@ def print_report(self):
trac_log.append("")
trac_log.append("-----")
trac_log.append(" = WARNING !!! = ")
# pylint: disable=consider-using-f-string
trac_log.append(
"This rose-stem suite included multiple "
+ "branches in {0:d} projects:".format(
len(self.multi_branches.keys())
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

                trac_log.append(
                    "This rose-stem suite included multiple "
                    + f"branches in {len(self.multi_branches.keys())}"
                    + " projects:"

Might get rid of the linter directives - I /think/ the line isn't too long...

raise

# pylint: disable=broad-exception-caught
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this needed here because it looks like it might have been an attempt to re-enable broad-exception-caught ?

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.

Replace optparse with argparse in scripts
3 participants