Skip to content

Commit

Permalink
Merge branch 'main' into deprecate-python-two
Browse files Browse the repository at this point in the history
  • Loading branch information
JelleZijlstra committed Oct 30, 2021
2 parents 07ff8f9 + 9afffac commit c8de399
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 137 deletions.
59 changes: 38 additions & 21 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,58 @@ labels: "T: bug"
assignees: ""
---

<!--
Please make sure that the bug is not already fixed either in newer versions or the
current development version. To confirm this, you have three options:
1. Update Black's version if a newer release exists: `pip install -U black`
2. Use the online formatter at <https://black.vercel.app/?version=main>, which will use
the latest main branch.
3. Or run _Black_ on your machine:
- create a new virtualenv (make sure it's the same Python version);
- clone this repository;
- run `pip install -e .[d,python2]`;
- run `pip install -r test_requirements.txt`
- make sure it's sane by running `python -m pytest`; and
- run `black` like you did last time.
-->

**Describe the bug**

<!-- A clear and concise description of what the bug is. -->

**To Reproduce**

<!-- Steps to reproduce the behavior:
<!--
Minimal steps to reproduce the behavior with source code and Black's configuration.
-->

For example:
1. Take this file '...'
1. Run _Black_ on it with these arguments '...'
1. See error -->
For example, take this code:

**Expected behavior**
```python
this = "code"
```

<!-- A clear and concise description of what you expected to happen. -->
And run it with these arguments:

**Environment (please complete the following information):**
```sh
$ black file.py --target-version py39
```

- Version: <!-- e.g. [main] -->
- OS and Python version: <!-- e.g. [Linux/Python 3.7.4rc1] -->
The resulting error is:

**Does this bug also happen on main?**
> cannot format file.py: INTERNAL ERROR: ...
<!-- To answer this, you have two options:
**Expected behavior**

1. Use the online formatter at <https://black.vercel.app/?version=main>, which will use
the latest main branch.
1. Or run _Black_ on your machine:
- create a new virtualenv (make sure it's the same Python version);
- clone this repository;
- run `pip install -e .[d,python2]`;
- run `pip install -r test_requirements.txt`
- make sure it's sane by running `python -m pytest`; and
- run `black` like you did last time. -->
<!-- A clear and concise description of what you expected to happen. -->

**Environment**

<!-- Please complete the following information: -->

- Black's version: <!-- e.g. [main] -->
- OS and Python version: <!-- e.g. [Linux/Python 3.7.4rc1] -->

**Additional context**

Expand Down
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@
- Fixed feature detection for positional-only arguments in lambdas (#2532)
- Bumped typed-ast version minimum to 1.4.3 for 3.10 compatiblity (#2519)
- Deprecate Python 2 formatting support (#2523)
- Fixed a Python 3.10 compatibility issue where the loop argument was still being passed
even though it has been removed (#2580)

### _Blackd_

- Remove dependency on aiohttp-cors (#2500)
- Bump required aiohttp version to 3.7.4 (#2509)

### _Black-Primer_

- Add primer support for --projects (#2555)
- Print primer summary after individual failures (#2570)

### Integrations

- Allow to pass `target_version` in the vim plugin (#1319)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Twisted, LocalStack, every Datadog Agent Integration, Home Assistant, Zulip, Ked
many more.

The following organizations use _Black_: Facebook, Dropbox, Mozilla, Quora, Duolingo,
QuantumBlack.
QuantumBlack, Tesla.

Are we missing anyone? Let us know.

Expand Down
16 changes: 8 additions & 8 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ strict_optional=True
warn_no_return=True
warn_redundant_casts=True
warn_unused_ignores=True
# Until we're not supporting 3.6 primer needs this
disallow_any_generics=False
disallow_any_generics=True

# The following are off by default. Flip them on if you feel
# adventurous.
Expand All @@ -33,9 +32,10 @@ check_untyped_defs=True
# No incremental mode
cache_dir=/dev/null

[mypy-aiohttp.*]
follow_imports=skip
[mypy-black]
# The following is because of `patch_click()`. Remove when
# we drop Python 3.6 support.
warn_unused_ignores=False
[mypy-black_primer.*]
# Until we're not supporting 3.6 primer needs this
disallow_any_generics=False

[mypy-tests.test_primer]
# Until we're not supporting 3.6 primer needs this
disallow_any_generics=False
17 changes: 10 additions & 7 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def validate_regex(
ctx: click.Context,
param: click.Parameter,
value: Optional[str],
) -> Optional[Pattern]:
) -> Optional[Pattern[str]]:
try:
return re_compile_maybe_verbose(value) if value is not None else None
except re.error:
Expand Down Expand Up @@ -388,10 +388,10 @@ def main(
quiet: bool,
verbose: bool,
required_version: str,
include: Pattern,
exclude: Optional[Pattern],
extend_exclude: Optional[Pattern],
force_exclude: Optional[Pattern],
include: Pattern[str],
exclude: Optional[Pattern[str]],
extend_exclude: Optional[Pattern[str]],
force_exclude: Optional[Pattern[str]],
stdin_filename: Optional[str],
workers: int,
src: Tuple[str, ...],
Expand Down Expand Up @@ -763,7 +763,10 @@ async def schedule_formatting(
sources_to_cache.append(src)
report.done(src, changed)
if cancelled:
await asyncio.gather(*cancelled, loop=loop, return_exceptions=True)
if sys.version_info >= (3, 7):
await asyncio.gather(*cancelled, return_exceptions=True)
else:
await asyncio.gather(*cancelled, loop=loop, return_exceptions=True)
if sources_to_cache:
write_cache(cache, sources_to_cache, mode)

Expand Down Expand Up @@ -1302,7 +1305,7 @@ def patch_click() -> None:
"""
try:
from click import core
from click import _unicodefun # type: ignore
from click import _unicodefun
except ModuleNotFoundError:
return

Expand Down
9 changes: 6 additions & 3 deletions src/black/concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ def shutdown(loop: asyncio.AbstractEventLoop) -> None:

for task in to_cancel:
task.cancel()
loop.run_until_complete(
asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)
)
if sys.version_info >= (3, 7):
loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True))
else:
loop.run_until_complete(
asyncio.gather(*to_cancel, loop=loop, return_exceptions=True)
)
finally:
# `concurrent.futures.Future` objects cannot be cancelled once they
# are already running. There might be some when the `shutdown()` happened.
Expand Down
72 changes: 37 additions & 35 deletions src/black/handle_ipynb_magics.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@
)
NON_PYTHON_CELL_MAGICS = frozenset(
(
"%%bash",
"%%html",
"%%javascript",
"%%js",
"%%latex",
"%%markdown",
"%%perl",
"%%ruby",
"%%script",
"%%sh",
"%%svg",
"%%writefile",
"bash",
"html",
"javascript",
"js",
"latex",
"markdown",
"perl",
"ruby",
"script",
"sh",
"svg",
"writefile",
)
)
TOKEN_HEX = secrets.token_hex
Expand Down Expand Up @@ -230,10 +230,11 @@ def replace_cell_magics(src: str) -> Tuple[str, List[Replacement]]:
cell_magic_finder.visit(tree)
if cell_magic_finder.cell_magic is None:
return src, replacements
if cell_magic_finder.cell_magic.header.split()[0] in NON_PYTHON_CELL_MAGICS:
if cell_magic_finder.cell_magic.name in NON_PYTHON_CELL_MAGICS:
raise NothingChanged
mask = get_token(src, cell_magic_finder.cell_magic.header)
replacements.append(Replacement(mask=mask, src=cell_magic_finder.cell_magic.header))
header = cell_magic_finder.cell_magic.header
mask = get_token(src, header)
replacements.append(Replacement(mask=mask, src=header))
return f"{mask}\n{cell_magic_finder.cell_magic.body}", replacements


Expand Down Expand Up @@ -311,11 +312,26 @@ def _is_ipython_magic(node: ast.expr) -> TypeGuard[ast.Attribute]:
)


def _get_str_args(args: List[ast.expr]) -> List[str]:
str_args = []
for arg in args:
assert isinstance(arg, ast.Str)
str_args.append(arg.s)
return str_args


@dataclasses.dataclass(frozen=True)
class CellMagic:
header: str
name: str
params: Optional[str]
body: str

@property
def header(self) -> str:
if self.params:
return f"%%{self.name} {self.params}"
return f"%%{self.name}"


@dataclasses.dataclass
class CellMagicFinder(ast.NodeVisitor):
Expand Down Expand Up @@ -345,14 +361,8 @@ def visit_Expr(self, node: ast.Expr) -> None:
and _is_ipython_magic(node.value.func)
and node.value.func.attr == "run_cell_magic"
):
args = []
for arg in node.value.args:
assert isinstance(arg, ast.Str)
args.append(arg.s)
header = f"%%{args[0]}"
if args[1]:
header += f" {args[1]}"
self.cell_magic = CellMagic(header=header, body=args[2])
args = _get_str_args(node.value.args)
self.cell_magic = CellMagic(name=args[0], params=args[1], body=args[2])
self.generic_visit(node)


Expand Down Expand Up @@ -404,12 +414,8 @@ def visit_Assign(self, node: ast.Assign) -> None:
and _is_ipython_magic(node.value.func)
and node.value.func.attr == "getoutput"
):
args = []
for arg in node.value.args:
assert isinstance(arg, ast.Str)
args.append(arg.s)
assert args
src = f"!{args[0]}"
(arg,) = _get_str_args(node.value.args)
src = f"!{arg}"
self.magics[node.value.lineno].append(
OffsetAndMagic(node.value.col_offset, src)
)
Expand All @@ -435,11 +441,7 @@ def visit_Expr(self, node: ast.Expr) -> None:
and we look for instances of any of the latter.
"""
if isinstance(node.value, ast.Call) and _is_ipython_magic(node.value.func):
args = []
for arg in node.value.args:
assert isinstance(arg, ast.Str)
args.append(arg.s)
assert args
args = _get_str_args(node.value.args)
if node.value.func.attr == "run_line_magic":
if args[0] == "pinfo":
src = f"?{args[1]}"
Expand Down

0 comments on commit c8de399

Please sign in to comment.