Repository: psf/black
File: src/black/__init__.py (Python)

Code before:
    root = find_project_root(src)
    sources: Set[Path] = set()
    path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)
    gitignore = get_gitignore(root)

    for s in src:
        if s == "-" and stdin_filename:
            p = Path(stdin_filename)
            is_stdin = True
        else:
            p = Path(s)
            is_stdin = False

        if p.is_dir():
            sources.update(
                gen_python_files(
                    p.iterdir(),
                    root,
                    include_regex,
                    exclude_regex,
                    force_exclude_regex,
                    report,
                    gitignore,
                )
            )
        elif p.is_file():
            normalized_path = normalize_path_maybe_ignore(p, root, report)
            if normalized_path is None:
                continue

            normalized_path = "/" + normalized_path
            # Hard-exclude any files that matches the `--force-exclude` regex.
            if force_exclude_regex:
                force_exclude_match = force_exclude_regex.search(normalized_path)
            else:
                force_exclude_match = None
            if force_exclude_match and force_exclude_match.group(0):
                report.path_ignored(p, "matches the --force-exclude regular expression")
                continue

            if is_stdin:
                p = Path("__BLACK_STDIN_FILENAME__" / p)

            sources.add(p)
        elif s == "-":
            sources.add(p)
        else:
            err(f"invalid path: {s}")
    return sources



Review comment (bug):
```suggestion
        elif p.is_file() or is_stdin:
```

With a custom stdin filepath given, Black will try to format it in place as if it was a file:

```console
(black) ichard26@acer-ubuntu:~/programming/oss/black$ echo "print('hello world')" | black -v --stdin-filename="hello.py" -
Traceback (most recent call last):
  File "/home/ichard26/programming/oss/black/src/black/__init__.py", line 706, in reformat_one
    if changed is not Changed.CACHED and format_file_in_place(
  File "/home/ichard26/programming/oss/black/src/black/__init__.py", line 845, in format_file_in_place
    then = datetime.utcfromtimestamp(src.stat().st_mtime)
  File "/opt/python3.8.5/lib/python3.8/pathlib.py", line 1194, in stat
    return self._accessor.stat(self)
FileNotFoundError: [Errno 2] No such file or directory: 'hello.py'
error: cannot format hello.py: [Errno 2] No such file or directory: 'hello.py'
Oh no! 💥 💔 💥
1 file failed to reformat.
```

This is because `Path("-").is_file` returns `False` because a file doesn't actually exist at that path ([See `pathlib.Path.is_file` docs](https://docs.python.org/3.8/library/pathlib.html#pathlib.Path.is_file)). Therefore the path isn't prefixed with the magic string that tells `reformat_one` to use `format_stdin_to_stdout` and not `format_file_in_place`. Also `force-exclude` wouldn't be checked, but Black trying to format a file that doesn't exist is a bigger problem without this suggestion :-)

Code after:

    root = find_project_root(src)
    sources: Set[Path] = set()
    path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)
    gitignore = get_gitignore(root)

    for s in src:
        if s == "-" and stdin_filename:
            p = Path(stdin_filename)
            is_stdin = True
        else:
            p = Path(s)
            is_stdin = False

        if is_stdin or p.is_file():
            normalized_path = normalize_path_maybe_ignore(p, root, report)
            if normalized_path is None:
                continue

            normalized_path = "/" + normalized_path
            # Hard-exclude any files that matches the `--force-exclude` regex.
            if force_exclude_regex:
                force_exclude_match = force_exclude_regex.search(normalized_path)
            else:
                force_exclude_match = None
            if force_exclude_match and force_exclude_match.group(0):
                report.path_ignored(p, "matches the --force-exclude regular expression")
                continue

            if is_stdin:
                p = Path(f"{STDIN_PLACEHOLDER}{str(p)}")

            sources.add(p)
        elif p.is_dir():
            sources.update(
                gen_python_files(
                    p.iterdir(),
                    root,
                    include_regex,
                    exclude_regex,
                    force_exclude_regex,
                    report,
                    gitignore,
                )
            )
        elif s == "-":
            sources.add(p)
        else:
            err(f"invalid path: {s}")
    return sources