-
Notifications
You must be signed in to change notification settings - Fork 680
output via generator #461
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
output via generator #461
Conversation
7c9066a to
6d0e7fb
Compare
mycli/main.py
Outdated
| rows, headers, format_name='vertical') | ||
|
|
||
| output.append(formatted) | ||
| if isinstance(formatted, str) or isinstance(formatted, unicode): |
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.
You might want to try adding from mycli.encodingutils import text_type to main.py so you can use that here.
mycli/main.py
Outdated
| from .lexer import MyCliLexer | ||
| from .__init__ import __version__ | ||
|
|
||
| from mycli.encodingutils import text_type |
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.
Looks like I told you wrong - you can add this to line 39 where we are already importing from encodingutils ;) Sorry about that!
mycli/main.py
Outdated
|
|
||
| output.append(formatted) | ||
| if isinstance(formatted, text_type): | ||
| formatted = formatted.splitlines() |
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.
When is formatted not a text_type? I think CLI Helpers always returns a text_type.
|
@meeuw Thanks for looking for more ways to improve mycli 😄 So, I'm wondering, what's the advantage of operating on the line level? I'm having trouble understanding what that gets us versus what we have now. Tabulate and Terminaltables don't return lists or iterables, so it's not like we can process the lines separately. This seems like it calls quite a bit of code for every line. |
|
Terminaltables is capable of returning an iterable, I'm working on a fix for cli_helpers. Terminaltables still needs to process the complete result set before outputting (to calculate the column width). But for csv/json/xml/tsv/wide output it's possible to iterate the database cursor and format/output the data without buffering the complete result set in memory. |
|
@meeuw Cool, sounds good to me 😄. Should I review this pull request? Or, wait until the CLI Helpers pull request? |
1e49d7f to
2ad542a
Compare
Codecov Report
@@ Coverage Diff @@
## master #461 +/- ##
==========================================
+ Coverage 77.83% 78.61% +0.78%
==========================================
Files 22 22
Lines 2012 2034 +22
==========================================
+ Hits 1566 1599 +33
+ Misses 446 435 -11
Continue to review full report at Codecov.
|
|
Related to dbcli/cli_helpers#13 |
mycli/main.py
Outdated
| click.secho(output) | ||
| size = self.cli.output.get_size() | ||
|
|
||
| margin = self.get_reserved_space() + self.get_prompt(self.prompt_format).count('\n') + 1 |
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 get why you're not calling output_fits_on_screen any longer (it compares the entire output), but let's rework that function so we can call it to get the margin so the margin code isn't directly in the output() function.
Since output_fits_on_screen is not used elsewhere, we can rename it and tweak it.
E.g. get_output_margin or something.
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 I accidentally removed output_fits_on_screen when I was resolving the merge conflicts, thanks for noticing, I'll try to fix it as soon as possible 😄
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.
Hmm that's a good idea, fixed this.
mycli/main.py
Outdated
|
|
||
| output.append(formatted) | ||
| if not isinstance(formatted, types.GeneratorType): | ||
| formatted = formatted.splitlines() |
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.
@meeuw, so if I understand this correctly, this line won't be needed once the CLI helpers changes are made, right?
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.
exactly
5d60435 to
162e824
Compare
|
So, one thing that's come up in my testing is that the output is always outputted to the pager, even if it fits on the screen. That's how mycli used to output results, but we recently changed it to only output via the pager if it doesn't fit (or there is the explicit pager). |
162e824 to
107be90
Compare
|
Ah you're right. I think I fixed it but I'd like to add additional tests. |
aecef31 to
0614e08
Compare
|
@tsroten I've added the additional tests but I think they could be a little bit more Pythonic and/or use more pytest features. |
0614e08 to
80185c8
Compare
80185c8 to
9e96d36
Compare
|
I'm thinking of using this to check if a generator returned from cli_helpers, but I don't like to add six as a dependency. |
|
I've created a PR: pallets/click#815 to allow outputting to the pager using a generator |
|
@tsroten thanks, could you please update the tests or tell me how, "if the output doesn't fit and it's not going to be output via a pager, then we lose all the rows after fits is set to False?" |
|
@meeuw Ok, I added a test that is failing. You can replicate it by:
You should see the results cut off because the output stops appending to |
|
You're the best 😄 thanks a lot! Fixed. |
mycli/main.py
Outdated
| for i, line in enumerate(output, 1): | ||
| self.log_output(line) | ||
| # line needs to be casted to unicode for click with Python 2.7 | ||
| special.write_tee(text_type(line)) |
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.
We need to fix whatever is not returning unicode. Do you know what it is? I know the CSV part of CLI Helpers wasn't at one point, but that should be fixed in the version that mycli requires.
If we can't fix it, then, we'll need to convert to unicode for the call to write_once() as well (line 715).
mycli/main.py
Outdated
| **output_kwargs) | ||
| first_line = formatted[:formatted.find('\n')] | ||
|
|
||
| if isinstance(formatted, (str, text_type)): |
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 we can drop str now that the unicode problems in CLI Helpers were fixed.
mycli/main.py
Outdated
| len(first_line) > max_width): | ||
| formatted = self.formatter.format_output( | ||
| cur, headers, format_name='vertical', column_types=column_types, **output_kwargs) | ||
| if isinstance(formatted, (str, text_type)): |
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.
Same here ^^
|
👍 thanks, the cast isn't required anymore. |
|
@meeuw Good work! I think this is ready to merge. If you could just move the changelog line up to the pending release, we'll be all set. I wonder if there is a way to word this change so that the end-user understands it. |
|
I've rephrased the changelog, English isn't my first language, could you please review? Feel free to change the text. |
|
@meeuw Ok, I reworded the changelog to be a bit shorter. It indicates that this is preliminary work to use less memory (preliminary, since CLI Helpers is still returning a string and not a generator). If you agree with the change, then go ahead and merge this in! It'll be good to get this one in finally. Sorry it took so long! 👍 🚀 |
|
I'm not in a hurry, thanks for your help! |
Description
output via generator to prevent:
Checklist
changelog.md.