# Interlacing ContextManager

**URL:** <https://discuss.python.org/t/interlacing-contextmanager/68838>\
**Category:** Ideas\
**Created:** [October 22, 2024, 8:29pm UTC](https://discuss.python.org/t/interlacing-contextmanager/68838 "2024-10-22T20:29:27Z")\
**Posts on this page:** 1\
**Showing post:** 18

<div class="post-metadata">

**Author:** ![zhangyx](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/zhangyx/32/23808_2.png) [@zhangyx](https://discuss.python.org/u/zhangyx)\
**Post date:** [October 23, 2024, 7:55pm UTC](https://discuss.python.org/t/interlacing-contextmanager/68838/18 "2024-10-23T19:55:59Z")

</div>

@gcewing @ncoghlan

### Regarding interrupt safety of Python’s own Lock implementation, I found some interesting facts:

#### 1. `Lock(). __enter__ ()` and `Lock(). __exit__ ()` seems to be internal C bindings that are _immune_ to interrupts.

#### 2. Wrappers around the lock (including Python’s own `Condition` variables) are vulnerable to `KeyboardInterrupt`.

### Here is the code I used for test:

```python3
from threading import Lock, Condition
from sys import stdout, stderr

class WrappedLock:
    def __init__ (self):
        self._lock = Lock()

    def locked(self):
        return self._lock.locked()

    def __enter__ (self):
        return self._lock. __enter__ ()

    def __exit__ (self, *args):
        # SIGINT here will cause unreleased lock (essentially a deadlock)
        return self._lock. __exit__ (*args)

lock1 = Lock()
lock2 = WrappedLock()
lock3 = Lock()
cond3 = Condition(lock3)

try:
    while True:
        with lock1, lock2, cond3:
            # Ask dispatcher to send SIGINT
            stdout.write("\n")
            stdout.flush()
except KeyboardInterrupt:
    pass

if lock1.locked():
    stderr.write("lock1\n")
if lock2.locked():
    stderr.write("lock2\n")
if lock3.locked():
    stderr.write("lock3\n")

```

I used a custom script to run this test in batches. You can find the code in my [Github Gist](https://gist.github.com/zhangyx1998/c216a7df8d50a5e811d672a04d72c8a6).

> I ran only 10000 tests because it already made my MacBook’s fan roaring at me. Please feel free to run more tests on a more powerful machine. I am also curious if this result is reproducible on other OS/Architectures.

### Here are the results:

```plaintext
# Python 3.12.5 on MacOS
Total 10000 tests                                                                                                                                                                                                                                                                                                                                                                       
lock1 failed 0 times (0.00%)
lock2 failed 430 times (4.30%)
lock3 failed 514 times (5.14%)

```

This result shows that `ContextManager` works (and ONLY works) with raw, unwrapped Python `Lock` primitives to provide robust interrupt handling. I guess this will cause some very intricate confusions if someone assumes ContextManagers are always immune to interrupts.

---

_[View the full topic](https://discuss.python.org/t/interlacing-contextmanager/68838)._
