GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Make `asyncio.Lock.locked()` return `True` when there are waiters · Issue #138121 · python/cpython

Make asyncio.Lock.locked() return True when there are waiters #138121

New issue
Copy link
New issue
Copy link
Open
Open
Make asyncio.Lock.locked() return True when there are waiters#138121
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-asynciotriagedThe issue has been accepted as valid by a triager.The issue has been accepted as valid by a triager.type-featureA feature request or enhancementA feature request or enhancement

Description

@olutra
olutra
opened on Aug 24, 2025
Issue body actions

Bug report

Bug description:

In issue #97028 everyone seemed to agree that asyncio.{Lock,Semaphore}.locked() should return True if there are waiters, but this change was implemented only for Semaphore.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Linked PRs

  • #gh-138121 Make asyncio.Lock.locked return True when waiters exist #153989

Activity

  1. olutra
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 24, 2025
  2. picnixz
    added
    type-featureA feature request or enhancementA feature request or enhancement
    topic-asyncio
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    and removed
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 24, 2025
  3. github-project-automation
    added this to asyncioon Aug 24, 2025
  4. github-project-automation
    moved this to Todo in asyncioon Aug 24, 2025
  5. ashm-dev commented on Sep 8, 2025

    @ashm-dev
    ashm-dev
    on Sep 8, 2025
    Contributor
    More actions

    Can I try to fix this issue?

    Just to clarify: am I correct that the main point of this issue is to backport the existing fix (already applied in 3.12+) into the <3.12 branches?

  6. picnixz commented on Sep 8, 2025

    @picnixz
    picnixz
    on Sep 8, 2025
    Member
    More actions

    Since we don't know the answer to the question I wouldn't say there is anything to fix. Let's ask @kumaraditya303

  7. olutra commented on Mar 7, 2026

    @olutra
    olutra
    on Mar 7, 2026
    Author
    More actions

    @kumaraditya303, could you please unblock the issue?

  8. kumaraditya303 commented on Mar 9, 2026

    @kumaraditya303
    kumaraditya303
    on Mar 9, 2026
    Contributor
    More actions

    I don't quite remember the details, maybe @gvanrossum remembers? if this should be case for Lock as well.

  9. gvanrossum commented on Mar 9, 2026

    @gvanrossum
    gvanrossum
    on Mar 9, 2026
    Member
    More actions

    Yeah, Lock.locked() should definitely return true if there are waiters.

  10. picnixz
    added
    triagedThe issue has been accepted as valid by a triager.The issue has been accepted as valid by a triager.
    on Mar 9, 2026
  11. picnixz
    changed the title [-]Should `asyncio.Lock.locked()` return `True` when there are waiters?[/-] [+]Make `asyncio.Lock.locked()` return `True` when there are waiters[/+] on Mar 9, 2026
  12. gvanrossum commented on Mar 10, 2026

    @gvanrossum
    gvanrossum
    on Mar 10, 2026
    Member
    More actions

    Small caveat: Maybe you can prove (or disprove!) that when there are waiters, the locked flag is always set?

  13. johng commented on Jul 17, 2026

    @johng
    johng
    on Jul 17, 2026
    Contributor
    More actions

    We can see in Semaphore we have

        def locked(self):
            """Returns True if semaphore cannot be acquired immediately."""
            # Due to state, or FIFO rules (must allow others to run first).
            return self._value == 0 or (
                any(not w.cancelled() for w in (self._waiters or ())))
    

    For Lock we have this driven by the state of the Lock

        def locked(self):
            """Return True if lock is acquired."""
            return self._locked
    

    This gets unset once releasing the lock and I don't see any logic for checking for waiters first.

        def release(self):
            if self._locked:
                self._locked = False
                self._wake_up_first()
            else:
                raise RuntimeError('Lock is not acquired.')
    
  14. johng commented on Jul 17, 2026

    @johng
    johng
    on Jul 17, 2026
    Contributor
    More actions

    Was able to reproduce this quite easily with some AI help

    import asyncio
    
    
    async def main():
        lock = asyncio.Lock()
        sem = asyncio.Semaphore(1)
    
        await lock.acquire()
        await sem.acquire()
    
        async def wait_lock():
            async with lock:
                pass
    
        async def wait_sem():
            async with sem:
                pass
    
        tl = asyncio.create_task(wait_lock())
        ts = asyncio.create_task(wait_sem())
        await asyncio.sleep(0)  # both tasks are now parked in acquire()
    
        # Release, then inspect *synchronously* (no await) so the woken waiter
        # has NOT run yet.
        lock.release()
        sem.release()
    
        print("Immediately after release(), with a waiter still queued:")
        print(f"  lock._locked={lock._locked}, "
              f"lock._waiters={len(lock._waiters or ())} -> lock.locked() = {lock.locked()}")
        print(f"  sem._value={sem._value}, "
              f"sem._waiters={len(sem._waiters or ())} -> sem.locked()  = {sem.locked()}")
    
        if lock.locked() != sem.locked():
            print("\n>>> INCONSISTENCY REPRODUCED: identical situation, "
                  "Lock says free, Semaphore says locked.")
        else:
            print("\n>>> no inconsistency (already fixed?)")
    
        await tl
        await ts
    
    
    asyncio.run(main())
    
    uv run repro_138121.py 
    Immediately after release(), with a waiter still queued:
      lock._locked=False, lock._waiters=1 -> lock.locked() = False
      sem._value=0, sem._waiters=1 -> sem.locked()  = True
    
    >>> INCONSISTENCY REPRODUCED: identical situation, Lock says free, Semaphore says locked.
    
  15. EmBeckwith commented on Jul 20, 2026

    @EmBeckwith
    EmBeckwith
    on Jul 20, 2026
    More actions

    Heya new to this but I've made a PR with a fairly naive solution here if someone wants to take a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-asynciotriagedThe issue has been accepted as valid by a triager.The issue has been accepted as valid by a triager.type-featureA feature request or enhancementA feature request or enhancement

    Projects

    • asyncio
      Status
      Todo
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.