import os
from pathlib import Path
from pathspec.patterns.gitwildmatch import GitWildMatchPatternError
-import regex as re
+import re
import signal
import sys
import tokenize
Union,
)
-from dataclasses import replace
import click
+from dataclasses import replace
+from mypy_extensions import mypyc_attr
from black.const import DEFAULT_LINE_LENGTH, DEFAULT_INCLUDES, DEFAULT_EXCLUDES
from black.const import STDIN_PLACEHOLDER
remove_trailing_semicolon,
put_trailing_semicolon_back,
TRANSFORMED_MAGICS,
+ PYTHON_CELL_MAGICS,
jupyter_dependencies_are_installed,
)
from _black_version import version as __version__
+COMPILED = Path(__file__).suffix in (".pyd", ".so")
+
# types
FileContent = str
Encoding = str
) -> Optional[Pattern[str]]:
try:
return re_compile_maybe_verbose(value) if value is not None else None
- except re.error:
- raise click.BadParameter("Not a valid regular expression") from None
+ except re.error as e:
+ raise click.BadParameter(f"Not a valid regular expression: {e}") from None
-@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
+@click.command(
+ context_settings={"help_option_names": ["-h", "--help"]},
+ # While Click does set this field automatically using the docstring, mypyc
+ # (annoyingly) strips 'em so we need to set it here too.
+ help="The uncompromising code formatter.",
+)
@click.option("-c", "--code", type=str, help="Format the code passed in as a string.")
@click.option(
"-l",
" due to exclusion patterns."
),
)
-@click.version_option(version=__version__)
+@click.version_option(
+ version=__version__,
+ message=f"%(prog)s, %(version)s (compiled: {'yes' if COMPILED else 'no'})",
+)
@click.argument(
"src",
nargs=-1,
experimental_string_processing: bool,
quiet: bool,
verbose: bool,
- required_version: str,
+ required_version: Optional[str],
include: Pattern[str],
exclude: Optional[Pattern[str]],
extend_exclude: Optional[Pattern[str]],
report.failed(src, str(exc))
+# diff-shades depends on being to monkeypatch this function to operate. I know it's
+# not ideal, but this shouldn't cause any issues ... hopefully. ~ichard26
+@mypyc_attr(patchable=True)
def reformat_many(
sources: Set[Path],
fast: bool,
worker_count = workers if workers is not None else DEFAULT_WORKERS
if sys.platform == "win32":
# Work around https://bugs.python.org/issue26903
+ assert worker_count is not None
worker_count = min(worker_count, 60)
try:
executor = ProcessPoolExecutor(max_workers=worker_count)
- except (ImportError, OSError):
+ except (ImportError, NotImplementedError, OSError):
# we arrive here if the underlying system does not support multi-processing
# like in AWS Lambda or Termux, in which case we gracefully fallback to
# a ThreadPoolExecutor with just a single worker (more workers would not do us
def validate_cell(src: str) -> None:
- """Check that cell does not already contain TransformerManager transformations.
+ """Check that cell does not already contain TransformerManager transformations,
+ or non-Python cell magics, which might cause tokenizer_rt to break because of
+ indentations.
If a cell contains ``!ls``, then it'll be transformed to
``get_ipython().system('ls')``. However, if the cell originally contained
"""
if any(transformed_magic in src for transformed_magic in TRANSFORMED_MAGICS):
raise NothingChanged
+ if src[:2] == "%%" and src.split()[0][2:] not in PYTHON_CELL_MAGICS:
+ raise NothingChanged
def format_cell(src: str, *, fast: bool, mode: Mode) -> str: