{"record":{"id":"0b7bcf38d3da8c86","repo":"python/cpython","slug":"build-gnu-type-is-not-defined","errorCode":null,"errorMessage":"BUILD_GNU_TYPE is not defined","messagePattern":"BUILD_GNU_TYPE is not defined","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_aix_support.py","lineNumber":91,"sourceCode":"    Again, the builddate of an AIX release is associated with bos.rte.\n    AIX ABI compatibility is described  as guaranteed at: https://www.ibm.com/\\\n    support/knowledgecenter/en/ssw_aix_72/install/binary_compatability.html\n\n    For pep425 purposes the AIX platform tag becomes:\n    \"aix-{:1x}{:1d}{:02d}-{:04d}-{}\".format(v, r, tl, builddate, bitsize)\n    e.g., \"aix-6107-1415-32\" for AIX 6.1 TL7 bd 1415, 32-bit\n    and, \"aix-6107-1415-64\" for AIX 6.1 TL7 bd 1415, 64-bit\n    \"\"\"\n    vrmf, bd = _aix_bos_rte()\n    return _aix_tag(_aix_vrtl(vrmf), bd)\n\n\n# extract vrtl from the BUILD_GNU_TYPE as an int\ndef _aix_bgt():\n    # type: () -> List[int]\n    gnu_type = sysconfig.get_config_var(\"BUILD_GNU_TYPE\")\n    if not gnu_type:\n        raise ValueError(\"BUILD_GNU_TYPE is not defined\")\n    return _aix_vrtl(vrmf=gnu_type)\n\n\ndef aix_buildtag():\n    # type: () -> str\n    \"\"\"\n    Return the platform_tag of the system Python was built on.\n    \"\"\"\n    # AIX_BUILDDATE is defined by configure with:\n    # lslpp -Lcq bos.rte | awk -F:  '{ print $NF }'\n    build_date = sysconfig.get_config_var(\"AIX_BUILDDATE\")\n    try:\n        build_date = int(build_date)\n    except (ValueError, TypeError):\n        raise ValueError(f\"AIX_BUILDDATE is not defined or invalid: \"\n                         f\"{build_date!r}\")\n    return _aix_tag(_aix_bgt(), build_date)\n","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_aix_support.py#L73-L109","documentation":"_ensure_fd_no_transport() raises RuntimeError when the fd being registered is already owned by a live (not closing) transport in this loop. The loop forbids two independent watchers on one fd because the transport would receive the events. It is a duplicate-registration guard, not a resource leak error.","triggerScenarios":"Calling loop.add_reader(sock)/add_writer or sock_* on a socket already attached to a transport created by create_connection/create_datagram_endpoint; passing the same socket to two create_*_endpoint calls; using a transport's socket (tr.get_extra_info('socket')) with raw loop APIs while the transport lives.","commonSituations":"Peeking at a connection's socket to do zero-copy reads or sendfile while the transport still polls it; writing custom protocols and mixing transport-level and sock-level APIs on the same fd; workarounds copied from selector-era code that manipulated fds directly; double-starting a server on the same listening socket.","solutions":["Pick one API per socket: either the transport/protocol layer or the raw sock_*/add_reader layer, never both","Detach the fd from the transport first (tr.get_extra_info('socket').detach()) if you truly must take over, accepting transport teardown","Reuse the existing transport's methods (tr.write, protocol callbacks) instead of watching its fd","For takeover scenarios, abort the old transport (tr.abort()) before registering the fd yourself"],"exampleFix":"# before\ntr, _ = await loop.create_connection(Proto, host, port)\nloop.add_reader(sock_from_tr, cb)  # fd owned by transport -> RuntimeError\n# after\ntr, proto = await loop.create_connection(Proto, host, port)\n# use the transport/protocol surface instead of add_reader on its fd\ntr.write(b'ping')  # responses arrive via proto.data_received","handlingStrategy":"validation","validationCode":"def assert_fd_free(loop, sock):\n    fd = sock.fileno()\n    tr = loop._transports.get(fd)          # same map the loop checks\n    if tr is not None and not tr.is_closing():\n        raise RuntimeError(f'fd {fd} owned by {tr!r}; use the transport instead')","typeGuard":null,"tryCatchPattern":"try:\n    loop.add_reader(sock, cb)\nexcept RuntimeError as e:\n    if 'is used by transport' in str(e):\n        tr = loop._transports.get(sock.fileno())\n        tr.abort()                      # release ownership, then re-register\n        loop.add_reader(sock, cb)\n    else:\n        raise","preventionTips":["One fd, one owner: transport/protocol OR raw sock_* APIs","Never add_reader on a socket obtained via tr.get_extra_info('socket')","Call tr.abort() or sock.detach() before taking over an fd","Reuse existing transports' write() instead of watching their fds"],"tags":["asyncio","file-descriptor","transport","duplicate-registration"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}