#black-formatter
1 messages · Page 8 of 1
Yep, that seems to be the case. There is an open issue for it https://github.com/executablebooks/MyST-Parser/issues/760 as well as a stalled PR fixing it https://github.com/executablebooks/MyST-Parser/pull/929. There is one workaround listed, which is using explicit HTML, which sucks but does work for me locally <a href="https://ichard26.github.io/next-pr-number/?owner=psf&name=black">Next PR Number</a>
Thanks for looking into that, feel free to make a PR to Black with the workaround for now
Should I make it as a standalone PR, or include it with the rest of the changes I'm making to the contributing basics page?
If you're making other changes to that page, feel free to bundle it in
Description
This PR contains some small improvements to the basics about contributing that I would have liked when making my first PR.
There are also a few small changes to make formatting more consistent/add clarity/make it flow better.
This also implements a workaround for a bug in MyST-Parser causing the Next PR Number query params to be rejected.
I'm not sure why in one part of the documentation it has (.venv)$ pip install -e ".[d]" while in another `(.venv)$ pip ins...
docs don't work out-of-the-box in current state
Description
docs
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
53a2190 Note required python version for use_pyproject:... - Mattwmaster58
It looks like whenever a new commit is merged to the main repo I get a diff-shades-comment workflow run failed for main branch notification, should I keep my PR branches synced to main even if the merged changes don't effect them, or just leave them be?
fine to leave them be
While writing a comment on #4494 that I found while trying to fix #4495, I came across a question I couldn't find the answer to. Does black give any guarentees about formatting invalid code? If this was said somewhere in the docs, I didn't see it. If it isn't, it would probably be a good thing to add. The thing in question is that black still formats code with invalid f-strings in them pre-3.11, even though they are invalid when run, ie f"{'"'}". This is also an issue for any future f-string formatting things since for normalizing quote styles, what's possible is different between pre-3.12 and 3.12+.
It doesn't. Black should run on any valid Python code, but if it parses some invalid code, that's fine
If you look closely you'll find we still format some Python 2-only syntax 🙂
For the f-string situation, one thing to be careful about is to make it so that if the user's code still supports 3.11 or earlier, we don't format to a state that is valid only in 3.12+
While trying to be exhaustive when re-writing the visible equals detection, I have found that f-strings are so much more cursed than I could have ever imagined. For example, this: "" f'{1:{""=}}'. And given stuff like this is also possible 3.12+ f'{1:{'{''=}'=}}' I'm not seeing how a single non-recursive regex could handle this. From how it looks to me it basically has to be a full f-string parser.
we do have that already, right?
we produce a full parse tree, we just don't format it right now
strange thing with pre-commit-uv. in the CPython repo with macOS, first update Black to 24.10.0:
pre-commit autoupdate --repo https://github.com/psf/black-pre-commit-mirror
then install pre-commit-uv (with Python 3.13.0) and run:
pre-commit run --all-files black
and it shows:
Python 3.12.5 has a memory safety issue that can cause Black's AST safety checks to fail. Please upgrade to Python 3.12.6 or downgrade to Python 3.12.4
if I uninstall pre-commit-uv, it works okay. we do have language_version: python3.12 in the config, but I don't know where 3.12.5 is coming from. uv python list --only-installed tells me I have 3.12.7, which corresponds to my python3.12...
I think so, the business about list[Leaf], right? Are f-strings actually parsed different from strings at wherever trans.py takes place? Since most of the code I've been looking at in trans.py only interacts with the Leaf.value and manipulates it as a string, or does a Leaf.type == token.STRING.
not sure exactly, I think trans.py mostly predates f-string parsing
I don't know where you get 3.12.5 from but the check in Black looks correct: https://github.com/psf/black/blob/53a219056d1ab092ee2d4e5181c55c2e58c4756c/src/black/__init__.py#L547
src/black/__init__.py line 547
if sys.version_info[:3] == (3, 12, 5):```
yep, Black is fine. it's because uv is picking 3.12.5:
$ rm -rf .venv && uv venv -p python3.12 -v
DEBUG uv 0.4.27 (36b729e92 2024-10-25)
DEBUG Searching for Python 3.12 in managed installations or system path
DEBUG Searching for managed installations at `/Users/hugo/.local/share/uv/python`
DEBUG Found managed installation `cpython-3.12.5-macos-aarch64-none`
DEBUG Found `cpython-3.12.5-macos-aarch64-none` at `/Users/hugo/.local/share/uv/python/cpython-3.12.5-macos-aarch64-none/bin/python3` (managed installations)
Using CPython 3.12.5
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
uv python list --only-installed does in fact list both 3.12.5 and 3.12.7. I'm guessing I used uv to install a 3.12 in September when I was playing the new thing and it's been sitting dormant ready to strike: seems uv venv will prefer its own "managed installations", even if it's an older version than the one on my PATH
Describe the bug
When running the test suite on a machine with high nproc (i.e. large number of CPUs/cores — we have 80 on arm64 and 256 on sparc), the test suite suddenly runs out of fds in middle of testing tests/test_blackd.py. The remaining blackd tests fail, then pytest hangs when it's supposed to exit.
To Reproduce
- Errr, get a system with high
nproc… (perhaps some mocking will work?) tox -e py312-ci(xdist in non-CI jobs works around the problem)
**Expec...
just want to say i fucking love using the black formatter. keep up the good work
Hello,
I'd like your opinion on black's handling of the following case and what I think would be preferable
# Original
A = func([fooooooooooooooooooooooooooooooooooooooo for bar in baaaaaaaaaaaaaaaaaaaaaaaaaaaaaz])
# Current black
A = func(
[
fooooooooooooooooooooooooooooooooooooooo
for bar in baaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
]
)
# Preferred
A = func([
fooooooooooooooooooooooooooooooooooooooo
for bar in baaaaaaaaaaaaaaaaaaaaaaaaa...
@dense jungle I've done the changes for the reviews you left on my PR, but I'm stuck on getting the code to format. The contributing docs say
# Format Black itself
(.venv) $tox -e run_self
But that just gives me the
Oh no! 💥 💔 💥
1 file would be reformatted, 63 files would be left unchanged.
message.
Is there some way to get it to actually do the formatting, instead of just saying it would reformat?
I guess I'd do pip install -e . and then run black src/
or temporarily edit the tox command so it doesn't --check
@dense jungle New commits are up.
Also question: If I want to open an issue about the tests in the repo, what category should I do it under? Since it's more of a meta issue on the repo itself, it doesn't quite fit any of the existing issue categories.
/ should I open an issue at all? The main thing I want is with the test organization, since currently it is very painful to parse the output from a single test, or edit a test, and that is something I think I could tackle if it's wanted.
feel free to open an issue! don't worry too much about the category, we can adjust labels later
I think there's some "internals" label I can apply
Part of #2238
While working on my first PR to the repo, I've noticed that interacting with the test cases is not easy.
This is because of how much is in each file, with the longest being ~1200 lines long. Because it's a test that uses # output, the input and output for a specific case are ~600 lines apart. This is made worse by the fact that formatting changes line counts, so getting back to the source isn't as easy as dividing the line number by 2. Running the test case also doesn't help...
This is not the right channel/server. This server is for python related things, not PHP. Additionally, this channel is for discussing the Black formatter for python. If you want to give help on PHP, I would suggest finding PHP specific servers, instead of this one.
[psf/black] Issue opened: #4507 Re-condensation / Simplification Of Code After Line Length Reduction
Generally i've come to really love the black formatter, so first off thanks for that!
There is really only one thing I dont like about it which is that if the length of a line is reduced such that it could be put simply on one line, the nested format remains and leaves sometimes goofy looking artifacts.
I believe the black formatter would be better off it attempted to (perhaps via option) to first eliminate any line nesting or extra space then performed a format.
Example - a list com...
Is this related to a problem? Please describe.
Describe the solution you'd like
Describe alternatives you've considered
Additional context
import random
import re
import time
import string
import sys
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from PyQt5.QtCore import QThread, pyqtSignal, QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QSpinBox, QLabel
from selenium.webdriver.support import expected_conditions as EC
import re
import sys
import...
https://github.com/psf/black/issues/236 is unreproducable on stable
Describe the bug
There is a clash between the process of reflowing multi-line strings and the rule that prevents formatting lines with # type: ignore pragma at the end. Here is what happens:
- A multi-line string gets first merged into a single-line string which can be arbitrarily long.
- Because of the pragma comment at the end of the line, the line is considered unsafe to split. Hence the final result is a single huge line.
To Reproduce
Here is a simple exam...
I am using VsCode on windows but black formatter is not working correctly
also having trouble with jinja template.
They are formatting incorrectly when I save the code.
How to do that?
Can anybody help me with this?
I tried to follow the guide of black formatter
It would be helpful if you can be specific about what you mean by “is not working correctly”. What are you expecting to happen, and what is happening instead that you don’t expect?
Describe the bug
If there is a f-string (single-line or multi-line) following a # fmt: off (with or without a pairing # fmt: on) and both the f-string and # fmt: off are inside a pair of brackets ((), [], {}), the code cannot be formatted.
The error reported is something like:
error: cannot format ???.py: {' ', 'r', 'f', 'o', ':', 'm', 't', '#', '\n'} is NOT a subset of {'U', 'r', 'f', 'u', 'F', 'R', 'b', 'B'}.
To Reproduce
Sample:
Thanks, this looks reasonable
One nit: could you move the logic down next to https://github.com/psf/black/blob/c98fc0c128e1a79a776b62046acaa28685a31089/src/black/lines.py#L674-L680 and also add a test case for when imports are within a function?
efd9778 Bump myst-parser from 3.0.1 to 4.0.0 in /docs (... - dependabot[bot]
5689626 Bump docutils from 0.20.1 to 0.21.2 in /docs (#... - dependabot[bot]
Github is breaking older upload-artifact in a few weeks
I found this while messing around with #4511
(
# fmt: skip
"""
"""
)
gives
Cannot parse: 2:0: EOF in multi-line string
[playground link](https://black.vercel.app/?version=stable&state...
<@&831776746206265384> spam account
!cban 696770552593121440 Ad spam
:incoming_envelope: :ok_hand: applied ban to @worthy mica permanently.
Perfect
Black https://github.com/psf/black/commit/c47255
Options
--line-length=88
--safe
Input
x = [
t
for t in y
if t n...
Describe the bug
Using # fmt: skip at the end of a line or # fmt: on/off for that matter does not change the output of black errors.
To Reproduce
python=3.11
pip install black=24.10.0
try:
import {{cookiecutter.repo_name}} # fmt: skip
except:
raise ImportError("The package, {{cookiecutter.repo_name}}, has not been installed.") # fmt: skip
And run it with these arguments:
$ black --line-length=120 conf.py
The re...
The problem
I'm always frustrated when formatting for a long if statement that involved in. So the if statement shall break with the "and", "or" keyword normally. However, if it is like a "key" in [array_item1, array_item2... ], it will break from the list and create a inconsistent layout with other if.
please think of every variable is with very long name
if a=b and c=d:
normally change to
if (
a=b
and c=d
):
but
if a=b and c in [d, e, f]:
it will change t...
Description
Updated the python version in the documentation in accordance with README.md a file, so as not to confuse users.
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
def set_collections_basedir(basedir: Path) -> None:
AnsibleCollectionConfig.playbook_paths = ( # this is a very long comment that is quite long
str(basedir.resolve()))
Based on https://github.com/psf/black/issues/4481#issuecomment-2498142196
Describe the bug
black hangs (or takes an extremely long time?) to process a file with a multiline f-string containing a bunch of escaped quotation marks.
To Reproduce
Run black against this file:
def testing():
somevar = "some value"
return f"""
{somevar} the following line causes the issue:
\" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \" \...
I used pdb to find the cause of this, very cool to have a debugger built in. Might have been faster to open black in pycharm and use it's debugger, but my computer may have also exploded
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
hi,
should i be able to install black with pipenv install git+https://github.com/psf/black#egg=black?
i ask because when i try to use it, i get TypeError: unhashable type: 'list'
(full log in pastebin: https://paste.pythondiscord.com/UETA)
a repo that shows what i've tried: https://github.com/keepitsimpledev/python-exploration/tree/add-pipenv-then-black
update: the above issue occurs in windows/gitbash. i tried it again in WSL/ubuntu and no issues ¯_(ツ)_/¯
i suppose that solves it enough for me, but i'll leave this up for anyone interested in the future
I tried to add black to a CI job on GitLab. The problem is that when I run it locally, it says that 11 files would need to be modified, but on the CI job it says there are 88 such files. Why do two instances of black behave so different? If I cannot easily fix the files on my local computer to match the expectations on the CI machine, than the CI job becomes useless.
I checked and both versions are 24.10.0. The version of Python is slightly different (3.10 vs. 3.11), and OS is different as well.
Interesting, Convert is Convert = Callable[[Grammar, RawNode], Union[Node, Leaf]] so I guess the list in there is somehow getting hashed. Any idea what version of Python that was running?
You are likely running different versions than you think you are running, or using a different configuration for Black
On my local machine I get
$ black --version
black, 24.10.0 (compiled: yes)
Python (CPython) 3.11.2
The CI job says
Downloading black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl (1.8 MB)
How do I verify what configuration I'm using? I did not configure black in any way.
Run black -v
That does not work:
$ black -v
Usage: black [OPTIONS] SRC ...
One of 'SRC' or 'code' is required.
But black --version on CI says
$ black --version
black, 24.10.0 (compiled: yes)
Python (CPython) 3.10.15
I think the mystery was solved: black and isort were changing each other's result inside CI.
I found a configuration option to fix that.
Thanks, just some wordsmithing
e54f86b Two blank lines after an import should be reduc... - kastkeepitjumpinlikekangaroos
3fab5ad Prevent f-string merge quote changes with neste... - MeGaGiGaGon
Refer to #4042 for 2024, #3407 for 2023, #4501 for some previous discussion
It's almost 2025, time to decide what Black's stable style will look like for next year. Any comments are welcome to help decide whether we should stabilize these changes.
My expectation is that we'll stabilize all of the features currently in the preview style, but not those in the unstable style. Here are the current preview rules, sorted in my estimate of most to least controversial:
hex_codes_in_unicod...
Was comfily reading this in bed, but had to get out of bed to test, and now open an issue in both black and ruff about the hex code case replacement
I had this idea while reading #4522. This probably shouldn't block hex_codes_in_unicode_sequences from being stabilized since it is an edge case, but would be nice to have.
playground link Currently, f"{'\xFF'}" does not get formatted....
fixing the swapping of words in index.md
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Adding more efficien security.md file to enhance the user interaction.
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
hey guyss
im new here and would love to work with u all
can someone brief about it to me once..?
This is the wrong channel for general python help, you should either ask in #python-discussion or open a post in #1035199133436354600
I would also recommend not asking people to write/improve your code for you. You'll get better results if you ask for help on specific problems you are having, and with the mindset of learning, not getting your issues magically solved. Also see the guide to asking good questions
A guide for how to ask good questions in our community.
If you'd like to help improve the black formatter, you can read the contributing guide. If you are referring to something besides the black formatter, then this is the wrong channel.
I just noticed you opened a few PRs in the past. I have a few suggestions for you:
- Spell check/grammar check your posts. Posts that are easier to read will get more responses, and a better reception. This doesn't mean they have to be perfect, but PRs/issues that have a lot of spelling/grammar errors generally indicate the post is low quality.
- Ensure your change is a meaningful improvement. This means fixing something quantifiable, ie an open issue, documentation errors, etc.
- Give as much context as possible. Include things like the rationale behind your changes, the history of the issue, alternate considerations, etc.
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
@dense jungle I've been going back through old issues and have found a few that have been fixed, but I can't do anything besides say "this was fixed at some point". Would you like me to give a list of the issues I've found so far and/or ping you in the "this was fixed at some point" message?
It's fine to just post on the issue, I will close them when I see the GitHub notif. It may also be helpful to send PRs adding test cases to show that the issue is indeed fixed
And thanks for doing this!
Do you have a recommended way to go about that? I have two concerns:
- Test organization improvements #4506 hasn't reached a conclusion yet, so any new tests I add now will be more work in the future for whoever splits out the tests, and adding the tests in the first place is a big pain
- Since these are unlinked issues, I don't know what PR fixed them, so I can't easily minimize them. I don't think I ever mentioned it on 4506, but I'd also like to minimize the tests, since currently a lot of them are very verbose, which makes changing them in the event of intentional breakage more difficult. If I am going to go through all the tests, I figure I might as well minimize them while I'm there to make future things easier.
I'd just stick with the current system of the tests. I'm not convinced the tests should be organized in a different way. As for adding tests for open issues, hopefully most will have a fairly minimized test case already in the issue. The test doesn't necessarily need to be the most minimized; the test is there to verify that the code that previously broke Black no longer breaks Black.
Ok, sounds reasonable. Then I guess the next question would be do I make a new file in cases for them, or put them into whichever case I feel they most match?
Also with #970 specifically, is there anything special I should do with it? My main concerns is that a solo \r usually doesn't play well with most editors, vscode turns it into a \n or \r\n, and I know git messes around with \n depending on the local user settings, so if it was set up like the normal cases it would be very easy to get accidentally messed up.
I'd put it in an existing file if there's a good match and the file isn't too big, a new file otherwise. Don't worry too much about which of the two options to pick, either is fine.
The \r case might be better with a test in test_black.py that passes that string to the parser directly, instead of a test case file handled by test_format
Ok. Then the last question should I make all of these separate PRs, or one big PR?
Separate
They won't need changelog entries, I'll add skip news when you make the PR
It looks like #2248 was fixed at some point, probably as part of the 2024 release. This adds an anti-regression test for, and closes #2248.
It looks like #1765 was fixed at some point. This adds an anti-regression test for, and closes #1765.
This adds the line *.py text diff=python to .gitattributes. I'm not 100% certain on all the effects this has, but it makes function name based finding git commands options like git log -L :: or git blame -L : work out of the box, which is a nice convenience.
:<test>
Huh, I wonder why the bot formats git log -L :<function_name>:<file_path> into git log -L ::
Hello, is there a way to configure the SRC from black's usage in my pyproject.toml rather than specifying it in the command ?
Do you mean the file/directory black is run on? No, you always have to pass in at least one file/directory to be formatted. You can modify which files black finds while it recursively searches, but you still have to specify at least one.
Ok, I thought perhaps there was a way to make it a parameter in configuration file like other tools. Thank you for the answer ! 👍
One other option is avoiding running the command entirely, ie using your ide to run black, or setting up a hook for it. See the integrations section for more details.
Actually that's for tox integration + git hook. But I'm finding specifying such arguments through configuration more elegant imho. But I've simply added SRC in the tox commands in the end.
Describe the style change
We had a SEV happening inside of Meta because somebody forgot a , in a list declaration. So what happened is that python considered the two strings next to each other a string concatenation instead of raising an exception.
Examples in the current Black style
x = [
"SuperLongStringSuperLongStringSuperLongString",
"SuperLongStringSuperLongStringSuperLongString" # missing ,
"SuperLongStringSuperLongStringSuperLongStri...
Description
Added some additional clarification and example to the "Global" configuration file documentation.
I had some trouble when I was trying to do this myself because I misunderstood what was being said in this section. (Had thought you needed to make a .toml file inside a directory called black...)
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
Is your feature request related to a problem? Please describe.
I have noticed that when writing functions with generics, black splits the generics into more space. This is frustrating, as it makes it harder to read. Also, I feel it goes against black's philosophy, as black always tries to minimise space whenever possible.
For example, instead of writing a function like:
def foo[TypeA](
input_a: TypeA,
input_b: TypeA,
input_c,
input_d,
input_e,
...
Describe the bug
Hi, # fmt: skip doesn't skip the formatting in this code:
def foo(): return "mock" # fmt: skip
$ black foo.py; cat foo.py
Output:
def foo():
return "mock" # fmt: skip
Similar case in the [playground](https://black.vercel.app/?version=stable&state=_Td6WFoAAATm1rRGAgAhARYAAAB0L-Wj4AEpAJNdAD2IimZxl1N_WlXnON2nzN36C8EDS2OdozrF3A8N-yRxMzveJgvGD0d8QKTaox5vY_DvNkC0MxTYAIJP6wYvhPX_6e8_eA8axqa4Y00iUpSPgGJNJ0BXC0...
Description
Replaces black's tokenizer with a from-scratch rewrite.
Should help resolve problems like #4520 and others.
What's left
ERRORTOKENhandling is not very proper just yet, it'll require some tweaks.- Edge case tests: Currently 366/381 tests are passing.
is it just me or is diff-shades broken
src/blib2to3/pgen2/pgen.py:360: error: Argument 2 to "SyntaxError" has incompatible type "tuple[str | PathLike[str], int, int, str]"; expected "tuple[str | None, int | None, int | None, str | None]" [arg-type]
same error on the build workflow
Description
Fixes a type error introduced in https://github.com/python/typeshed/pull/13141
As mentioned in that PR, it is a legitimate bug, however self.filename is never not a string at runtime
Regardless, the type error is currently causing CI to fail and needs to be resolved
Checklist - did you ...
- [N/A] Add an entry in
CHANGES.mdif necessary? - [N/A] Add / update tests if necessary?
- [N/A] Add new / update outdated documentation?
Description
This fixes #3678. The fix is done by adding two new functions to node.py, is_tuple_containing_star and is_generator, which are then added to the checks in maybe_make_parens_invisible_in_atom inside linegen.py, which is used by the function remove_with_parens that Jelle suggested modifying in a comment on #3678
Both functions are based on the existing is_tuple_containing_walrus. That makes me fairly confident in is_tuple_containing_star, since it d...
Description
This fixes #4232. This issue happening is different from what was stated. At least with the given bash script, black does correctly find and apply the settings from the pyproject.toml, the force exclude just doesn't get applied. This happens because the check for if formatting should be skipped when using stdin is constructed via
root_relative_path = best_effort_relative_path(path, root).as_posix()
root_relative_path = "/" + root_r...
Huh, I wonder why 3678 got closed twice in a row
commit with message fix #XXXX auto-closes the issue XXXX
i guess jelle made two such commits somehow, which closed the issue twice
One is because the PR description contains the "Fixes #3678" text, the other is because the commit also contained that text
That's what you see in @slow ibex's screenshot above
I haven't looked at black's CI in ages, but I wonder if you could make diff-shades faster by moving it onto an arm macOS runner. They're surprisingly fast, even faster than the Ubuntu runners: https://github.com/pypa/pip/actions/runs/12507249179?pr=13129
Although IIRC y'all adjusted diff-shades' parallelisation so it may not benefit as the arm macOS runners seem to have 3 cores.
Good tip! Although many projects are on the Free plan so get max 20 concurrent jobs for Ubuntu+Windows, but only 5 for macOS, so the speed difference might not matter too much for projects with large macOS matrices.
GitHub has upgraded the pypa org to Enterprise, with 500 and 50 max concurrent, respectively. But worth looking into!
Yes, ARM macOS have 3 cores, compared to 4 for the others (for public repos) https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories
Ah, I forgot about that, haha. I've gotten too used to our Enterprise plan :P
It's actually 1000 concurrent jobs / 50 concurrent macOS jobs
Describe the bug
is_fstring_start using builtin.any for prefix matching is too slow and slows down fstring tokenization.
def is_fstring_start(token: str) -> bool:
return builtins.any(token.startswith(prefix) for prefix in fstring_prefix) # using `any` with `` is too slow
To Reproduce
Run this minimal reproducing script:
import cProfile, pstats, io
from blib2to3.pgen2 import tokenize
profiler = cProfile.Profile()
example = io.StringIO(','...
Description
Fixes #4540.
Checklist - did you ...
- [X] Add an entry in
CHANGES.mdif necessary? - [X] Add / update tests if necessary?
- [X] Add new / update outdated documentation?
Description: This PR addresses an issue with the handling of type comments in Black. Previously, type comments with multiple spaces after # were not recognized correctly, and formatting could lead to unnecessary whitespace.
Changes:
Fixed the handling of type comments by normalizing whitespace after # and : (e.g., converting # type: str to # type: str).
The function now trims extra spaces and ensures consistent formatting for type comments.
Added a check for comments starting with type:...
Description:
This PR refactors the code to align with the feedback provided by @cobaltt7. Below are the key changes made:
Ensured Function Purity:
Refactored the function to ensure it remains pure by separating the modification logic into a different function.
The function now focuses solely on extracting the type annotation and avoids directly modifying any external state (e.g., leaf.value).
Integrated with Preview Style:
The modification logic has been moved to align with th...
..ok
Is there a way to stop block for multilining type vars
def toasycn[**P, R](fn: Callable[P, Generator[None, None, R]]) -> Callable[P, Coroutine[None, None, R]]:
...
it outputs
def toasycn[
**P, R
](fn: Callable[P, Generator[None, None, R]]) -> Callable[
P, Coroutine[None, None, R]
]: ...
I want it to output
def toasycn[**P, R](
fn: Callable[P, Generator[None, None, R]]
) -> Callable[P, Coroutine[None, None, R]:
...
and yes, I added a trailing comma to the arguments and this was the mess it generated
def toasycn[
**P, R
](
fn: Callable[P, Generator[None, None, R]],
) -> Callable[
P, Coroutine[None, None, R]
]: ...
This is a known issue, see https://github.com/psf/black/issues/4071
GitHub
Context: When a function has many parameters, it's more readable when on multiple lines, enforcing black to wrap lines adding a comma after the last parameter. See https://black.readthedocs.io/...
Unfortunately, I get this error only on AppVeyor and cannot reproduce it locally. It only happens under Python 3.13. According to their documentation, they recently switched from a release candidate to 3.13.1. I waited for this switch before filing this issue, but the problem remains.
Here is the complete traceback:
Traceback (most recent call last):
File "C:\projects\hydpy-hep1s\prepare_...
Added information about PyInstaller Binaries. This is my first contribution for learning purpose.
While working on a different issue, I of course stumbled across a rabbit-hole: ```ps
(.venv) PS C:...\black>py -c "'''rar''';print(repr(doc))"
'\na\n'
(.venv) PS C:...\black>black -c "'''rar''';print(repr(doc))" | py -
'a'
This comes from `is_multiline_string` in `nodes.py`, which does `return has_triple_quotes(leaf.value) and "\n" in leaf.value`. I'm not sure if this is an actual issue, since black's support for files that use just `\r` seems... tenuous at best. There are also a bunch more places that make this same assumption of a lone `\r` not existing.
Description
I noticed these two things while looking through the coverage reports.
For the first change to fix_docstring, the only use I could find of it is behind a call to is_multiline_string. Since is_multiline_string is false if the string is empty, fix_docstring could never receive an empty string as an argument. I didn't closely analyze what fix_docstring does to see if it breaks if passed a single line string, but given how it is used I decided the easier fi...
Also this is a way to get the \r issue, so I was wrong :( ```ps
(.venv) PS C:...\black>black -c "{`r}"
}
error: cannot format <string>: Cannot parse for target version Python 3.9: 1:1: {
I wonder if something should be added to the docs for `-c` saying like "lone `\r` may or may not work, no guarantees". I wonder if this miss-match would be fixed by the pytokens re-write.
black 24.10.0 formats this:
type AttachmentTuple = tuple[str, str | bytes] | tuple[str | None, str | bytes, str] | tuple[str, str | bytes, None]
Into this: (playground)
type AttachmentTuple = tuple[str, str | bytes] | tuple[
str | None, str | bytes, str
] | tuple[str, str | bytes, None]
I think this is much more readable, which I can get by adding the parenthesis manually:
type AttachmentTuple = (
tuple[str, str | bytes]
| tuple[str | None, str | bytes, str]
| tuple[str, str | bytes, None]
)
Is this the same issue as #4071, or should I open a new issue? In that issue, black is also eager to split the contents of [] across multiple lines instead of breaking the line at a point higher up in the AST.
This is probably a different issue, since the issue still happens with []->(), and goes away if you remove the type, so it's probably the type alias that is the issue. I did a quick search and couldn't find an open issue that looks like this.
40b73f2 [pre-commit.ci] pre-commit autoupdate (#4547) - pre-commit-ci[bot]
- Company is not meta anymore and not a primary user anymore
Hello! Thanks for submitting a PR. To help make things go a bit more
smoothly we would appreciate it if you could go through this template.
Description
Good things to put here include: reasoning for the change (please link
any relevant issues!), any noteworthy (or hacky) choices to be aware of,
or what the problem resolved here looked like ... we won't mind a ranty
story :)
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessa...
I don't know how anyone manages to run a big OSS project, even just reading all these PRs is driving me insane.
I'm specifically talking about #4542 #4543 #4545 and #4549. Like... do people not read anymore? Especially #4549, they commented on #4545, but seem to have not bothered reading the several paragraphs of advice I gave to the other person. >:(
We pray for lots of helpful people like you 🙂
please don’t burn yourself out.
All you can do is try … everyone is donating time. So I like to remember to be thankful for that 🙂
FWIW … people don’t read for their job where they are paid to be a “professional” 🤪
They strike me as either CS students or recent CS grads who are looking for a way to boost their profile / dip their feet into the OSS world without really thinking it through.
IMO, I'd just close the PR saying that this looks AI generated and we can't accept it as it wholly misses the mark. I doubt they put much effort into the PR, you can simply return that lack of effort in your response /shrug.
You can be nice, but keep it concise and terse.
I probably would do that, but I'm not a collaborator/maintainer so I'm limited to polite but sternly worded comments :)
Also profile looks really sus for some reason
Somehow remembers me of north korean Cyberspies, but i'm not saying that it is
Describe the bug
I just installed into my PC (Ubuntu 24.01). It fails to load in the VsCode extension. When I run manually it is working.
To Reproduce
The resulting error is:
2025-01-10 11:39:29.096 [info] Global settings (client side): {
"cwd": "/home/nerve",
"workspace": "/home/nerve",
"args": [
"--line-length=240"
],
"path": [
"/usr/local/bin/black"
],
"interpreter": [],
"importStrategy": "useBundled"...
Your patience in dealing with these is commendable, thank you
I just closed a couple of the worst ones
I was very tired that night so I couldn’t stop myself from going on a mini rant
Btw. thanks for the response. I would like to, but haven't gotten around to creating an issue. Will do at some point, unless someone beats me to it.
I believe https://github.com/psf/black/pull/4377 is finally ready for review now.
I probably would do that, but I'm not a collaborator/maintainer so I'm limited to polite but sternly worded comments 🙂
انا زهقت والله خلااااص حد ادمن يوثقني
اقصد يعني يعطيني رتبة اعرف اتكلم صوتي
عشان تعبتخ
تعبتتت
Hello, we only speak english here
ok
i speak english fifty fifty
i am from egybt
i need tell in voice
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Thanks! Let's wait with moving into the preview style until we get a 2025 stable release.
I submitted a separate PR to attempt to fix CI.
Going through old issues again, I came across https://github.com/psf/black/issues/236, the second oldest still open issue. The main complaint looks to have been fixed at some point, so I'd like to be able to say "it was fixed here, tests are here, closable". The issue I'm having is that I can't seem to do that. I looked through a good number of tests, but couldn't find one that had the exact structure from this issue. I tried to git bisect, but I couldn't get the first bisection commit from 2021 working. This also applies to a lot of other issues, where I'd like to bisect them to see when they got solved, but I either can't get black working from that far back, or running py src\black\__init__.py -c "code" never reproduces the issue. Does anyone else know of a way to run these older versions of black for bisection?
What goes wrong when you try to run these old versions? I'd expect it to work, maybe needs an older version of Python though
But if it's too much trouble, it's fine to just say that it works now, it doesn't matter that much exactly when it got fixed
With that one specifically, it first gave me a No module named 'regex' error, and after I re-ran the dependency install commands it gives ImportError: cannot import name '_unicodefun' from 'click'. With newer issues instead of errors, the problem just never happens, even if I check out black with a commit on the day the issue was made.
oh I think you need an older version of click, there was some weirdness with that. regex used to be a dependency, so yes you just need to install that
one principled way to do this could be to use the uv invocation that only installs dependencies older than some date, that should get you the right version of click
(don't remember the exact command)
I'm still very not good with anything CI, so no clue, I would need a lot of handholding. I did have a different idea though, which is I should be able to at least bisect using the release binaries to narrow the search scope
It's --exclude-newer!
At least for 236 my idea worked. It's funny that so far I've found 3 different issues that were fixed by 4010
Make that 4
Actually I'm not sure what to do with this. https://github.com/psf/black/issues/1187 The opening issue was fixed by 4010, but then as people commented it got turned from an issue with f(x=1 if y else 2) into running into issues with fluent-interface styles? to issues with what black does with inline comments. There still should be a test added for that original issue, but should the entire issue be closed?
Description
Fixes the handling of # fmt: skip in one-liner functions. (#4535).
The fix involves modifying the algorithm that determines which nodes to ignore in the _generate_ignored_nodes_from_fmt_skip function. Specifically, the adjustment applies to cases where the # fmt: skip comment is not on the colon line of an if, while, def, class, etc.
Previous Algorithm
The previous algorithm for selecting ignored nodes worked as follows:
- Add the *previo...
What's the progress on v25.1? Is there anything I could help with getting an alpha released soon?
I'll try to make some progress on it soon
Hello I am new member here trying to contribute my first open source, need the guidance.
Need the information about what this PROJECT is all about ? and how can I involve in there to contribute anything in my capacity ?
Can somebody explain or provide me document to review and study please.
https://black.readthedocs.io/en/stable/contributing/index.html the contributing docs are the best place to start for learning about contributing to black
For things to help on, any issue marked “good first issue” is a good place to start https://github.com/psf/black/labels/good first issue
Description
This PR addresses #4071 by improving how Black wraps function definitions that include generic type declarations.
Current Behavior
When a function with generic type declarations is formatted, Black prioritizes wrapping the generic type definitions, even in cases where splitting the arguments would result in a cleaner layout. For example:
Input:
def func[T](a: T, b: T,) -> T:
return a
Cur...
Describe the style change
When a "dot-chain" extends over the line length, black does different line breaks depending on a number of parameters that I don't fully understand, but I think include e.g.
- Whether elements of the chain have brackets (i.e. We are choosing an element from a list or a map)
- Whether the chain is standalone, or a function argument.
- Possibly the target python version
Simply breaking before or after the dot seems very sensible, but black sometimes does this, so...
Description
Docs CLI is now failing thanks to
The
sphinx.configurationkey is missing. This key is now required, see our blog post for more information.
It looks like black does the same thing as the .readthedocs.yaml example from that post, so I just copied it.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update...
I have a .py file which runs as notebook
# Databricks notebook source
!pip install -U dspy python-dotenv
!pip install torchmetrics
dbutils.library.restartPython()
# COMMAND ----------
from tqdm.notebook import tqdm
tqdm.pandas()
import logging
# COMMAND ----------
!pip install matplotlib seaborn
The above is python file which runs as notebook where each cell is defined by # COMMAND in databricks. When applying black formatting I want to skip the pip install related lines. I tried ...
Describe the style change
When creating class or function definitions within an if-else statement, Black currently enforces empty newlines above and below the definition so that things look more readable. This generally works perfectly, but in certain circumstances, it can create a very odd looking if-else clause. In my experience, this specifically happens when the definition appears in the last block, while no definitions appear in the preceding block or blocks.
**Examples in the cu...
Thanks for this PR, it's great!
I think the trailing comma handling isn't exactly right, see e.g. both_magic in the new test cases I pushed.
I guess this doesn't handle generic class defs, but that can be a separate PR :-)
Description
As part of my issue cleanups, this adds a regression test for the now fixed #1187, fixes #1187
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
And make that 5 issues I've found that 4010 fixed
You list other formatters like gofmt and yapf as keywords in https://github.com/psf/black/blob/main/pyproject.toml#L41-L49
Maybe add ruff?!
pyproject.toml lines 41 to 49
keywords = [
"automation",
"autopep8",
"formatter",
"gofmt",
"pyfmt",
"rustfmt",
"yapf",
]```
Fixes #4504, fixes #3251
99dbf30 Cache executor to avoid hitting open file limit... - hauntsaninja
Description
Moves wrap_long_dict_values_in_parens from the unstable to the preview style. Follows-up #4377, which closed both open issues about this feature (#3452 and #4158).
Checklist - did you ...
- [y] Add an entry in
CHANGES.mdif necessary? - [y] Add / update tests if necessary?
- [y] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
As the text calls out, this style is only relevant for 3.8 and older. We're not going to make any style changes that benefit only out-of-support versions of Python.
d330dee docs: We're not going to use backslashes for th... - JelleZijlstra
fun #21 1954.6 gcc: internal compiler error: Segmentation fault signal terminated program cc1 #21 1954.6 Please submit a full bug report, with preprocessed source (by using -freport-bug). #21 1954.6 See <file:///usr/share/doc/gcc-12/README.Bugs> for instructions. #21 1954.6 error: command '/usr/bin/gcc' failed with exit code 4
from our docker build
ok passed on retry
urp all the macosx wheels failed ERROR InvalidDistribution: Invalid distribution metadata: license-expression introduced in metadata version 2.4, not 2.1
ah we have hardcoded hatchling==1.20.0 somewhere?
looks like this was introduced in https://github.com/psf/black/pull/4017 to workaround a hatch missing feature that got fixed in https://github.com/pypa/hatch/commit/64005a2106293dd33019c63027d9263b6d05dd53 which is in 1.25.0
GitHub
Fixes #3981
Don't hate me for this
^ wheels are created only on pushes to main
ok I manually uploaded the macos wheels now
Description
The message has been updated to indicate Python 3.9+, but the check still compared to 3.8.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
c02ca47 Fix mis-synced version check in black.vim (#4567) - mgorny
Description
Looks like #4567 replaced the comment with their entry, which bugs me, so this adds it back.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
While we're here, do you want to move the changelog entry to "Integrations" actually?
Describe the bug
There is a formatting difference depending on whether you have Python 3.10.15 installed but with the same version of Black (currently 25.1.0).
Under 3.10.15 this gets reformatted:
match args:
case _ if ("test" in "testing" and True is True):
print("YAY")
to this:
match args:
case _ if "test" in "testing" and True is True:
print("YAY")
Under 3.10.16 this reformatting doesn't occur and the parentheses remain in pla...
^ oh no what did we do
I was going to try and repro this, but 3.10.15/16 don't have installers and thus I am too small brain to do anything
I guess they're security-only releases? Should be possible to build from source
(both locally with 3.13 and on the playground it removes the parens)
Building CPython from source is not entirely trivial but shouldn't be too hard, https://devguide.python.org/ is the best resource on how to do it
Describe the style change
Strings should remain on separate lines if they end with “\n”. The newline has already the meaning of a line-break in a string. I think it would improve the readability if black uses this information to format strings.
Examples in the current Black style
a = "a=1\n" "b=2\n" "c=3\n"
Desired style
a = (
"a=1\n"
"b=2\n"
"c=3\n"
)
Additional context
I'm the author of [inline-snapshot](https://github.com...
This file:
class ModelError(Exception):
"Models can raise this error, which will be displayed to the user"
pass
When run through the latest Black is reformatted to look like this:
class ModelError(Exception):
"Models can raise this error, which will be displayed to the user"
pass
Here's a way to see that happen using uvx. With the previous Black version:
echo 'class ModelError(Exception):
"Models can raise this error, which will be ...
Description
This PR fixes the is_type_comment() function to correctly handle type comments with excessive whitespace. It normalizes spacing after # and :, ensuring that type comments are properly detected, even if they have extra spaces. This improves comment detection and prevents issues with misformatted type annotations.
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated ...
Hello, thank you for your contribution to Black! I have a few things that need addressed before this is ready to be merged.
- Make sure you should read https://black.readthedocs.io/en/latest/contributing/the_basics.html . The next couple items of feedback all come from there, and it goes much more in-depth on exactly how and why to do things.
- Since this is a user-facing change, you need to add a changelog entry
- I'll admit I'm not familiar with this element of Black's formatting, so...
Black transforms
assert f(a,) == (b)
assert f(a,) == b
into
assert f(
a,
) == (b)
assert (
f(
a,
)
== b
)
which doesn’t make too much sense because
- there’s no need to insert the outer parentheses
- the parentheses around
bshould have no effect on anything.
im good thank
Hey, i have a question.
Black recently got introduced to our workplace and i find the formatting a bit odd in some places and can't find an explanation as to why it is formatted the way it is, so i am hoping to get more infos here.
or 'very long text ' not in element.get_attribute('aria-label'):
return workday_handle_custom_fields_hook(element, dict, category, _)```
gets formatted to
``` if not element.get_attribute(
'aria-label'
) or 'very long text' not in element.get_attribute('aria-label'):
return False```
when i expected it to be
``` if (
not element.get_attribute('aria-label')
or 'very long text' not in element.get_attribute('aria-label')
):
return False```
Why is it going for the second option and not the third?
Is there a way to get the third option as a result by disabling a rule?
The TLDR is because it’s not implemented due to existing code breakage, and no there isn’t an option. The relevant issue is very storied since this is an often requested thing, but very hard to actually implement. https://github.com/psf/black/issues/2156
Alright, thank you!
Description
Looks like upload-artifact@v3 is now deprecated. Reading through the migration guide it looks like Black doesn't do any of the deprecated/changed behaviors, so this PR just bumps the number from 3 to 4.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary?- Not user f...
From click 8.2.0 changelog:
Keep stdout and stderr streams independent in CliRunner. Always collect stderr output and never raise an exception. Add a new output stream to simulate what the user sees in its terminal. Removes the mix_stderr parameter in CliRunner. [:issue:`2522`](https://github.com/pallets/click/blob/main/CHANGES.rst#id27) [:pr:`2523`](https://github.com/pallets/click/blob/main/CHANGES.rst#id29)
so mix_stderr=False throws an error and is redundant.
Added detailed documentation on PyInstaller which was unavailable. Please review and accept/let me know of any changes. Thank you very much. Happy to be of help! Good day!
Description
Issue #3623 appears to be resolved, added regression tests to monitor this formatting issue and track any potential recurrence.
Regression tests were created based on Black's current stable version (25.1.0) formatting results, see [Black Playground](https://black.vercel.app/?version=stable&state=_Td6WFoAAATm1rRGAgAhARYAAAB0L-Wj4AQTANldAD2IimZxl1N_Wg0-A00Q7AStP7a3q0sqVQPWdY1xadXvajUNDqf4hsar9JsSEjvUIkO86voFmeTFwICDsImuEkAIHQ_jOFRyFZO2d_RDtELcNHSgMoIla6f1d7fosYp-0UUDHqBX...
Describe the style change
Current black format the slice notation just after a multiline string literal over multiple lines, but that's unnecessary when the line containing closing triple quote is short.
Examples in the current Black style
s = """
lorem ipsum dolor sit amet
consectetur adipiscing elit
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua
ut enim ad minim veniam
quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo
conse...
Describe the bug
When running the test suite on PyPy3.11 7.3.18, I'm seeing two test failures:
========================================================= test session starts =========================================================
platform linux -- Python 3.11.11[pypy-7.3.18-final], pytest-8.3.4, pluggy-1.5.0
cachedir: .tox/pypy311/.pytest_cache
rootdir: /tmp/black
configfile: pyproject.toml
plugins: cov-6.0.0, xdist-3.6.1
12 workers [386 items] ipped ...
Description
Enable more strict checks from future mypy@2.0 --strict mode.
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Describe the bug
To Reproduce
For example, take this code:
this = "code"
And run it with these arguments:
$ black file.py --target-version py39
The resulting error is:
cannot format file.py: INTERNAL ERROR: ...
Expected behavior
Environment
- Black's version:
- OS and Python version:
Additional context
Beterbiev vs Bivol 2 live stream: How to watch boxing online today – start time, TV channel, full fight card. Artur Beterbiev vs Dmitry Bivol 2 – aka The Last Crescendo – for the undisputed world light heavyweight title isn't only one of the best pound-for-pound fights of 2025, it's got arguably the highest-quality card this century. Beterbiev won a razor-thin decision when these two met in October, as Bivol seeks revenge
The epic rematch in the light heavyweight division is ready to get und...
Beterbiev vs Bivol 2 live stream: How to watch boxing online today – start time, TV channel, full fight card. Artur Beterbiev vs Dmitry Bivol 2 – aka The Last Crescendo – for the undisputed world light heavyweight title isn't only one of the best pound-for-pound fights of 2025, it's got arguably the highest-quality card this century. Beterbiev won a razor-thin decision when these two met in October, as Bivol seeks revenge
The epic rematch in the light heavyweight division is ready to get und...
:incoming_envelope: :ok_hand: applied timeout to @jade lintel until <t:1740316112:f> (10 minutes) (reason: duplicates spam - sent 4 duplicate messages).
The <@&831776746206265384> have been alerted for review.
Describe the bug
Black errs on format string while Python runs the code without error.
To Reproduce
x = "test"
if f"{x}:\\":y = f'{x}'; print(y)
And run it with these arguments:
$ black test.py --target-version py310
The resulting error is:
error: cannot format test.py: Cannot parse for target version Python 3.10: 3:22: EOF in multi-line string
Expected behavior
The same code but formatted. Python does accept this input and will print y.
**...
any reason you didn't migrate to Trusted Publishing? It can produce digital attestations out of the box now: https://blog.pypi.org/posts/2024-11-14-pypi-now-supports-digital-attestations/.
_Originally posted by @webknjaz in https://github.com/psf/black/issues/4512#issuecomment-2483427381_
We should move to Trusted Publishing at some point, but that's a bit more work, so we'll do it when we do it I suppose. I'd probably accept a PR that does it f...
Describe the style change
black version: 25.1.0
Currently this example could not be formatted at all if line length is set to 80.
Examples in the current Black style
class Foobar:
def method(self, foobar_long_dictionary: dict):
return [
(foobar_long_key, foobar_long_value)
for foobar_long_key, foobar_long_value in foobar_long_dictionary.items()
]
Desired style
class Foobar:
def method(self, fooba...
Description
Additional fix for the upcoming click 8.2.0; this is a backwards compatible fix with previous releases of click.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
This change will help with reproducibility in downstreams.
Ref: https://setuptools-scm.rtfd.io/en/latest/usage/#git-archives
The wildcard at the beginning used to match tags with arbitrary prefixes otherwise. This patch corrects that, making it more accurate.
It's a follow-up to #4592. The docs provide a very generic example of the .git_archival.txt template file, suggesting that it's tailored per project needs later [1]:
Feel free to alter the
matchfield indescribe-nameto match your project's tagging style.
Describe the bug
In some cases the current black version (25.1.0) reformats a string that is too long. Also the behaviour differs between not specifying a line length and specifying the default length of 88 chars.
To Reproduce
class A:
def foo(self):
return (
"This is a very loooooooooooooooooooooooooooooooooooooooooooooong string"
)
Note: The long line is exactly 86 chars wide. The bug does not occur when I add one character.
$...
Describe the bug
Using pre-commit in Django and want to exclude the migrations directory and all files of it from formatting because these are auto-generated files by Django. Tried with exclude, extend-exclude, and force-exclude but none of them seems to be working as expected
To Reproduce
repos:
- repo: https://github.com/psf/black
rev: 25.1.0 # Use the latest stable version
hooks:
- id: black
language_version: python3
exclude: |
...
$ conda create -n myenv python=3.12.6 -y
$ conda activate myenv
$ python --version
Python 3.12.6
$ black foo/bar/myfile.py
Python 3.12.5 has a memory safety issue that can cause Black's AST safety checks to fail. Please upgrade to Python 3.12.6 or downgrade to Python 3.12.4
$ python --version
Python 3.12.6
- Black's version:
- OS and Python version:
Additional context
https://black.readthedocs.io is still the 24.8 docs
oh it's because the stable branch didn't get updated because of wheel shenanigans. just updated it manually
Black v25.1.0
Options
--line-length=88
--safe
--target-version=py313
Input
def main():
print("Hello...
Description
To stay within quota, it now has just under 30 days of data, so the filename has been updated. Both will be available for a while. See https://github.com/hugovk/top-pypi-packages/pull/46.
Checklist - did you ...
- [n/a] Add an entry in
CHANGES.mdif necessary? - [n/a] Add / update tests if necessary?
- [n/a] Add new / update outdated documentation?
Describe the bug
The following code can not be parsed/formatted by black:
class name_5[name_4: lambda: something]:
pass
❯ black -t py312 bug.py
error: cannot format bug.py: Cannot parse for target version Python 3.12: 1:21: class name_5[name_4: lambda: something]:
Oh no! 💥 💔 💥
1 file failed to reformat.
but it can be parsed by cpython.
python3.12 scripts/min_code.py
Environment
- Black's version: current main (00c0d6d91ae3dc31894fadd37968e...
Describe the bug
The following code can not be parsed/formatted by black:
{name_4: name_1 for name_2 in something if f'\\' if {}}
❯ .venv/bin/black -t py312 scripts/min_code.py
error: cannot format scripts/min_code.py: Cannot parse for target version Python 3.12: 1:53: {name_4: name_1 for name_2 in something if f'\\' if {}}
Oh no! 💥 💔 💥
1 file failed to reformat.
but it can be parsed by cpython.
❯ python3.12 scripts/min_code.py
Traceback (most recent call ...
Description
updates to test_docs explained the preview style updates and the test is just to confirm docs are updated properly
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
45cbe57 Add regression tests for Black’s previous incon... - rdrll
3e9dd25 Fix bug where # fmt: skip is not being respecte... - Pedro-Muller29
Describe the bug
Black unexpectedly changes binary content as per the example below.
└➜ cat main.py
invalid_binary_char = b"\xFEFEF"
└➜ black --check --verbose --diff ./main.py
Identified `/` as project root containing a file system root.
Found input source: "main.py"
--- main.py 2025-03-04 04:21:22.184368+00:00
+++ main.py 2025-03-04 04:22:25.247730+00:00
@@ -1 +1 @@
-invalid_binary_char = b"\xFEFEF"
+invalid_binary_char = b"\xfeFEF"
would reformat main.py
Oh no! 💥 💔 💥
1 f...
Hello
Hello
Description
"dependency-groups" is the mechanism for storing package requirements in pyproject.toml, recommended for formatting tools (see https://packaging.python.org/en/latest/specifications/dependency-groups/ )
this change allow the black action to look also in those locations when determining the version of black to install
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / u...
see https://github.com/actions/runner-images/issues/11101
Description
This is a minor housekeeping update and should not require new tests or a changelog entry.
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
When working in a project where some paths are not blacked yet, you may configure file discovery and run something like:
black .
Once you have this, you may need to integrate black in your editor, and some plugins end up piping from stdin:
stdin | black - --stdin-filename "$FILEPATH"
The problem is the integration will fail when trying to format a file being excluded by force-exclude directive.
You can check other tools like ruff output unformatted stdin in this case:
Description
This change tries to fix https://github.com/psf/black/issues/4609, so you can use black piping stdin and expect the new content in the output, formatted or not. This is the way other formatters such as ruff or clang-format works too.
I'm not really sure if this is the best place to output the content, feel free to modify or make any suggestion.
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if nece...
Fixes #4589
This PR upgrades the PyPI publishing workflow to use Trusted Publishing instead of token-based authentication. This change:
- Improves security by using OpenID Connect (OIDC) instead of long-lived tokens
- Removes the need for maintaining PyPI tokens in GitHub secrets
- Uses the official PyPA publishing action
Changes made:
- Added
id-token: writepermission for OIDC authentication - Changed environment name to 'release'
- Switched to
pypa/gh-action-pypi-publishac...
CI seems to be working here - Is it just failing locally for you?
This looks good - I would imagine our next test run of this would confirm? Should we force run the skipped tests maybe?
Thoughts here other maintainers?
so me and my friends tried to calculate the truck/bus factor of this project using the git repository and the resulting answer was "1" with the author being "Łukasz Langa" dropping the coverage to below 50%.
Would the developers agree with this result, given no new developer joins the team, removing them would pose significant setbacks to the further development of this project?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
ugh may need psf folks to ban that person
lol
:(
5342d2e Replace the blib2to3 tokenizer with pytokens (#... - tusharsadhwani
🎉
Describe the bug
The following code can not be parsed/formatted by black:
del ([], name_2), [(), [], name_4, name_3], name_1[[name_2 for name_1 in name_0]]
black reported the following error:
> black -l 80 -C bug.py
error: cannot format bug.py: INTERNAL ERROR: Black 25.1.1.dev21+g254e829.d20250317 on Python (CPython) 3
.12.6 produced code that is not equivalent to the source. Please report a bug on https://github.com/psf
/black/issues. This diff might be helpful: /...
Black v25.1.0
Options
--line-length=88
--safe
--target-version=py313
Input
value = "aldkfdskdksfjdskfj dslkfj sdkl dklsfj dsklfj sdklfj...
Description
Resolves #4625
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
[psf/black] Issue opened: #4629 failed to format a file with a with-statement and a named-expression
Describe the bug
The following code can not be parsed/formatted by black:
with {} as name_3, (name_2 := name_4):
def name_3[**name_1]():
pass
black reported the following error:
> black -l 100 -C bug.py
error: cannot format bug.py: Cannot parse: 1:26: with {} as name_3, name_2 := name_4:
Oh no! 💥 💔 💥
1 file failed to reformat.
but it can be parsed by cpython:
from ast import parse
parse(
'with {} as name_3, (name_2 := name_4):\n'
...
Resolves #4629
Description
- [ ] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
Describe the bug
Internal Error when reformatting file with comments at the end, where the first line has # fmt: skip added to it. All additional comment lines are removed.
To Reproduce
For example, take this code:
def foo():
pass
# comment1 # fmt: skip
# comment2
And run it with these arguments:
$ black file.py
The resulting error is:
cannot format file.py: INTERNAL ERROR: Black 25.1.1.dev21+gdbb14ea on Python (CPython) 3.12.8 produced diff...
6144c46 Fix parsing of walrus operator in complex with ... - tusharsadhwani
Describe the bug
The following code can not be parsed/formatted by black:
with (name_2, name_2) as name_2:
pass
black reported the following error:
> black -l 100 -t py312 bug.py
error: cannot format bug.py: INTERNAL ERROR: Black 25.1.1.dev21+g944a38e.d20250317 on Python (CPython) 3
.12.6 produced code that is not equivalent to the source. Please report a bug on https://github.com/psf
/black/issues. This diff might be helpful: /tmp/blk_umh51eiz.log
Oh no! 💥 💔 ...
@dapper rapids Thanks for the amazing tool/work for the issues, but since the descriptions say it I have a couple of things that are mostly just nitpicks/out of laziness, feel free to ignore if they are too much work for not enough value.
nitpicks:
The "black reported the following error" code block has an extra newline, I think it should be strippable
Same thing with the "result:" code block
Laziness:
With issues that are inequivalent to source, often the output with --fast/"Skip temporary sanity checks" can quickly show where it went wrong (ie with (a, b) as c: pass vs with a, b as c: pass) more easilly than reading the diff (for me, might be skill issue)
It would be nice to have a link to the playground in the message somewhere with the broken code, these should be generatable without actually going to the playground since the compression/decompression code is very simple and so is the stored json link:
{'sc': 'source code here', 'll': 88, 'ssfl': False, 'ssn': False, 'smtc': False, 'pyi': False, 'fast': False, 'prv': False, 'usb': False, 'tv': []}
api/app.py lines 38 to 45
def compress_state(data):
compressed = lzma.compress(json.dumps(data).encode("utf-8"))
return base64.urlsafe_b64encode(compressed).decode("utf-8")
def decompress_state(state):
compressed = base64.urlsafe_b64decode(state)
return json.loads(lzma.decompress(compressed))```
Describe the bug
The following code can not be parsed/formatted by black:
with (name_5, something): # type: ignoresome text
pass
black reported the following...
@azure plank thank you for your feedback. here is how the new generated issues look like.
Description
Resolves #4632
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
Description
Resolves #4631
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
This PR fixes the inconsistent formatting of 'with' statements when using tuples.
Previously, Black formatted 'with' conditions inconsistently when they contained bracketes.
Now, the formatting is consistent across different cases.
##Changes:
- Fixed inconsistent formatting of with statements when they contain brackets (tuples, lists, function calls).
- Ensured that Black formats with statements consistently, avoiding unnecessary line breaks or misalignment when using brackets. ...
Describe the style change
Black reformat defs and classes with 3 dots ("...") inside to one line. May be it should leave it as is, like with the "pass"
Examples in the current Black style
from this
def f():
pass
Black leaves as is
def f():
pass
from this
def f():
...
Black do
def f(): ...
It raise an flake8 error E704 (multiple statements on one line (def))
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
Unfortunately this doesn’t look to fix the issue, the defined function is never used to actually format code. The proper way to test this is adding a new test case to a file in the tests/data/cases folder. The fix should probably happen somewhere in the src/black/linegen.py file, and it would involve manipulating the produced ast instead of using regex.
łukasz hasn't really been actively involved for several years at this point, so don't think your calculation is right
I understand. We did include a falloff for older commits to the repo, might need to increase the coefficients. Thank you!
bus factor often reflected in contributions that aren’t commits too
do you have any suggestion besides commits? which we can extract from the repo?
reviews / merges is the big one
oh, that's useful. will definitely try to include them
(involvement in issues is a pulse check. releases is another kind of bus factor you might be interested in)
The perils of reading code on your phone, I somehow didn’t even notice the test case was js xD
that code looks like it could be legal python 😄
hi does anyone know how i can format python
in discord
Hey! To format Python code in Discord, use triple backticks around your code. Add ‘python’ right after the opening backticks for syntax highlighting. Like this:
def say_hello():
print("Hello, Discord!")
You can put "python" after the first 3x inverted commas to get synyax highlighting
#```python
print("hello")
Describe the bug
Given the following code snippet:
help(lambda x=(
# comment
"bar",
): False)
black crashes within the reformatting code with the error message:
error: cannot format : Opening paren not found in `leaves`
I reproduced this using the current head of black (black, 25.1.1.dev24+g2c135ed (compiled: no)) and on the online formatter. I can see this on both Linux and macOS and multiple versions of Python (3.12 and 3.13).
I bisected the repro, and...
@t.overload
def get_components(self) -> t_abc.Iterable[tuple[ID, tuple[()]]]: ...
@t.overload
def get_components[
C1: Component,
](self, c1: type[C1],) -> t_abc.Iterable[tuple[ID, tuple[C1,]]]: ...
@t.overload
def get_components[
C1: Component,
C2: Component,
](self, c1: type[C1], c2: type[C2],) -> t_abc.Iterable[
tuple[
ID,
tuple[
C1,
C2,
],
]
]: ...
@t.overload
def get_components[
C1: Component,
C2: Component,
C3: Component,
](self, c1: type[C1], c2: type[C2], c3: type[C3],) -> t_abc.Iterable[
tuple[
ID,
tuple[
C1,
C2,
C3,
],
]
]: ...
@t.overload
def get_components[
C1: Component,
C2: Component,
C3: Component,
C4: Component,
](self, c1: type[C1], c2: type[C2], c3: type[C3], c4: type[C4],) -> t_abc.Iterable[
tuple[
ID,
tuple[
C1,
C2,
C3,
C4,
],
]
]: ...
i am doing nasty stuff with 3.12 generics
i noticed weird formatting of func args in these cases: even if there is a trailing comma, func args are not split into several lines
@t.overload
def get_components[
C1: Component,
C2: Component,
C3: Component,
C4: Component,
- ](self, c1: type[C1], c2: type[C2], c3: type[C3], c4: type[C4], /,) -> t_abc.Iterable[
+ ](
+ self,
+ c1: type[C1],
+ c2: type[C2],
+ c3: type[C3],
+ c4: type[C4],
+ /,
+ ) -> t_abc.Iterable[
tuple[
ID,
tuple[
C1,
C2,
C3,
C4,
],
]
]: ...
^ this is what i would like to see
Seems to work fine on the playground, maybe your version is out of date? Playground link
Off the top of my head I remember https://github.com/psf/black/pull/4553 changing this behavior, so you might need current stable
indeed, that fixed it, i was on v24.4 💀
thank you
The formatting applied by black on imports is not compatible with isort.
That prevents using both black --check and isort --check in CI testing.
Example:
Original code:
from .common_options import help_option, config_option, parm_options, \
target_options
After formatting by isort:
from .common_options import (help_option, config_option, parm_options,
target_options)
After formatting by black:
from .common_options import (
help...
Describe the bug
The following code can not be parsed/formatted by black:
with (name_5, name_4), name_5:
pass
black reported the following error:
> black -l 100 -C -t py313 ...
Describe the bug
When saving the file, black does a great job with formatting. But today it caused the an issue in the code by changing the below - it removed the parenthesis:
list_filter = ("region")
to:
list_filter = "region"
This created an issue as list_filter has to be a tuple.
Unless this is an expected behavior and I missed something in the usage of the black, I don't think it should change a defined type.
To Reproduce
just run
list...
Description
Fixes: #2095 – is_type_comment() is wrong
Summary of Changes:
- Modified function signatures across several modules to pass the
modeparameter tois_type_commentandmake_comment. - Incorporated parts of PR #4467 by @Pedro-Muller29, particularly the fix in
mode.pyaddressing theunhashable type: modeissue.
Acknowledgment:
Credit to @Pedro-Muller29 for the initial work in PR #4467.
Che...
a41dc89 [pre-commit.ci] pre-commit autoupdate (#4644) - pre-commit-ci[bot]
Description
Resolves https://github.com/psf/black/issues/4642
Checklist - did you ...
- [X] Add an entry in
CHANGES.mdif necessary? - [X] Add / update tests if necessary?
- [X] Add new / update outdated documentation?
Describe the bug
The following code can not be parsed/formatted by black:
def name_3[name_0: [] if name_2 else name_3]():
pass
black reported the following error:
>...
Describe the style change
The current Black style for tuple assignment, as shown in the example below, is concise but lacks readability, especially when dealing with tuples that contain multiple elements. This can make it harder for readers to quickly understand the intent of the code.
Examples in the current Black style
(a,) = ("a",)
This style places the tuple elements on a single line, which might require the reader to spend extra time parsing the structure, espe...
Is your feature request related to a problem? Please describe.
I'd like to use it in Node.js or browser environment.
Describe the solution you'd like
https://github.com/pyodide/pyodide
Describe alternatives you've considered
https://wasmer.io/posts/py2wasm-a-python-to-wasm-compiler
Additional context
As mentioned in my comment, I believe my initial PR already handled both cases correctly. Therefore, this PR just add new test cases.
I have not added a changelog entry, as I believe it is not necessary for this kind of PR.
Resolves #4642
- [X] Add an entry in
CHANGES.mdif necessary? - [X] Add / update tests if necessary?
- [X] Add new / update outdated documentation?
Describe the style change
If inline comments have been aligned, that has most likely been done for a reason and breaking the alignment is likely to make the code worse. As an example, we have this code in our project:
TypeHint = Union[
type, # Actual type.
str, # Type name or alias.
UnionType, # Union syntax (e.g. `int | float`).
'tuple[TypeHint, ...]' # Tuple of type hints. Behaves like a union.
]
...
Fixes #2097
Description
Currently, Black fails to recognize # type: and # type: ignore comments if there's extra whitespace after the # (e.g., # type:), as described in issue #2097. This can lead to these comments being treated as regular comments, potentially causing incorrect formatting or instability.
This PR updates the comment recognition logic (is_type_comment, is_type_ignore_comment, and helper functions like is_type_comment_string / `is_type_ignore_commen...
Black is exploding the if guard in case patterns which have trailing commas in them, even if the guard expression fits in one line. The trailing comma logic should apply only to the case pattern, not the if guard.
Description:
While testing Black’s output, I observed that deeply nested f-strings (e.g., f"outer {f'inner {x}'}") sometimes lose indentation alignment or break unpredictably. This reduces code clarity, especially in templating or SQL query generation.
Evidence:
Input (before formatting)
query = f"SELECT {f"COUNT(*) FROM {f"users WHERE id = {user_id}"}"}"
Current output may misalign the nested f-strings.
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [X] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Hello, thank you for the contribution!
I've looked at your changes, but there are a few things that need fixing before it's good to go.
First and foremost, the contributing basics docs page is your best friend. It guides you though how to set up everything for developing and how to run the pre-commit hooks/tests. It also guides you through how to make a changelog entry, which will be required.
I ran your change through ...
I have multiple configurations in my pyproject.toml. Black and flake8 seem to be conflicting. Here is the configuration I have for the two linters.
[tool.black]
line-length = 120
include = '\.pyi?$'
check = true
[tool.flake8]
filename = folder1,folder2,folder3
When running black it gives the following error:
black .
Error: Could not open file '/example/gitfolder/pyproject.toml': Error reading configuration file: Invalid value (at line 15, column 12)
To reproduce:
Add the ...
Description
Resolves #4159
As I summarized there, most of the issues described can not be fixed easily. This PR resolves the two problems with obvious fixes: dictionary values with multiline strings should stay parenthesized, and ternaries with multiline strings in the value should stay parenthesized. Again, I don't believe we can do anything for the other pain points mentioned, so this PR resolves the issue as ...
Description
Fixes #4640
This PR fixes a bug where Black would crash when formatting code with standalone comments within parentheses in lambda default arguments.
The issue occurs in the has_magic_trailing_comma method in src/black/lines.py. When a standalone comment is present within parentheses in a lambda default argument, the method tries to find the opening bracket in the line's leaves, but it wouldn't be there, causing a LookupError.
The fix adds a try-except blo...
Looks like some resource is not responding, because the formatter just keeps loading without formatting the input code.
Black v25.1.0
Describe the style change
Having a comment after an import to disable a pylint issue results in Black formatting it by putting both the imported Object and the comment in ( ) and stopping the comments purpose.
Examples in the current Black style
from django.contrib.auth.models import User # We use default User model, pylint:disable=E5142
Results in
from django.contrib.auth.models import (
User, # We use default User model, pylint:disable=E5142
)
``...
Description
Updated the Prettier configuration and re-ran Prettier.
The pre-commit hook we were using has been archived, so I switched to an active and decently popular (600+ repo) fork. We were previously on an alpha version, and the fork doesn't support alpha versions, so I did have to downgrade the version. However, no changes in v4 affected us, and v3 is more freuently updated.
I also modified the file type list to include Markdown and remove language this project does not use.
...
Starting to investigate why CI hypothesis is failing, at least on the surface it looks legit, though I don't know why this wasn't caught before. Maybe a hypothesis update? ```pycon
black.format_str('try:\\r# type: ignore\n pass\nfinally:\n pass\n', mode=black.FileMode())
'try:\n pass\nfinally:\n pass\n'
That is also valid code even if it looks very weird ```ps
PS> py -c "try:`r# type: ignoren passnfinally:n passnprint(1)"
1
PS D:\python_projects\black> uv run black -c "try:\`r# type: ignore`n pass`nfinally:`n pass`n"
# type: ignore
pass
finally:
pass
error: cannot format <string>: INTERNAL ERROR: Black 25.1.1.dev27+gd0ff3bd on Python (CPython) 3.13.0 produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues.
Like usual \r certainly is something to deal with
Doing some bisection, it looks like at least the failing behavior changed with the new tokenizer.
Before new tokenizer: ```ps
PS D:\python_projects\jam-game> uvx --from git+https://github.com/psf/black@9f38928 black -c "try:`r# type: ignoren passnfinally:n passn"
Built black @ git+https://github.com/psf/black@9f38928414e6a39044f9b148692e90f3e1fd3433
Installed 7 packages in 45ms
type: ignore
pass
finally:
pass
error: cannot format <string>: Cannot parse for target version Python 3.13: 1:4: try:\
After new tokenizer: ```ps
PS D:\python_projects\jam-game> uvx --from git+https://github.com/psf/black@5342d2e black -c "try:\`r# type: ignore`n pass`nfinally:`n pass`n"
Built black @ git+https://github.com/psf/black@5342d2eeda6935a96d2bd0c74072b3c441d76bde
Installed 8 packages in 55ms
# type: ignore
pass
finally:
pass
error: cannot format <string>: INTERNAL ERROR: Black 25.1.1.dev20+g5342d2e on Python (CPython) 3.13.0 produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: C:\Users\gigagon\AppData\Local\Temp\blk_56kx39se.log
After a bit of editing to the NL repr code so it shows the prefixes and a good amount of stepping through the line generator, my basic understanding is that for some reason the comment is never being generated ```
PS D:\python_projects\black> uv run black -c "try:`r# type: ignoren passnfinally:n passn"
d:\python_projects\black\src\black_init_.py(1222)format_str_once()
-> breakpoint()
(Pdb) n
d:\python_projects\black\src\black_init.py(1223)format_str_once()
-> src_node = lib2to3_parse(src_contents.lstrip(), mode.target_versions)
(Pdb) n
d:\python_projects\black\src\black_init.py(1224)_format_str_once()
-> dst_blocks: list[LinesBlock] = []
(Pdb) src_node
Node(file_input, '' [Node(try_stmt, '' [Leaf(NAME, '' 'try'), Leaf(COLON, '' ':'), Node(suite, '\\r# type: ignore' [Leaf(NEWLINE, '\\r# type: ignore' '\n'), Leaf(INDENT, '' ''), Node(simple_stmt, ' ' [Leaf(NAME, ' ' 'pass'), Leaf(NEWLINE, '' '\n')]), Leaf(DEDENT, '' '')]), Leaf(NAME, '' 'finally'), Leaf(COLON, '' ':'), Node(suite, '' [Leaf(NEWLINE, '' '\n'), Leaf(INDENT, '' ''), Node(simple_stmt, ' ' [Leaf(NAME, ' ' 'pass'), Leaf(NEWLINE, '' '\n')]), Leaf(DEDENT, '' '')])]), Leaf(ENDMARKER, '' '')])
After a lot more stepping, it looks like the issue starts in generate_comments because it can't deal with the starting \
I finally got to the bottom of it, making PR now
Description
Fixes a \ followed by a \r followed by a comment causing the comment to be deleted. This also fixes Hypothesis failing the CI. This originally went under the radar since the old tokenizer largely didn't support carriage returns, so this example would crash with error: cannot format : Cannot parse for target version Python 3.13: 1:4: try:\ before getting to linegen. The new tokenizer supports carriage returns much better, and so this issue was revealed. I'm not...
(Also even though I have merge rights now I am very tired currently and would appreciate another set of eyes to make sure I didn't explode everything on accident)
:/ I ran the 3.13 fuzz and it came out fine, but I guess this didn't fix the 3.11 fuzz, so the investigation continues
So the issue is with the code \n#\r0. I think this might be a tokenizer issue, since comparing it with how \n#\n0 behaves:
\n#\r0 lib2to3 tokens: ```py
(54, '\n', (1, 0), (1, 1), '\n')
(53, '#\r0', (2, 0), (2, 3), '#\r0')
(54, '', (2, 3), (2, 3), '#\r0')
(0, '', (3, 0), (3, 0), '')
`\n#\n0` lib2to3 tokens: ```py
(54, '\n', (1, 0), (1, 1), '\n')
(53, '#', (2, 0), (2, 1), '#\n')
(54, '\n', (2, 1), (2, 2), '#\n')
(2, '0', (3, 0), (3, 1), '0')
(0, '', (4, 0), (4, 0), '')
So it looks like something is broken with #\r, starting from lib2to3.
\n#\r0 black tokens: ```py
TokenInfo(type=63 (NL), string='\n', start=(1, 0), end=(1, 1), line='\n')
TokenInfo(type=62 (COMMENT), string='#', start=(2, 0), end=(2, 1), line='#\r0')
TokenInfo(type=2 (NUMBER), string='\r0', start=(2, 1), end=(2, 3), line='#\r0')
TokenInfo(type=63 (NL), string='', start=(2, 3), end=(2, 4), line='#\r0')
TokenInfo(type=0 (ENDMARKER), string='', start=(3, 0), end=(3, 0), line='')
`\n#\n0` black tokens: ```py
TokenInfo(type=63 (NL), string='\n', start=(1, 0), end=(1, 1), line='\n')
TokenInfo(type=62 (COMMENT), string='#', start=(2, 0), end=(2, 1), line='#\n')
TokenInfo(type=63 (NL), string='\n', start=(2, 1), end=(2, 2), line='#\n')
TokenInfo(type=2 (NUMBER), string='0', start=(3, 0), end=(3, 1), line='0')
TokenInfo(type=4 (NEWLINE), string='', start=(3, 1), end=(3, 2), line='0')
TokenInfo(type=0 (ENDMARKER), string='', start=(4, 0), end=(4, 0), line='')
The black tokens also have similar behavior, where the \r version doesn't separate from the 0 correctly.
@lavish scroll since you did the new tokenizer, thoughts? I'm unsure how to fix this
I also have no clue why this seems to be only found on 3.11.
I'd still recommend waiting for review from others before merging
Personally on open-source projects I usually merge without review only for obvious quick fixes (e.g. fixing CI)
And sometimes when I'm impatient 🙂
What does Python itself produce? I get $ echo '\n#\r0' | ./python.exe -m tokenize <stdin>:1:7: error: unexpected character after line continuation character but maybe I didn't escape something properly
As for why 3.11 only, it's random, so I think that sort of thing might just happen
It works "fine" for me in PS. ```ps
PS D:\python_projects\black> echo "n#r0" | py -m tokenize
1,0-1,1: NL '\n'
2,0-2,1: COMMENT '#'
2,1-2,2: NL '\n'
3,0-3,1: NUMBER '0'
3,1-3,2: NEWLINE '\n'
4,0-4,0: ENDMARKER ''
PS D:\python_projects\black> py
Python 3.13.0 (tags/v3.13.0:60403a5, Oct 7 2024, 09:38:07) [MSC v.1941 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
import tokenize
from io import StringIO;print(*tokenize.generate_tokens(StringIO("\n#\r0").readline), sep="\n")
TokenInfo(type=63 (NL), string='\n', start=(1, 0), end=(1, 1), line='\n')
TokenInfo(type=62 (COMMENT), string='#', start=(2, 0), end=(2, 1), line='#\r0')
TokenInfo(type=2 (NUMBER), string='\r0', start=(2, 1), end=(2, 3), line='#\r0')
TokenInfo(type=63 (NL), string='', start=(2, 3), end=(2, 4), line='#\r0')
TokenInfo(type=0 (ENDMARKER), string='', start=(3, 0), end=(3, 0), line='')
Of course I get inconsistent results depending on if I run it inside or outside of python, but I'd think that's probably either python or windows normalizing to NL at some point.
Trying it out in Git Bash, it looks like `echo` gives back the input literally, so python ends up with the equivalent of `"\\n#\\r0"`, which is why it's saying unexpected line continuation character. Using `printf` seems to work, and it gives the same result as on PS. ```bash
$ echo "\n#\r0"
\n#\r0
$ printf "\n#\r0"
0
$ printf "\n#\r0" | py -m tokenize
1,0-1,1: NL '\n'
2,0-2,1: COMMENT '#'
2,1-2,2: NL '\n'
3,0-3,1: NUMBER '0'
3,1-3,2: NEWLINE ''
4,0-4,0: ENDMARKER ''
Well almost the same, but close enough
Interesting I get something else on 3.14 ```$ printf "\n#\r0" | ./python.exe -m tokenize
1,0-1,1: NL '\n'
2,0-2,1: COMMENT '#'
2,1-2,3: NUMBER '\r0'
2,3-2,4: NL ''
3,0-3,0: ENDMARKER ''
Seems like tokenize was buggy in 3.11 and earlier, checking with -m ast shows it always compiled to the same code
Hm, it may just be windows things but trying both on Git Bash and PS I never get the \r0 from running from -m tokenize, and I always get it if I run from -c with generate_tokens.
Yeah I'm on a Mac, it's possible these things get interpreted differently somewhere along the way
I dug into pytokens, and it looks like the tokenization is because a lone \r is not considered a newline, only \r\n and \n are considered newlines, while \r is just white space. This causes the comment to over-expand and include the following line(s) until a NL is encountered or EOF. It should be a fairly simple fix (around line 764 in __init__.py), but wow are CRs such a pain to work with. Part of me wonders if we should even keep bothering with special casing CRs and instead just normalize everything before running, since the output already normalizes and \r isn’t even a valid normalization option.
Also I’ve got no clue how to handle the cross-project/cross-repo update to fix this
It looks like this is probably also just a re-emergence of https://github.com/python/cpython/issues/128233 , with it surfacing because of whatever hypothesis change
I do think pytokens should diverge from CPython here, since in the lexical analysis docs section it says all line ending forms including CR can be used equally regardless of platform, and we can see that’s the case by ```ps
PS>py -c "#rprint(1)r#nprint(2)n#rnprint(3)"
1
2
3
I think CPython itself normalizes before running, which is why I can only observe this when running directly though generate_tokens, since this gives 10 instead of 13 ```PS
PS> py -c "print(ord('''`r'''))"
10
Describe the bug
formatting the following string takes ~35s on my machine:
f"""
{{"xxxxx": "xxx xxxx xx xx xxxxxxxxxx xxx xx xxxxxxxx xxxx xxxxxxxx xx xxxxxxxx xxxxxx xxxxxxxx xx xxx xxx xxxxxx xx xxxxxxxxxxx.", "xxxxxxx": ["xxxxxx xxxx xx xxxxx xxxx xxx xxxxxxxxx xxxxxx: xxxx xx xx xxxxxxx xx x xxxxx (xxxx xxxxx) xxxxxx xxxxx xxxx xxxxx xxxxxxxxxx x xxxx xxxx x xx x, xxxx x xxxxxxxxxxxxx xxxxxxxxxxx xxxxx:. xxxx xxx xxx xxxxx xx xxxxxxxx xxxxxxx xxxxxxxxx xxxxxx xxxx xx xxxxx ...
Signed-off-by: cobalt
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
oh tests failing, maybe they weren't so unneeded :p
the test failure is not obviously related but I didn't look deeply
oh it's on main too
might also be due to the click release
looks like it
https://github.com/psf/black/pull/4577 apparently didn't do what it tried to do
ohhhh, no it's working fine, mypy's just confused
i'll look further probably on tuesday
This patch fixes the test test_code_option_safe that's failing with click 8.2.0 after https://github.com/psf/black/pull/4591
what seems to be wrong with this code? it compiles on 3.9 and 3.12
@silent knoll thanks for looking into the \r thing! I was unavailable for a bit. The fix should most likely go into pytokens.
(that was @azure plank)
misclick :P
we pass a flag to pytokens in black for handling the carriage return edge cases (i think it's called handle_issue_128233 or something). this is another edge case that should be handled within that. If you want to give that a shot go ahead, I'll probably try to fix it Sunday.
fixing it there also has the added benefit of having a fully cpython compliant python tokenizer written in pure python.
it seems like mypy uses different versions of Click stubs depending on if it's run in the action vs on pre-commit.ci, so pre-commit.ci complains about an unknown parameter, but if i type:ignore it the action complains about unused type:ignore
I looked at the pytokens code, and I'm confused why a lone \r isn't considered a newline link to code
def is_whitespace(self) -> bool:
if self.is_newline():
return False
char = self.source[self.current_index]
return (
char == " "
or char == "\r"
or char == "\t"
or char == "\x0b"
or char == "\x0c"
)
def is_newline(self) -> bool:
if self.source[self.current_index] == "\n":
return True
if (
self.source[self.current_index] == "\r"
and self.current_index + 1 < len(self.source)
and self.source[self.current_index + 1] == "\n"
):
return True
return False
Why is \r considered whitespace instead of a newline? I'm probably missing something, but the python docs say it's a valid newline in 2.1.2 Physical lines
A physical line is a sequence of characters terminated by an end-of-line sequence. In source files and strings, any of the standard platform line termination sequences can be used - the Unix form using ASCII LF (linefeed), the Windows form using the ASCII sequence CR LF (return followed by linefeed), or the old Macintosh form using the ASCII CR (return) character. All of these forms can be used equally, regardless of platform.
Is it just for matching the behavior of the old blib2to3 tokenizer?
it's just mimicking cpython
Huh, I thought you could always use any return type on any platform
the docs may not be in line with the tokenize module
try piping some code to tokenize and pytokens
on python 3.13 and up, and if you see any divergence that's a bug
Hm, (jumping around a bit in thought), so then wouldn’t the simplest way to handle the 128233 issue be to consider \r as always a newline? Since the current workaround works, at least in that a strange op token isn’t produced, but the next line of code gets eaten by the comment since the \r is considered white space
And with this new knowledge, it's very easy to cook up some \r crashes, ie a=b\rc=d crashes since black sees a=b c=d, and a=b\r=d crashes with a saftey error since black sees a=b =d
is there a reason why we run pre-commit both in the action and through pre-commit.ci? it seems like pre-commit uses different versions of Click (and therefore its types) depending on if it's run in the action vs on pre-commit.ci
i think the website runner is caching the old version and i don't know that there's a way to clear it
probably no good reason
can we require the newer version somehow?
forgot the syntax but isn't there something like additional deps
yeah we can
the only reason i didn't is right now it's the same as the pyproject, and i didn't really want to bring them out of sync
or we could just bump it to 3.2.0 throught the whole project and remove the things we added to support both versions
that might be annoying for some users
if they install other apps in the same env that want older click
Hey guys, I created a python library called ParaTkinter (https://github.com/Proxypro2012/ParaTkinter/tree/main). It is a python package created to add beautiful mouse-pointer parallax effects/layouts into a (custom)tkinter application.
Just a data point, I was surprised by how black treated my code: reformatting some chained ternaries decreases their readability.
To Reproduce
assert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx == (
xxxxxxxxxxxxx if xxxxxxxxxxx == 0 else
xxxxxxxxxxxxxxxxxx if xxxxxxxxxxx == 1 else
xxxxxxxxxxxxxxxxxxxx
)
is reformatted as:
assert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx == (
xxxxxxx...
For anyone running black via pre-commit often and wishing it was snappier, I just released this pre-commit wrapper which uses JumpTheGun to make it start near-instantly:
https://pypi.org/project/jumpthegun-precommit-wrapper/
(Works for most other formatters/linters as well.)
Describe the bug
Originally I realized that in VSCode the black formatter does not format my code anymore, i.e. the --line-ranges is broken and raises a parser error.
Observation: Difference between black file.py and black --line-range #-# file.py
If there is a def foo(self): ... with ... on the same line black fails to format anything after when used with --line-range.
To Reproduce
For example, take this code:
class Foo:
@overload
def ...
Description
Fixes #4669
The issue happens because on a single line decorated item, due to the special handling of decorators there is a missing newline between the decorator(s) and decorated item. Like usual with my fixes, I approach it in the most blunt way possible: Add back in the missing newline. This should always be the correct thing to do, since multiline decorated items would have taken a different code path in _convert_unchanged_line_by_line that doesn't have this...
Currently getting bullied by the ci, one of the failures I could fix, but not sure how. The node.type == syms.decorated also implies that node is a node, not a leaf, since there shouldn’t be a leaf of type decorated, but I’m not sure how to tell mypy that. The diff-shades is failing because mypyc is failing inside the parser, but I don’t know why that’s just started now.
you can always add an assert isinstance(node, Node)
That’s a good idea
It looks like both the mypyc tests and diff-shades are now using the new mypy 1.16, so probably some improvement to mypyc is causing the failures
Description
This should fix the new failure happening with mypyc 1.16. I don't understand what was changed, and I also don't understand why the original code is so complex, so this reverts it to hopefully equivalent more normal code, which hopefully won't trip up mypyc.
I did not test this locally since I have no clue how.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary?- N/A, fixing CI failure, should not result in any changes at ru...
@lavish scroll Hypothesis found an error and I tracked down the cause, but I don't know how we should fix it.
await ... crashes the parser, since a ... op token (52 is op) (52, '...', (1, 6), (1, 9), 'await ...') slips through. tokenize.tokenize is supposed to fix that by turning a ... back into 3 .s, but in the case of await ..., the special handling for await takes precedence, and the token after the await gets to skip the later ... handling. I'm not sure how to cleanly deal with this since the ... handling has to happen on both paths, and I'm not comfortable enough with yields to pull it out into a function on my own, and you might have an ever better idea than that.
The right hand side is better than the left hand side, which is what you want out of a diff :-)
@azure plank is it a pytokens bug?
It's in the translation layer between pytoken's output and the tokens black expects
But pytokens itself is fine
i see, can you make a bug report? i can take it up
sure
The code await ... crashes the parser with error: cannot format : '...' locally / misparses into '...' online (not sure why the difference here, I think directly running __init__.py has more dev checks enabled?).
This happens because [`tokenize.token...
Nice
Description
This fixes another one of the hypothesis errors. It took me a long time to track down, but it was again in this translation layer:
Since transform_whitespace only checked for \\\n, any \\\r\n whitespace token would break everything. This is because since the offset adjustments never happened, on the token after the \\\r\n there would be a position mismatch, triggering the code to add a \n to the prefix of that token. This is fine for the first pass, but after ...
Description
This is my attempt at fixing the carriage return problems. In combination with https://github.com/tusharsadhwani/pytokens/pull/1 , this should fix the hypothesis errors around \r.
I'm making both PRs drafts since my changes were made with the consideration of a sledgehammer, and were just focused on getting the issue to go away, so I'm uncertain if I've accidentally broken other things. All the black tests pass, as well as a local hypothesis run gave no problems, but I...
Description
This fixes #2547 for the (default) case when g:black_use_virtualenv = 1.
The fix for g:black_use_virtualenv = 0 is a superset of these changes but is more invasive so I'll create a separate branch for it.
To trigger the bug on Linux:
- make sure you don't have
blackinstalled as a system package:apt purge black - launch vim built with Python 3.X
- run
:BlackVersion, let it finish creating the virtualenv, close vim - launch vim built with Python 3.Y
-...
Description
Fixes #4672
This resolves the await ... bug from hypothesis. By removing support for async/await as soft keywords, it allows for making the pytokens->black's expected tokens much simpler, and in doing so removes the issue causing a ... op token to slip through.
I'd like to clean up both the remaining async/await and ... transforms, but those require much more sweeping changes, so for now this just fixes the one error from hypothesis.
This removes ...
Describe the bug
When a long f-string is wrapped / split due to exceeding the line limit, Black will never put a substitution at the end of a f-string, resulting in unexpected wrapping behaviour.
To Reproduce
Input:
print(
f"short {1} loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"
)
Output with --unstable:
print(
"short"
f" {1} loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"
)
``...
Describe the style change
With PEP 758 and python 3.14 its possible to remove the braces around a except block.
I would like to propose that black will do this.
Examples in the current Black style
try:
pass
except (ValueError, TypeError):
pass
Desired style
try:
pass
except ValueError, TypeError:
pass
Additional context
https://peps.python.org/pep-0758/
Black is a cool code formatter but as many other projects that I like it is quite hard to contribute as the project is big and feels intimidating at the begining. That is why I want to improve this on-boarding (get-to-know) process for all people who want to help the OSS community.
This PR adds auto-generated high-level diagrams and component-level documentation using CodeBoarding, aimed at improving developer onboarding by making it easier to get to know the codebase and lowering the barr...
Description
Fixes #4677
My assumption on how the issue started is from a documentation issue on iter_fexpr_spans - the docs said "Spans are half-open ranges (left inclusive, right exclusive)", but it actually returns closed ranges. I assume the author of _get_illegal_split_indices then saw that, and added one to the range, making the ranges include the char after the f-string expr.
To fix this, I just removed that +1 to fix the ranges.
I looked at the other usages ...
^ I decided to look through some of the other PRs from that account, and there is a very funny and true statement on a similar matplotlib pr:
I am impressed with AI in topics I do not know much about, but in topics I know about, it is flawed
Olá, colegas espectadores do jogo Alemanha x Portugal. Semifinal da Liga das Nações da UEFA 2025. Sou fã do jogo Alemanha x Portugal. Semifinal da Liga das Nações da UEFA 2025 e, sem a TV Alemanha x Portugal.
🔴GO Live==►► CLICK HERE TO WATCH Live
🔴GO Live==►► CLICK HERE TO WATCH Live
Semifinal da Liga das Nações da UEFA 2025 disponível, estou procurando uma boa opção para assistir ao Weeks aqui na Austrália. Veja como posso encontrar a...
Describe the bug
After running pre-commit, the black hook removed an exception alias - it must've though it was redundant given a prior still-in-scope iterable of the same name e. Regardless that renaming e is a fix, this is still incorrect behavior, since the except block is of course referring to the alias.
for e in emails:
pass
...
- except Exception as e:
+ except Exception:
logger.error(f"err: {str(e)}")
To Reproduce
Description
Fixes #4647
As best I can tell, the error happens because in line gen, optional parenthesis get added:
def name_3[name_0: ([] if name_2 else name_3)](): pass
Then when left_hand_split runs, it mistakes the parenthesis inside the type params for the function arguments, and since it needs splitting adds a comma, which turns it into a tuple, and causes the equivalence error.
There's probably a better way to fix this, but since I don't understand t...
Description
I got annoyed with dealing with percent formatting, so I decided to convert them to f-strings.
I'm not 100% sure about the pytree change since it's a reduction in quality, but I did it anyways because consistency.
There are still a couple instances of percent formatting in places, but they deal with external things like logging or tests so I didn't touch them.
There's a few more things I'd like to modernize since older python runtimes have stopped support...
Looks good apart from the one I commented on
e5e5dad Fix await ellipses and remove async/await sof... - MeGaGiGaGon
7987951 Convert legacy string formatting to f-strings (... - MeGaGiGaGon
Description
Update python image to 3.13:
Python version 3.8 is EOL and the gallery.py script depends on type hinting functionality introduced in version 3.9.
Reduce size by adding --no-install-recommends and removing /var/lib/apt/lists/*:
This reduces the size of the resulting docker image (approx. 0.25Gb) by not installing of keeping unneeded files.
Checklist - did ...
Reformatting dict oddities
If the list has more than 6 dicts, only 6 dicts are formatted. Rest are formatted in one line. Even if reformatted manually, they get reset when black is rerun on the file.
Examples in the current Black style
client.collections.create(
{
"name": "sites",
"fields": [
...
{
"name": "placeType",
"type": "string",
},
{"name": "groupUuids", "type...
Thanks! All makes sense to me.
Will merge if CI is happy. Don't think we really test it here tho.
Description
This has the changes mentioned in #4685 for not having the driver always use debug True, since while running black normally there is no way to change the log level to make those debug log calls useful.
This also has a small improvement to the release.py file since while I was reading the docs I noticed a part of the docs that said pr welcome for this. I updated the comment detection logic using https://www.rexegg.com/regex-quantifiers.php#lazy_solution as fut...
Is your feature request related to a problem? Please describe.
It would be kinda helpful if black detecs comments used for pylint e.g. and move them to the correct line / trys to do that.
example the following inline statement:
query_plan = utils.__get_original_query_plan(file_content) # pylint: disable=protected-access # pyright: ignore[reportPrivateUsage]
gets formatted into this:
query_plan = utils.__get_original_query_plan(
file_content
) # pylint: disable=prot...
Description
MacOS CI started failing because it updated to 3.13.4 before the rest of the OSs. With the fixing of https://github.com/python/cpython/issues/129958 , some of the code in the pep_701 test is now invalid, so this makes that code valid by converting it to a multiline f-string. Since this was a change to the lexer in cpython, a corresponding change should be made in pytokens to fix this, so I'll open an issue there after I open this PR.
Checklist - did you ...
...
All changes make sense but I'd have put the parsing.py changes in a separate PR since they seem unrelated.
Description
This has the changes mentioned in #4685 for not having the driver always use debug True, since while running black normally there is no way to change the log level to make those debug log calls useful, and should give a very small speedup.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary?- N/A, no user facing changes made
- [x] Add / update tests if necessary?
- N/A, no tests affected
- [x] Add new / update outdated do...
Description
While reading the docs I noticed that there was a typo in the line ranges note, so this fixes that typo, and also makes it more clear what the potential issue might be with duplicate lines.
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary?- N/A small docs change
- [x] Add / update tests if necessary?
- N/A no tests affected
- [x] Add new / update outdated documentation?
I avoided regex's on purpose, cause they are evil, but don't have a better suggestion here :)
Description
I was bored so I decided to run all the ruff lints against src/black, and only fix the ones I liked, so here's the results. I tried my best to only pick ones that I thought made a clear improvement to the code without causing too much churn. All the reasoning is in the commit messages, but I also copied it here because github cuts it off.
SIM201 negate-equal-op seems reasonable
RUF010 explicit-f-string-type-conversion seems reasonable
RUF003 ambiguou...
Thanks - Will merge should CI pass.
Description
windows-2019 will be will be fully unsupported by 2025-06-30:
Replace it with windows-2025. Or alternatively windows-latest to save time in ~2031 :)
Checklist - did you ...
- [x] Add an entry in
CHANGES.mdif necessary? - [x] Add / update tests if necessary?
- [x] Add new / update outdated documentation?
Describe the bug
When upgrading our system Python to 3.13.5 test_simple_format test starts to fail:
[ 126s] =================================== FAILURES ===================================
[ 126s] _________________________ test_simple_format[pep_701] __________________________
[ 126s]
[ 126s] src = 'x = f"foo"\nx = f\'foo\'\nx = f"""foo"""\nx = f\'\'\'foo\'\'\'\nx = f"foo {{ bar {{ baz"\nx = f"foo {{ {2 + 2}bar {{ ...\'\'\'\n\'\'\'}"""\n\nf"{\'\\\'\'}"\nf"{f\'\\\'\'}"\n\nf\'{...
Description
Fixes #3498
Still need to move it to preview style - I can't easily access it within BracketTracker or is_split_before_delimiter()
Checklist - did you ...
- [y] Add an entry in
CHANGES.mdif necessary? - [y] Add / update tests if necessary?
- [y] Add new / update outdated documentation?
should i be able tow rite here?
#1632 is reproducible again.
Not sure when it got reintroduced, I am using the latest version (also tested the main branch with the browser app). I can confirm with v22.6.0, where it has been fixed once, it's also working on my machine as intended.
@azure plank what's the status on black#4674/pytokens#1? it's a bit difficult to create/review prs when tox is failing and I can't immediately tell if it's the same issue or not
from what i can tell, it looks like the prs are "ready" and you're just unsure if this is the best solution?
It’s both that, and I’m not sure how to handle this sort of cross-repo change, since it only works if you have the modifications from both the black and pytokens sides.
I’m also a lot more confident on the black side of things than the pytokens, since I’m making a much larger change on that side than on blacks.
interesting, i see
imo they probably shouldn't be drafts then, because for me a draft says "this isn't ready for review yet, please ignore it, just know i'm working on it", and in this case you do want feedback
df0ac36 New tests for better covering of tuples inside ... - Pedro-Muller29
8310a11 Add default exclusions and inclusions to docs (... - AshSta512
I make the black side PR a draft since even though it’s simple, it’s useless until the pytokens side is complete, and the pytokens side PR is a draft since my changes are very rough, and I think there’s a good chance tursharsadhwani will do something completely different. (They also said they were going to look at it a while ago, but I guess they never got the chance)
fair enough
I think the fix is right, but the change to the comment is wrong
Would like to ask, does black formatter work with marimo notebooks?
yes cause the files are just normal scripts i dont know if theres a plugin for it directly though to run
Describe the bug
No spacing between argument assignment operator when calling functions.
To Reproduce
For example, take this code:
apple(aapple=10,banana=20,charlie=30, delta=40, echo = 60, udvchuhbdichbasduhbfwdh=40, your_mums_nice_lady=69)
And run it with these arguments:
$ black file.py --target-version py39
The resulting error is:
apple(
aapple=10,
banana=20,
charlie=30,
delta=40,
echo=60,
udvchuhbdichbasduhbfwdh=40,
yo...
This PR adds a standardized DETAILS.md generated by Detailer to improve project onboarding, AI-agent integration, and maintainability.
Why DETAILS.md?
- Provides architecture overview automatically
- Optimized for AI assistants and IDEs
- Keeps docs in sync with code via automated generation
Add missing space in documentation
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Learn to plan your study time, balance workload, and avoid last-minute stress.
Description
Checklist - did you ...
- [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Input code:
# chain of 2 methods
foo = (
bar.do_something(longish, listof, arguments)
.do_something_else(also, a, long, listof, arguments)
)
# chain of 3 methods
other_foo = (
bar.do_something(longish, listof, arguments)
.do_something_else(also, a, long, listof, arguments)
.do_a_third_thing(the, final, long, listof, arguments)
)
Output code:
# chain of 2 methods, formatted by black
foo = bar.do_something(longish, listof, arguments).do_something_else(
al...
Description
This is another way to fix the issues with \r, and should permanently get rid of them - currently \r isn't included in the normalization due to limitations with io.BytesIO and probably other things. This PR makes it so that they are included in the normalization to \n, and are a valid target for all newlines to normalize to. This should permanently fix all \r-related issues, since now there will be none given to the tokenizer / parser / formatter internals...
CrackStreams provides live streams for all major MMA and UFC events, including Fight Nights, main events, and title matches. Enjoy uninterrupted ...When is UFC 318? How to watch Max Holloway vs. Dustin Poirier 3: TV, odds, predictions.[Here's How To Watch] UFC 318 Live Fight Streams On TV's ReddiT.[Here's How To Watch] UFC 318 Fight Live Stream On TV's ReddiT
[▶️Click Here 'Watch Now' UFC 318 Streams
[▶️Click Here 'Watch Now' [UFC 318 Streams](https://tinyurl...
CrackStreams provides live streams for all major MMA and UFC events, including Fight Nights, main events, and title matches. Enjoy uninterrupted ...When is UFC 318? How to watch Max Holloway vs. Dustin Poirier 3: TV, odds, predictions.[Here's How To Watch] UFC 318 Live Fight Streams On TV's ReddiT.[Here's How To Watch] UFC 318 Fight Live Stream On TV's ReddiT
[▶️Click Here 'Watch Now' UFC 318 Streams
[▶️Click Here 'Watch Now' [UFC 318 Streams](https://tinyurl...
Sorry for the delay in review. Looks pretty good! Just a few small things
Description
This PR adds an FAQ section on Windows emojis. The TDLR is "Black can't fix this, use Windows Terminal".
This closes #3156, as it will now be documented that the issues with emojis are not Black's problem.
One piece of relevant reading is #3374, specifically this comment by Jelle:
Coming back to this, I'm not enthusiastic about including this in Black:...
Please see https://github.com/astral-sh/ruff/issues/19536 for details.
I hope it's okay if I just link that ticket here. I opened it before realizing that I should probably direct my feedback here.
Thanks so much!
Description
Minor changes to the PR template. Mainly small grammar and formatting tweaks, but I also added information about the stability policy and a checkbox ensuring any code style changes were added to preview.
Checklist - did you ...
- [-] Add an entry in
CHANGES.mdif necessary? - [-] Add / update tests if necessary?
- [-] Add new / update outdated documentation?
Describe the bug
Use of asyncio.get_event_loop_policy(), which is deprecated as of Python 3.14, triggers DeprecationWarnings during test runs.
To Reproduce
- Install Python 3.14.
sudo apt install python3.14-dev python3.14-venv
The
devvariant is needed becauseaiohttpdoesn’t have wheels for Python 3.14 yet. Without it,piptries to build from source but fails due to missing Python headers.
- Clone the Black repository:
git clone https:/...
Description
Python 3.14 deprecates asyncio.get_event_loop_policy(), which causes multiple unit tests to emit warnings or fail. This PR replaces usage of the deprecated function with a modern alternative to ensure compatibility with Python 3.14+.
Checklist - did you ...
- [ ] Implement any code style changes under the
--previewstyle, following the
stability policy? - [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if neces...
Description
Closes: #4678
Previously, catching multiple exception types required writing:
try:
…
except (A, B, C):
…
With PEP 758 you can now omit the parentheses when you’re not using an as clause:
try:
…
except A, B, C:
…
This change streamlines the syntax, reduces visual clutter when catching several exceptions, and brings except closer in style to other comma‑separated constructs in the language.
This P...
bdd7fcd Fix test failures on Python 3.14 caused by depr... - ranjodhsingh1729
Describe the bug
In unit tests, specifying the --target-version flag raises AttributeError: 'tuple' object has no attribute 'append'.
To Reproduce
Just add # flags: --target-version=py310 on top of any unit test and then run with tox -e py.
The resulting error is:
AttributeError: 'tuple' object has no attribute 'append'.
Expected behavior
The unit test should be run with target_versions set to exactly what was specified.
Environment
- Black's ver...
Description
Fixes: #4721.
Checklist - did you ...
- [ ] Implement any code style changes under the
--previewstyle, following the
stability policy? - [ ] Add an entry in
CHANGES.mdif necessary? - [X] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
The problem is that when mode.target_versions is empty, supports_feature ends up evaluating to all([]), which returns True. That means supports_feature(empty_set, some_feature) incorrectly returns True, and Black removes parentheses from except types even on older Python versions. Modifying support_feature causes multiple tests to fail which seem to be relying this quirk so i just check before calling it.
that doesn't sound good
Describe the bug
I expect the wrapping to look nicer
To Reproduce
For example, take this code:
class Example:
@overload
@classmethod
def create_from[TBool: (Literal[True], Literal[False])](
cls: type[SearchConfig[Any]],
search_config: SearchConfig[Any],
*,
allow_boolean: TBool,
**overrides: Any,
) -> SearchConfig[TBool]: ...
And run it with these arguments:
$ black t.py --target-version py313 --line-...
There are code style rules for logical blocks in pycharm. Is it possible to make the same in black?
Describe the style change
If you have (...) = something, the LHS parenthesis, I think, should not be kept.
Examples in the current Black style
def a():
return 1, 2, 3
(b) = a()[0]
(c, *_) = a()
Desired style
def a():
return 1, 2, 3
b = a()[0]
c, *_ = a()
Apologies for the confusion earlier — I didn’t realize that some unit tests ( test_black) also check formatting of some source files. I was using another editor that didn’t auto-format on save, so the failures were due to formatting issues, not behavior changes (my mistake 😞). I’ve verified that tests pass on the main branch and will update the GitHub comment right away.
Also, should I add a patch to supports_feature to align current behavior with the expected one?
And once again sorry about that
Description
def supports_feature(target_versions: set[TargetVersion], feature: Feature) -> bool:
return all(feature in VERSION_TO_FEATURES[version] for version in target_versions)
Here when target_versions is empty, expression gets reduced to all([]) which evaluates to False which is not the correct behaviour.
Checklist - did you ...
- [ ] Implement any code style changes under the
--previewstyle, following the
stability p...
In my pyproject.toml: `black = { version = ">=25.1.0, Warning: The locked version 8.2.2 for click is a yanked version. Reason for being yanked: Unintended change in behavior of boolean options and None
Because no versions of black match >=25.0.0,25.1.0, So, because no versions of click match >=8.0.0
and {{project-name}} depends on black[d] (>=25.0.0,<26.0.0), version solving failed.
New to Black - is there an option to insert/validate line 1 of a file has the project path and name of the file as a comment - e.g. # srv/directory/myfile.py
No, Black is just for formatting your code. That would be the job of a linter, but as far as I'm aware no linter has that sort of functionality.
Describe the bug
#fmt: skip is ignored in the specific case demonstrated below.
To Reproduce
Let black format this piece of code:
class ClassWithALongName:
Constant1 = 1
Constant2 = 2
Constant3 = 3
def test():
if (
"cond1" == "cond1"
and "cond2" == "cond2"
and 1 in ( # fmt: skip
ClassWithALongName.Constant1,
ClassWithALongName.Constant2,
ClassWithALongName.Constant3,
)
):
...
Python ka vs course chahie
Describe the bug
Black crashes on the following valid python code:
class ClassWithALongName:
Constant1 = 1
Constant2 = 2
Constant3 = 3
def test():
if (
"cond1" == "cond1"
and "cond2" == "cond2"
and 1 in (
ClassWithALongName.Constant1,
ClassWithALongName.Constant2,
ClassWithALongName.Constant3, # fmt: skip
)
): # fmt: skip
return True
return False
To Reproduce
Jus...
Description
This PR improves the performance of the is_chained_assignment method by replacing a list comprehension followed by .count() with a generator expression passed to sum(). This change avoids building an intermediate list, which improves both memory efficiency and runtime.
The original implementation constructs an intermediate list of leaf.type values before calling .count(token.EQUAL). The updated version uses a generator expression to directly count match...
Cambios solucionados
Describe the bug
error: cannot format foo.py: INTERNAL ERROR: Black 25.1.1.dev56+gb3ae57b on Python (CPython) 3.13.5 produced different code on the second pass of the formatter. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_kir8cfms.log
To Reproduce
Minimal repro:
def foo():
possibly_redundant_lowlevel_checkpoints: list[ # pyright: ignore[reportUnknownVariableType]
cst.BaseExpression
] = field( ...
695d76d2c668fca4ce46f8a3d5d21c26ebcb66ab
_Originally posted by @cumcum8197 in https://github.com/bnb-chain/example-hub/pull/86#issuecomment-3130286359_
Description
This PR introduces an optimization for the Line.__str__ method, improving runtime efficiency when rendering lines.
The original implementation repeatedly concatenates strings using +=, which is inefficient in Python due to the creation of intermediate string objects.
The refactored version significantly speeds up string creation by replacing repeated concatenation (res += ...) with the much more efficient "".join() method.
This approach avoids creating a n...
Hello everyone, i'm new here
I'm a software developer and also a computer science student in uni
Hi @coarse quiver
Describe the bug
when formatting the following snippet
def func1[T: (int, str)](a,): ...
we get
def func1[T: (
int,
str,
)](a,): ...
we would expect:
def func[T: (int, str)](
a,
): ...
black version
black --version
black, 25.1.0 (compiled: yes)
Python (CPython) 3.12.7
Description
This PR changes diff-shades to run on the stable and unstable styles as opposed to the stable and preview styles.
I opted to replace the preview job with the unstable job instead of adding a new job because all preview changes also exist in unstable so running both feels redundant, and it takes a long time to run so it wouldn't be worth it to have both jobs.
I wasn't sure if the "preview-changes" mode was meant to be interpreted as "Changes in the preview style" or "Previ...
Description
Checklist - did you ...
- [ ] Implement any code style changes under the
--previewstyle, following the
stability policy? - [ ] Add an entry in
CHANGES.mdif necessary? - [ ] Add / update tests if necessary?
- [ ] Add new / update outdated documentation?
Code:
a=1 # aa
bb=2 # bb
ccc=3 # cc
will be formatted as:
a=1 # aa
bb=2 # bb
ccc=3 # cc
which is ugly...
I know Black has a statement that "it does not consider the current format". But for the above, let's be practical. The formatted one is ugly.
I've been an inactive maintainer for a long time now, but I don't have any concerns. As long as you've tested this and it has worked OK, I'd say you're good to press the :green_circle: button.
Hi
racist
4d55e60 Bump actions/setup-python from 5 to 6 (#4744) - dependabot[bot]
24f5169 ci: Run diff-shades on unstable instead of prev... - cobaltt7
Does black ever plan to stop developing now that a replacement tool (ruff format) exists?
No
Hi
hell yeah, thanks