Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
Jelle Zijlstra [Sat, 4 Dec 2021 23:57:40 +0000 (15:57 -0800)]
Reorganize changelog (#2669)
I believe it would be useful to split up the long list of changes a bit more.
Specific changes:
- Removed the entry for new flake8 plugins; this is purely internal and not of interest to users
- Put regex in the packaging section
- New section for Jupyter Notebook
- New section for Python 3.10, mostly match/case stuff
Jelle Zijlstra [Thu, 2 Dec 2021 22:35:02 +0000 (14:35 -0800)]
Remove regex dependency (GH-2663)
We were no longer using it since GH-2644 and GH-2654. This should hopefully
make using Black easier to use as there's one less compiled dependency.
The core team also doesn't have to deal with the surprisingly frequent fires
the regex packaging setup goes through.
Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
Richard Si [Wed, 1 Dec 2021 23:05:59 +0000 (18:05 -0500)]
Treat functions/classes in blocks as if they're nested (GH-2472)
* Treat functions/classes in blocks as if they're nested
One curveball is that we still want two preceding newlines before blocks
that are probably logically disconnected. In other words:
if condition:
def foo():
return "hi"
# <- aside: this is the goal of this commit
else:
def foo():
return "cya"
# <- the two newlines spacing here should stay
# since this probably isn't related
with open("db.json", encoding="utf-8") as f:
data = f.read()
Unfortunately that means we have to special case specific clause types
instead of just being able to just for a colon leaf. The hack used here
is to check whether we're adding preceding newlines for a standalone or
dependent clause. "Standalone" being a clause that doesn't need another
clause to be valid (eg. if) and vice versa.
Jelle Zijlstra [Wed, 1 Dec 2021 02:01:36 +0000 (18:01 -0800)]
Reduce usage of regex (#2644)
This removes all but one usage of the `regex` dependency. Tricky bits included:
- A bug in test_black.py where we were incorrectly using a character range. Fix also submitted separately in #2643.
- `tokenize.py` was the original use case for regex (#1047). The important bit is that we rely on `\w` to match anything valid in an identifier, and `re` fails to match a few characters as part of identifiers. My solution is to instead match all characters *except* those we know to mean something else in Python: whitespace and ASCII punctuation. This will make Black able to parse some invalid Python programs, like those that contain non-ASCII punctuation in the place of an identifier, but that seems fine to me.
- One import of `regex` remains, in `trans.py`. We use a recursive regex to parse f-strings, and only `regex` supports that. I haven't thought of a better fix there (except maybe writing a manual parser), so I'm leaving that for now.
My goal is to remove the `regex` dependency to reduce the risk of breakage due to dependencies and make life easier for users on platforms without wheels.
Jameel Al-Aziz [Tue, 30 Nov 2021 16:20:27 +0000 (08:20 -0800)]
Remove hidden import from PyInstaller build (#2657)
The recent 2021.4 release of pyinstaller-hooks-contrib now contains a
built-in hook for platformdirs. Manually specifying the hidden import
arg should no longer be needed.
Daniel Sparing [Mon, 29 Nov 2021 23:07:35 +0000 (18:07 -0500)]
Return `NothingChanged` if non-Python cell magic is detected, to avoid tokenize error (#2630)
Fixes https://github.com/psf/black/issues/2627 , a non-Python cell magic such as `%%writeline` can legitimately contain "incorrect" indentation, however this causes `tokenize-rt` to return an error. To avoid this, `validate_cell` should early detect cell magics (just like it detects `TransformerManager` transformations).
Test added too, in the shape of a "badly indented" `%%writefile` within `test_non_python_magics`.
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com> Co-authored-by: Marco Edward Gorelli <marcogorelli@protonmail.com>
Batuhan Taskaya [Tue, 16 Nov 2021 02:38:40 +0000 (05:38 +0300)]
black/parser: optimize deepcopying nodes (#2611)
The implementation of the new backtracking logic depends heavily on deepcopying the current state of the parser before seeing one of the new keywords, which by default is an very expensive operations. On my system, formatting these 3 files takes 1.3 seconds.
```
$ touch tests/data/pattern_matching_*; time python -m black -tpy310 tests/data/pattern_matching_* 19ms
All done! ✨ 🍰 ✨
3 files left unchanged.
python -m black -tpy310 tests/data/pattern_matching_* 2,09s user 0,04s system 157% cpu 1,357 total
```
which can be optimized 3X if we integrate the existing copying logic (`clone`) to the deepcopy system;
```
$ touch tests/data/pattern_matching_*; time python -m black -tpy310 tests/data/pattern_matching_* 1ms
All done! ✨ 🍰 ✨
3 files left unchanged.
python -m black -tpy310 tests/data/pattern_matching_* 0,66s user 0,02s system 147% cpu 0,464 total
```
This still might have some potential, but that would be way trickier than this initial patch.
Richard Si [Fri, 12 Nov 2021 01:28:48 +0000 (20:28 -0500)]
Improve Python 2 only syntax detection (GH-2592)
* Improve Python 2 only syntax detection
First of all this fixes a mistake I made in Python 2 deprecation PR
using token.* to check for print/exec statements. Turns out that
for nodes with a type value higher than 256 its numeric type isn't
guaranteed to be constant. Using syms.* instead fixes this.
Also add support for the following cases:
print "hello, world!"
exec "print('hello, world!')"
def set_position((x, y), value):
pass
try:
pass
except Exception, err:
pass
raise RuntimeError, "I feel like crashing today :p"
`wow_these_really_did_exist`
10L
* Add octal support, more test cases, and fixup long ints
LordOfPolls [Sat, 6 Nov 2021 16:04:27 +0000 (16:04 +0000)]
Add a missing space in Python 2 deprecation (GH-2590)
`DEPRECATION: Python 2 support will be removed in the first stable releaseexpected in January 2022` - > `DEPRECATION: Python 2 support will be removed in the first stable release expected in January 2022`
install build-essential to compile dependencies and use multi-stage build (#2582)
- Install build-essential to avoid build issues like #2568 when dependencies don't have prebuilt wheels available
- Use multi-stage build instead of trying to purge packages and cache from the image
Copying `/root/.local/` installs only black's built Python dependencies (< 20 MB).
So the image is barely larger than python:3-slim base image
Richard Si [Sun, 31 Oct 2021 23:46:12 +0000 (19:46 -0400)]
Deprecate Python 2 formatting support (#2523)
* Prepare for Python 2 depreciation
- Use BlackRunner and .stdout in command line test
So the next commit won't break this test. This is in its own commit so
we can just revert the depreciation commit when dropping Python 2
support completely.
Nipunn Koorapati [Sat, 30 Oct 2021 18:54:43 +0000 (11:54 -0700)]
Use STDIN project in test_projects to ensure it runs quickly (#2575)
Existing test was actually running a full black-primer
run which could be slow. This goes from 8 seconds to
0.4 seconds on my machine.
Needed to move to top level scope to leverage the caplog
feature of pytest in order to test that the command line
was parsing the bogus arguments and dumping to stderr.
dawn [Sat, 30 Oct 2021 15:50:45 +0000 (11:50 -0400)]
fix: allow tests to be run from (hopefully) any directory (GH-2574)
* fix: allow tests to be run from the tests/ directory
* fix: try fixing windows build with MarcoGorelli's suggestion
* Windows hotfix + better respect test's spirit
Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
Nipunn Koorapati [Thu, 28 Oct 2021 17:35:37 +0000 (10:35 -0700)]
black-primer: Print summary after individual failures (#2570)
If the individual failures are verbose, it's useful to have
the summary at the end. Otherwise, it can be really difficult
to figure out which projects have an issue.
Nipunn Koorapati [Wed, 27 Oct 2021 14:37:20 +0000 (07:37 -0700)]
Print out line diff on test failure (#2552)
It currently prints both ASTs - this also
adds the line diff, making it much easier to visualize
the changes as well. Not too verbose since it's only a diff.
Jelle Zijlstra [Thu, 21 Oct 2021 15:02:38 +0000 (08:02 -0700)]
Define a stability policy (#2529)
Fixes #2394. Eventually fixes #517.
This is essentially @pradyunsg's suggestion from #2394. I suggest that at the
same time we start the formal stability policy, we take a few other disruptive steps
and drop Python 2 and the "b" marker.
Richard Si [Sat, 2 Oct 2021 23:37:32 +0000 (19:37 -0400)]
MNT: remove unnecessary test deps + some refactoring (GH-2510)
The main goals of this commit include:
* improving consistency on how strict the test suite is -- Jelle has
seen cases where a test did not fail to an incomplete test setup
even though it should've
* simplifying tests for both ease of creation and reading via
parametrization and helpers
* reorganizing the test suite by grouping more tests
* dropping test suite dependencies that aren't strictly necessary
The test suite could definitely do with more refactoring, but this is a
good first pass. Anyway it would've gotten too big to review effectively
if I did continue on this PR.
Commit history before squash merge:
* Drop parameterized dep and refactor format tests
Since the test suite is already using pytest-only features we can drop
the parameterized test dependency in favour of pytest's own offering.
I also added an utility function called assert_format that makes it
even easier to verify Black formats some code correctly. We already
have great tooling if the case is very simple in test_format.py but
any sort of complication makes it hard to use. Also if you're writing
a non-standard test case, you have to be careful to include all of
the steps so issues don't go undetected. assert_format aims to
1) improve consistency, 2) avoid wasted CPU cycles, and 3) avoid
logical errors that hide issues.
Finally, quite a few tests were either moved and/or simplified with
the new setup.
* Move file collection tests
* Add assert_collected_sources helper function
Testing source collection involves a lot of repetitive boilerplate,
something that black.files.get_sources's signature does not help with.
So to cut down on boilerplate like `report=black.Report()` I added
a convenience function to tests/test_black.py which wraps
black.get_sources. Its signature is designed to be much more lax to
make it much easier to use. Somehow this leads to cutting 100 lines!
Also IMO the test cases are much easier to read since it's more
declarative than really procedural now.
* Run isort on some test files
* Move cache tests
* Use pytest-style asserts & add parametrization
* Drop now unnecessary test dependencies
*pytest-cases might be interesting for further refactoring but I
haven't been able to wrap my head around it for the time being. We
can always revisit anyway.
This release includes an important security fix
(https://github.com/aio-libs/aiohttp/security/advisories/GHSA-v6wp-4m6f-gcjg) and many
other improvements.
* add changelog entry
* Let's not forget about Pipfile
Co-authored-by: Richard Si <63936253+ichard26@users.noreply.github.com>
Add new platformdirs dependencies as hidden imports when creating
PyInstaller-based binaries.
platformdirs imports the module for each platform dynamically, which
PyInstaller is unable to correctly detect for packing. By adding the
modules as hidden imports, we are telling PyInstaller to include the
modules in the packaged binary.
This issue seems to have been introduce when switching to platformdirs
in #2375. fixes #2464
Commit history before merge:
* Add hidden import to PyInstaller build
Add new platformdirs dependency as a hidden import when creating
PyInstaller based binaries.
* Only include the platformdirs for the relevant os
Richard Si [Sun, 29 Aug 2021 21:04:49 +0000 (17:04 -0400)]
Exclude broken typing-extensions version + fix import (#2460)
re. import, the ipynb code was assuming that typing-extensions would
always be available, but that's not the case! There's an environment
marker on the requirement meaning it won't get installed on 3.10 or
higher. The test suite didn't catch this issue since aiohttp pulls in
typing-extensions unconditionally.