Repository: celery/celery
File: celery/canvas.py (Python)

Code before:
            # unroll group with one member
            other = maybe_unroll_group(other)
            # chain | group() -> chain
            tasks = self.unchain_tasks()
            if not tasks:
                # If the chain is empty, return the group
                return other
            if isinstance(tasks[-1], chord):
                # CHAIN [last item is chord] | GROUP -> chain with chord body.
                tasks[-1].body = tasks[-1].body | other
                return type(self)(tasks, app=self.app)
            # use type(self) for _chain subclasses
            return type(self)(seq_concat_item(
                tasks, other), app=self._app)
        elif isinstance(other, _chain):
            # chain | chain -> chain
            # use type(self) for _chain subclasses
            return type(self)(seq_concat_seq(
                self.unchain_tasks(), other.unchain_tasks()), app=self._app)
        elif isinstance(other, Signature):
            if self.tasks and isinstance(self.tasks[-1], group):
                # CHAIN [last item is group] | TASK -> chord
                sig = self.clone()
                sig.tasks[-1] = chord(
                    sig.tasks[-1], other, app=self._app)
                for task_idx in range(len(sig.tasks) - 2, -1, -1):
                    if isinstance(sig.tasks[task_idx], chord):
                        sig.tasks[task_idx].body = sig.tasks[task_idx].body | sig.tasks.pop(task_idx + 1)
                    else:
                        break
                return sig
            elif self.tasks and isinstance(self.tasks[-1], chord):
                # CHAIN [last item is chord] -> chain with chord body.
                sig = self.clone()
                sig.tasks[-1].body = sig.tasks[-1].body | other
                return sig
            else:
                # chain | task -> chain
                # use type(self) for _chain subclasses
                return type(self)(seq_concat_item(
                    self.unchain_tasks(), other), app=self._app)
        else:
            return NotImplemented

    def clone(self, *args, **kwargs):
        to_signature = maybe_signature
        signature = super().clone(*args, **kwargs)
        signature.kwargs['tasks'] = [
            to_signature(sig, app=self._app, clone=True)
            for sig in signature.kwargs['tasks']
        ]

Review comment (suggestion):
First of all seems to be maintaining the same results as the other (less preferred) fix 💯 
```bash
celery -A myapp worker -l info
[2023-11-23 11:09:10,604: WARNING/MainProcess] No hostname was supplied. Reverting to default 'localhost'

 -------------- celery@Tomers-MacBook-Pro.local v5.3.6 (emerald-rush)
--- ***** -----
-- ******* ---- macOS-14.1.1-arm64-arm-64bit 2023-11-23 11:09:10
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app:         myapp:0x104475160
- ** ---------- .> transport:   amqp://guest:**@localhost:5672//
- ** ---------- .> results:     redis://
- *** --- * --- .> concurrency: 10 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . myapp.identity

[2023-11-23 11:09:10,753: WARNING/MainProcess] /Users/nusnus/dev/GitHub/celery/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
  warnings.warn(

[2023-11-23 11:09:10,766: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2023-11-23 11:09:10,766: WARNING/MainProcess] /Users/nusnus/dev/GitHub/celery/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
  warnings.warn(

[2023-11-23 11:09:10,778: INFO/MainProcess] mingle: searching for neighbors
[2023-11-23 11:09:11,801: INFO/MainProcess] mingle: all alone
[2023-11-23 11:09:11,845: INFO/MainProcess] celery@Tomers-MacBook-Pro.local ready.
[2023-11-23 11:09:11,847: INFO/MainProcess] Task myapp.identity[dec706dc-9ed0-4303-a1ea-44202fedb777] received
[2023-11-23 11:09:11,848: INFO/MainProcess] Task myapp.identity[7793c8d1-0f9f-4755-8777-3a51d9d94b5d] received
[2023-11-23 11:09:11,849: INFO/MainProcess] Task myapp.identity[23990f68-57ce-4d30-9789-97df8c97b8d7] received
[2023-11-23 11:09:11,850: INFO/MainProcess] Task myapp.identity[92ce1634-86fb-42cb-94bd-5533316089b7] received
[2023-11-23 11:09:11,850: INFO/MainProcess] Task myapp.identity[36459f1d-746c-4416-8cbc-c2c92ee3d816] received
[2023-11-23 11:09:11,968: INFO/ForkPoolWorker-9] Task myapp.identity[92ce1634-86fb-42cb-94bd-5533316089b7] succeeded in 0.01002600000356324s: 3
[2023-11-23 11:09:11,968: INFO/ForkPoolWorker-2] Task myapp.identity[36459f1d-746c-4416-8cbc-c2c92ee3d816] succeeded in 0.009935750014847144s: 4
[2023-11-23 11:09:11,968: INFO/ForkPoolWorker-7] Task myapp.identity[dec706dc-9ed0-4303-a1ea-44202fedb777] succeeded in 0.012489000015193596s: 0
[2023-11-23 11:09:11,969: INFO/ForkPoolWorker-1] Task myapp.identity[23990f68-57ce-4d30-9789-97df8c97b8d7] succeeded in 0.010686583002097905s: 2
[2023-11-23 11:09:11,973: WARNING/ForkPoolWorker-8] No hostname was supplied. Reverting to default 'localhost'
[2023-11-23 11:09:12,003: INFO/MainProcess] Task myapp.identity[fb6288e9-f0f2-453a-9c9c-037cb277d093] received
[2023-11-23 11:09:12,004: INFO/MainProcess] Task myapp.identity[a7f5e25a-9be1-455a-beec-a5eba7445610] received
[2023-11-23 11:09:12,005: INFO/MainProcess] Task myapp.identity[950a8c2f-e55e-4434-9211-0b091f4589dd] received
[2023-11-23 11:09:12,008: INFO/MainProcess] Task myapp.identity[56e394e6-8737-41d6-a879-f5266ddddf87] received
[2023-11-23 11:09:12,010: INFO/ForkPoolWorker-8] Task myapp.identity[7793c8d1-0f9f-4755-8777-3a51d9d94b5d] succeeded in 0.05107258399948478s: 1
[2023-11-23 11:09:12,010: INFO/MainProcess] Task myapp.identity[d65cd219-99b6-45c8-8a54-f292f4af2bfb] received
[2023-11-23 11:09:12,011: INFO/ForkPoolWorker-1] Task myapp.identity[a7f5e25a-9be1-455a-beec-a5eba7445610] succeeded in 0.002511750004487112s: 11
[2023-11-23 11:09:12,012: INFO/ForkPoolWorker-9] Task myapp.identity[950a8c2f-e55e-4434-9211-0b091f4589dd] succeeded in 0.0029922920220997185s: 12
[2023-11-23 11:09:12,012: INFO/ForkPoolWorker-2] Task myapp.identity[56e394e6-8737-41d6-a879-f5266ddddf87] succeeded in 0.003027625003596768s: 13
[2023-11-23 11:09:12,012: INFO/ForkPoolWorker-7] Task myapp.identity[fb6288e9-f0f2-453a-9c9c-037cb277d093] succeeded in 0.003146915987599641s: 10
[2023-11-23 11:09:12,019: INFO/MainProcess] Task myapp.identity[cf83a4b6-43cb-43f4-ac59-96f85eb2cd49] received
[2023-11-23 11:09:12,019: INFO/MainProcess] Task myapp.identity[1f0f0a6b-210d-4114-8891-73ffaa550ef9] received
[2023-11-23 11:09:12,019: INFO/MainProcess] Task myapp.identity[d8c43e31-0275-4463-b841-7804a8b5bb35] received
[2023-11-23 11:09:12,020: INFO/MainProcess] Task myapp.identity[3fdfe7aa-116a-4670-a818-455b58caf7ac] received
[2023-11-23 11:09:12,020: INFO/MainProcess] Task myapp.identity[e47f2884-c826-4e02-b20a-1286b6fb4f56] received
[2023-11-23 11:09:12,020: INFO/ForkPoolWorker-8] Task myapp.identity[d65cd219-99b6-45c8-8a54-f292f4af2bfb] succeeded in 0.009106416982831433s: 14
[2023-11-23 11:09:12,021: INFO/ForkPoolWorker-7] Task myapp.identity[cf83a4b6-43cb-43f4-ac59-96f85eb2cd49] succeeded in 0.0013970419822726399s: 20
[2023-11-23 11:09:12,021: INFO/ForkPoolWorker-1] Task myapp.identity[1f0f0a6b-210d-4114-8891-73ffaa550ef9] succeeded in 0.001614667009562254s: 21
[2023-11-23 11:09:12,021: INFO/ForkPoolWorker-2] Task myapp.identity[3fdfe7aa-116a-4670-a818-455b58caf7ac] succeeded in 0.0013205829891376197s: 23
[2023-11-23 11:09:12,021: INFO/ForkPoolWorker-9] Task myapp.identity[d8c43e31-0275-4463-b841-7804a8b5bb35] succeeded in 0.001461582985939458s: 22
[2023-11-23 11:09:12,027: WARNING/ForkPoolWorker-10] No hostname was supplied. Reverting to default 'localhost'
[2023-11-23 11:09:12,033: INFO/MainProcess] Task myapp.identity[cbeeece2-9e93-49e6-b938-31a15b735f50] received
[2023-11-23 11:09:12,033: INFO/ForkPoolWorker-10] Task myapp.identity[e47f2884-c826-4e02-b20a-1286b6fb4f56] succeeded in 0.012541624979348853s: 24
[2023-11-23 11:09:12,034: INFO/ForkPoolWorker-7] Task myapp.identity[cbeeece2-9e93-49e6-b938-31a15b735f50] succeeded in 0.0007918750052340329s: [20, 21, 22, 23, 24]
```

Code after:
            # unroll group with one member
            other = maybe_unroll_group(other)
            if not isinstance(other, group):
                return self.__or__(other)
            # chain | group() -> chain
            tasks = self.unchain_tasks()
            if not tasks:
                # If the chain is empty, return the group
                return other
            if isinstance(tasks[-1], chord):
                # CHAIN [last item is chord] | GROUP -> chain with chord body.
                tasks[-1].body = tasks[-1].body | other
                return type(self)(tasks, app=self.app)
            # use type(self) for _chain subclasses
            return type(self)(seq_concat_item(
                tasks, other), app=self._app)
        elif isinstance(other, _chain):
            # chain | chain -> chain
            # use type(self) for _chain subclasses
            return type(self)(seq_concat_seq(
                self.unchain_tasks(), other.unchain_tasks()), app=self._app)
        elif isinstance(other, Signature):
            if self.tasks and isinstance(self.tasks[-1], group):
                # CHAIN [last item is group] | TASK -> chord
                sig = self.clone()
                sig.tasks[-1] = chord(
                    sig.tasks[-1], other, app=self._app)
                # In the scenario where the second-to-last item in a chain is a chord,
                # it leads to a situation where two consecutive chords are formed.
                # In such cases, a further upgrade can be considered.
                # This would involve chaining the body of the second-to-last chord with the last chord."
                if len(sig.tasks) > 1 and isinstance(sig.tasks[-2], chord):
                    sig.tasks[-2].body = sig.tasks[-2].body | sig.tasks[-1]
                    sig.tasks = sig.tasks[:-1]
                return sig
            elif self.tasks and isinstance(self.tasks[-1], chord):
                # CHAIN [last item is chord] -> chain with chord body.
                sig = self.clone()
                sig.tasks[-1].body = sig.tasks[-1].body | other
                return sig
            else:
                # chain | task -> chain
                # use type(self) for _chain subclasses
                return type(self)(seq_concat_item(
                    self.unchain_tasks(), other), app=self._app)
        else:
            return NotImplemented

    def clone(self, *args, **kwargs):
        to_signature = maybe_signature
        signature = super().clone(*args, **kwargs)