[Bug] Python process consuming ~98% CPU on macOS — tight async loop with TypeError in bytes.contains

Hi,

I noticed that PlatformIO’s background Python process was consuming ~98% CPU on my Mac, causing significant fan noise and heat. After stopping all but one process, the issue subsided.

I captured a macOS sample profile of the process (pid 83226, python3.11) and analysed the call graph. Here’s what I found:


Environment

  • macOS 15.4 (Apple Silicon, ARM64)
  • Python 3.11
  • PlatformIO (started via the IDE extension)

Root cause (from call graph analysis)

Two hotspots account for most of the CPU usage:

  1. ~25% of samples — _Py_bytes_contains_PyNumber_IndexPyErr_Format
    An async task is using the in operator on a bytes object while passing a non-integer type. This raises a TypeError internally, which is caught and ignored — but because this runs in a tight asyncio loop with no sleep(), it fires hundreds of thousands of times per second. The cost of building the exception string via PyUnicode_FromFormatV, allocating and deallocating exception objects, and clearing the error repeatedly adds up to significant CPU load.

  2. ~21% of samples — time.time()clock_gettimemach_absolute_time
    Very frequent calls to time.time() suggest a polling loop running without any asyncio.sleep() or equivalent yield, keeping the event loop spinning continuously.

The affected modules visible in the binary images are md.cpython-311-darwin.so and md__mypyc.cpython-311-darwin.so.


Suggested fix

  • Add a type check before the bytes.__contains__ call to avoid the repeated TypeError.
  • Add await asyncio.sleep(0) or a small sleep in the polling loop to yield control and reduce CPU usage to near 0% when idle.

Impact

On Apple Silicon this causes sustained high CPU load, elevated temperatures, and loud fan noise even when no build or upload is running — just having PlatformIO open in the background is enough to trigger it.

I’m happy to share the full sample output if that would help with debugging.

Thanks!

What is the exact process name and arguments? Is it really platformio / pio getting run in the python process or is it the VSCode C/C++ Intellisense process? That makes a huge difference.