Skip to content

fix: don't let kitty graphics detection crash IPython startup#15264

Open
chrisburr wants to merge 1 commit into
ipython:mainfrom
chrisburr:fix/kitty-graphics-detection-access-denied
Open

fix: don't let kitty graphics detection crash IPython startup#15264
chrisburr wants to merge 1 commit into
ipython:mainfrom
chrisburr:fix/kitty-graphics-detection-access-denied

Conversation

@chrisburr

Copy link
Copy Markdown

_supports_kitty_graphics() walks the process tree with psutil at import time to detect a graphics-capable terminal. On shared multi-user systems where /proc is mounted with hidepid (common on HPC clusters), reaching an ancestor process owned by another user raises psutil.AccessDenied, which was unhandled and aborted the entire import IPython:

$ pixi run ipython
Traceback (most recent call last):
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_pslinux.py", line 1593, in wrapper
    return fun(self, *args, **kwargs)
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_common.py", line 377, in wrapper
    raise err from None
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_common.py", line 375, in wrapper
    return fun(self)
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_pslinux.py", line 1683, in _parse_stat_file
    data = bcat(f"{self._procfs_path}/{self.pid}/stat")
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_common.py", line 730, in bcat
    return cat(fname, fallback=fallback, _open=open_binary)
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_common.py", line 718, in cat
    with _open(fname) as f:
         ~~~~~^^^^^^^
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_common.py", line 682, in open_binary
    return open(fname, "rb", buffering=FILE_READ_BUFFER_SIZE)
PermissionError: [Errno 1] Operation not permitted: '/proc/902595/stat'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/tmp/cburr/xxx/.pixi/envs/default/bin/ipython", line 3, in <module>
    from IPython import start_ipython
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/IPython/__init__.py", line 56, in <module>
    from .terminal.embed import embed
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/IPython/terminal/embed.py", line 16, in <module>
    from IPython.terminal.interactiveshell import TerminalInteractiveShell
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/IPython/terminal/interactiveshell.py", line 11, in <module>
    from IPython.core.kitty import (
    ...<2 lines>...
    )
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/IPython/core/kitty.py", line 37, in <module>
    supports_kitty_graphics = _supports_kitty_graphics()
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/IPython/core/kitty.py", line 31, in _supports_kitty_graphics
    while process := process.parent():
                     ~~~~~~~~~~~~~~^^
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/__init__.py", line 607, in parent
    if parent.create_time() <= proc_ctime:
       ~~~~~~~~~~~~~~~~~~^^
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/__init__.py", line 783, in create_time
    self._create_time = self._proc.create_time()
                        ~~~~~~~~~~~~~~~~~~~~~~^^
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_pslinux.py", line 1593, in wrapper
    return fun(self, *args, **kwargs)
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_pslinux.py", line 1857, in create_time
    float(self._parse_stat_file()['create_time']) / CLOCK_TICKS
          ~~~~~~~~~~~~~~~~~~~~~^^
  File "/tmp/cburr/xxx/.pixi/envs/default/lib/python3.14t/site-packages/psutil/_pslinux.py", line 1595, in wrapper
    raise AccessDenied(pid, name) from err
psutil.AccessDenied: (pid=902595)

Catch errors during the walk and treat them as "graphics unsupported" instead. A real supported terminal is one of the user's own near ancestors and is found before any restricted PID, so detection capability is unchanged.

_supports_kitty_graphics() walks the process tree with psutil at import
time to detect a graphics-capable terminal. On shared multi-user systems
where /proc is mounted with hidepid (common on HPC clusters), reaching an
ancestor process owned by another user raises psutil.AccessDenied, which
was unhandled and aborted the entire `import IPython`.

Catch psutil/OS errors during the walk and treat them as "graphics
unsupported" instead. A real supported terminal is one of the user's own
near ancestors and is found before any restricted PID, so detection
capability is unchanged.
@chrisburr chrisburr marked this pull request as ready for review June 18, 2026 13:05
@wahajahmed010

Copy link
Copy Markdown

test

@dkwo

dkwo commented Jun 22, 2026

Copy link
Copy Markdown

Thank you! Tested on aarch64-gnu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants