{"record":{"id":"e7afa253a30cfe3b","repo":"RustPython/RustPython","slug":"objc-runtime-library-couldn-t-be-loaded","errorCode":null,"errorMessage":"ObjC runtime library couldn't be loaded","messagePattern":"ObjC runtime library couldn't be loaded","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"Lib/_ios_support.py","lineNumber":16,"sourceCode":"import sys\ntry:\n    from ctypes import cdll, c_void_p, c_char_p, util\nexcept ImportError:\n    # ctypes is an optional module. If it's not present, we're limited in what\n    # we can tell about the system, but we don't want to prevent the module\n    # from working.\n    print(\"ctypes isn't available; iOS system calls will not be available\", file=sys.stderr)\n    objc = None\nelse:\n    # ctypes is available. Load the ObjC library, and wrap the objc_getClass,\n    # sel_registerName methods\n    lib = util.find_library(\"objc\")\n    if lib is None:\n        # Failed to load the objc library\n        raise ImportError(\"ObjC runtime library couldn't be loaded\")\n\n    objc = cdll.LoadLibrary(lib)\n    objc.objc_getClass.restype = c_void_p\n    objc.objc_getClass.argtypes = [c_char_p]\n    objc.sel_registerName.restype = c_void_p\n    objc.sel_registerName.argtypes = [c_char_p]\n\n\ndef get_platform_ios():\n    # Determine if this is a simulator using the multiarch value\n    is_simulator = sys.implementation._multiarch.endswith(\"simulator\")\n\n    # We can't use ctypes; abort\n    if not objc:\n        return None\n\n    # Most of the methods return ObjC objects\n    objc.objc_msgSend.restype = c_void_p","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/_ios_support.py#L1-L34","documentation":"_SSLProtocolTransport is the transport your protocol sees when TLS is enabled (create_connection(..., ssl=ctx), start_server with SSL). Its write() pushes application data into the SSL state machine and accepts only bytes, bytearray, or memoryview; anything else raises TypeError('data: expecting a bytes-like instance, got ...') before any TLS processing. The encrypted record layer cannot consume str, so no implicit encoding exists on TLS transports either.","triggerScenarios":"transport.write('hello') on a TLS connection; passing int/None/dict; feeding json.dumps() output (a str) to the transport returned by open_connection(..., ssl=ctx); code that 'worked' with plain sockets in a library tolerating str.","commonSituations":"Adding TLS to a plain-socket protocol and discovering payload types; producers handing unicode strings after a refactor removed encoding; wrapping third-party transports that accept str in their own send helpers.","solutions":["Encode strings: transport.write(data.encode('utf-8')).","Encode once at the protocol boundary and keep the transport layer strictly bytes.","Convert other objects explicitly: bytes(obj) or memoryview(obj).","Annotate the write path with bytes-only type hints and enforce with mypy/pyright."],"exampleFix":"# before\nreader, writer = await asyncio.open_connection(host, port, ssl=ctx)\nwriter.write('GET / HTTP/1.0\\r\\n\\r\\n')\n\n# after\nreader, writer = await asyncio.open_connection(host, port, ssl=ctx)\nwriter.write(b'GET / HTTP/1.0\\r\\n\\r\\n')\n# or for dynamic strings:\nwriter.write(request.encode('utf-8'))","handlingStrategy":"type-guard","validationCode":"def to_wire(data):\n    if isinstance(data, str):\n        return data.encode('utf-8')\n    if not isinstance(data, (bytes, bytearray, memoryview)):\n        raise TypeError(f'not writable by TLS transport: {type(data).__name__}')\n    return data\n\nwriter.transport.write(to_wire(data))  # or writer.write(to_wire(data))","typeGuard":"def is_tls_wire_bytes(data: object) -> bool:\n    \"\"\"Types accepted by _SSLProtocolTransport.write().\"\"\"\n    return isinstance(data, (bytes, bytearray, memoryview))","tryCatchPattern":null,"preventionTips":["Keep the TLS write path strictly bytes - encode strings at the producer","Apply the same to_wire() choke point used for plain sockets","Use writelines() with bytes elements for batched writes","Add bytes-only type hints and enforce with mypy/pyright"],"tags":["asyncio","ssl","transport","typeerror","bytes"],"backgroundTag":"bytes-like-object-required","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}