psf/black

INTERNAL ERROR: Black produced code that is not equivalent to the source

Closed this issue · 4 comments

Describe the bug

Formatting the code snippet below produces an internal error.

To Reproduce

Format the following code snippet:

foo(
    bar()    # fmt: skip
  + bar()    # fmt: skip
)

The resulting error is:

INTERNAL ERROR: Black 24.10.1.dev3+g9995bff on Python (CPython) 3.12.5 produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: /tmp/blk_vu09qp1g.log

Log:

INTERNAL ERROR: Black 24.10.1.dev3+g9995bff on Python (CPython) 3.12.5 produced code that is not equivalent to the source.  Please report a bug on https://github.com/psf/black/issues.  This diff might be helpful: /tmp/blk_vu09qp1g.log

--- src
+++ dst
@@ -2,41 +2,22 @@
     body=
     Expr(
         value=
         Call(
             args=
-            BinOp(
-                left=
-                Call(
-                    args=
-                    func=
-                    Name(
-                        ctx=
-                        Load(
-                        )  # /Load
-                        id=
-                        'bar',  # str
-                    )  # /Name
-                    keywords=
-                )  # /Call
-                op=
-                Add(
-                )  # /Add
-                right=
-                Call(
-                    args=
-                    func=
-                    Name(
-                        ctx=
-                        Load(
-                        )  # /Load
-                        id=
-                        'bar',  # str
-                    )  # /Name
-                    keywords=
-                )  # /Call
-            )  # /BinOp
+            Call(
+                args=
+                func=
+                Name(
+                    ctx=
+                    Load(
+                    )  # /Load
+                    id=
+                    'bar',  # str
+                )  # /Name
+                keywords=
+            )  # /Call
             func=
             Name(
                 ctx=
                 Load(
                 )  # /Load

Expected behavior

The lines should be left untouched.

Environment

  • Black's version: Black 24.10.1.dev3+g9995bff
  • OS and Python version: Python (CPython) 3.12.5

Can also be reproduced on https://black.vercel.app/?version=main&state=_Td6WFoAAATm1rRGAgAhARYAAAB0L-Wj4ADHAGZdAD2IimZxl1N_WlkOE2WKO8q04xFLHliTY02DINaThb5NmXp3LURBIVoPx1hVWZbZyQHzS7z4xwAjKn-Mq7mHuHTZTmuDTTSwvMjOpdZEDkCdYF5Qlw2K-7fLc9LT6VrsBXcNyBZpZgAAANIVr-TpMphLAAGCAcgBAABg5HYfscRn-wIAAAAABFla .

Black 24.10.1.dev3+g9995bff

Hmm, we should ban running on 3.12.5 as of #4447 , because an upstream memory safety issue can cause AST safety checks to fail. Do you have a local repro, if so, could you figure out why the check against 3.12.5 isn't working for you?

Looks like the issue is unrelated to that, though. Probably a duplicate of #3608

Hmm, we should ban running on 3.12.5 as of #4447, because an upstream memory safety issue can cause AST safety checks to fail.

Just to clarify, Python 3.12.5 was being used in the playground, and I was able to reproduce the same issue locally as well. My local setup uses Black 24.10.0 and CPython 3.11.2.

Do you have a local repro? If so, could you figure out why the check against 3.12.5 isn't working for you?

Yes, I was able to reproduce the issue locally with Black 24.10.0 and CPython 3.11.2. The same internal error occurs with the provided code snippet.

Another piece of code that seems to hit this bug (happens at least with 3.11-3.13):

Mode(target_versions={<TargetVersion.PY310: 10>}, line_length=88, string_normalization=True, is_pyi=False, is_ipynb=False, skip_source_first_line=False, magic_trailing_comma=True, python_cell_magics=set(), preview=False, unstable=False, enabled_features=set())
--- source
+++ first pass
@@ -261,12 +261,13 @@
 def set_collections_basedir(basedir: Path) -> None:
     """Set the playbook directory as playbook_paths for the collection loader."""
     # Ansible expects only absolute paths inside `playbook_paths` and will
     # produce weird errors if we use a relative one.
     # pyright: ignore[reportAttributeAccessIssue]
-    AnsibleCollectionConfig.playbook_paths = (  # pyright: ignore[reportAttributeAccessIssue]
-        str(basedir.resolve()))
+    AnsibleCollectionConfig.playbook_paths = (
+        str(basedir.resolve())  # pyright: ignore[reportAttributeAccessIssue]
+    )
 
 
 def template(
     basedir: Path,
     value: Any,
@@ -959,19 +960,23 @@
                         raise RuntimeError(msg)
     else:
         yield from each_entry(data, position)
 
 
-def add_action_type(actions: AnsibleBaseYAMLObject, action_type: str) -> AnsibleSequence:
+def add_action_type(
+    actions: AnsibleBaseYAMLObject, action_type: str
+) -> AnsibleSequence:
     """Add action markers to task objects."""
     results = AnsibleSequence()
     if isinstance(actions, Iterable):
         for action in actions:
             # ignore empty task
             if not action:
                 continue
-            action["__ansible_action_type__"] = BLOCK_NAME_TO_ACTION_TYPE_MAP[action_type]
+            action["__ansible_action_type__"] = BLOCK_NAME_TO_ACTION_TYPE_MAP[
+                action_type
+            ]
             results.append(action)
     return results
 
 
 @cache
@@ -998,11 +1003,13 @@
     # signature of AnsibleConstructor.construct_mapping
     def construct_mapping(
         node: yaml.MappingNode,
         deep: bool = False,  # noqa: FBT002
     ) -> AnsibleMapping:
-        mapping = AnsibleConstructor.construct_mapping(loader, node, deep=deep)  # pyright: ignore[reportArgumentType]
+        mapping = AnsibleConstructor.construct_mapping(
+            loader, node, deep=deep
+        )  # pyright: ignore[reportArgumentType]
         if hasattr(node, LINE_NUMBER_KEY):
             mapping[LINE_NUMBER_KEY] = getattr(node, LINE_NUMBER_KEY)
         else:
             mapping[LINE_NUMBER_KEY] = mapping._line_number  # noqa: SLF001
         mapping[FILENAME_KEY] = lintable.path
--- first pass
+++ second pass
@@ -261,13 +261,13 @@
 def set_collections_basedir(basedir: Path) -> None:
     """Set the playbook directory as playbook_paths for the collection loader."""
     # Ansible expects only absolute paths inside `playbook_paths` and will
     # produce weird errors if we use a relative one.
     # pyright: ignore[reportAttributeAccessIssue]
-    AnsibleCollectionConfig.playbook_paths = (
-        str(basedir.resolve())  # pyright: ignore[reportAttributeAccessIssue]
-    )
+    AnsibleCollectionConfig.playbook_paths = str(
+        basedir.resolve()
+    )  # pyright: ignore[reportAttributeAccessIssue]
 
 
 def template(
     basedir: Path,
     value: Any,

Still, in my case, I have no case of using no fmt comments.

I opened an issue for your example at #4519

Seems different from OP's case, which I think is a duplicate of #3608