Improve fmt:skip handling in nested expressions with checks (#4903)

* Fix #4730: honor fmt: skip in nested in-clause

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
diff --git a/CHANGES.md b/CHANGES.md
index 3924cfe..d9b50cb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,8 @@
 
 <!-- Changes that affect Black's stable style -->
 
+- Fix `# fmt: skip` being ignored in nested `if` expressions with parenthesized `in`
+  clauses (#4903)
 - Fix crash when an f-string follows a `# fmt: off` comment inside brackets (#5097)
 - Add support for unpacking in comprehensions (PEP 798) and for lazy imports (PEP 810),
   both new syntactic features in Python 3.15 (#5048)
diff --git a/src/black/comments.py b/src/black/comments.py
index b3dda1d..3487647 100644
--- a/src/black/comments.py
+++ b/src/black/comments.py
@@ -7,6 +7,7 @@
 from black.mode import Mode
 from black.nodes import (
     CLOSING_BRACKETS,
+    OPENING_BRACKETS,
     STANDALONE_COMMENT,
     STATEMENT,
     WHITESPACE,
@@ -448,6 +449,14 @@ def stringify_node(n: LN) -> str:
 
     hidden_value = "".join(parts)
     comment_lineno = leaf.lineno - comment.newlines
+    leaf_is_ignored = any(
+        ignored is leaf
+        or (
+            isinstance(ignored, Node)
+            and any(child is leaf for child in ignored.leaves())
+        )
+        for ignored in ignored_nodes
+    )
 
     if contains_fmt_directive(comment.value, FMT_OFF):
         fmt_off_prefix = ""
@@ -461,7 +470,7 @@ def stringify_node(n: LN) -> str:
         standalone_comment_prefix += fmt_off_prefix
         hidden_value = comment.value + "\n" + hidden_value
 
-    if is_fmt_skip:
+    if is_fmt_skip and not leaf_is_ignored:
         hidden_value += comment.leading_whitespace + comment.value
 
     if hidden_value.endswith("\n"):
@@ -630,6 +639,17 @@ def _get_compound_statement_header(
     return header_leaves
 
 
+def _find_closest_previous_sibling(node: LN) -> LN | None:
+    """Find the closest previous sibling by walking up the ancestor chain."""
+    current: LN | None = node
+    while current is not None:
+        prev_sibling = current.prev_sibling
+        if prev_sibling is not None:
+            return prev_sibling
+        current = current.parent
+    return None
+
+
 def _generate_ignored_nodes_from_fmt_skip(
     leaf: Leaf, comment: ProtoComment, mode: Mode
 ) -> Iterator[LN]:
@@ -643,12 +663,13 @@ def _generate_ignored_nodes_from_fmt_skip(
     if not comments or comment.value != comments[0].value:
         return
 
-    if not prev_sibling and parent:
+    if prev_sibling is None and parent is not None:
         prev_sibling = parent.prev_sibling
 
-    if prev_sibling is not None:
-        leaf.prefix = leaf.prefix[comment.consumed :]
+    if prev_sibling is None and comment.type == token.COMMENT:
+        prev_sibling = _find_closest_previous_sibling(leaf)
 
+    if prev_sibling is not None:
         # Generates the nodes to be ignored by `fmt: skip`.
 
         # Nodes to ignore are the ones on the same line as the
@@ -669,6 +690,14 @@ def _generate_ignored_nodes_from_fmt_skip(
         # or NEWLINE leaves.
 
         current_node = prev_sibling
+        if (
+            isinstance(current_node, Leaf)
+            and current_node.type in OPENING_BRACKETS
+            and current_node.parent
+            and current_node.parent.type == syms.atom
+        ):
+            current_node = current_node.parent
+
         ignored_nodes = [current_node]
         if current_node.prev_sibling is None and current_node.parent is not None:
             current_node = current_node.parent
@@ -734,6 +763,17 @@ def _generate_ignored_nodes_from_fmt_skip(
                 if header_nodes:
                     ignored_nodes = header_nodes + ignored_nodes
 
+        leaf_is_ignored = any(
+            ignored is leaf
+            or (
+                isinstance(ignored, Node)
+                and any(child is leaf for child in ignored.leaves())
+            )
+            for ignored in ignored_nodes
+        )
+        if not leaf_is_ignored:
+            leaf.prefix = leaf.prefix[comment.consumed :]
+
         yield from ignored_nodes
     elif (
         parent is not None and parent.type == syms.suite and leaf.type == token.NEWLINE
diff --git a/tests/data/cases/fmtskip_in_clause.py b/tests/data/cases/fmtskip_in_clause.py
new file mode 100644
index 0000000..fb79254
--- /dev/null
+++ b/tests/data/cases/fmtskip_in_clause.py
@@ -0,0 +1,43 @@
+# Single fmt: skip in multi-part if-clause
+class ClassWithALongName:
+    Constant1 = 1
+    Constant2 = 2
+    Constant3 = 3
+
+
+def test():
+    if (
+        "cond1" == "cond1"
+        and "cond2" == "cond2"
+        and 1 in (  # fmt: skip
+            ClassWithALongName.Constant1,
+            ClassWithALongName.Constant2,
+            ClassWithALongName.Constant3,
+        )
+    ):
+        return True
+    return False
+
+
+# output
+
+
+# Single fmt: skip in multi-part if-clause
+class ClassWithALongName:
+    Constant1 = 1
+    Constant2 = 2
+    Constant3 = 3
+
+
+def test():
+    if (
+        "cond1" == "cond1"
+        and "cond2" == "cond2"
+        and 1 in (  # fmt: skip
+            ClassWithALongName.Constant1,
+            ClassWithALongName.Constant2,
+            ClassWithALongName.Constant3,
+        )
+    ):
+        return True
+    return False