Repository: psf/black

Issue:
Determine file type from `--stdin-filename`
**Is your feature request related to a problem? Please describe.**

Currently, `black` ignores the filename passed to `--stdin-filename` to determine if it is a python file or stub file for formatting. This is frustrating for me because I have to set up a separate file type for python stub files to use `coc.nvim` + `coc-diagnostic` in order to use a different command line invocation (adding `--pyi`) to process stub files.

**Describe the solution you'd like**

When `black` is invoked with `--stdin-filename`, it should set the `is_pyi` flag on the `Mode` like what is done at the beginning of `format_file_in_place()`.

Discussion:

Patch:
diff --git a/CHANGES.md b/CHANGES.md
index 6675c48..321f8c0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,11 @@
 ## Change Log
 
+### Unreleased
+
+#### _Black_
+
+- Set `--pyi` mode if `--stdin-filename` ends in `.pyi` (#2169)
+
 ### 21.4b2
 
 #### _Black_
diff --git a/src/black/__init__.py b/src/black/__init__.py
index 1c69cc4..49d088b 100644
--- a/src/black/__init__.py
+++ b/src/black/__init__.py
@@ -755,6 +755,8 @@ def reformat_one(
             is_stdin = False
 
         if is_stdin:
+            if src.suffix == ".pyi":
+                mode = replace(mode, is_pyi=True)
             if format_stdin_to_stdout(fast=fast, write_back=write_back, mode=mode):
                 changed = Changed.YES
         else:
diff --git a/src/black_primer/primer.json b/src/black_primer/primer.json
index 75469ad..5017a56 100644
--- a/src/black_primer/primer.json
+++ b/src/black_primer/primer.json
@@ -112,7 +112,7 @@
     },
     "tox": {
       "cli_arguments": [],
-      "expect_formatting_changes": true,
+      "expect_formatting_changes": false,
       "git_clone_url": "https://github.com/tox-dev/tox.git",
       "long_checkout": false,
       "py_versions": ["all"]
diff --git a/tox.ini b/tox.ini
index 71b02e9..affc3c9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,7 +9,7 @@ deps =
 commands =
     pip install -e .[d,python2]
     coverage erase
-    coverage run -m pytest tests
+    coverage run -m pytest tests {posargs}
     coverage report
 
 [testenv:fuzz]


Test patch:
diff --git a/tests/test_black.py b/tests/test_black.py
index c643f27..43368d4 100644
--- a/tests/test_black.py
+++ b/tests/test_black.py
@@ -1578,8 +1578,34 @@ def test_reformat_one_with_stdin_filename(self) -> None:
                 mode=DEFAULT_MODE,
                 report=report,
             )
-            fsts.assert_called_once()
-            # __BLACK_STDIN_FILENAME__ should have been striped
+            fsts.assert_called_once_with(
+                fast=True, write_back=black.WriteBack.YES, mode=DEFAULT_MODE
+            )
+            # __BLACK_STDIN_FILENAME__ should have been stripped
+            report.done.assert_called_with(expected, black.Changed.YES)
+
+    def test_reformat_one_with_stdin_filename_pyi(self) -> None:
+        with patch(
+            "black.format_stdin_to_stdout",
+            return_value=lambda *args, **kwargs: black.Changed.YES,
+        ) as fsts:
+            report = MagicMock()
+            p = "foo.pyi"
+            path = Path(f"__BLACK_STDIN_FILENAME__{p}")
+            expected = Path(p)
+            black.reformat_one(
+                path,
+                fast=True,
+                write_back=black.WriteBack.YES,
+                mode=DEFAULT_MODE,
+                report=report,
+            )
+            fsts.assert_called_once_with(
+                fast=True,
+                write_back=black.WriteBack.YES,
+                mode=replace(DEFAULT_MODE, is_pyi=True),
+            )
+            # __BLACK_STDIN_FILENAME__ should have been stripped
             report.done.assert_called_with(expected, black.Changed.YES)
 
     def test_reformat_one_with_stdin_and_existing_path(self) -> None:
@@ -1603,7 +1629,7 @@ def test_reformat_one_with_stdin_and_existing_path(self) -> None:
                 report=report,
             )
             fsts.assert_called_once()
-            # __BLACK_STDIN_FILENAME__ should have been striped
+            # __BLACK_STDIN_FILENAME__ should have been stripped
             report.done.assert_called_with(expected, black.Changed.YES)
 
     def test_gitignore_exclude(self) -> None: