-
-
Notifications
You must be signed in to change notification settings - Fork 1
Perceptive Porcupines #6
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
This is just something to get us started, and most if not all of this will probably need to be changed as we start doing things.
Sorry i accidentally closed this instead of merging it
Fix flake8 errors
updated yaml files
Parsing stderr and identifying the key parts of the error.
Looks like textual doesn't accept params properly, they are getting over-wrriten in the package. Probably because it is in beta.
…tual Hook up Texttual
Stack Overflow API
hello world example
This will help explain what is happening in #89
Add command line option to clear the HTTP cache
…h-contribution Add installation and contribution instructions
…he-instructions Add instructions for clearning cache
Fallback to searching class name if no results
Also, a minified version of the Usage is shown if the arguments are not correct. This is usually the expected behaviour for command line applications unless `-h` or `--help` are explicitly passed in.
minor display updates
changed to version 0.1
updated readme for codejam submission
HassanAbouelela
left a comment
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.
First Impressions - README
"All good projects start with the readme."
- Not an actual quote
I was very impressed by the readme. For end-users, it's short and straight to the point. The images were a nice touch!
I followed the contributing guide when setting up the project, and didn't run into any problems. That's usually a good sign you're doing something right. The contributing portion mentions all the details I'd need to contribute myself, big thumbs up from me.
One problem I have with the README is it's not clear what the relation between your project and the theme is, it would've been nice to touch on that briefly. The README is also a bit long. One thing that would've helped with that is breaking the contributing guide off into its own page (CONTRIBUTING.md is a common standard you may see in other open-source projects), and linking that in the README.
One more thing to note is that the image on your PyPI page is 404ing.
Use of Python and Rich/Textual
All green on pre-commit!
There is a very consistent use of docstrings and type annotations, making working with this project very nice. There were a few errors with annotations around the project, and I commented on them, but overall very minor. Nice job!
Rich is used nicely throughout the project, and the main display makes good use of textual.
The project is split up in a very logical way, and overall, it's pretty easy to follow.
Commit Quality
The quality of commits is pretty average. There are quite a few commits with too long a title, and quite a few with no messages, or unclear changes.
To address the first point, I personally have a hard limit of 72 characters for commit titles and messages, which allows them to display nicely in a timeline or list. Some people recommend 50 characters max for the title as well. If you're finding it difficult to give your commits short titles, remember that the title is just the most basic summary of all your changes. There isn't the same sort of limit for the bodies, so you can include all the other details there. If you are still finding it difficult to fit everything, could you possibly be packing too much into a single commit?
For the second point, make use of the commit's body to help future reviewers figure out why things are the way they are. They can help your peers and even yourself in the future.
Things you did well
This was an awesome project to review. It was clean, smart, and a really cool tool. These are a few things I believe were really well done:
- The UX of the tool is really awesome. From the simple installation to the ease of use.
- The code is very clean and easy to follow.
- Caching the results is a smart decision, which I appreciate greatly.
- The examples provided were a good way of getting familiar with the project.
- The state of your repo is really neat. Having the issue templates is a great step towards future maintainability of the project. It's also nice to see you taking an active step towards maintaining the state of your license.
Things that could be improved
Here are a few things that I noticed while reviewing that could use some work:
- Automatic publishing of the package in CI. This is really useful when it comes to having a healthy open source project in the future. A lot of tools make it pretty easy to do, including flit which can publish directly to PyPI.
- General cleanliness. There are a few clean-up tasks that should be done. The placeholder code jam document needs to be removed, or possibly updated to mention this project originated from a code jam. If you end up updating the code jam document, it might be nice to link it in your readme, possibly under a title like "Our history".
- Mypy. There seem to be the beginnings (or remenants) of a mypy setup. I see the config file, and I see a commit claiming to add it, but as far as I can tell, it was never added to the project dependencies and was never enforced in CI.
| display_app_error(e) | ||
|
|
||
|
|
||
| if __name__ == "__main__": |
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.
This is redundant. The name will never be anything other than main, unless someone explicitly imports this file (import wtpython.__main__). Since there doesn't seem to be a case where that's expected to happen, you don't need this check.
| ) | ||
|
|
||
|
|
||
| def parse_arguments() -> dict: |
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 love how you've handled parsing. It's really clean and straightforward, and the product interface feels very intuitive. The additional information text is a nice touch.
| parser.error("Please specify a script to run") | ||
| sys.exit(1) | ||
|
|
||
| if not os.path.isfile(opts['args'][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.
I wouldn't have thought of doing this, but it makes for really nice UX. Well done!
| return tb | ||
|
|
||
|
|
||
| def run(args: list[str]) -> Exception: |
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.
The return type for this function should probably be marked as optional, since it'll return None if there is no exception.
| SO_MAX_RESULTS = 10 | ||
| SO_API = "https://api.stackexchange.com/2.3" | ||
|
|
||
| REQUEST_CACHE_LOCATION = Path.home() / Path(".wtpython_cache") |
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.
This is a sensible default, though it would've been nice if it could be configured or changed. Ultimately, it's not a big deal, just user preference.
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 hope to have a config file setup, but I'm curious where you would choose to put the cache. I suspect /tmp might be a good spot as well.
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.
This is a good place for most cases, it's just that as I'm running on windows, I'd probably place it with other caches in AppData.
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.
That's not a bad idea either. Thanks!
| if clear_cache: | ||
| self.session.cache.clear() | ||
|
|
||
| def get_answers(self, question: dict) -> List[StackOverflowAnswer]: |
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.
This return type is a bit misleading. There are two main problems with it:
- The code doesn't actually return a list. It returns a dict. The
itemskey would return the list of answers. - The
itemskey will return the list of answers, but not as instances of theStackOverflowAnswer(L62), but rather regular python dicts.
I believe this is just a mistake in the type hint, since you do in fact expect the full JSON result based on the way this output is used in StackOverflowQuestion. The return here should be marked as a dict, and if you want to clarify what a developer can expect to find in this dict, that should be added to the docstring.
| so_results = so.search(error, SO_MAX_RESULTS) | ||
| if len(so_results) == 0: | ||
| # If no results have been found, search the error class name. | ||
| so_results = so.search(error.split(" ")[0].strip(":"), SO_MAX_RESULTS) |
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.
This is a pretty clever fallback!
I do want to note that when the fallback returns 0 hits, a special message is displayed in normal mode, but not no-display mode. I think it'll be neat if that gave a similar message.
| traceback.print_exception(type(exc), exc, exc.__traceback__) | ||
| print(HorizontalRule()) | ||
| print( | ||
| f":nerd_face: [bold][green]Please let us know by by opening a new issue at:[/] [blue underline]{GH_ISSUES}" |
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 may be interested in checking out hyperlinks. This goes for anywhere you use links. (Admittedly, they don't work on all terminals - including the one I tested on - but leaving in the visible link, as well as making it a hyper link would still work for everyone, and make it a bit easier for those that have it).
Example of what I mean:
| f":nerd_face: [bold][green]Please let us know by by opening a new issue at:[/] [blue underline]{GH_ISSUES}" | |
| f":nerd_face: [bold][green]Please let us know by by opening a new issue at:[/] [link={GH_ISSUES}][blue underline]{GH_ISSUES}[/link]" |
| questions: List[StackOverflowQuestion] = None, | ||
| ) -> None: | ||
| if questions is not None: | ||
| self.questions = questions |
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 don't believe the default value for questions is ever used, making it redundant.
If questions does end up as None though, the program will run into other errors as self.questions will not be defined.
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.
Good catch. At the very least, it should be an empty list when passed.
| footer.add_key("q", "Quit") | ||
| footer.add_key("←", "Prev Q") | ||
| footer.add_key("→", "Next Q") | ||
| footer.add_key("s", "Show Questions") |
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.
Since you're using a builtin widget, I'm not sure whether the following should be considered a bug or not, but here goes anyways:
Pressing show questions ends up hiding the footer. Clicking s again to go back leads to a broken footer. Here is an example:
Reproduction info:
GIF above is WSL on CMD, though I've tested and reproduced on powershell as well.
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'm pretty sure this is something from Textual, and is likely a windows specific issue since it's not really supported on Windows properly yet. I don't think any of us had this issue
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.
That's fair!
This is a really minor problem, and overall, the experience is really smooth on windows.

No description provided.