Migration guide

This page summarises the breaking changes introduced in each major release and shows the code changes required to upgrade.

Note

Minor and patch releases (e.g. 6.1.x, 7.1.x) do not contain breaking changes. Only major releases are listed here.

Migrating to 8.0

Key breaking changes in 8.0:

Important

Do not rely on positional unpacking of named tuples. Always use attribute access (e.g. t.rss).

Named tuple field order changed

  • cpu_times(): user, system, idle fields changed order on Linux, macOS and BSD. They are now always the first 3 fields on all platforms, with platform-specific fields (e.g. nice) following. Positional access (e.g. cpu_times()[3]) silently returns the wrong field.

    # before
    user, nice, system, idle = psutil.cpu_times()
    
    # after
    t = psutil.cpu_times()
    user, system, idle = t.user, t.system, t.idle
    
  • Process.memory_info(): the returned named tuple changed size and field order.

    • Linux: lib and dirty fields removed (they were always 0 since Linux 2.6). Aliases returning 0 and emitting DeprecationWarning are kept.

    • macOS: pfaults and pageins removed with no aliases. Use Process.page_faults() instead.

    • Windows: old fields were renamed: wset → rss, peak_wset → peak_rss, pagefile and private → vms, peak_pagefile → peak_vms, num_page_faults → Process.page_faults(). The old names still work but raise DeprecationWarning. paged_pool, nonpaged_pool, peak_paged_pool, peak_nonpaged_pool moved to Process.memory_extras().

    • BSD: a new peak_rss field was added.

  • virtual_memory(): on Windows, new cached and wired fields were added.

Process.info is deprecated

The attributes collected by process_iter(attrs=...) are now exposed as a read-only ProcessSnapshot via Process.snapshot, with one attribute per requested name. The info dict is deprecated and still works, but raises DeprecationWarning.

Before:

for p in psutil.process_iter(["name", "username"]):
    print(p.info["name"], p.info["username"])

After:

for p in psutil.process_iter(["name", "username"]):
    print(p.snapshot.name, p.snapshot.username)

Accessing an attribute that was not requested raises AttributeError instead of KeyError. If you need a dict, use p.snapshot.as_dict().

New Process.attrs class attribute

Process.attrs is a new frozenset containing the valid attribute names accepted by Process.as_dict() and process_iter(). It avoids creating a throwaway process just to discover them:

# before
attrs = list(psutil.Process().as_dict().keys())

# after
attrs = psutil.Process.attrs

It also makes it easy to pass all or a subset of attributes. process_iter(attrs=[]) (empty list meaning “all”) is now deprecated; use Process.attrs instead:

# all attrs
psutil.process_iter(attrs=psutil.Process.attrs)

# all except connections
psutil.process_iter(attrs=psutil.Process.attrs - {"net_connections"})

cpu_times() interrupt renamed to irq on Windows

The interrupt field of cpu_times() on Windows was renamed to irq to match Linux and BSD. The old name still works but raises DeprecationWarning.

Constants and fields are now enums

These now yield enum members instead of plain str / int, and the matching module constants are members of the same enums:

They subclass enum.StrEnum / enum.IntEnum, so they compare equal to the values they replace: p.status() == psutil.STATUS_RUNNING keeps working. Only code inspecting repr() or type needs updating.

memory_full_info() is deprecated

Process.memory_full_info() is deprecated. Use Process.memory_footprint() instead; it returns the footprint fields (uss, plus pss and swap on Linux) and adds a new shared field.

New memory_extras() method

8.0 introduces a new Process.memory_extras() method, returning extra platform-specific memory metrics which complement Process.memory_info():

  • Linux: peak_rss, peak_vms, rss_anon, rss_file, rss_shmem, swap_anon, locked.

  • macOS: phys_footprint, peak_footprint.

  • Windows: virtual, peak_virtual, paged_pool, nonpaged_pool, peak_paged_pool, peak_nonpaged_pool.

Python 3.6 and 3.7 dropped

The minimum version is now Python 3.8.

Windows < 10 dropped

Support for Windows Vista, 7, 8, 8.1 and their server counterparts (Server 2008 to 2012 R2) was removed. The minimum version is now Windows 10 / Windows Server 2016. The last release supporting older versions is the 7.2.x series. See #2893.

Git tags renamed

Git tags were renamed from release-X.Y.Z to vX.Y.Z (e.g. release-7.2.2 → v7.2.2). Old tags remain for backward compatibility. If your scripts or URLs reference psutil tags, update them to the new format. See #2788.


Migrating to 7.0

Process.memory_info_ex() removed

Process.memory_info_ex(), deprecated since 4.0.0 in 2016, was removed. Use Process.memory_full_info() instead.

# before
p.memory_info_ex()

# after
p.memory_full_info()

Python 2.7 dropped

Python 2.7 is no longer supported. The last release supporting it is psutil 6.1.x:

pip2 install "psutil==6.1.*"

Migrating to 6.0

Process.connections() renamed

Process.connections() was renamed to Process.net_connections() for consistency with the system-level net_connections(). The old name raises DeprecationWarning and will be removed in a future release:

# before
p.connections()
p.connections(kind="tcp")

# after
p.net_connections()
p.net_connections(kind="tcp")

disk_partitions() lost two fields

The maxfile and maxpath fields were removed from the named tuple returned by disk_partitions(). Positional unpacking will break:

# before (broken)
device, mountpoint, fstype, opts, maxfile, maxpath = part

# after
device, mountpoint, fstype, opts = (
    part.device, part.mountpoint, part.fstype, part.opts
)

process_iter() no longer checks for PID reuse

process_iter() no longer preemptively checks whether yielded PIDs have been reused, making it ~20× faster. To verify that a process object is still alive and refers to the same process, use Process.is_running() explicitly:

for p in psutil.process_iter(["name"]):
    if p.is_running():
        print(p.pid, p.snapshot.name)