python/cpython · warning · RuntimeError
Must run this script from the repo root
Error message
Must run this script from the repo root
What it means
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.
Source
Thrown at Doc/tools/check-warnings.py:312
"--fail-if-new-news-nit",
metavar="threshold",
type=int,
nargs="?",
const=NEWS_NIT_THRESHOLD,
help="Fail if new NEWS nit found before threshold line number",
)
args = parser.parse_args(argv)
if args.annotate_diff is not None and len(args.annotate_diff) > 2:
parser.error(
"--annotate-diff takes between 0 and 2 ref args, not "
f"{len(args.annotate_diff)} {tuple(args.annotate_diff)}"
)
exit_code = 0
wrong_directory_msg = "Must run this script from the repo root"
if not Path("Doc").exists() or not Path("Doc").is_dir():
raise RuntimeError(wrong_directory_msg)
warnings = (
Path("Doc/sphinx-warnings.txt")
.read_text(encoding="UTF-8")
.splitlines()
)
cwd = str(Path.cwd()) + os.path.sep
files_with_nits = {
warning.removeprefix(cwd).split(":")[0]
for warning in warnings
if "Doc/" in warning
}
with Path("Doc/tools/.nitignore").open(encoding="UTF-8") as clean_files:
files_with_expected_nits = {
filename.strip()
for filename in clean_filesView on GitHub (pinned to bc6749cc3b)
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
Example fix
# before sock = socket.socket() await loop.sock_connect(sock, addr) # debug mode: ValueError # after sock = socket.socket() sock.setblocking(False) await loop.sock_connect(sock, addr)
Defensive patterns
Strategy: validation
Validate before calling
def loop_ready_socket(sock):
if sock.gettimeout() != 0:
sock.setblocking(False)
return sock
async def connect(loop, sock, addr):
return await loop.sock_connect(loop_ready_socket(sock), addr) Try / catch
try:
await loop.sock_connect(sock, addr)
except ValueError as e:
if 'non-blocking' in str(e):
sock.setblocking(False)
return await loop.sock_connect(sock, addr)
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- AIX_BUILDDATE is not defined or invalid: {build_date!r}
- write() argument must be str, not {type(s).__name__}
- write() argument must be bytes-like, not {type(b).__name__}
- write() argument must be str, not {type(s).__name__}
- write() argument must be bytes-like, not {type(b).__name__}
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/9ae0ab2149ec1c19.
Report an issue: GitHub.