deephaven / web-client-ui

Deephaven Web Client UI
Apache License 2.0
29 stars 31 forks source link

Automatic code formatting for notebooks #1255

Closed mofojed closed 1 month ago

mofojed commented 1 year ago

As a user, I want automatic code formatting in my notebooks so that my code looks pretty.

I would like to have formatting applied by something like black: https://github.com/psf/black.

Ruff wasm Python formatter and linter:

devinrsmith commented 1 year ago

I think this is a great idea. +1 on black.

dsmmcken commented 1 year ago

https://github.com/charliermarsh/ruff is just a linter, but I believe they are working on adding an autoformatter.

The list of projects using it is very impressive, so I can imagine it might replace black in the near future.

devinrsmith commented 1 year ago

Big fan of anything written in rust! Looks like a neat project, I'll definitely keep an eye on it.

https://github.com/charliermarsh/ruff/issues/4041

I believe we have plans to add a Ruff formatter, but it's a ways off. For now, black is still required.

That's right. For now, we don't autofix line wrapping, and we do recommend using Ruff alongside Black.

So, it looks like the devs of ruff like black too; my guess is if they eventually get a Ruff formatter, it will have a black-compatible mode. I think black is still our best bet today.

dsmmcken commented 1 year ago

Black is probably the best choice today, but yeah that could change in the future https://github.com/charliermarsh/ruff/issues/1904

We use prettier for our stuff, so them combining black plus some basic config options like prettier allows would be great.

devinrsmith commented 1 year ago

https://github.com/jpadilla/black-playground https://black.vercel.app

could be useful starting point?

devinrsmith commented 1 year ago

It could be useful to use bidirection plugins to support this use case.

mattrunyon commented 10 months ago

Ruff has a wasm package (have to build it from src) that can be used to format and lint completely client-side

mattrunyon commented 10 months ago

Not something I will currently continue working on (I have other priorities), but I made a quick POC using ruff as wasm. https://github.com/mattrunyon/web-client-ui/tree/ruff-wasm

I built the wasm from source and just included it as part of the branch. Looked at https://github.com/astral-sh/ruff/blob/main/playground/src/Editor/SourceEditor.tsx for how to call the linter/formatter and map the linter results to actions and markers.

I roughly implemented

Would still need to cleanup the code and add

Some issues on my branch

devinrsmith commented 6 months ago

Potentially related would be catching syntax errors on the web UI; I don't know if the code formatting tools considered would expose the appropriate syntax error hints, but that would also be a great addition.

dsmmcken commented 6 months ago

Two questions we should decide an answer on:

  1. Do we enable format on save by default? (my opinion is yes)
  2. Are there any linting rules we turn on beyond the default? Probably, but not sure. We should have our Pythonistas look through the available rule sets.
dsmmcken commented 5 months ago

@jnumainville for investigating any additional default rules sets that are commonly enabled

mattrunyon commented 5 months ago

https://docs.astral.sh/ruff/settings/#lintflake8-implicit-str-concat I think we should add this rule by default

t = t.update([
  "X=X+1" # missing comma at the end not flagged by other rulesets
  "Y=Y+1"
])
jnumainville commented 5 months ago

a quick survey indicates to me that there isn't much of a consistently chosen ruleset https://github.com/pola-rs/polars/blob/f6b4f48f3f7a981f6d022b5ca8a50b40a467d74c/py-polars/pyproject.toml#L133 https://github.com/jupyter/notebook/blob/a1e25b92bf10ef13a760353837114db9b498f242/pyproject.toml#L243 https://github.com/pandas-dev/pandas/blob/529bcc1e34d18f94c2839813d2dba597235c460d/pyproject.toml#L190 https://github.com/vega/altair/blob/f1b4e2c84da2fba220022c8a285cc8280f824ed8/pyproject.toml#L166 https://github.com/matplotlib/matplotlib/blob/46b39ab5bea6668e56140da568bde60276f6f906/pyproject.toml#L139 https://github.com/scikit-learn/scikit-learn/blob/4449ded95bdc7468f7465a3e89ea1b90b1426dfd/pyproject.toml#L143 https://github.com/pytorch/pytorch/blob/56b271fd7a87e03dc6cb4329a702eb5f5031f3e3/pyproject.toml#L91

mattrunyon commented 5 months ago

We should probably default to no style specific rules and focus only on rules that can show actual problems with the code (like inconsistent tabs/spaces). Or if they are style related, they should be to prevent easy to miss mistakes like the implicit string concatenation. That rule is technically style because it's valid Python.

Another style rule we should consider is warning for unused imports/variables.

Users would be able to add the other rules if they wanted to enforce something like mandatory pep8 naming conventions. We shouldn't enforce those on everyone by default unless we feel that strongly about it.

mattrunyon commented 5 months ago

I've been looking at the ruff rules https://docs.astral.sh/ruff/rules

I think we should enable

Maybe enable, but might not be very useful. I need a Python person to provide more insight

Probably should not enable, but individual users might want to use these

mattrunyon commented 5 months ago

Formatter settings we should leave as default I think with the following exceptions

dsmmcken commented 5 months ago

The default is ["E", "F"] which encompasses all the E and F rules, I would propose we only add rules to those, not remove any.

mattrunyon commented 5 months ago

Many of the E rules outside 1xx/2xx/9xx are more stylistic to me. If @jnumainville wants to chime in I'd like his thoughts on the other E rules.

Also, the default is ["E4", "E7", "E9", "F"]. I don't think E4 and E7 (4xx and 7xx) are actual problems with code

jnumainville commented 5 months ago

To address some specific points - On one hand E731 is certainly one I don't think we'd want considering the usefulness of lambdas in React style code. On the other hand: E402 could be a code problem if you've accidentally imported something after the fact. E721 is one that could be a problem if you're subclassing. E722 could definitely be a code problem by swallowing up exceptions that you shouldn't.

More broadly though, the E rules are PEP8 - these are rules that most people are going to be used to and reasonably expect. I don't think it's unreasonable to have those in a basic rule set, even though some are stylistic choices. Or at least E4 and E7 (besides E731) are reasonable. Seems like E1, E2, E3 rules are unstable? E3 are ones I wouldn't argue as being important.

devinrsmith commented 5 months ago

Are we planning to provide an easy way to turn off formatting and turn off linting (likely, two different settings)?

devinrsmith commented 5 months ago

I think @jmao-denver and @chipkent should take a look specifically. I'm hoping that the settings we choose to use for web UI can be adopted by deephaven-core python development, ala https://github.com/deephaven/deephaven-core/issues/3638

mattrunyon commented 5 months ago

Yes they will be toggles either in the notebook settings (like mini-map) or the user settings (like shortcuts).

Linting config will be user customizable. Formatting has a few options as well, but I think it's only indent size and single/double quotes for strings.

For aligning w/ deephaven-core Python development, the web UI might be a subset of the rules you want there. There are some rules that are more preference/style that we might want in deephaven-core, but not necessarily applied to all users of DH

chipkent commented 5 months ago

DM me if you want me to dig in beyond the list you have.

mattrunyon commented 5 months ago

@chipkent just to clarify the rules list I proposed was for the web UI to show to users in notebooks/terminal. I think most of what you added would probably not be annoying to users, but pep8-naming might be something we leave up to users to add if they want it. Or we can enable it by default and users can disable if they don't care about it. Just depends on what we want the default experience to be in the web UI.

We can also set some rules to warning (yellow squiggly underline) and others to error (red squiggly underline). That would be up to us to determine the defaults as ruff does not assign any default levels to rules.

If we're adding linting rules to deephaven-core then we can definitely be as opinionated as we want and should add things like pep8-naming.

The required imports rule is something you can customize. I think by default it does nothing when on because you have to configure a list of required imports. https://docs.astral.sh/ruff/settings/#lint_isort_required-imports

chipkent commented 5 months ago

I see. My bad. Let me reasses the list with that in mind.

DM me if you want me to dig in beyond the list you have.

mattrunyon commented 5 months ago

I002 we don't need. It lets you configure a list of imports that must occur in every file. So you could require every file do from __future__ import typings or import deephaven.special_sauce if that were required for every file

jmao-denver commented 5 months ago

I am in agreement with @chipkent's preference. During my discussion with @mattrunyon , I raised the issue of Python version compliance/compatibility check, it seems that that's currently not available with Ruff and the rulesets. But one can argue that it is more important to DH than to the users.

mofojed commented 5 months ago

Will add to a feature branch first, starting with this PR #2043

mofojed commented 3 months ago

@rbasralian would like to make sure there is an option to disable/enable auto format on save.