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

Pyupgrade: Printf string formatting #1803

Merged
merged 77 commits into from
Jan 21, 2023
Merged

Pyupgrade: Printf string formatting #1803

merged 77 commits into from
Jan 21, 2023

Conversation

colin99d
Copy link
Contributor

@colin99d colin99d commented Jan 12, 2023

A part of #827. This one is complicated so it will take me some more time.

Please Note: I purposely did NOT implement the --keep-percent-format flag because it looks like the last flag I added was removed. If you want this flag in, just let me know.

Note: the issue of the /N{dog} format will plague us in UP030 and UP032. Whatever solution we find here needs to be applied in both of those places. Right now I am just thinking of looking for it, and if it exists, only showing a warning but not attempting top fix. I have NEVER seen this syntax in practice, and I think it is reasonable to give the people using it a warning, but don't fix.

@colin99d
Copy link
Contributor Author

colin99d commented Jan 14, 2023

@charliermarsh I have hit a blocker and I would love some assistance. Pyupgrade uses the regex "(?<!\)(?:\\)*(\N{[^}]+})" to get an outcome like below:
Screenshot 2023-01-13 at 8 41 24 PM

We cannot use this regex in rust, because the regex uses look behinds, which are not implemented in rust. I tried taking the post's advice and reimplementing the regex without look behinds, "^\*(\N{[^}]+})", but then the character before is included in the string, which causes the program to break:
Screenshot 2023-01-13 at 8 44 51 PM
This SO post seems to indicate that there is NOT a way to accomplish what I am looking to do.

After this I tried using the fancy_regex create; however, they do not implement the split method which is required. With this I am unsure of what to do next. We could check for my ugly regex, and just ignore those (or report them as issues but not fix them). But that really bothers the perfectionist in me. Let me know how you think we should handle this.

If we do go the ignore/only report a check route I believe this is the regex we should use: "(?:\\)*(\N{[^}]+})"

@charliermarsh
Copy link
Member

Why do we need / why does the regex exist? Is it to avoid treating named unicode characters as {}-style formatting placeholders?

@colin99d
Copy link
Contributor Author

I know its for statements like these: "%s \N{snowman}" % (a,), because they are currently causing issues in my code. However, I am not sure the specific reason they are needed.

@colin99d
Copy link
Contributor Author

colin99d commented Jan 14, 2023

It looks like it exists so that "%s \N{snowman}" % (a,) does not turn into "%s \N{{snowman}}" % (a,). If this happens we get the following error in python:
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 3-14: unknown Unicode character name

But we DO need to convert "brace {} %s" % (1,) => "brace {{}} {}".format(1)

@charliermarsh
Copy link
Member

Is there a way that we could run the regex, extract the match, then run a second regex over the match to get a more precise range?

@colin99d
Copy link
Contributor Author

colin99d commented Jan 14, 2023

Is there a way that we could run the regex, extract the match, then run a second regex over the match to get a more precise range?

Right now the regex I have developed that is the closest is "[^\\](?:\\\\)*(\\N\{[^}]+\})". It has two issues:

  1. It grabs one character before the match starts (this could in theory be fixed by your solution)
  2. It would never match: \N{snowman}" % (a,) because there is no character before the strong (we can't make it optional because then it would lose all effect), I am not sure how to overcome this shortcoming

Additionally, I am not sure if we could use this "double regex" with methods like split. I have been trying to think of other ways we could do this. I am sure we could do something with tokens, but not sure how we could turn this back into a string simply.

Basically all we need to confirm is that there is an odd number of \ before a N{something}

@charliermarsh
Copy link
Member

Okay thanks. Just LMK when it's ready. I'll point to the updated RustPython branch and get it into a finished state, hopefully.

@charliermarsh
Copy link
Member

charliermarsh commented Jan 20, 2023

And yeah -- I think we map %.f to {:.0f}. Same with %.s to {:.0} etc.

@colin99d
Copy link
Contributor Author

@charliermarsh I am ready for you. Running cargo test printf_string_formatting currently results in two failures. Both are related to the precision issue.

@charliermarsh
Copy link
Member

Working my way through this one, found at least one bug but I think it might be in our logic and not the parser.

@charliermarsh
Copy link
Member

@colin99d - Ok, I think this is passing all tests now. I can think of a few ways that it could be improved so I might iterate on it a bit more. (For example: it'd be nice if we could avoid transforms that create really long string format calls.) It's a really significant transform, so I want it to be rock-solid before it goes out.

@colin99d
Copy link
Contributor Author

colin99d commented Jan 21, 2023

One thing I did in another check, is that if the new string is longer I would not do the change. But sounds good! Thanks for helping me out on this. It was definitely a lot trickier than I thought it would be.

@charliermarsh
Copy link
Member

I guess I'm also thinking about whether we should be fixing multi-line strings.

@colin99d
Copy link
Contributor Author

I can see it either way. Pyupgrade did NOT fix the strings that you sent me earlier that broke.

@charliermarsh
Copy link
Member

charliermarsh commented Jan 21, 2023

Alright, I'm gonna merge this as soon as RustPython/RustPython#4463 is merged.

@charliermarsh charliermarsh merged commit 80295f3 into astral-sh:main Jan 21, 2023
renovate bot added a commit to ixm-one/pytest-cmake-presets that referenced this pull request Jan 21, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [ruff](https://togithub.com/charliermarsh/ruff) | `^0.0.228` ->
`^0.0.229` |
[![age](https://badges.renovateapi.com/packages/pypi/ruff/0.0.229/age-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://badges.renovateapi.com/packages/pypi/ruff/0.0.229/adoption-slim)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://badges.renovateapi.com/packages/pypi/ruff/0.0.229/compatibility-slim/0.0.228)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://badges.renovateapi.com/packages/pypi/ruff/0.0.229/confidence-slim/0.0.228)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>charliermarsh/ruff</summary>

###
[`v0.0.229`](https://togithub.com/charliermarsh/ruff/releases/tag/v0.0.229)

[Compare
Source](https://togithub.com/charliermarsh/ruff/compare/v0.0.228...v0.0.229)

##### What's Changed

- README: `--force-exclude` is already set by
[@&#8203;hugovk](https://togithub.com/hugovk) in
[astral-sh/ruff#2042
- Upgrade to toml v0.5.11 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#2040
- Add support for pycodestyle E101 by
[@&#8203;ericroberts](https://togithub.com/ericroberts) in
[astral-sh/ruff#2038
- \[`flake8-executable`] EXE003-005 by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#2023
- perf: Reduce allocations by
[@&#8203;Stranger6667](https://togithub.com/Stranger6667) in
[astral-sh/ruff#2045
- refactor: RuleOrigin, RuleCodePrefix and Rule::origin by
[@&#8203;not-my-profile](https://togithub.com/not-my-profile) in
[astral-sh/ruff#2029
- Add scaffolding for `flake8-type-checking` extension by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#2048
- De-duplicate SIM102 by [@&#8203;harupy](https://togithub.com/harupy)
in
[astral-sh/ruff#2050
- Fix S101 range to only highlight `assert` by
[@&#8203;harupy](https://togithub.com/harupy) in
[astral-sh/ruff#2052
- Avoid removing comments in RUF005 by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#2057
- Revert "Upgrade to toml v0.5.11" by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#2058
- Pyupgrade: Printf string formatting by
[@&#8203;colin99d](https://togithub.com/colin99d) in
[astral-sh/ruff#1803
- \[`flake8-builtins`] Add `builtins-ignorelist` Option by
[@&#8203;saadmk11](https://togithub.com/saadmk11) in
[astral-sh/ruff#2061
- feat: plugin scaffold for tryceratops with TRY300 by
[@&#8203;sbrugman](https://togithub.com/sbrugman) in
[astral-sh/ruff#2055
- Avoid flagging redefined imports as unused in same-scope by
[@&#8203;charliermarsh](https://togithub.com/charliermarsh) in
[astral-sh/ruff#2065

##### New Contributors

- [@&#8203;hugovk](https://togithub.com/hugovk) made their first
contribution in
[astral-sh/ruff#2042
- [@&#8203;ericroberts](https://togithub.com/ericroberts) made their
first contribution in
[astral-sh/ruff#2038
- [@&#8203;sbrugman](https://togithub.com/sbrugman) made their first
contribution in
[astral-sh/ruff#2023

**Full Changelog**:
astral-sh/ruff@v0.0.228...v0.0.229

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://app.renovatebot.com/dashboard#github/ixm-one/pytest-cmake-presets).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC4xMDguMSIsInVwZGF0ZWRJblZlciI6IjM0LjEwOC4xIn0=-->

Signed-off-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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.

None yet

3 participants