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

Add generic output formatter interface. #388

Merged
merged 80 commits into from
Apr 21, 2017
Merged

Conversation

tsroten
Copy link
Member

@tsroten tsroten commented Mar 29, 2017

Description

  • Adds a generic OutputFormatter class with all of tabulate's output formats.
  • Moves expanded output to the output formatter.
  • Adds terminaltables formats.

Checklist

  • I've added this contribution to the changelog.md.
  • I've added my name to the AUTHORS file (or it's already there).

@tsroten
Copy link
Member Author

tsroten commented Mar 29, 2017

@meeuw @amjith This includes tabulate's formats, but not terminaltables. It also doesn't include any of @meeuw's handling of decimals as strings.

This is just a start, please feel free to edit/push changes as needed. The tests need some work as well...

@tsroten
Copy link
Member Author

tsroten commented Mar 29, 2017

I believe @meeuw's number-as-string is working now in this PR since tabulate has disable_numparse, which seems like what we want here.

@amjith
Copy link
Member

amjith commented Mar 29, 2017

This is an excellent refactor. I love seeing the progression of changes as I step through the commits.

I have a few questions that I'll sprinkle throughout the diffs. Nicely done! 👍

mycli/main.py Outdated
for line in output:
click.echo(line, nl=new_line)

def format_output(self, title, cur, headers, status, expanded=False,
max_width=None):
table_format = 'expanded' if expanded else self.table_format
Copy link
Member

Choose a reason for hiding this comment

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

We used to store the table format on the Mycli instance as self.table_format. Now that we have OutputFormat, we should place the table_format on the instance of OutputFormat. MyCli class shouldn't be in the business of holding state for other objects.

When we want to override the table_format based on the width, we'll simply overwite the value in the OutputFormat instance.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a good point. What do you think of having an optional keyword override for table format as well. For instance:

formatter = OutputFormatter(format_name='simple')
formatter.format_output(data, headers)  # formats as simple
formatter.format_output(data, headers, format_name='expanded')  # formats as expanded

fkwargs.update(kwargs)
preprocessor = fkwargs.pop('preprocessor', None)
if preprocessor:
data = preprocessor(data, **fkwargs)
Copy link
Member

Choose a reason for hiding this comment

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

The preprocessor should get all the args passed into the format_output. Right now we're only passing in the data, but what if the preprocessor wanted to color the headers?

Copy link
Member Author

Choose a reason for hiding this comment

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

Great point! We should definitely include headers in the preprocessor since they are part of the output.

@meeuw meeuw force-pushed the feature/output_formatter branch from 041973f to 5fb6f2a Compare April 1, 2017 10:13
@meeuw meeuw force-pushed the feature/output_formatter branch from e2aa7e0 to 3dbe5c0 Compare April 1, 2017 10:54
@codecov-io
Copy link

codecov-io commented Apr 1, 2017

Codecov Report

❗ No coverage uploaded for pull request base (master@a380707). Click here to learn what that means.
The diff coverage is 78.28%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #388   +/-   ##
=========================================
  Coverage          ?   72.68%           
=========================================
  Files             ?       29           
  Lines             ?     2544           
  Branches          ?        0           
=========================================
  Hits              ?     1849           
  Misses            ?      695           
  Partials          ?        0
Impacted Files Coverage Δ
mycli/output_formatter/expanded.py 100% <100%> (ø)
mycli/completion_refresher.py 94.73% <100%> (ø)
mycli/sqlcompleter.py 81.9% <100%> (ø)
mycli/sqlexecute.py 91.02% <100%> (ø)
mycli/output_formatter/preprocessors.py 100% <100%> (ø)
mycli/packages/tabulate.py 67.82% <65.97%> (ø)
mycli/main.py 61.43% <76.31%> (ø)
mycli/output_formatter/terminaltables_adapter.py 83.33% <83.33%> (ø)
mycli/encodingutils.py 76% <87.5%> (ø)
mycli/output_formatter/tabulate_adapter.py 91.66% <91.66%> (ø)
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a380707...8fa96a2. Read the comment docs.

self.register_output_format('expanded', expanded_table,
preprocessor=override_missing_value,
missing_value='<null>')

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 register_output_format should be called outside of OutputFormatter (from MyCli.__init__ ?)

Or else we could also just directly initialize the self._output_formats dict like:

self._output_formats = {
    'csv' : csv_wrapper, {preprocessor=override_missing_value, missing_value='null')
...
}

And remove register_output_format

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that's a good point.

I favor the idea of OutputFormatter setting up the dict when it's initialized. My main reason for liking this is keeping all details of formatting away from MyCli (e.g. wrappers, format names, format packages, etc.).

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm yes, that's true. Let's keep it this way. I was thinking of letting the user configure more output formatters at runtime but we can always refactor it by then (now it's too far fetched).

Copy link
Member Author

Choose a reason for hiding this comment

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

I do think there is a lot of room for new features in the future. I think you're right that we should keep it simple for now.

@meeuw meeuw force-pushed the feature/output_formatter branch from 09cd34f to 152a16c Compare April 1, 2017 14:28
@meeuw meeuw force-pushed the feature/output_formatter branch from 152a16c to 434aea0 Compare April 1, 2017 14:37
@tsroten tsroten force-pushed the feature/output_formatter branch from 0ab3327 to 359044c Compare April 12, 2017 20:47
_output_formats = {}

def __init__(self, format_name=None):
"""Register the supported output formats."""
Copy link
Member

Choose a reason for hiding this comment

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

This doc string is outdated. Looks like I missed it in my refactor.

@amjith
Copy link
Member

amjith commented Apr 12, 2017

Looks like we lost the ability to auto-complete on the \T command.

@tsroten
Copy link
Member Author

tsroten commented Apr 13, 2017

@amjith Good catches. Looks like the background refresher wasn't setting the table formats when it created the SQLCompleter object. Should be fixed now.

@amjith
Copy link
Member

amjith commented Apr 13, 2017

I'm on linux (Ubuntu). When I choose 'Single' or 'fancy_grid' as the table format the output is completely garbled. Is anyone else seeing this?

It works fine with other table formats.

@tsroten
Copy link
Member Author

tsroten commented Apr 13, 2017

@amjith Yes, that happens to me as well on MacOS. I'll try to track down what's going on later today.

@meeuw
Copy link
Contributor

meeuw commented Apr 13, 2017

@tsroten is has to do with the less pager and escape codes. If you use cat as a pager it works.

@meeuw meeuw force-pushed the feature/output_formatter branch from 8696bf7 to cdbc7cd Compare April 15, 2017 15:23
@meeuw meeuw force-pushed the feature/output_formatter branch from 48b1daa to 8fa96a2 Compare April 15, 2017 19:22
@amjith
Copy link
Member

amjith commented Apr 21, 2017

Are we ready to merge this or should we wait for cli_helpers to land?

@tsroten
Copy link
Member Author

tsroten commented Apr 21, 2017

@amjith I'm up for it being merged now. Then, when CLI Helpers is released we can update mycli to use it instead.

@amjith amjith merged commit 818f5cd into master Apr 21, 2017
@amjith amjith deleted the feature/output_formatter branch April 21, 2017 16:41
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.

4 participants