{"record":{"id":"9ae0ab2149ec1c19","repo":"python/cpython","slug":"must-run-this-script-from-the-repo-root","errorCode":null,"errorMessage":"Must run this script from the repo root","messagePattern":"Must run this script from the repo root","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"Doc/tools/check-warnings.py","lineNumber":312,"sourceCode":"        \"--fail-if-new-news-nit\",\n        metavar=\"threshold\",\n        type=int,\n        nargs=\"?\",\n        const=NEWS_NIT_THRESHOLD,\n        help=\"Fail if new NEWS nit found before threshold line number\",\n    )\n\n    args = parser.parse_args(argv)\n    if args.annotate_diff is not None and len(args.annotate_diff) > 2:\n        parser.error(\n            \"--annotate-diff takes between 0 and 2 ref args, not \"\n            f\"{len(args.annotate_diff)} {tuple(args.annotate_diff)}\"\n        )\n    exit_code = 0\n\n    wrong_directory_msg = \"Must run this script from the repo root\"\n    if not Path(\"Doc\").exists() or not Path(\"Doc\").is_dir():\n        raise RuntimeError(wrong_directory_msg)\n\n    warnings = (\n        Path(\"Doc/sphinx-warnings.txt\")\n        .read_text(encoding=\"UTF-8\")\n        .splitlines()\n    )\n\n    cwd = str(Path.cwd()) + os.path.sep\n    files_with_nits = {\n        warning.removeprefix(cwd).split(\":\")[0]\n        for warning in warnings\n        if \"Doc/\" in warning\n    }\n\n    with Path(\"Doc/tools/.nitignore\").open(encoding=\"UTF-8\") as clean_files:\n        files_with_expected_nits = {\n            filename.strip()\n            for filename in clean_files","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Doc/tools/check-warnings.py#L294-L330","documentation":"In debug mode, selector- and proactor-based event loops verify that sockets used with the sock_* APIs are non-blocking (gettimeout() == 0), because the whole sock_* design assumes the loop drives readiness. This instance is in BaseSelectorEventLoop.sock_connect (Lib/asyncio/selector_events.py:381 region). A blocking socket would freeze the loop, so debug mode fails fast with ValueError instead.","triggerScenarios":"Enabling asyncio debug mode (PYTHONASYNCIODEBUG=1, asyncio.run(debug=True), or loop.set_debug(True)) and calling sock_connect()/sock_* with a socket whose timeout is not 0 — e.g. a freshly created socket (default timeout None) or one set with settimeout(5). The proactor loop's sock_connect applies the same check.","commonSituations":"Code that worked in normal mode suddenly raising after debug mode is turned on for diagnosis; sockets created by third-party libraries (requests, socket.create_connection) that have blocking timeouts; tests running with faulthandler/debug fixtures that enable loop debug globally.","solutions":["Set the socket non-blocking before use: sock.setblocking(False) (equivalently settimeout(0.0))","Pass the socket through the loop-managed APIs (loop.sock_connect + await) consistently instead of mixing blocking and async calls on one fd","Disable debug mode only as a last resort and never as the real fix — the check indicates a genuine freeze hazard"],"exampleFix":"# before\nsock = socket.socket()\nawait loop.sock_connect(sock, addr)  # debug mode: ValueError\n# after\nsock = socket.socket()\nsock.setblocking(False)\nawait loop.sock_connect(sock, addr)","handlingStrategy":"validation","validationCode":"def loop_ready_socket(sock):\n    if sock.gettimeout() != 0:\n        sock.setblocking(False)\n    return sock\n\nasync def connect(loop, sock, addr):\n    return await loop.sock_connect(loop_ready_socket(sock), addr)","typeGuard":null,"tryCatchPattern":"try:\n    await loop.sock_connect(sock, addr)\nexcept ValueError as e:\n    if 'non-blocking' in str(e):\n        sock.setblocking(False)\n        return await loop.sock_connect(sock, addr)\n    raise","preventionTips":["setblocking(False) every socket before any sock_* call","Create sockets inside async code paths where non-blocking is the norm","Wrap accepts with asyncio.wait_for instead of socket timeouts","Assert gettimeout() == 0 in test doubles for loop-used sockets"],"tags":["asyncio","socket","debug-mode","non-blocking"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}