summaryrefslogtreecommitdiffstats
path: root/contrib/python
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-03-03 01:22:13 +0300
committerrobot-piglet <[email protected]>2025-03-03 01:34:11 +0300
commite4edb481962c16c208a1f0f2d7fd698f86f98525 (patch)
treebad447ca4778aedf9d8b83079f275a9a2a2a9727 /contrib/python
parent6678165e016ba474f1b8dd6d49af92b0d46350b9 (diff)
Intermediate changes
commit_hash:7c10655440be1add16ba4307493e0143ef552dbf
Diffstat (limited to 'contrib/python')
-rw-r--r--contrib/python/psutil/py3/.dist-info/METADATA24
-rw-r--r--contrib/python/psutil/py3/README.rst11
-rw-r--r--contrib/python/psutil/py3/patches/01-arcadia.patch14
-rw-r--r--contrib/python/psutil/py3/psutil/__init__.py323
-rw-r--r--contrib/python/psutil/py3/psutil/_common.py212
-rw-r--r--contrib/python/psutil/py3/psutil/_compat.py477
-rw-r--r--contrib/python/psutil/py3/psutil/_psaix.py62
-rw-r--r--contrib/python/psutil/py3/psutil/_psbsd.py102
-rw-r--r--contrib/python/psutil/py3/psutil/_pslinux.py427
-rw-r--r--contrib/python/psutil/py3/psutil/_psosx.py24
-rw-r--r--contrib/python/psutil/py3/psutil/_psposix.py62
-rw-r--r--contrib/python/psutil/py3/psutil/_pssunos.py101
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_common.c9
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_common.h21
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_linux.c51
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_osx.c46
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_posix.c47
-rw-r--r--contrib/python/psutil/py3/psutil/_psutil_windows.c35
-rw-r--r--contrib/python/psutil/py3/psutil/_pswindows.py220
-rw-r--r--contrib/python/psutil/py3/psutil/arch/linux/proc.c12
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/disk.c6
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/mem.c13
-rw-r--r--contrib/python/psutil/py3/psutil/arch/osx/proc.c4
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/disk.c29
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/net.c11
-rw-r--r--contrib/python/psutil/py3/psutil/arch/windows/proc.c4
-rw-r--r--contrib/python/psutil/py3/ya.make5
27 files changed, 680 insertions, 1672 deletions
diff --git a/contrib/python/psutil/py3/.dist-info/METADATA b/contrib/python/psutil/py3/.dist-info/METADATA
index eced53b9c36..685d2e23f38 100644
--- a/contrib/python/psutil/py3/.dist-info/METADATA
+++ b/contrib/python/psutil/py3/.dist-info/METADATA
@@ -1,7 +1,7 @@
Metadata-Version: 2.1
Name: psutil
-Version: 6.1.1
-Summary: Cross-platform lib for process and system monitoring in Python.
+Version: 7.0.0
+Summary: Cross-platform lib for process and system monitoring in Python. NOTE: the syntax of this script MUST be kept compatible with Python 2.7.
Home-page: https://github.com/giampaolo/psutil
Author: Giampaolo Rodola
Author-email: [email protected]
@@ -34,8 +34,6 @@ Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: POSIX :: SunOS/Solaris
Classifier: Operating System :: POSIX
Classifier: Programming Language :: C
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -52,12 +50,15 @@ Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Operating System
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
+Requires-Python: >=3.6
Description-Content-Type: text/x-rst
License-File: LICENSE
Provides-Extra: dev
+Requires-Dist: pytest ; extra == 'dev'
+Requires-Dist: pytest-xdist ; extra == 'dev'
+Requires-Dist: setuptools ; extra == 'dev'
Requires-Dist: abi3audit ; extra == 'dev'
-Requires-Dist: black ; extra == 'dev'
+Requires-Dist: black (==24.10.0) ; extra == 'dev'
Requires-Dist: check-manifest ; extra == 'dev'
Requires-Dist: coverage ; extra == 'dev'
Requires-Dist: packaging ; extra == 'dev'
@@ -82,7 +83,7 @@ Requires-Dist: setuptools ; extra == 'test'
| |downloads| |stars| |forks| |contributors| |coverage|
| |version| |py-versions| |packages| |license|
-| |github-actions-wheels| |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
+| |github-actions-wheels| |github-actions-bsd| |doc| |twitter| |tidelift|
.. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pepy.tech/project/psutil
@@ -108,10 +109,6 @@ Requires-Dist: setuptools ; extra == 'test'
:target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
:alt: FreeBSD, NetBSD, OpenBSD
-.. |appveyor| image:: https://img.shields.io/appveyor/build/giampaolo/psutil/master.svg?maxAge=3600&label=Windows%20(py2)
- :target: https://ci.appveyor.com/project/giampaolo/psutil
- :alt: Windows (Appveyor)
-
.. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
@@ -177,8 +174,9 @@ psutil currently supports the following platforms:
- **Sun Solaris**
- **AIX**
-Supported Python versions are **2.7**, **3.6+** and
-`PyPy <http://pypy.org/>`__.
+Supported Python versions are cPython 3.6+ and `PyPy <https://pypy.org/>`__.
+Latest psutil version supporting Python 2.7 is
+`psutil 6.1.1 <https://pypi.org/project/psutil/6.1.1/>`__.
Funding
=======
diff --git a/contrib/python/psutil/py3/README.rst b/contrib/python/psutil/py3/README.rst
index 3fc6e601b12..16c756c50e2 100644
--- a/contrib/python/psutil/py3/README.rst
+++ b/contrib/python/psutil/py3/README.rst
@@ -1,6 +1,6 @@
| |downloads| |stars| |forks| |contributors| |coverage|
| |version| |py-versions| |packages| |license|
-| |github-actions-wheels| |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
+| |github-actions-wheels| |github-actions-bsd| |doc| |twitter| |tidelift|
.. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pepy.tech/project/psutil
@@ -26,10 +26,6 @@
:target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
:alt: FreeBSD, NetBSD, OpenBSD
-.. |appveyor| image:: https://img.shields.io/appveyor/build/giampaolo/psutil/master.svg?maxAge=3600&label=Windows%20(py2)
- :target: https://ci.appveyor.com/project/giampaolo/psutil
- :alt: Windows (Appveyor)
-
.. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
:target: https://coveralls.io/github/giampaolo/psutil?branch=master
:alt: Test coverage (coverall.io)
@@ -98,8 +94,9 @@ psutil currently supports the following platforms:
- **Sun Solaris**
- **AIX**
-Supported Python versions are **2.7**, **3.6+** and
-`PyPy <http://pypy.org/>`__.
+Supported Python versions are cPython 3.6+ and `PyPy <https://pypy.org/>`__.
+Latest psutil version supporting Python 2.7 is
+`psutil 6.1.1 <https://pypi.org/project/psutil/6.1.1/>`__.
Funding
=======
diff --git a/contrib/python/psutil/py3/patches/01-arcadia.patch b/contrib/python/psutil/py3/patches/01-arcadia.patch
index 54b53d1db5c..6a0b3aff1df 100644
--- a/contrib/python/psutil/py3/patches/01-arcadia.patch
+++ b/contrib/python/psutil/py3/patches/01-arcadia.patch
@@ -1,17 +1,3 @@
---- contrib/python/psutil/py3/psutil/_pslinux.py (index)
-+++ contrib/python/psutil/py3/psutil/_pslinux.py (working tree)
-@@ -322,7 +322,10 @@ try:
- except ImportError:
- import ctypes
-
-- libc = ctypes.CDLL(None, use_errno=True)
-+ try:
-+ libc = ctypes.CDLL(None, use_errno=True)
-+ except:
-+ libc = None
-
- if hasattr(libc, "prlimit"):
-
--- contrib/python/psutil/py3/psutil/arch/windows/disk.c (index)
+++ contrib/python/psutil/py3/psutil/arch/windows/disk.c (working tree)
@@ -7,6 +7,7 @@
diff --git a/contrib/python/psutil/py3/psutil/__init__.py b/contrib/python/psutil/py3/psutil/__init__.py
index 56483393827..cf4a58057f9 100644
--- a/contrib/python/psutil/py3/psutil/__init__.py
+++ b/contrib/python/psutil/py3/psutil/__init__.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -17,17 +15,16 @@ sensors) in Python. Supported platforms:
- Sun Solaris
- AIX
-Works with Python versions 2.7 and 3.6+.
+Supported Python versions are cPython 3.6+ and PyPy.
"""
-from __future__ import division
-
import collections
import contextlib
import datetime
import functools
import os
import signal
+import socket
import subprocess
import sys
import threading
@@ -54,16 +51,16 @@ from ._common import CONN_NONE
from ._common import CONN_SYN_RECV
from ._common import CONN_SYN_SENT
from ._common import CONN_TIME_WAIT
-from ._common import FREEBSD # NOQA
+from ._common import FREEBSD
from ._common import LINUX
from ._common import MACOS
-from ._common import NETBSD # NOQA
+from ._common import NETBSD
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
-from ._common import OPENBSD # NOQA
+from ._common import OPENBSD
from ._common import OSX # deprecated alias
-from ._common import POSIX # NOQA
+from ._common import POSIX
from ._common import POWER_TIME_UNKNOWN
from ._common import POWER_TIME_UNLIMITED
from ._common import STATUS_DEAD
@@ -88,11 +85,6 @@ from ._common import ZombieProcess
from ._common import debug
from ._common import memoize_when_activated
from ._common import wrap_numbers as _wrap_numbers
-from ._compat import PY3 as _PY3
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import SubprocessTimeoutExpired as _SubprocessTimeoutExpired
-from ._compat import long
if LINUX:
@@ -101,24 +93,24 @@ if LINUX:
PROCFS_PATH = "/proc"
from . import _pslinux as _psplatform
- from ._pslinux import IOPRIO_CLASS_BE # NOQA
- from ._pslinux import IOPRIO_CLASS_IDLE # NOQA
- from ._pslinux import IOPRIO_CLASS_NONE # NOQA
- from ._pslinux import IOPRIO_CLASS_RT # NOQA
+ from ._pslinux import IOPRIO_CLASS_BE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_IDLE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_NONE # noqa: F401
+ from ._pslinux import IOPRIO_CLASS_RT # noqa: F401
elif WINDOWS:
from . import _pswindows as _psplatform
- from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import HIGH_PRIORITY_CLASS # NOQA
- from ._psutil_windows import IDLE_PRIORITY_CLASS # NOQA
- from ._psutil_windows import NORMAL_PRIORITY_CLASS # NOQA
- from ._psutil_windows import REALTIME_PRIORITY_CLASS # NOQA
- from ._pswindows import CONN_DELETE_TCB # NOQA
- from ._pswindows import IOPRIO_HIGH # NOQA
- from ._pswindows import IOPRIO_LOW # NOQA
- from ._pswindows import IOPRIO_NORMAL # NOQA
- from ._pswindows import IOPRIO_VERYLOW # NOQA
+ from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import HIGH_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import IDLE_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import NORMAL_PRIORITY_CLASS # noqa: F401
+ from ._psutil_windows import REALTIME_PRIORITY_CLASS # noqa: F401
+ from ._pswindows import CONN_DELETE_TCB # noqa: F401
+ from ._pswindows import IOPRIO_HIGH # noqa: F401
+ from ._pswindows import IOPRIO_LOW # noqa: F401
+ from ._pswindows import IOPRIO_NORMAL # noqa: F401
+ from ._pswindows import IOPRIO_VERYLOW # noqa: F401
elif MACOS:
from . import _psosx as _psplatform
@@ -128,8 +120,8 @@ elif BSD:
elif SUNOS:
from . import _pssunos as _psplatform
- from ._pssunos import CONN_BOUND # NOQA
- from ._pssunos import CONN_IDLE # NOQA
+ from ._pssunos import CONN_BOUND # noqa: F401
+ from ._pssunos import CONN_IDLE # noqa: F401
# This is public writable API which is read from _pslinux.py and
# _pssunos.py via sys.modules.
@@ -143,7 +135,8 @@ elif AIX:
PROCFS_PATH = "/proc"
else: # pragma: no cover
- raise NotImplementedError('platform %s is not supported' % sys.platform)
+ msg = f"platform {sys.platform} is not supported"
+ raise NotImplementedError(msg)
# fmt: off
@@ -214,8 +207,8 @@ if hasattr(_psplatform.Process, "rlimit"):
AF_LINK = _psplatform.AF_LINK
__author__ = "Giampaolo Rodola'"
-__version__ = "6.1.1"
-version_info = tuple([int(num) for num in __version__.split('.')])
+__version__ = "7.0.0"
+version_info = tuple(int(num) for num in __version__.split('.'))
_timer = getattr(time, 'monotonic', time.time)
_TOTAL_PHYMEM = None
@@ -231,22 +224,19 @@ _SENTINEL = object()
if int(__version__.replace('.', '')) != getattr(
_psplatform.cext, 'version', None
):
- msg = "version conflict: %r C extension " % _psplatform.cext.__file__
+ msg = f"version conflict: {_psplatform.cext.__file__!r} C extension "
msg += "module was built for another version of psutil"
if hasattr(_psplatform.cext, 'version'):
- msg += " (%s instead of %s)" % (
- '.'.join([x for x in str(_psplatform.cext.version)]),
- __version__,
- )
+ v = ".".join(list(str(_psplatform.cext.version)))
+ msg += f" ({v} instead of {__version__})"
else:
- msg += " (different than %s)" % __version__
- msg += "; you may try to 'pip uninstall psutil', manually remove %s" % (
- getattr(
- _psplatform.cext,
- "__file__",
- "the existing psutil install directory",
- )
+ msg += f" (different than {__version__})"
+ what = getattr(
+ _psplatform.cext,
+ "__file__",
+ "the existing psutil install directory",
)
+ msg += f"; you may try to 'pip uninstall psutil', manually remove {what}"
msg += " or clean the virtual env somehow, then reinstall"
raise ImportError(msg)
@@ -282,12 +272,20 @@ def _pprint_secs(secs):
return datetime.datetime.fromtimestamp(secs).strftime(fmt)
+def _check_conn_kind(kind):
+ """Check net_connections()'s `kind` parameter."""
+ kinds = tuple(_common.conn_tmap)
+ if kind not in kinds:
+ msg = f"invalid kind argument {kind!r}; valid ones are: {kinds}"
+ raise ValueError(msg)
+
+
# =====================================================================
# --- Process class
# =====================================================================
-class Process(object): # noqa: UP004
+class Process:
"""Represents an OS process with the given PID.
If PID is omitted current process PID (os.getpid()) is used.
Raise NoSuchProcess if PID does not exist.
@@ -322,17 +320,14 @@ class Process(object): # noqa: UP004
if pid is None:
pid = os.getpid()
else:
- if not _PY3 and not isinstance(pid, (int, long)):
- msg = "pid must be an integer (got %r)" % pid
- raise TypeError(msg)
if pid < 0:
- msg = "pid must be a positive integer (got %s)" % pid
+ msg = f"pid must be a positive integer (got {pid})"
raise ValueError(msg)
try:
_psplatform.cext.check_pid_range(pid)
- except OverflowError:
- msg = "process PID out of range (got %s)" % pid
- raise NoSuchProcess(pid, msg=msg)
+ except OverflowError as err:
+ msg = "process PID out of range"
+ raise NoSuchProcess(pid, msg=msg) from err
self._pid = pid
self._name = None
@@ -365,9 +360,8 @@ class Process(object): # noqa: UP004
except NoSuchProcess:
if not _ignore_nsp:
msg = "process PID not found"
- raise NoSuchProcess(pid, msg=msg)
- else:
- self._gone = True
+ raise NoSuchProcess(pid, msg=msg) from None
+ self._gone = True
def _get_ident(self):
"""Return a (pid, uid) tuple which is supposed to identify a
@@ -419,10 +413,10 @@ class Process(object): # noqa: UP004
if self._create_time is not None:
info['started'] = _pprint_secs(self._create_time)
- return "%s.%s(%s)" % (
+ return "{}.{}({})".format(
self.__class__.__module__,
self.__class__.__name__,
- ", ".join(["%s=%r" % (k, v) for k, v in info.items()]),
+ ", ".join([f"{k}={v!r}" for k, v in info.items()]),
)
__repr__ = __str__
@@ -556,12 +550,12 @@ class Process(object): # noqa: UP004
valid_names = _as_dict_attrnames
if attrs is not None:
if not isinstance(attrs, (list, tuple, set, frozenset)):
- msg = "invalid attrs type %s" % type(attrs)
+ msg = f"invalid attrs type {type(attrs)}"
raise TypeError(msg)
attrs = set(attrs)
invalid_names = attrs - valid_names
if invalid_names:
- msg = "invalid attr name%s %s" % (
+ msg = "invalid attr name{} {}".format(
"s" if len(invalid_names) > 1 else "",
", ".join(map(repr, invalid_names)),
)
@@ -1049,7 +1043,7 @@ class Process(object): # noqa: UP004
"""
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval!r})"
raise ValueError(msg)
num_cpus = cpu_count() or 1
@@ -1127,10 +1121,6 @@ class Process(object): # noqa: UP004
"""
return self._proc.memory_info()
- @_common.deprecated_method(replacement="memory_info")
- def memory_info_ex(self):
- return self.memory_info()
-
def memory_full_info(self):
"""This method returns the same information as memory_info(),
plus, on some platform (Linux, macOS, Windows), also provides
@@ -1159,9 +1149,9 @@ class Process(object): # noqa: UP004
"""
valid_types = list(_psplatform.pfullmem._fields)
if memtype not in valid_types:
- msg = "invalid memtype %r; valid types are %r" % (
- memtype,
- tuple(valid_types),
+ msg = (
+ f"invalid memtype {memtype!r}; valid types are"
+ f" {tuple(valid_types)!r}"
)
raise ValueError(msg)
fun = (
@@ -1178,7 +1168,7 @@ class Process(object): # noqa: UP004
# we should never get here
msg = (
"can't calculate process memory percent because total physical"
- " system memory is not positive (%r)" % (total_phymem)
+ f" system memory is not positive ({total_phymem!r})"
)
raise ValueError(msg)
return (value / float(total_phymem)) * 100
@@ -1203,11 +1193,11 @@ class Process(object): # noqa: UP004
path = tupl[2]
nums = tupl[3:]
try:
- d[path] = map(lambda x, y: x + y, d[path], nums)
+ d[path] = list(map(lambda x, y: x + y, d[path], nums))
except KeyError:
d[path] = nums
nt = _psplatform.pmmap_grouped
- return [nt(path, *d[path]) for path in d] # NOQA
+ return [nt(path, *d[path]) for path in d]
else:
nt = _psplatform.pmmap_ext
return [nt(*x) for x in it]
@@ -1241,6 +1231,7 @@ class Process(object): # noqa: UP004
| all | the sum of all the possible families and protocols |
+------------+----------------------------------------------------+
"""
+ _check_conn_kind(kind)
return self._proc.net_connections(kind)
@_common.deprecated_method(replacement="net_connections")
@@ -1254,7 +1245,9 @@ class Process(object): # noqa: UP004
def _send_signal(self, sig):
assert not self.pid < 0, self.pid
self._raise_if_pid_reused()
- if self.pid == 0:
+
+ pid, ppid, name = self.pid, self._ppid, self._name
+ if pid == 0:
# see "man 2 kill"
msg = (
"preventing sending signal to process with PID 0 as it "
@@ -1263,17 +1256,16 @@ class Process(object): # noqa: UP004
)
raise ValueError(msg)
try:
- os.kill(self.pid, sig)
- except ProcessLookupError:
- if OPENBSD and pid_exists(self.pid):
+ os.kill(pid, sig)
+ except ProcessLookupError as err:
+ if OPENBSD and pid_exists(pid):
# We do this because os.kill() lies in case of
# zombie processes.
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- self._gone = True
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ raise ZombieProcess(pid, name, ppid) from err
+ self._gone = True
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
def send_signal(self, sig):
"""Send a signal *sig* to process pre-emptively checking
@@ -1358,11 +1350,12 @@ class Process(object): # noqa: UP004
# The valid attr names which can be processed by Process.as_dict().
# fmt: off
-_as_dict_attrnames = set(
- [x for x in dir(Process) if not x.startswith('_') and x not in
+_as_dict_attrnames = {
+ x for x in dir(Process) if not x.startswith("_") and x not in
{'send_signal', 'suspend', 'resume', 'terminate', 'kill', 'wait',
'is_running', 'as_dict', 'parent', 'parents', 'children', 'rlimit',
- 'memory_info_ex', 'connections', 'oneshot'}])
+ 'connections', 'oneshot'}
+}
# fmt: on
@@ -1439,16 +1432,13 @@ class Popen(Process):
try:
return object.__getattribute__(self.__subproc, name)
except AttributeError:
- msg = "%s instance has no attribute '%s'" % (
- self.__class__.__name__,
- name,
- )
- raise AttributeError(msg)
+ msg = f"{self.__class__!r} has no attribute {name!r}"
+ raise AttributeError(msg) from None
def wait(self, timeout=None):
if self.__subproc.returncode is not None:
return self.__subproc.returncode
- ret = super(Popen, self).wait(timeout) # noqa
+ ret = super().wait(timeout)
self.__subproc.returncode = ret
return ret
@@ -1525,7 +1515,7 @@ def process_iter(attrs=None, ad_value=None):
remove(pid)
while _pids_reused:
pid = _pids_reused.pop()
- debug("refreshing Process instance for reused PID %s" % pid)
+ debug(f"refreshing Process instance for reused PID {pid}")
remove(pid)
try:
ls = sorted(list(pmap.items()) + list(dict.fromkeys(new_pids).items()))
@@ -1542,7 +1532,7 @@ def process_iter(attrs=None, ad_value=None):
_pmap = pmap
-process_iter.cache_clear = lambda: _pmap.clear() # noqa
+process_iter.cache_clear = lambda: _pmap.clear() # noqa: PLW0108
process_iter.cache_clear.__doc__ = "Clear process_iter() internal cache."
@@ -1586,9 +1576,7 @@ def wait_procs(procs, timeout=None, callback=None):
def check_gone(proc, timeout):
try:
returncode = proc.wait(timeout=timeout)
- except TimeoutExpired:
- pass
- except _SubprocessTimeoutExpired:
+ except (TimeoutExpired, subprocess.TimeoutExpired):
pass
else:
if returncode is not None or not proc.is_running():
@@ -1599,12 +1587,12 @@ def wait_procs(procs, timeout=None, callback=None):
callback(proc)
if timeout is not None and not timeout >= 0:
- msg = "timeout must be a positive integer, got %s" % timeout
+ msg = f"timeout must be a positive integer, got {timeout}"
raise ValueError(msg)
gone = set()
alive = set(procs)
if callback is not None and not callable(callback):
- msg = "callback %r is not a callable" % callback
+ msg = f"callback {callback!r} is not a callable"
raise TypeError(msg)
if timeout is not None:
deadline = _timer() + timeout
@@ -1627,7 +1615,7 @@ def wait_procs(procs, timeout=None, callback=None):
check_gone(proc, timeout)
else:
check_gone(proc, max_timeout)
- alive = alive - gone # noqa PLR6104
+ alive = alive - gone # noqa: PLR6104
if alive:
# Last attempt over processes survived so far.
@@ -1646,7 +1634,7 @@ def wait_procs(procs, timeout=None, callback=None):
def cpu_count(logical=True):
"""Return the number of logical CPUs in the system (same as
- os.cpu_count() in Python 3.4).
+ os.cpu_count()).
If *logical* is False return the number of physical cores only
(e.g. hyper thread CPUs are excluded).
@@ -1804,7 +1792,7 @@ def cpu_percent(interval=None, percpu=False):
tid = threading.current_thread().ident
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval})"
raise ValueError(msg)
def calculate(t1, t2):
@@ -1864,7 +1852,7 @@ def cpu_times_percent(interval=None, percpu=False):
tid = threading.current_thread().ident
blocking = interval is not None and interval > 0.0
if interval is not None and interval < 0:
- msg = "interval is not positive (got %r)" % interval
+ msg = f"interval is not positive (got {interval!r})"
raise ValueError(msg)
def calculate(t1, t2):
@@ -2202,6 +2190,7 @@ def net_connections(kind='inet'):
On macOS this function requires root privileges.
"""
+ _check_conn_kind(kind)
return _psplatform.net_connections(kind)
@@ -2223,35 +2212,46 @@ def net_if_addrs():
Note: you can have more than one address of the same family
associated with each interface.
"""
- has_enums = _PY3
- if has_enums:
- import socket
rawlist = _psplatform.net_if_addrs()
rawlist.sort(key=lambda x: x[1]) # sort by family
ret = collections.defaultdict(list)
for name, fam, addr, mask, broadcast, ptp in rawlist:
- if has_enums:
- try:
- fam = socket.AddressFamily(fam)
- except ValueError:
- if WINDOWS and fam == -1:
- fam = _psplatform.AF_LINK
- elif (
- hasattr(_psplatform, "AF_LINK")
- and fam == _psplatform.AF_LINK
- ):
- # Linux defines AF_LINK as an alias for AF_PACKET.
- # We re-set the family here so that repr(family)
- # will show AF_LINK rather than AF_PACKET
- fam = _psplatform.AF_LINK
+ try:
+ fam = socket.AddressFamily(fam)
+ except ValueError:
+ if WINDOWS and fam == -1:
+ fam = _psplatform.AF_LINK
+ elif (
+ hasattr(_psplatform, "AF_LINK") and fam == _psplatform.AF_LINK
+ ):
+ # Linux defines AF_LINK as an alias for AF_PACKET.
+ # We re-set the family here so that repr(family)
+ # will show AF_LINK rather than AF_PACKET
+ fam = _psplatform.AF_LINK
+
if fam == _psplatform.AF_LINK:
# The underlying C function may return an incomplete MAC
# address in which case we fill it with null bytes, see:
# https://github.com/giampaolo/psutil/issues/786
separator = ":" if POSIX else "-"
while addr.count(separator) < 5:
- addr += "%s00" % separator
- ret[name].append(_common.snicaddr(fam, addr, mask, broadcast, ptp))
+ addr += f"{separator}00"
+
+ nt = _common.snicaddr(fam, addr, mask, broadcast, ptp)
+
+ # On Windows broadcast is None, so we determine it via
+ # ipaddress module.
+ if WINDOWS and fam in {socket.AF_INET, socket.AF_INET6}:
+ try:
+ broadcast = _common.broadcast_addr(nt)
+ except Exception as err: # noqa: BLE001
+ debug(err)
+ else:
+ if broadcast is not None:
+ nt._replace(broadcast=broadcast)
+
+ ret[name].append(nt)
+
return dict(ret)
@@ -2404,83 +2404,4 @@ def _set_debug(value):
_psplatform.cext.set_debug(bool(value))
-def test(): # pragma: no cover
- from ._common import bytes2human
- from ._compat import get_terminal_size
-
- today_day = datetime.date.today()
- # fmt: off
- templ = "%-10s %5s %5s %7s %7s %5s %6s %6s %6s %s"
- attrs = ['pid', 'memory_percent', 'name', 'cmdline', 'cpu_times',
- 'create_time', 'memory_info', 'status', 'nice', 'username']
- print(templ % ("USER", "PID", "%MEM", "VSZ", "RSS", "NICE", # NOQA
- "STATUS", "START", "TIME", "CMDLINE"))
- # fmt: on
- for p in process_iter(attrs, ad_value=None):
- if p.info['create_time']:
- ctime = datetime.datetime.fromtimestamp(p.info['create_time'])
- if ctime.date() == today_day:
- ctime = ctime.strftime("%H:%M")
- else:
- ctime = ctime.strftime("%b%d")
- else:
- ctime = ''
- if p.info['cpu_times']:
- cputime = time.strftime(
- "%M:%S", time.localtime(sum(p.info['cpu_times']))
- )
- else:
- cputime = ''
-
- user = p.info['username'] or ''
- if not user and POSIX:
- try:
- user = p.uids()[0]
- except Error:
- pass
- if user and WINDOWS and '\\' in user:
- user = user.split('\\')[1]
- user = user[:9]
- vms = (
- bytes2human(p.info['memory_info'].vms)
- if p.info['memory_info'] is not None
- else ''
- )
- rss = (
- bytes2human(p.info['memory_info'].rss)
- if p.info['memory_info'] is not None
- else ''
- )
- memp = (
- round(p.info['memory_percent'], 1)
- if p.info['memory_percent'] is not None
- else ''
- )
- nice = int(p.info['nice']) if p.info['nice'] else ''
- if p.info['cmdline']:
- cmdline = ' '.join(p.info['cmdline'])
- else:
- cmdline = p.info['name']
- status = p.info['status'][:5] if p.info['status'] else ''
-
- line = templ % (
- user[:10],
- p.info['pid'],
- memp,
- vms,
- rss,
- nice,
- status,
- ctime,
- cputime,
- cmdline,
- )
- print(line[: get_terminal_size()[0]]) # NOQA
-
-
-del memoize_when_activated, division
-if sys.version_info[0] < 3:
- del num, x # noqa
-
-if __name__ == "__main__":
- test()
+del memoize_when_activated
diff --git a/contrib/python/psutil/py3/psutil/_common.py b/contrib/python/psutil/py3/psutil/_common.py
index 4b99b093e30..4096c0a18c8 100644
--- a/contrib/python/psutil/py3/psutil/_common.py
+++ b/contrib/python/psutil/py3/psutil/_common.py
@@ -2,17 +2,14 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Common objects shared by __init__.py and _ps*.py modules."""
+"""Common objects shared by __init__.py and _ps*.py modules.
-# Note: this module is imported by setup.py so it should not import
-# psutil or third-party modules.
-
-from __future__ import division
-from __future__ import print_function
+Note: this module is imported by setup.py, so it should not import
+psutil or third-party modules.
+"""
import collections
-import contextlib
-import errno
+import enum
import functools
import os
import socket
@@ -36,14 +33,6 @@ except ImportError:
AF_UNIX = None
-# can't take it from _common.py as this script is imported by setup.py
-PY3 = sys.version_info[0] >= 3
-if PY3:
- import enum
-else:
- enum = None
-
-
PSUTIL_DEBUG = bool(os.getenv('PSUTIL_DEBUG'))
_DEFAULT = object()
@@ -57,7 +46,7 @@ __all__ = [
'CONN_FIN_WAIT1', 'CONN_FIN_WAIT2', 'CONN_LAST_ACK', 'CONN_LISTEN',
'CONN_NONE', 'CONN_SYN_RECV', 'CONN_SYN_SENT', 'CONN_TIME_WAIT',
# net constants
- 'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN',
+ 'NIC_DUPLEX_FULL', 'NIC_DUPLEX_HALF', 'NIC_DUPLEX_UNKNOWN', # noqa: F822
# process status constants
'STATUS_DEAD', 'STATUS_DISK_SLEEP', 'STATUS_IDLE', 'STATUS_LOCKED',
'STATUS_RUNNING', 'STATUS_SLEEPING', 'STATUS_STOPPED', 'STATUS_SUSPENDED',
@@ -134,42 +123,29 @@ CONN_LISTEN = "LISTEN"
CONN_CLOSING = "CLOSING"
CONN_NONE = "NONE"
+
# net_if_stats()
-if enum is None:
+class NicDuplex(enum.IntEnum):
NIC_DUPLEX_FULL = 2
NIC_DUPLEX_HALF = 1
NIC_DUPLEX_UNKNOWN = 0
-else:
- class NicDuplex(enum.IntEnum):
- NIC_DUPLEX_FULL = 2
- NIC_DUPLEX_HALF = 1
- NIC_DUPLEX_UNKNOWN = 0
- globals().update(NicDuplex.__members__)
+globals().update(NicDuplex.__members__)
+
# sensors_battery()
-if enum is None:
+class BatteryTime(enum.IntEnum):
POWER_TIME_UNKNOWN = -1
POWER_TIME_UNLIMITED = -2
-else:
- class BatteryTime(enum.IntEnum):
- POWER_TIME_UNKNOWN = -1
- POWER_TIME_UNLIMITED = -2
- globals().update(BatteryTime.__members__)
+globals().update(BatteryTime.__members__)
# --- others
ENCODING = sys.getfilesystemencoding()
-if not PY3:
- ENCODING_ERRS = "replace"
-else:
- try:
- ENCODING_ERRS = sys.getfilesystemencodeerrors() # py 3.6
- except AttributeError:
- ENCODING_ERRS = "surrogateescape" if POSIX else "replace"
+ENCODING_ERRS = sys.getfilesystemencodeerrors()
# ===================================================================
@@ -273,7 +249,7 @@ if AF_INET6 is not None:
"udp6": ([AF_INET6], [SOCK_DGRAM]),
})
-if AF_UNIX is not None:
+if AF_UNIX is not None and not SUNOS:
conn_tmap.update({"unix": ([AF_UNIX], [SOCK_STREAM, SOCK_DGRAM])})
@@ -293,9 +269,7 @@ class Error(Exception):
info = collections.OrderedDict()
for name in attrs:
value = getattr(self, name, None)
- if value: # noqa
- info[name] = value
- elif name == "pid" and value == 0:
+ if value or (name == "pid" and value == 0):
info[name] = value
return info
@@ -303,8 +277,8 @@ class Error(Exception):
# invoked on `raise Error`
info = self._infodict(("pid", "ppid", "name"))
if info:
- details = "(%s)" % ", ".join(
- ["%s=%r" % (k, v) for k, v in info.items()]
+ details = "({})".format(
+ ", ".join([f"{k}={v!r}" for k, v in info.items()])
)
else:
details = None
@@ -313,8 +287,8 @@ class Error(Exception):
def __repr__(self):
# invoked on `repr(Error)`
info = self._infodict(("pid", "ppid", "name", "seconds", "msg"))
- details = ", ".join(["%s=%r" % (k, v) for k, v in info.items()])
- return "psutil.%s(%s)" % (self.__class__.__name__, details)
+ details = ", ".join([f"{k}={v!r}" for k, v in info.items()])
+ return f"psutil.{self.__class__.__name__}({details})"
class NoSuchProcess(Error):
@@ -380,7 +354,7 @@ class TimeoutExpired(Error):
self.seconds = seconds
self.pid = pid
self.name = name
- self.msg = "timeout after %s seconds" % seconds
+ self.msg = f"timeout after {seconds} seconds"
def __reduce__(self):
return (self.__class__, (self.seconds, self.pid, self.name))
@@ -391,26 +365,6 @@ class TimeoutExpired(Error):
# ===================================================================
-# This should be in _compat.py rather than here, but does not work well
-# with setup.py importing this module via a sys.path trick.
-if PY3:
- if isinstance(__builtins__, dict): # cpython
- exec_ = __builtins__["exec"]
- else: # pypy
- exec_ = getattr(__builtins__, "exec") # noqa
-
- exec_("""def raise_from(value, from_value):
- try:
- raise value from from_value
- finally:
- value = None
- """)
-else:
-
- def raise_from(value, from_value):
- raise value
-
-
def usage_percent(used, total, round_=None):
"""Calculate percentage usage of 'used' against 'total'."""
try:
@@ -456,7 +410,7 @@ def memoize(fun):
try:
ret = cache[key] = fun(*args, **kwargs)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
return ret
def cache_clear():
@@ -505,14 +459,14 @@ def memoize_when_activated(fun):
try:
return fun(self)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
except KeyError:
# case 3: we entered oneshot() ctx but there's no cache
# for this entry yet
try:
ret = fun(self)
except Exception as err: # noqa: BLE001
- raise raise_from(err, None)
+ raise err from None
try:
self._cache[fun] = ret
except AttributeError:
@@ -546,9 +500,9 @@ def isfile_strict(path):
"""
try:
st = os.stat(path)
- except OSError as err:
- if err.errno in {errno.EPERM, errno.EACCES}:
- raise
+ except PermissionError:
+ raise
+ except OSError:
return False
else:
return stat.S_ISREG(st.st_mode)
@@ -561,9 +515,9 @@ def path_exists_strict(path):
"""
try:
os.stat(path)
- except OSError as err:
- if err.errno in {errno.EPERM, errno.EACCES}:
- raise
+ except PermissionError:
+ raise
+ except OSError:
return False
else:
return True
@@ -575,11 +529,10 @@ def supports_ipv6():
if not socket.has_ipv6 or AF_INET6 is None:
return False
try:
- sock = socket.socket(AF_INET6, socket.SOCK_STREAM)
- with contextlib.closing(sock):
+ with socket.socket(AF_INET6, socket.SOCK_STREAM) as sock:
sock.bind(("::1", 0))
return True
- except socket.error:
+ except OSError:
return False
@@ -615,26 +568,20 @@ def sockfam_to_enum(num):
"""Convert a numeric socket family value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
- if enum is None:
+ try:
+ return socket.AddressFamily(num)
+ except ValueError:
return num
- else: # pragma: no cover
- try:
- return socket.AddressFamily(num)
- except ValueError:
- return num
def socktype_to_enum(num):
"""Convert a numeric socket type value to an IntEnum member.
If it's not a known member, return the numeric value itself.
"""
- if enum is None:
+ try:
+ return socket.SocketKind(num)
+ except ValueError:
return num
- else: # pragma: no cover
- try:
- return socket.SocketKind(num)
- except ValueError:
- return num
def conn_to_ntuple(fd, fam, type_, laddr, raddr, status, status_map, pid=None):
@@ -656,15 +603,37 @@ def conn_to_ntuple(fd, fam, type_, laddr, raddr, status, status_map, pid=None):
return sconn(fd, fam, type_, laddr, raddr, status, pid)
+def broadcast_addr(addr):
+ """Given the address ntuple returned by ``net_if_addrs()``
+ calculates the broadcast address.
+ """
+ import ipaddress
+
+ if not addr.address or not addr.netmask:
+ return None
+ if addr.family == socket.AF_INET:
+ return str(
+ ipaddress.IPv4Network(
+ f"{addr.address}/{addr.netmask}", strict=False
+ ).broadcast_address
+ )
+ if addr.family == socket.AF_INET6:
+ return str(
+ ipaddress.IPv6Network(
+ f"{addr.address}/{addr.netmask}", strict=False
+ ).broadcast_address
+ )
+
+
def deprecated_method(replacement):
"""A decorator which can be used to mark a method as deprecated
'replcement' is the method name which will be called instead.
"""
def outer(fun):
- msg = "%s() is deprecated and will be removed; use %s() instead" % (
- fun.__name__,
- replacement,
+ msg = (
+ f"{fun.__name__}() is deprecated and will be removed; use"
+ f" {replacement}() instead"
)
if fun.__doc__ is None:
fun.__doc__ = msg
@@ -789,8 +758,6 @@ wrap_numbers.cache_info = _wn.cache_info
# is 8K. We use a bigger buffer (32K) in order to have more consistent
# results when reading /proc pseudo files on Linux, see:
# https://github.com/giampaolo/psutil/issues/2050
-# On Python 2 this also speeds up the reading of big files:
-# (namely /proc/{pid}/smaps and /proc/net/*):
# https://github.com/giampaolo/psutil/issues/708
FILE_READ_BUFFER_SIZE = 32 * 1024
@@ -800,17 +767,13 @@ def open_binary(fname):
def open_text(fname):
- """On Python 3 opens a file in text mode by using fs encoding and
- a proper en/decoding errors handler.
- On Python 2 this is just an alias for open(name, 'rt').
+ """Open a file in text mode by using the proper FS encoding and
+ en/decoding error handlers.
"""
- if not PY3:
- return open(fname, buffering=FILE_READ_BUFFER_SIZE)
-
# See:
# https://github.com/giampaolo/psutil/issues/675
# https://github.com/giampaolo/psutil/pull/733
- fobj = open(
+ fobj = open( # noqa: SIM115
fname,
buffering=FILE_READ_BUFFER_SIZE,
encoding=ENCODING,
@@ -842,7 +805,7 @@ def cat(fname, fallback=_DEFAULT, _open=open_text):
try:
with _open(fname) as f:
return f.read()
- except (IOError, OSError):
+ except OSError:
return fallback
@@ -852,7 +815,7 @@ def bcat(fname, fallback=_DEFAULT):
def bytes2human(n, format="%(value).1f%(symbol)s"):
- """Used by various scripts. See: http://goo.gl/zeJZl.
+ """Used by various scripts. See: https://code.activestate.com/recipes/578019-bytes-to-human-human-to-bytes-converter/?in=user-4178764.
>>> bytes2human(10000)
'9.8K'
@@ -875,15 +838,8 @@ def get_procfs_path():
return sys.modules['psutil'].PROCFS_PATH
-if PY3:
-
- def decode(s):
- return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
-
-else:
-
- def decode(s):
- return s
+def decode(s):
+ return s.decode(encoding=ENCODING, errors=ENCODING_ERRS)
# =====================================================================
@@ -927,13 +883,12 @@ def hilite(s, color=None, bold=False): # pragma: no cover
try:
color = colors[color]
except KeyError:
- raise ValueError(
- "invalid color %r; choose between %s" % (list(colors.keys()))
- )
+ msg = f"invalid color {color!r}; choose amongst {list(colors.keys())}"
+ raise ValueError(msg) from None
attr.append(color)
if bold:
attr.append('1')
- return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), s)
+ return f"\x1b[{';'.join(attr)}m{s}\x1b[0m"
def print_color(
@@ -941,9 +896,9 @@ def print_color(
): # pragma: no cover
"""Print a colorized version of string."""
if not term_supports_colors():
- print(s, file=file) # NOQA
+ print(s, file=file)
elif POSIX:
- print(hilite(s, color, bold), file=file) # NOQA
+ print(hilite(s, color, bold), file=file)
else:
import ctypes
@@ -958,10 +913,11 @@ def print_color(
try:
color = colors[color]
except KeyError:
- raise ValueError(
- "invalid color %r; choose between %r"
- % (color, list(colors.keys()))
+ msg = (
+ f"invalid color {color!r}; choose between"
+ f" {list(colors.keys())!r}"
)
+ raise ValueError(msg) from None
if bold and color <= 7:
color += 8
@@ -970,7 +926,7 @@ def print_color(
handle = GetStdHandle(handle_id)
SetConsoleTextAttribute(handle, color)
try:
- print(s, file=file) # NOQA
+ print(s, file=file)
finally:
SetConsoleTextAttribute(handle, DEFAULT_COLOR)
@@ -984,11 +940,11 @@ def debug(msg):
inspect.currentframe().f_back
)
if isinstance(msg, Exception):
- if isinstance(msg, (OSError, IOError, EnvironmentError)):
+ if isinstance(msg, OSError):
# ...because str(exc) may contain info about the file name
- msg = "ignoring %s" % msg
+ msg = f"ignoring {msg}"
else:
- msg = "ignoring %r" % msg
- print( # noqa
- "psutil-debug [%s:%s]> %s" % (fname, lineno, msg), file=sys.stderr
+ msg = f"ignoring {msg!r}"
+ print( # noqa: T201
+ f"psutil-debug [{fname}:{lineno}]> {msg}", file=sys.stderr
)
diff --git a/contrib/python/psutil/py3/psutil/_compat.py b/contrib/python/psutil/py3/psutil/_compat.py
deleted file mode 100644
index 92e01713c3f..00000000000
--- a/contrib/python/psutil/py3/psutil/_compat.py
+++ /dev/null
@@ -1,477 +0,0 @@
-# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module which provides compatibility with older Python versions.
-This is more future-compatible rather than the opposite (prefer latest
-Python 3 way of doing things).
-"""
-
-import collections
-import contextlib
-import errno
-import functools
-import os
-import sys
-import types
-
-
-# fmt: off
-__all__ = [
- # constants
- "PY3",
- # builtins
- "long", "range", "super", "unicode", "basestring",
- # literals
- "b",
- # collections module
- "lru_cache",
- # shutil module
- "which", "get_terminal_size",
- # contextlib module
- "redirect_stderr",
- # python 3 exceptions
- "FileNotFoundError", "PermissionError", "ProcessLookupError",
- "InterruptedError", "ChildProcessError", "FileExistsError",
-]
-# fmt: on
-
-
-PY3 = sys.version_info[0] >= 3
-_SENTINEL = object()
-
-if PY3:
- long = int
- xrange = range
- unicode = str
- basestring = str
- range = range
-
- def b(s):
- return s.encode("latin-1")
-
-else:
- long = long
- range = xrange
- unicode = unicode
- basestring = basestring
-
- def b(s):
- return s
-
-
-# --- builtins
-
-
-# Python 3 super().
-# Taken from "future" package.
-# Credit: Ryan Kelly
-if PY3:
- super = super
-else:
- _builtin_super = super
-
- def super(type_=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1):
- """Like Python 3 builtin super(). If called without any arguments
- it attempts to infer them at runtime.
- """
- if type_ is _SENTINEL:
- f = sys._getframe(framedepth)
- try:
- # Get the function's first positional argument.
- type_or_obj = f.f_locals[f.f_code.co_varnames[0]]
- except (IndexError, KeyError):
- msg = 'super() used in a function with no args'
- raise RuntimeError(msg)
- try:
- # Get the MRO so we can crawl it.
- mro = type_or_obj.__mro__
- except (AttributeError, RuntimeError):
- try:
- mro = type_or_obj.__class__.__mro__
- except AttributeError:
- msg = 'super() used in a non-newstyle class'
- raise RuntimeError(msg)
- for type_ in mro:
- # Find the class that owns the currently-executing method.
- for meth in type_.__dict__.values():
- # Drill down through any wrappers to the underlying func.
- # This handles e.g. classmethod() and staticmethod().
- try:
- while not isinstance(meth, types.FunctionType):
- if isinstance(meth, property):
- # Calling __get__ on the property will invoke
- # user code which might throw exceptions or
- # have side effects
- meth = meth.fget
- else:
- try:
- meth = meth.__func__
- except AttributeError:
- meth = meth.__get__(type_or_obj, type_)
- except (AttributeError, TypeError):
- continue
- if meth.func_code is f.f_code:
- break # found
- else:
- # Not found. Move onto the next class in MRO.
- continue
- break # found
- else:
- msg = 'super() called outside a method'
- raise RuntimeError(msg)
-
- # Dispatch to builtin super().
- if type_or_obj is not _SENTINEL:
- return _builtin_super(type_, type_or_obj)
- return _builtin_super(type_)
-
-
-# --- exceptions
-
-
-if PY3:
- FileNotFoundError = FileNotFoundError # NOQA
- PermissionError = PermissionError # NOQA
- ProcessLookupError = ProcessLookupError # NOQA
- InterruptedError = InterruptedError # NOQA
- ChildProcessError = ChildProcessError # NOQA
- FileExistsError = FileExistsError # NOQA
-else:
- # https://github.com/PythonCharmers/python-future/blob/exceptions/
- # src/future/types/exceptions/pep3151.py
- import platform
-
- def _instance_checking_exception(base_exception=Exception):
- def wrapped(instance_checker):
- class TemporaryClass(base_exception):
- def __init__(self, *args, **kwargs):
- if len(args) == 1 and isinstance(args[0], TemporaryClass):
- unwrap_me = args[0]
- for attr in dir(unwrap_me):
- if not attr.startswith('__'):
- setattr(self, attr, getattr(unwrap_me, attr))
- else:
- super(TemporaryClass, self).__init__( # noqa
- *args, **kwargs
- )
-
- class __metaclass__(type):
- def __instancecheck__(cls, inst):
- return instance_checker(inst)
-
- def __subclasscheck__(cls, classinfo):
- value = sys.exc_info()[1]
- return isinstance(value, cls)
-
- TemporaryClass.__name__ = instance_checker.__name__
- TemporaryClass.__doc__ = instance_checker.__doc__
- return TemporaryClass
-
- return wrapped
-
- @_instance_checking_exception(EnvironmentError)
- def FileNotFoundError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ENOENT
-
- @_instance_checking_exception(EnvironmentError)
- def ProcessLookupError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ESRCH
-
- @_instance_checking_exception(EnvironmentError)
- def PermissionError(inst):
- return getattr(inst, 'errno', _SENTINEL) in {errno.EACCES, errno.EPERM}
-
- @_instance_checking_exception(EnvironmentError)
- def InterruptedError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.EINTR
-
- @_instance_checking_exception(EnvironmentError)
- def ChildProcessError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.ECHILD
-
- @_instance_checking_exception(EnvironmentError)
- def FileExistsError(inst):
- return getattr(inst, 'errno', _SENTINEL) == errno.EEXIST
-
- if platform.python_implementation() != "CPython":
- try:
- raise OSError(errno.EEXIST, "perm")
- except FileExistsError:
- pass
- except OSError:
- msg = (
- "broken or incompatible Python implementation, see: "
- "https://github.com/giampaolo/psutil/issues/1659"
- )
- raise RuntimeError(msg)
-
-
-# --- stdlib additions
-
-
-# py 3.2 functools.lru_cache
-# Taken from: http://code.activestate.com/recipes/578078
-# Credit: Raymond Hettinger
-try:
- from functools import lru_cache
-except ImportError:
- try:
- from threading import RLock
- except ImportError:
- from dummy_threading import RLock
-
- _CacheInfo = collections.namedtuple(
- "CacheInfo", ["hits", "misses", "maxsize", "currsize"]
- )
-
- class _HashedSeq(list): # noqa: FURB189
- __slots__ = ('hashvalue',)
-
- def __init__(self, tup, hash=hash):
- self[:] = tup
- self.hashvalue = hash(tup)
-
- def __hash__(self):
- return self.hashvalue
-
- def _make_key(
- args,
- kwds,
- typed,
- kwd_mark=(_SENTINEL,),
- fasttypes=set((int, str, frozenset, type(None))), # noqa
- sorted=sorted,
- tuple=tuple,
- type=type,
- len=len,
- ):
- key = args
- if kwds:
- sorted_items = sorted(kwds.items())
- key += kwd_mark
- for item in sorted_items:
- key += item
- if typed:
- key += tuple(type(v) for v in args)
- if kwds:
- key += tuple(type(v) for k, v in sorted_items)
- elif len(key) == 1 and type(key[0]) in fasttypes:
- return key[0]
- return _HashedSeq(key)
-
- def lru_cache(maxsize=100, typed=False):
- """Least-recently-used cache decorator, see:
- http://docs.python.org/3/library/functools.html#functools.lru_cache.
- """
-
- def decorating_function(user_function):
- cache = {}
- stats = [0, 0]
- HITS, MISSES = 0, 1
- make_key = _make_key
- cache_get = cache.get
- _len = len
- lock = RLock()
- root = []
- root[:] = [root, root, None, None]
- nonlocal_root = [root]
- PREV, NEXT, KEY, RESULT = 0, 1, 2, 3
- if maxsize == 0:
-
- def wrapper(*args, **kwds):
- result = user_function(*args, **kwds)
- stats[MISSES] += 1
- return result
-
- elif maxsize is None:
-
- def wrapper(*args, **kwds):
- key = make_key(args, kwds, typed)
- result = cache_get(key, root)
- if result is not root:
- stats[HITS] += 1
- return result
- result = user_function(*args, **kwds)
- cache[key] = result
- stats[MISSES] += 1
- return result
-
- else:
-
- def wrapper(*args, **kwds):
- if kwds or typed:
- key = make_key(args, kwds, typed)
- else:
- key = args
- lock.acquire()
- try:
- link = cache_get(key)
- if link is not None:
- (root,) = nonlocal_root
- link_prev, link_next, key, result = link
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
- last = root[PREV]
- last[NEXT] = root[PREV] = link
- link[PREV] = last
- link[NEXT] = root
- stats[HITS] += 1
- return result
- finally:
- lock.release()
- result = user_function(*args, **kwds)
- lock.acquire()
- try:
- (root,) = nonlocal_root
- if key in cache:
- pass
- elif _len(cache) >= maxsize:
- oldroot = root
- oldroot[KEY] = key
- oldroot[RESULT] = result
- root = nonlocal_root[0] = oldroot[NEXT]
- oldkey = root[KEY]
- root[KEY] = root[RESULT] = None
- del cache[oldkey]
- cache[key] = oldroot
- else:
- last = root[PREV]
- link = [last, root, key, result]
- last[NEXT] = root[PREV] = cache[key] = link
- stats[MISSES] += 1
- finally:
- lock.release()
- return result
-
- def cache_info():
- """Report cache statistics."""
- lock.acquire()
- try:
- return _CacheInfo(
- stats[HITS], stats[MISSES], maxsize, len(cache)
- )
- finally:
- lock.release()
-
- def cache_clear():
- """Clear the cache and cache statistics."""
- lock.acquire()
- try:
- cache.clear()
- root = nonlocal_root[0]
- root[:] = [root, root, None, None]
- stats[:] = [0, 0]
- finally:
- lock.release()
-
- wrapper.__wrapped__ = user_function
- wrapper.cache_info = cache_info
- wrapper.cache_clear = cache_clear
- return functools.update_wrapper(wrapper, user_function)
-
- return decorating_function
-
-
-# python 3.3
-try:
- from shutil import which
-except ImportError:
-
- def which(cmd, mode=os.F_OK | os.X_OK, path=None):
- """Given a command, mode, and a PATH string, return the path which
- conforms to the given mode on the PATH, or None if there is no such
- file.
-
- `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
- of os.environ.get("PATH"), or can be overridden with a custom search
- path.
- """
-
- def _access_check(fn, mode):
- return (
- os.path.exists(fn)
- and os.access(fn, mode)
- and not os.path.isdir(fn)
- )
-
- if os.path.dirname(cmd):
- if _access_check(cmd, mode):
- return cmd
- return None
-
- if path is None:
- path = os.environ.get("PATH", os.defpath)
- if not path:
- return None
- path = path.split(os.pathsep)
-
- if sys.platform == "win32":
- if os.curdir not in path:
- path.insert(0, os.curdir)
-
- pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
- if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
- files = [cmd]
- else:
- files = [cmd + ext for ext in pathext]
- else:
- files = [cmd]
-
- seen = set()
- for dir in path:
- normdir = os.path.normcase(dir)
- if normdir not in seen:
- seen.add(normdir)
- for thefile in files:
- name = os.path.join(dir, thefile)
- if _access_check(name, mode):
- return name
- return None
-
-
-# python 3.3
-try:
- from shutil import get_terminal_size
-except ImportError:
-
- def get_terminal_size(fallback=(80, 24)):
- try:
- import fcntl
- import struct
- import termios
- except ImportError:
- return fallback
- else:
- try:
- # This should work on Linux.
- res = struct.unpack(
- 'hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234')
- )
- return (res[1], res[0])
- except Exception: # noqa: BLE001
- return fallback
-
-
-# python 3.3
-try:
- from subprocess import TimeoutExpired as SubprocessTimeoutExpired
-except ImportError:
-
- class SubprocessTimeoutExpired(Exception):
- pass
-
-
-# python 3.5
-try:
- from contextlib import redirect_stderr
-except ImportError:
-
- @contextlib.contextmanager
- def redirect_stderr(new_target):
- original = sys.stderr
- try:
- sys.stderr = new_target
- yield new_target
- finally:
- sys.stderr = original
diff --git a/contrib/python/psutil/py3/psutil/_psaix.py b/contrib/python/psutil/py3/psutil/_psaix.py
index 2ccc638bcea..ba2725fdc10 100644
--- a/contrib/python/psutil/py3/psutil/_psaix.py
+++ b/contrib/python/psutil/py3/psutil/_psaix.py
@@ -28,10 +28,6 @@ from ._common import conn_to_ntuple
from ._common import get_procfs_path
from ._common import memoize_when_activated
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
__extra__all__ = ["PROCFS_PATH"]
@@ -148,12 +144,10 @@ def cpu_count_cores():
cmd = ["lsdev", "-Cc", "processor"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (x.decode(sys.stdout.encoding) for x in (stdout, stderr))
if p.returncode != 0:
- raise RuntimeError("%r command error\n%s" % (cmd, stderr))
+ msg = f"{cmd!r} command error\n{stderr}"
+ raise RuntimeError(msg)
processors = stdout.strip().splitlines()
return len(processors) or None
@@ -211,12 +205,6 @@ def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only).
"""
- cmap = _common.conn_tmap
- if kind not in cmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in cmap]))
- )
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid)
ret = []
@@ -243,7 +231,7 @@ def net_connections(kind, _pid=-1):
def net_if_stats():
"""Get NIC stats (isup, duplex, speed, mtu)."""
duplex_map = {"Full": NIC_DUPLEX_FULL, "Half": NIC_DUPLEX_HALF}
- names = set([x[0] for x in net_if_addrs()])
+ names = {x[0] for x in net_if_addrs()}
ret = {}
for name in names:
mtu = cext_posix.net_if_mtu(name)
@@ -260,10 +248,9 @@ def net_if_stats():
stderr=subprocess.PIPE,
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if p.returncode == 0:
re_result = re.search(
r"Running: (\d+) Mbps.*?(\w+) Duplex", stdout
@@ -330,18 +317,18 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except (FileNotFoundError, ProcessLookupError):
+ except (FileNotFoundError, ProcessLookupError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ if not pid_exists(pid):
+ raise NoSuchProcess(pid, name) from err
+ raise ZombieProcess(pid, name, ppid) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
return wrapper
@@ -444,7 +431,7 @@ class Process:
# is no longer there.
if not retlist:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
return retlist
@wrap_exceptions
@@ -457,7 +444,7 @@ class Process:
# is no longer there.
if not ret:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
return ret
@wrap_exceptions
@@ -503,10 +490,10 @@ class Process:
def cwd(self):
procfs_path = self._procfs_path
try:
- result = os.readlink("%s/%s/cwd" % (procfs_path, self.pid))
+ result = os.readlink(f"{procfs_path}/{self.pid}/cwd")
return result.rstrip('/')
except FileNotFoundError:
- os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
+ os.stat(f"{procfs_path}/{self.pid}") # raise NSP or AD
return ""
@wrap_exceptions
@@ -533,10 +520,9 @@ class Process:
stderr=subprocess.PIPE,
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if "no such process" in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
procfiles = re.findall(r"(\d+): S_IFREG.*name:(.*)\n", stdout)
@@ -554,7 +540,7 @@ class Process:
def num_fds(self):
if self.pid == 0: # no /proc/0/fd
return 0
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def num_ctx_switches(self):
@@ -570,10 +556,10 @@ class Process:
def io_counters(self):
try:
rc, wc, rb, wb = cext.proc_io_counters(self.pid)
- except OSError:
+ except OSError as err:
# if process is terminated, proc_io_counters returns OSError
# instead of NSP
if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
+ raise NoSuchProcess(self.pid, self._name) from err
raise
return _common.pio(rc, wc, rb, wb)
diff --git a/contrib/python/psutil/py3/psutil/_psbsd.py b/contrib/python/psutil/py3/psutil/_psbsd.py
index 77b99c0fd8b..13bd926fabf 100644
--- a/contrib/python/psutil/py3/psutil/_psbsd.py
+++ b/contrib/python/psutil/py3/psutil/_psbsd.py
@@ -10,7 +10,7 @@ import functools
import os
from collections import defaultdict
from collections import namedtuple
-from xml.etree import ElementTree # noqa ICN001
+from xml.etree import ElementTree # noqa: ICN001
from . import _common
from . import _psposix
@@ -28,10 +28,6 @@ from ._common import debug
from ._common import memoize
from ._common import memoize_when_activated
from ._common import usage_percent
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import which
__extra__all__ = []
@@ -196,8 +192,8 @@ def virtual_memory():
# #2233), so zabbix seems to be wrong. Htop calculates it
# differently, and the used value seem more realistic, so let's
# match htop.
- # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162 # noqa
- # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135 # noqa
+ # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162
+ # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135
used = active + wired
avail = total - used
else:
@@ -206,7 +202,7 @@ def virtual_memory():
# * https://people.freebsd.org/~rse/dist/freebsd-memory
# * https://www.cyberciti.biz/files/scripts/freebsd-memory.pl.txt
# matches zabbix:
- # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143 # noqa
+ # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143
avail = inactive + cached + free
used = active + wired + cached
@@ -439,14 +435,8 @@ def net_if_stats():
def net_connections(kind):
"""System-wide network connections."""
- if kind not in _common.conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
ret = set()
-
if OPENBSD:
rawlist = cext.net_connections(-1, families, types)
elif NETBSD:
@@ -495,7 +485,7 @@ if FREEBSD:
current, high = cext.sensors_cpu_temperature(cpu)
if high <= 0:
high = None
- name = "Core %s" % cpu
+ name = f"Core {cpu}"
ret["coretemp"].append(
_common.shwtemp(name, current, high, high)
)
@@ -600,21 +590,18 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except ProcessLookupError:
- if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except OSError:
- if self.pid == 0:
- if 0 in pids():
- raise AccessDenied(self.pid, self._name)
- else:
- raise
+ except ProcessLookupError as err:
+ if is_zombie(pid):
+ raise ZombieProcess(pid, name, ppid) from err
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except OSError as err:
+ if pid == 0 and 0 in pids():
+ raise AccessDenied(pid, name) from err
raise
return wrapper
@@ -623,18 +610,19 @@ def wrap_exceptions(fun):
@contextlib.contextmanager
def wrap_exceptions_procfs(inst):
"""Same as above, for routines relying on reading /proc fs."""
+ pid, name, ppid = inst.pid, inst._name, inst._ppid
try:
yield
- except (ProcessLookupError, FileNotFoundError):
+ except (ProcessLookupError, FileNotFoundError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
if is_zombie(inst.pid):
- raise ZombieProcess(inst.pid, inst._name, inst._ppid)
+ raise ZombieProcess(pid, name, ppid) from err
else:
- raise NoSuchProcess(inst.pid, inst._name)
- except PermissionError:
- raise AccessDenied(inst.pid, inst._name)
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
class Process:
@@ -683,16 +671,18 @@ class Process:
# /proc/0 dir exists but /proc/0/exe doesn't
return ""
with wrap_exceptions_procfs(self):
- return os.readlink("/proc/%s/exe" % self.pid)
+ return os.readlink(f"/proc/{self.pid}/exe")
else:
# OpenBSD: exe cannot be determined; references:
# https://chromium.googlesource.com/chromium/src/base/+/
# master/base_paths_posix.cc
# We try our best guess by using which against the first
# cmdline arg (may return None).
+ import shutil
+
cmdline = self.cmdline()
if cmdline:
- return which(cmdline[0]) or ""
+ return shutil.which(cmdline[0]) or ""
else:
return ""
@@ -709,15 +699,15 @@ class Process:
return cext.proc_cmdline(self.pid)
except OSError as err:
if err.errno == errno.EINVAL:
+ pid, name, ppid = self.pid, self._name, self._ppid
if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- elif not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name, self._ppid)
- else:
- # XXX: this happens with unicode tests. It means the C
- # routine is unable to decode invalid unicode chars.
- debug("ignoring %r and returning an empty list" % err)
- return []
+ raise ZombieProcess(pid, name, ppid) from err
+ if not pid_exists(self.pid):
+ raise NoSuchProcess(pid, name, ppid) from err
+ # XXX: this happens with unicode tests. It means the C
+ # routine is unable to decode invalid unicode chars.
+ debug(f"ignoring {err!r} and returning an empty list")
+ return []
else:
raise
else:
@@ -822,11 +812,6 @@ class Process:
@wrap_exceptions
def net_connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
ret = []
@@ -945,12 +930,11 @@ class Process:
# Pre-emptively check if CPUs are valid because the C
# function has a weird behavior in case of invalid CPUs,
# see: https://github.com/giampaolo/psutil/issues/586
- allcpus = tuple(range(len(per_cpu_times())))
+ allcpus = set(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in allcpus:
- raise ValueError(
- "invalid CPU #%i (choose between %s)" % (cpu, allcpus)
- )
+ msg = f"invalid CPU {cpu!r} (choose between {allcpus})"
+ raise ValueError(msg)
try:
cext.proc_cpu_affinity_set(self.pid, cpus)
except OSError as err:
@@ -961,10 +945,11 @@ class Process:
if err.errno in {errno.EINVAL, errno.EDEADLK}:
for cpu in cpus:
if cpu not in allcpus:
- raise ValueError(
- "invalid CPU #%i (choose between %s)"
- % (cpu, allcpus)
+ msg = (
+ f"invalid CPU {cpu!r} (choose between"
+ f" {allcpus})"
)
+ raise ValueError(msg) from err
raise
@wrap_exceptions
@@ -977,9 +962,10 @@ class Process:
return cext.proc_getrlimit(self.pid, resource)
else:
if len(limits) != 2:
- raise ValueError(
- "second argument must be a (soft, hard) tuple, got %s"
- % repr(limits)
+ msg = (
+ "second argument must be a (soft, hard) tuple, got"
+ f" {limits!r}"
)
+ raise ValueError(msg)
soft, hard = limits
return cext.proc_setrlimit(self.pid, resource, soft, hard)
diff --git a/contrib/python/psutil/py3/psutil/_pslinux.py b/contrib/python/psutil/py3/psutil/_pslinux.py
index 3e7f3e402a7..8cc64e9a100 100644
--- a/contrib/python/psutil/py3/psutil/_pslinux.py
+++ b/contrib/python/psutil/py3/psutil/_pslinux.py
@@ -4,15 +4,16 @@
"""Linux platform implementation."""
-from __future__ import division
import base64
import collections
+import enum
import errno
import functools
import glob
import os
import re
+import resource
import socket
import struct
import sys
@@ -24,6 +25,7 @@ from . import _common
from . import _psposix
from . import _psutil_linux as cext
from . import _psutil_posix as cext_posix
+from ._common import ENCODING
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
@@ -44,18 +46,6 @@ from ._common import parse_environ_block
from ._common import path_exists_strict
from ._common import supports_ipv6
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import b
-from ._compat import basestring
-
-
-if PY3:
- import enum
-else:
- enum = None
# fmt: off
@@ -69,6 +59,11 @@ __extra__all__ = [
"CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT",
"CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING",
]
+
+if hasattr(resource, "prlimit"):
+ __extra__all__.extend(
+ [x for x in dir(cext) if x.startswith('RLIM') and x.isupper()]
+ )
# fmt: on
@@ -78,8 +73,8 @@ __extra__all__ = [
POWER_SUPPLY_PATH = "/sys/class/power_supply"
-HAS_PROC_SMAPS = os.path.exists('/proc/%s/smaps' % os.getpid())
-HAS_PROC_SMAPS_ROLLUP = os.path.exists('/proc/%s/smaps_rollup' % os.getpid())
+HAS_PROC_SMAPS = os.path.exists(f"/proc/{os.getpid()}/smaps")
+HAS_PROC_SMAPS_ROLLUP = os.path.exists(f"/proc/{os.getpid()}/smaps_rollup")
HAS_PROC_IO_PRIORITY = hasattr(cext, "proc_ioprio_get")
HAS_CPU_AFFINITY = hasattr(cext, "proc_cpu_affinity_get")
@@ -102,29 +97,21 @@ LITTLE_ENDIAN = sys.byteorder == 'little'
# * https://lkml.org/lkml/2015/8/17/234
DISK_SECTOR_SIZE = 512
-if enum is None:
- AF_LINK = socket.AF_PACKET
-else:
- AddressFamily = enum.IntEnum(
- 'AddressFamily', {'AF_LINK': int(socket.AF_PACKET)}
- )
- AF_LINK = AddressFamily.AF_LINK
+AddressFamily = enum.IntEnum(
+ 'AddressFamily', {'AF_LINK': int(socket.AF_PACKET)}
+)
+AF_LINK = AddressFamily.AF_LINK
+
# ioprio_* constants http://linux.die.net/man/2/ioprio_get
-if enum is None:
+class IOPriority(enum.IntEnum):
IOPRIO_CLASS_NONE = 0
IOPRIO_CLASS_RT = 1
IOPRIO_CLASS_BE = 2
IOPRIO_CLASS_IDLE = 3
-else:
- class IOPriority(enum.IntEnum):
- IOPRIO_CLASS_NONE = 0
- IOPRIO_CLASS_RT = 1
- IOPRIO_CLASS_BE = 2
- IOPRIO_CLASS_IDLE = 3
- globals().update(IOPriority.__members__)
+globals().update(IOPriority.__members__)
# See:
# https://github.com/torvalds/linux/blame/master/fs/proc/array.c
@@ -211,7 +198,7 @@ pcputimes = namedtuple('pcputimes',
def readlink(path):
"""Wrapper around os.readlink()."""
- assert isinstance(path, basestring), path
+ assert isinstance(path, str), path
path = os.readlink(path)
# readlink() might return paths containing null bytes ('\x00')
# resulting in "TypeError: must be encoded string without NULL
@@ -255,9 +242,9 @@ def is_storage_device(name):
name = name.replace('/', '!')
including_virtual = True
if including_virtual:
- path = "/sys/block/%s" % name
+ path = f"/sys/block/{name}"
else:
- path = "/sys/block/%s/device" % name
+ path = f"/sys/block/{name}/device"
return os.access(path, os.F_OK)
@@ -270,7 +257,7 @@ def set_scputimes_ntuple(procfs_path):
Used by cpu_times() function.
"""
global scputimes
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
values = f.readline().split()[1:]
fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
vlen = len(values)
@@ -290,66 +277,11 @@ try:
set_scputimes_ntuple("/proc")
except Exception as err: # noqa: BLE001
# Don't want to crash at import time.
- debug("ignoring exception on import: %r" % err)
+ debug(f"ignoring exception on import: {err!r}")
scputimes = namedtuple('scputimes', 'user system idle')(0.0, 0.0, 0.0)
# =====================================================================
-# --- prlimit
-# =====================================================================
-
-# Backport of resource.prlimit() for Python 2. Originally this was done
-# in C, but CentOS-6 which we use to create manylinux wheels is too old
-# and does not support prlimit() syscall. As such the resulting wheel
-# would not include prlimit(), even when installed on newer systems.
-# This is the only part of psutil using ctypes.
-
-prlimit = None
-try:
- from resource import prlimit # python >= 3.4
-except ImportError:
- import ctypes
-
- try:
- libc = ctypes.CDLL(None, use_errno=True)
- except:
- libc = None
-
- if hasattr(libc, "prlimit"):
-
- def prlimit(pid, resource_, limits=None):
- class StructRlimit(ctypes.Structure):
- _fields_ = [
- ('rlim_cur', ctypes.c_longlong),
- ('rlim_max', ctypes.c_longlong),
- ]
-
- current = StructRlimit()
- if limits is None:
- # get
- ret = libc.prlimit(pid, resource_, None, ctypes.byref(current))
- else:
- # set
- new = StructRlimit()
- new.rlim_cur = limits[0]
- new.rlim_max = limits[1]
- ret = libc.prlimit(
- pid, resource_, ctypes.byref(new), ctypes.byref(current)
- )
-
- if ret != 0:
- errno_ = ctypes.get_errno()
- raise OSError(errno_, os.strerror(errno_))
- return (current.rlim_cur, current.rlim_max)
-
-
-if prlimit is not None:
- __extra__all__.extend(
- [x for x in dir(cext) if x.startswith('RLIM') and x.isupper()]
- )
-
-
-# =====================================================================
# --- system memory
# =====================================================================
@@ -392,14 +324,13 @@ def calculate_avail_vmem(mems):
slab_reclaimable = mems[b'SReclaimable:']
except KeyError as err:
debug(
- "%s is missing from /proc/meminfo; using an approximation for "
- "calculating available memory"
- % err.args[0]
+ f"{err.args[0]} is missing from /proc/meminfo; using an"
+ " approximation for calculating available memory"
)
return fallback
try:
- f = open_binary('%s/zoneinfo' % get_procfs_path())
- except IOError:
+ f = open_binary(f"{get_procfs_path()}/zoneinfo")
+ except OSError:
return fallback # kernel 2.6.13
watermark_low = 0
@@ -428,7 +359,7 @@ def virtual_memory():
"""
missing_fields = []
mems = {}
- with open_binary('%s/meminfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/meminfo") as f:
for line in f:
fields = line.split()
mems[fields[0]] = int(fields[1]) * 1024
@@ -530,7 +461,7 @@ def virtual_memory():
# Warn about missing metrics which are set to 0.
if missing_fields:
- msg = "%s memory stats couldn't be determined and %s set to 0" % (
+ msg = "{} memory stats couldn't be determined and {} set to 0".format(
", ".join(missing_fields),
"was" if len(missing_fields) == 1 else "were",
)
@@ -554,7 +485,7 @@ def virtual_memory():
def swap_memory():
"""Return swap memory metrics."""
mems = {}
- with open_binary('%s/meminfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/meminfo") as f:
for line in f:
fields = line.split()
mems[fields[0]] = int(fields[1]) * 1024
@@ -574,12 +505,12 @@ def swap_memory():
percent = usage_percent(used, total, round_=1)
# get pgin/pgouts
try:
- f = open_binary("%s/vmstat" % get_procfs_path())
- except IOError as err:
+ f = open_binary(f"{get_procfs_path()}/vmstat")
+ except OSError as err:
# see https://github.com/giampaolo/psutil/issues/722
msg = (
"'sin' and 'sout' swap memory stats couldn't "
- + "be determined and were set to 0 (%s)" % str(err)
+ f"be determined and were set to 0 ({err})"
)
warnings.warn(msg, RuntimeWarning, stacklevel=2)
sin = sout = 0
@@ -620,7 +551,7 @@ def cpu_times():
"""
procfs_path = get_procfs_path()
set_scputimes_ntuple(procfs_path)
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
values = f.readline().split()
fields = values[1 : len(scputimes._fields) + 1]
fields = [float(x) / CLOCK_TICKS for x in fields]
@@ -634,7 +565,7 @@ def per_cpu_times():
procfs_path = get_procfs_path()
set_scputimes_ntuple(procfs_path)
cpus = []
- with open_binary('%s/stat' % procfs_path) as f:
+ with open_binary(f"{procfs_path}/stat") as f:
# get rid of the first line which refers to system wide CPU stats
f.readline()
for line in f:
@@ -654,7 +585,7 @@ def cpu_count_logical():
except ValueError:
# as a second fallback we try to parse /proc/cpuinfo
num = 0
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
for line in f:
if line.lower().startswith(b'processor'):
num += 1
@@ -664,7 +595,7 @@ def cpu_count_logical():
# try to parse /proc/stat as a last resort
if num == 0:
search = re.compile(r'cpu\d')
- with open_text('%s/stat' % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/stat") as f:
for line in f:
line = line.split(' ')[0]
if search.match(line):
@@ -697,7 +628,7 @@ def cpu_count_cores():
# Method #2
mapping = {}
current_info = {}
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
for line in f:
line = line.strip().lower()
if not line:
@@ -720,7 +651,7 @@ def cpu_count_cores():
def cpu_stats():
"""Return various CPU stats as a named tuple."""
- with open_binary('%s/stat' % get_procfs_path()) as f:
+ with open_binary(f"{get_procfs_path()}/stat") as f:
ctx_switches = None
interrupts = None
soft_interrupts = None
@@ -745,12 +676,12 @@ def cpu_stats():
def _cpu_get_cpuinfo_freq():
"""Return current CPU frequency from cpuinfo if available."""
- ret = []
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
- for line in f:
- if line.lower().startswith(b'cpu mhz'):
- ret.append(float(line.split(b':', 1)[1]))
- return ret
+ with open_binary(f"{get_procfs_path()}/cpuinfo") as f:
+ return [
+ float(line.split(b':', 1)[1])
+ for line in f
+ if line.lower().startswith(b'cpu mhz')
+ ]
if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or os.path.exists(
@@ -781,9 +712,7 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or os.path.exists(
# https://github.com/giampaolo/psutil/issues/1071
curr = bcat(pjoin(path, "cpuinfo_cur_freq"), fallback=None)
if curr is None:
- online_path = (
- "/sys/devices/system/cpu/cpu{}/online".format(i)
- )
+ online_path = f"/sys/devices/system/cpu/cpu{i}/online"
# if cpu core is offline, set to all zeroes
if cat(online_path, fallback=None) == "0\n":
ret.append(_common.scpufreq(0.0, 0.0, 0.0))
@@ -854,12 +783,12 @@ class NetConnections:
def get_proc_inodes(self, pid):
inodes = defaultdict(list)
- for fd in os.listdir("%s/%s/fd" % (self._procfs_path, pid)):
+ for fd in os.listdir(f"{self._procfs_path}/{pid}/fd"):
try:
- inode = readlink("%s/%s/fd/%s" % (self._procfs_path, pid, fd))
+ inode = readlink(f"{self._procfs_path}/{pid}/fd/{fd}")
except (FileNotFoundError, ProcessLookupError):
# ENOENT == file which is gone in the meantime;
- # os.stat('/proc/%s' % self.pid) will be done later
+ # os.stat(f"/proc/{self.pid}") will be done later
# to force NSP (if it's the case)
continue
except OSError as err:
@@ -917,8 +846,7 @@ class NetConnections:
# no end-points connected
if not port:
return ()
- if PY3:
- ip = ip.encode('ascii')
+ ip = ip.encode('ascii')
if family == socket.AF_INET:
# see: https://github.com/giampaolo/psutil/issues/201
if LITTLE_ENDIAN:
@@ -942,9 +870,8 @@ class NetConnections:
except ValueError:
# see: https://github.com/giampaolo/psutil/issues/623
if not supports_ipv6():
- raise _Ipv6UnsupportedError
- else:
- raise
+ raise _Ipv6UnsupportedError from None
+ raise
return _common.addr(ip, port)
@staticmethod
@@ -961,10 +888,11 @@ class NetConnections:
line.split()[:10]
)
except ValueError:
- raise RuntimeError(
- "error while parsing %s; malformed line %s %r"
- % (file, lineno, line)
+ msg = (
+ f"error while parsing {file}; malformed line"
+ f" {lineno} {line!r}"
)
+ raise RuntimeError(msg) from None
if inode in inodes:
# # We assume inet sockets are unique, so we error
# # out if there are multiple references to the
@@ -1002,11 +930,11 @@ class NetConnections:
if ' ' not in line:
# see: https://github.com/giampaolo/psutil/issues/766
continue
- raise RuntimeError(
- "error while parsing %s; malformed line %r"
- % (file, line)
+ msg = (
+ f"error while parsing {file}; malformed line {line!r}"
)
- if inode in inodes: # noqa
+ raise RuntimeError(msg) # noqa: B904
+ if inode in inodes: # noqa: SIM108
# With UNIX sockets we can have a single inode
# referencing many file descriptors.
pairs = inodes[inode]
@@ -1026,11 +954,6 @@ class NetConnections:
yield (fd, family, type_, path, raddr, status, pid)
def retrieve(self, kind, pid=None):
- if kind not in self.tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in self.tmap]))
- )
self._procfs_path = get_procfs_path()
if pid is not None:
inodes = self.get_proc_inodes(pid)
@@ -1041,7 +964,7 @@ class NetConnections:
inodes = self.get_all_inodes()
ret = set()
for proto_name, family, type_ in self.tmap[kind]:
- path = "%s/net/%s" % (self._procfs_path, proto_name)
+ path = f"{self._procfs_path}/net/{proto_name}"
if family in {socket.AF_INET, socket.AF_INET6}:
ls = self.process_inet(
path, family, type_, inodes, filter_pid=pid
@@ -1073,7 +996,7 @@ def net_io_counters():
"""Return network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
"""
- with open_text("%s/net/dev" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/net/dev") as f:
lines = f.readlines()
retdict = {}
for line in lines[2:]:
@@ -1134,8 +1057,7 @@ def net_if_stats():
# https://github.com/giampaolo/psutil/issues/1279
if err.errno != errno.ENODEV:
raise
- else:
- debug(err)
+ debug(err)
else:
output_flags = ','.join(flags)
isup = 'running' in flags
@@ -1175,7 +1097,7 @@ def disk_io_counters(perdisk=False):
# See:
# https://www.kernel.org/doc/Documentation/iostats.txt
# https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats
- with open_text("%s/diskstats" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/diskstats") as f:
lines = f.readlines()
for line in lines:
fields = line.split()
@@ -1198,7 +1120,8 @@ def disk_io_counters(perdisk=False):
reads, rbytes, writes, wbytes = map(int, fields[3:])
rtime = wtime = reads_merged = writes_merged = busy_time = 0
else:
- raise ValueError("not sure how to interpret line %r" % line)
+ msg = f"not sure how to interpret line {line!r}"
+ raise ValueError(msg)
yield (name, reads, writes, rbytes, wbytes, rtime, wtime,
reads_merged, writes_merged, busy_time)
# fmt: on
@@ -1218,16 +1141,16 @@ def disk_io_counters(perdisk=False):
wtime, reads_merged, writes_merged, busy_time)
# fmt: on
- if os.path.exists('%s/diskstats' % get_procfs_path()):
+ if os.path.exists(f"{get_procfs_path()}/diskstats"):
gen = read_procfs()
elif os.path.exists('/sys/block'):
gen = read_sysfs()
else:
- raise NotImplementedError(
- "%s/diskstats nor /sys/block filesystem are available on this "
- "system"
- % get_procfs_path()
+ msg = (
+ f"{get_procfs_path()}/diskstats nor /sys/block are available on"
+ " this system"
)
+ raise NotImplementedError(msg)
retdict = {}
for entry in gen:
@@ -1273,7 +1196,7 @@ class RootFsDeviceFinder:
self.minor = os.minor(dev)
def ask_proc_partitions(self):
- with open_text("%s/partitions" % get_procfs_path()) as f:
+ with open_text(f"{get_procfs_path()}/partitions") as f:
for line in f.readlines()[2:]:
fields = line.split()
if len(fields) < 4: # just for extra safety
@@ -1283,19 +1206,19 @@ class RootFsDeviceFinder:
name = fields[3]
if major == self.major and minor == self.minor:
if name: # just for extra safety
- return "/dev/%s" % name
+ return f"/dev/{name}"
def ask_sys_dev_block(self):
- path = "/sys/dev/block/%s:%s/uevent" % (self.major, self.minor)
+ path = f"/sys/dev/block/{self.major}:{self.minor}/uevent"
with open_text(path) as f:
for line in f:
if line.startswith("DEVNAME="):
name = line.strip().rpartition("DEVNAME=")[2]
if name: # just for extra safety
- return "/dev/%s" % name
+ return f"/dev/{name}"
def ask_sys_class_block(self):
- needle = "%s:%s" % (self.major, self.minor)
+ needle = f"{self.major}:{self.minor}"
files = glob.iglob("/sys/class/block/*/dev")
for file in files:
try:
@@ -1307,24 +1230,24 @@ class RootFsDeviceFinder:
data = f.read().strip()
if data == needle:
name = os.path.basename(os.path.dirname(file))
- return "/dev/%s" % name
+ return f"/dev/{name}"
def find(self):
path = None
if path is None:
try:
path = self.ask_proc_partitions()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
if path is None:
try:
path = self.ask_sys_dev_block()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
if path is None:
try:
path = self.ask_sys_class_block()
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
# We use exists() because the "/dev/*" part of the path is hard
# coded, so we want to be sure.
@@ -1337,7 +1260,7 @@ def disk_partitions(all=False):
fstypes = set()
procfs_path = get_procfs_path()
if not all:
- with open_text("%s/filesystems" % procfs_path) as f:
+ with open_text(f"{procfs_path}/filesystems") as f:
for line in f:
line = line.strip()
if not line.startswith("nodev"):
@@ -1352,7 +1275,7 @@ def disk_partitions(all=False):
if procfs_path == "/proc" and os.path.isfile('/etc/mtab'):
mounts_path = os.path.realpath("/etc/mtab")
else:
- mounts_path = os.path.realpath("%s/self/mounts" % procfs_path)
+ mounts_path = os.path.realpath(f"{procfs_path}/self/mounts")
retlist = []
partitions = cext.disk_partitions(mounts_path)
@@ -1395,7 +1318,7 @@ def sensors_temperatures():
# https://github.com/giampaolo/psutil/issues/971
# https://github.com/nicolargo/glances/issues/1060
basenames.extend(glob.glob('/sys/class/hwmon/hwmon*/device/temp*_*'))
- basenames = sorted(set([x.split('_')[0] for x in basenames]))
+ basenames = sorted({x.split('_')[0] for x in basenames})
# Only add the coretemp hwmon entries if they're not already in
# /sys/class/hwmon/
@@ -1404,7 +1327,7 @@ def sensors_temperatures():
basenames2 = glob.glob(
'/sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_*'
)
- repl = re.compile('/sys/devices/platform/coretemp.*/hwmon/')
+ repl = re.compile(r"/sys/devices/platform/coretemp.*/hwmon/")
for name in basenames2:
altname = repl.sub('/sys/class/hwmon/', name)
if altname not in basenames:
@@ -1416,7 +1339,7 @@ def sensors_temperatures():
current = float(bcat(path)) / 1000.0
path = os.path.join(os.path.dirname(base), 'name')
unit_name = cat(path).strip()
- except (IOError, OSError, ValueError):
+ except (OSError, ValueError):
# A lot of things can go wrong here, so let's just skip the
# whole entry. Sure thing is Linux's /sys/class/hwmon really
# is a stinky broken mess.
@@ -1455,15 +1378,15 @@ def sensors_temperatures():
current = float(bcat(path)) / 1000.0
path = os.path.join(base, 'type')
unit_name = cat(path).strip()
- except (IOError, OSError, ValueError) as err:
+ except (OSError, ValueError) as err:
debug(err)
continue
trip_paths = glob.glob(base + '/trip_point*')
- trip_points = set([
+ trip_points = {
'_'.join(os.path.basename(p).split('_')[0:3])
for p in trip_paths
- ])
+ }
critical = None
high = None
for trip_point in trip_points:
@@ -1511,11 +1434,11 @@ def sensors_fans():
# https://github.com/giampaolo/psutil/issues/971
basenames = glob.glob('/sys/class/hwmon/hwmon*/device/fan*_*')
- basenames = sorted(set([x.split('_')[0] for x in basenames]))
+ basenames = sorted({x.split("_")[0] for x in basenames})
for base in basenames:
try:
current = int(bcat(base + '_input'))
- except (IOError, OSError) as err:
+ except OSError as err:
debug(err)
continue
unit_name = cat(os.path.join(os.path.dirname(base), 'name')).strip()
@@ -1557,7 +1480,7 @@ def sensors_battery():
# Get the first available battery. Usually this is "BAT0", except
# some rare exceptions:
# https://github.com/giampaolo/psutil/issues/1238
- root = os.path.join(POWER_SUPPLY_PATH, sorted(bats)[0])
+ root = os.path.join(POWER_SUPPLY_PATH, min(bats))
# Base metrics.
energy_now = multi_bcat(root + "/energy_now", root + "/charge_now")
@@ -1634,14 +1557,15 @@ def users():
def boot_time():
"""Return the system boot time expressed in seconds since the epoch."""
global BOOT_TIME
- path = '%s/stat' % get_procfs_path()
+ path = f"{get_procfs_path()}/stat"
with open_binary(path) as f:
for line in f:
if line.startswith(b'btime'):
ret = float(line.strip().split()[1])
BOOT_TIME = ret
return ret
- raise RuntimeError("line 'btime' not found in %s" % path)
+ msg = f"line 'btime' not found in {path}"
+ raise RuntimeError(msg)
# =====================================================================
@@ -1651,7 +1575,8 @@ def boot_time():
def pids():
"""Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir(b(get_procfs_path())) if x.isdigit()]
+ path = get_procfs_path().encode(ENCODING)
+ return [int(x) for x in os.listdir(path) if x.isdigit()]
def pid_exists(pid):
@@ -1673,7 +1598,7 @@ def pid_exists(pid):
# Note: already checked that this is faster than using a
# regular expr. Also (a lot) faster than doing
# 'return pid in pids()'
- path = "%s/%s/status" % (get_procfs_path(), pid)
+ path = f"{get_procfs_path()}/{pid}/status"
with open_binary(path) as f:
for line in f:
if line.startswith(b"Tgid:"):
@@ -1681,8 +1606,9 @@ def pid_exists(pid):
# If tgid and pid are the same then we're
# dealing with a process PID.
return tgid == pid
- raise ValueError("'Tgid' line not found in %s" % path)
- except (EnvironmentError, ValueError):
+ msg = f"'Tgid' line not found in {path}"
+ raise ValueError(msg)
+ except (OSError, ValueError):
return pid in pids()
@@ -1694,7 +1620,7 @@ def ppid_map():
procfs_path = get_procfs_path()
for pid in pids():
try:
- with open_binary("%s/%s/stat" % (procfs_path, pid)) as f:
+ with open_binary(f"{procfs_path}/{pid}/stat") as f:
data = f.read()
except (FileNotFoundError, ProcessLookupError):
# Note: we should be able to access /stat for all processes
@@ -1709,28 +1635,27 @@ def ppid_map():
def wrap_exceptions(fun):
- """Decorator which translates bare OSError and IOError exceptions
+ """Decorator which translates bare OSError and OSError exceptions
into NoSuchProcess and AccessDenied.
"""
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, name = self.pid, self._name
try:
return fun(self, *args, **kwargs)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except ProcessLookupError:
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except ProcessLookupError as err:
self._raise_if_zombie()
- raise NoSuchProcess(self.pid, self._name)
- except FileNotFoundError:
+ raise NoSuchProcess(pid, name) from err
+ except FileNotFoundError as err:
self._raise_if_zombie()
# /proc/PID directory may still exist, but the files within
# it may not, indicating the process is gone, see:
# https://github.com/giampaolo/psutil/issues/2418
- if not os.path.exists(
- "%s/%s/stat" % (self._procfs_path, self.pid)
- ):
- raise NoSuchProcess(self.pid, self._name)
+ if not os.path.exists(f"{self._procfs_path}/{pid}/stat"):
+ raise NoSuchProcess(pid, name) from err
raise
return wrapper
@@ -1755,8 +1680,8 @@ class Process:
# it's empty. Instead of returning a "null" value we'll raise an
# exception.
try:
- data = bcat("%s/%s/stat" % (self._procfs_path, self.pid))
- except (IOError, OSError):
+ data = bcat(f"{self._procfs_path}/{self.pid}/stat")
+ except OSError:
return False
else:
rpar = data.rfind(b')')
@@ -1771,7 +1696,7 @@ class Process:
"""Raise NSP if the process disappeared on us."""
# For those C function who do not raise NSP, possibly returning
# incorrect or incomplete result.
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
@wrap_exceptions
@memoize_when_activated
@@ -1784,7 +1709,7 @@ class Process:
The return value is cached in case oneshot() ctx manager is
in use.
"""
- data = bcat("%s/%s/stat" % (self._procfs_path, self.pid))
+ data = bcat(f"{self._procfs_path}/{self.pid}/stat")
# Process name is between parentheses. It can contain spaces and
# other parentheses. This is taken into account by looking for
# the first occurrence of "(" and the last occurrence of ")".
@@ -1819,13 +1744,13 @@ class Process:
The return value is cached in case oneshot() ctx manager is
in use.
"""
- with open_binary("%s/%s/status" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/status") as f:
return f.read()
@wrap_exceptions
@memoize_when_activated
def _read_smaps_file(self):
- with open_binary("%s/%s/smaps" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/smaps") as f:
return f.read().strip()
def oneshot_enter(self):
@@ -1840,28 +1765,25 @@ class Process:
@wrap_exceptions
def name(self):
- name = self._parse_stat_file()['name']
- if PY3:
- name = decode(name)
# XXX - gets changed later and probably needs refactoring
- return name
+ return decode(self._parse_stat_file()['name'])
@wrap_exceptions
def exe(self):
try:
- return readlink("%s/%s/exe" % (self._procfs_path, self.pid))
+ return readlink(f"{self._procfs_path}/{self.pid}/exe")
except (FileNotFoundError, ProcessLookupError):
self._raise_if_zombie()
# no such file error; might be raised also if the
# path actually exists for system processes with
# low pids (about 0-20)
- if os.path.lexists("%s/%s" % (self._procfs_path, self.pid)):
+ if os.path.lexists(f"{self._procfs_path}/{self.pid}"):
return ""
raise
@wrap_exceptions
def cmdline(self):
- with open_text("%s/%s/cmdline" % (self._procfs_path, self.pid)) as f:
+ with open_text(f"{self._procfs_path}/{self.pid}/cmdline") as f:
data = f.read()
if not data:
# may happen in case of zombie process
@@ -1887,7 +1809,7 @@ class Process:
@wrap_exceptions
def environ(self):
- with open_text("%s/%s/environ" % (self._procfs_path, self.pid)) as f:
+ with open_text(f"{self._procfs_path}/{self.pid}/environ") as f:
data = f.read()
return parse_environ_block(data)
@@ -1901,11 +1823,11 @@ class Process:
return None
# May not be available on old kernels.
- if os.path.exists('/proc/%s/io' % os.getpid()):
+ if os.path.exists(f"/proc/{os.getpid()}/io"):
@wrap_exceptions
def io_counters(self):
- fname = "%s/%s/io" % (self._procfs_path, self.pid)
+ fname = f"{self._procfs_path}/{self.pid}/io"
fields = {}
with open_binary(fname) as f:
for line in f:
@@ -1920,7 +1842,8 @@ class Process:
else:
fields[name] = int(value)
if not fields:
- raise RuntimeError("%s file was empty" % fname)
+ msg = f"{fname} file was empty"
+ raise RuntimeError(msg)
try:
return pio(
fields[b'syscr'], # read syscalls
@@ -1931,10 +1854,11 @@ class Process:
fields[b'wchar'], # write chars
)
except KeyError as err:
- raise ValueError(
- "%r field was not found in %s; found fields are %r"
- % (err.args[0], fname, fields)
+ msg = (
+ f"{err.args[0]!r} field was not found in {fname}; found"
+ f" fields are {fields!r}"
)
+ raise ValueError(msg) from None
@wrap_exceptions
def cpu_times(self):
@@ -1979,7 +1903,7 @@ class Process:
# | data | data + stack | drs | DATA |
# | dirty | dirty pages (unused in Linux 2.6) | dt | |
# ============================================================
- with open_binary("%s/%s/statm" % (self._procfs_path, self.pid)) as f:
+ with open_binary(f"{self._procfs_path}/{self.pid}/statm") as f:
vms, rss, shared, text, lib, data, dirty = (
int(x) * PAGESIZE for x in f.readline().split()[:7]
)
@@ -1998,7 +1922,7 @@ class Process:
# compared to /proc/pid/smaps_rollup.
uss = pss = swap = 0
with open_binary(
- "{}/{}/smaps_rollup".format(self._procfs_path, self.pid)
+ f"{self._procfs_path}/{self.pid}/smaps_rollup"
) as f:
for line in f:
if line.startswith(b"Private_"):
@@ -2023,8 +1947,6 @@ class Process:
# Note: using 3 regexes is faster than reading the file
# line by line.
- # XXX: on Python 3 the 2 regexes are 30% slower than on
- # Python 2 though. Figure out why.
#
# You might be tempted to calculate USS by subtracting
# the "shared" value from the "resident" value in
@@ -2062,7 +1984,7 @@ class Process:
def memory_maps(self):
"""Return process's mapped memory regions as a list of named
tuples. Fields are explained in 'man proc'; here is an updated
- (Apr 2012) version: http://goo.gl/fmebo.
+ (Apr 2012) version: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt?id=b76437579d1344b612cf1851ae610c636cec7db0.
/proc/{PID}/smaps does not exist on kernels < 2.6.14 or if
CONFIG_MMU kernel configuration option is not enabled.
@@ -2083,11 +2005,8 @@ class Process:
if fields[0].startswith(b'VmFlags:'):
# see issue #369
continue
- else:
- raise ValueError(
- "don't know how to interpret line %r"
- % line
- )
+ msg = f"don't know how to interpret line {line!r}"
+ raise ValueError(msg) from None
yield (current_block.pop(), data)
data = self._read_smaps_file()
@@ -2109,8 +2028,7 @@ class Process:
if not path:
path = '[anon]'
else:
- if PY3:
- path = decode(path)
+ path = decode(path)
path = path.strip()
if path.endswith(' (deleted)') and not path_exists_strict(
path
@@ -2136,7 +2054,7 @@ class Process:
@wrap_exceptions
def cwd(self):
- return readlink("%s/%s/cwd" % (self._procfs_path, self.pid))
+ return readlink(f"{self._procfs_path}/{self.pid}/cwd")
@wrap_exceptions
def num_ctx_switches(
@@ -2145,34 +2063,29 @@ class Process:
data = self._read_status_file()
ctxsw = _ctxsw_re.findall(data)
if not ctxsw:
- raise NotImplementedError(
- "'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'"
- "lines were not found in %s/%s/status; the kernel is "
- "probably older than 2.6.23" % (self._procfs_path, self.pid)
+ msg = (
+ "'voluntary_ctxt_switches' and"
+ " 'nonvoluntary_ctxt_switches'lines were not found in"
+ f" {self._procfs_path}/{self.pid}/status; the kernel is"
+ " probably older than 2.6.23"
)
- else:
- return _common.pctxsw(int(ctxsw[0]), int(ctxsw[1]))
+ raise NotImplementedError(msg)
+ return _common.pctxsw(int(ctxsw[0]), int(ctxsw[1]))
@wrap_exceptions
def num_threads(self, _num_threads_re=re.compile(br'Threads:\t(\d+)')):
- # Note: on Python 3 using a re is faster than iterating over file
- # line by line. On Python 2 is the exact opposite, and iterating
- # over a file on Python 3 is slower than on Python 2.
+ # Using a re is faster than iterating over file line by line.
data = self._read_status_file()
return int(_num_threads_re.findall(data)[0])
@wrap_exceptions
def threads(self):
- thread_ids = os.listdir("%s/%s/task" % (self._procfs_path, self.pid))
+ thread_ids = os.listdir(f"{self._procfs_path}/{self.pid}/task")
thread_ids.sort()
retlist = []
hit_enoent = False
for thread_id in thread_ids:
- fname = "%s/%s/task/%s/stat" % (
- self._procfs_path,
- self.pid,
- thread_id,
- )
+ fname = f"{self._procfs_path}/{self.pid}/task/{thread_id}/stat"
try:
with open_binary(fname) as f:
st = f.read().strip()
@@ -2194,7 +2107,7 @@ class Process:
@wrap_exceptions
def nice_get(self):
- # with open_text('%s/%s/stat' % (self._procfs_path, self.pid)) as f:
+ # with open_text(f"{self._procfs_path}/{self.pid}/stat") as f:
# data = f.read()
# return int(data.split()[18])
@@ -2233,15 +2146,17 @@ class Process:
all_cpus = tuple(range(len(per_cpu_times())))
for cpu in cpus:
if cpu not in all_cpus:
- raise ValueError(
- "invalid CPU number %r; choose between %s"
- % (cpu, eligible_cpus)
+ msg = (
+ f"invalid CPU {cpu!r}; choose between"
+ f" {eligible_cpus!r}"
)
+ raise ValueError(msg) from None
if cpu not in eligible_cpus:
- raise ValueError(
- "CPU number %r is not eligible; choose "
- "between %s" % (cpu, eligible_cpus)
+ msg = (
+ f"CPU number {cpu} is not eligible; choose"
+ f" between {eligible_cpus}"
)
+ raise ValueError(msg) from err
raise
# only starting from kernel 2.6.13
@@ -2250,22 +2165,25 @@ class Process:
@wrap_exceptions
def ionice_get(self):
ioclass, value = cext.proc_ioprio_get(self.pid)
- if enum is not None:
- ioclass = IOPriority(ioclass)
+ ioclass = IOPriority(ioclass)
return _common.pionice(ioclass, value)
@wrap_exceptions
def ionice_set(self, ioclass, value):
if value is None:
value = 0
- if value and ioclass in {IOPRIO_CLASS_IDLE, IOPRIO_CLASS_NONE}:
- raise ValueError("%r ioclass accepts no value" % ioclass)
+ if value and ioclass in {
+ IOPriority.IOPRIO_CLASS_IDLE,
+ IOPriority.IOPRIO_CLASS_NONE,
+ }:
+ msg = f"{ioclass!r} ioclass accepts no value"
+ raise ValueError(msg)
if value < 0 or value > 7:
msg = "value not in 0-7 range"
raise ValueError(msg)
return cext.proc_ioprio_set(self.pid, ioclass, value)
- if prlimit is not None:
+ if hasattr(resource, "prlimit"):
@wrap_exceptions
def rlimit(self, resource_, limits=None):
@@ -2278,16 +2196,16 @@ class Process:
try:
if limits is None:
# get
- return prlimit(self.pid, resource_)
+ return resource.prlimit(self.pid, resource_)
else:
# set
if len(limits) != 2:
msg = (
"second argument must be a (soft, hard) "
- + "tuple, got %s" % repr(limits)
+ f"tuple, got {limits!r}"
)
raise ValueError(msg)
- prlimit(self.pid, resource_, limits)
+ resource.prlimit(self.pid, resource_, limits)
except OSError as err:
if err.errno == errno.ENOSYS:
# I saw this happening on Travis:
@@ -2298,18 +2216,17 @@ class Process:
@wrap_exceptions
def status(self):
letter = self._parse_stat_file()['status']
- if PY3:
- letter = letter.decode()
+ letter = letter.decode()
# XXX is '?' legit? (we're not supposed to return it anyway)
return PROC_STATUSES.get(letter, '?')
@wrap_exceptions
def open_files(self):
retlist = []
- files = os.listdir("%s/%s/fd" % (self._procfs_path, self.pid))
+ files = os.listdir(f"{self._procfs_path}/{self.pid}/fd")
hit_enoent = False
for fd in files:
- file = "%s/%s/fd/%s" % (self._procfs_path, self.pid, fd)
+ file = f"{self._procfs_path}/{self.pid}/fd/{fd}"
try:
path = readlink(file)
except (FileNotFoundError, ProcessLookupError):
@@ -2332,11 +2249,7 @@ class Process:
# absolute path though.
if path.startswith('/') and isfile_strict(path):
# Get file position and flags.
- file = "%s/%s/fdinfo/%s" % (
- self._procfs_path,
- self.pid,
- fd,
- )
+ file = f"{self._procfs_path}/{self.pid}/fdinfo/{fd}"
try:
with open_binary(file) as f:
pos = int(f.readline().split()[1])
@@ -2363,7 +2276,7 @@ class Process:
@wrap_exceptions
def num_fds(self):
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def ppid(self):
diff --git a/contrib/python/psutil/py3/psutil/_psosx.py b/contrib/python/psutil/py3/psutil/_psosx.py
index ed9b319de7f..620497b30a0 100644
--- a/contrib/python/psutil/py3/psutil/_psosx.py
+++ b/contrib/python/psutil/py3/psutil/_psosx.py
@@ -22,8 +22,6 @@ from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import usage_percent
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
__extra__all__ = []
@@ -114,8 +112,7 @@ def virtual_memory():
"""System virtual memory as a namedtuple."""
total, active, inactive, wired, free, speculative = cext.virtual_mem()
# This is how Zabbix calculate avail and used mem:
- # https://github.com/zabbix/zabbix/blob/trunk/src/libs/zbxsysinfo/
- # osx/memory.c
+ # https://github.com/zabbix/zabbix/blob/master/src/libs/zbxsysinfo/osx/memory.c
# Also see: https://github.com/giampaolo/psutil/issues/1277
avail = inactive + free
used = active + wired
@@ -345,15 +342,15 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except ProcessLookupError:
- if is_zombie(self.pid):
- raise ZombieProcess(self.pid, self._name, self._ppid)
- else:
- raise NoSuchProcess(self.pid, self._name)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
+ except ProcessLookupError as err:
+ if is_zombie(pid):
+ raise ZombieProcess(pid, name, ppid) from err
+ raise NoSuchProcess(pid, name) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
return wrapper
@@ -502,11 +499,6 @@ class Process:
@wrap_exceptions
def net_connections(self, kind='inet'):
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
rawlist = cext.proc_net_connections(self.pid, families, types)
ret = []
diff --git a/contrib/python/psutil/py3/psutil/_psposix.py b/contrib/python/psutil/py3/psutil/_psposix.py
index 42bdfa7ef6c..88703fdbd26 100644
--- a/contrib/python/psutil/py3/psutil/_psposix.py
+++ b/contrib/python/psutil/py3/psutil/_psposix.py
@@ -4,10 +4,10 @@
"""Routines common to all posix systems."""
+import enum
import glob
import os
import signal
-import sys
import time
from ._common import MACOS
@@ -15,25 +15,12 @@ from ._common import TimeoutExpired
from ._common import memoize
from ._common import sdiskusage
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import ChildProcessError
-from ._compat import FileNotFoundError
-from ._compat import InterruptedError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import unicode
if MACOS:
from . import _psutil_osx
-if PY3:
- import enum
-else:
- enum = None
-
-
__all__ = ['pid_exists', 'wait_pid', 'disk_usage', 'get_terminal_map']
@@ -59,23 +46,16 @@ def pid_exists(pid):
return True
-# Python 3.5 signals enum (contributed by me ^^):
-# https://bugs.python.org/issue21076
-if enum is not None and hasattr(signal, "Signals"):
- Negsignal = enum.IntEnum(
- 'Negsignal', dict([(x.name, -x.value) for x in signal.Signals])
- )
-
- def negsig_to_enum(num):
- """Convert a negative signal value to an enum."""
- try:
- return Negsignal(num)
- except ValueError:
- return num
+Negsignal = enum.IntEnum(
+ 'Negsignal', {x.name: -x.value for x in signal.Signals}
+)
-else: # pragma: no cover
- def negsig_to_enum(num):
+def negsig_to_enum(num):
+ """Convert a negative signal value to an enum."""
+ try:
+ return Negsignal(num)
+ except ValueError:
return num
@@ -139,7 +119,7 @@ def wait_pid(
# can't determine its exit status code.
while _pid_exists(pid):
interval = sleep(interval)
- return
+ return None
else:
if retpid == 0:
# WNOHANG flag was used and PID is still running.
@@ -171,7 +151,8 @@ def wait_pid(
# continue
else:
# Should never happen.
- raise ValueError("unknown process exit status %r" % status)
+ msg = f"unknown process exit status {status!r}"
+ raise ValueError(msg)
def disk_usage(path):
@@ -181,24 +162,7 @@ def disk_usage(path):
total and used disk space whereas "free" and "percent" represent
the "free" and "used percent" user disk space.
"""
- if PY3:
- st = os.statvfs(path)
- else: # pragma: no cover
- # os.statvfs() does not support unicode on Python 2:
- # - https://github.com/giampaolo/psutil/issues/416
- # - http://bugs.python.org/issue18695
- try:
- st = os.statvfs(path)
- except UnicodeEncodeError:
- if isinstance(path, unicode):
- try:
- path = path.encode(sys.getfilesystemencoding())
- except UnicodeEncodeError:
- pass
- st = os.statvfs(path)
- else:
- raise
-
+ st = os.statvfs(path)
# Total space which is only available to root (unless changed
# at system level).
total = st.f_blocks * st.f_frsize
diff --git a/contrib/python/psutil/py3/psutil/_pssunos.py b/contrib/python/psutil/py3/psutil/_pssunos.py
index a38d939d793..78d941cc5ff 100644
--- a/contrib/python/psutil/py3/psutil/_pssunos.py
+++ b/contrib/python/psutil/py3/psutil/_pssunos.py
@@ -18,6 +18,7 @@ from . import _psposix
from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext
from ._common import AF_INET6
+from ._common import ENCODING
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
@@ -28,11 +29,6 @@ from ._common import memoize_when_activated
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import FileNotFoundError
-from ._compat import PermissionError
-from ._compat import ProcessLookupError
-from ._compat import b
__extra__all__ = ["CONN_IDLE", "CONN_BOUND", "PROCFS_PATH"]
@@ -147,17 +143,17 @@ def swap_memory():
p = subprocess.Popen(
[
'/usr/bin/env',
- 'PATH=/usr/sbin:/sbin:%s' % os.environ['PATH'],
+ f"PATH=/usr/sbin:/sbin:{os.environ['PATH']}",
'swap',
'-l',
],
stdout=subprocess.PIPE,
)
stdout, _ = p.communicate()
- if PY3:
- stdout = stdout.decode(sys.stdout.encoding)
+ stdout = stdout.decode(sys.stdout.encoding)
if p.returncode != 0:
- raise RuntimeError("'swap -l' failed (retcode=%s)" % p.returncode)
+ msg = f"'swap -l' failed (retcode={p.returncode})"
+ raise RuntimeError(msg)
lines = stdout.strip().split('\n')[1:]
if not lines:
@@ -244,7 +240,7 @@ def disk_partitions(all=False):
continue
except OSError as err:
# https://github.com/giampaolo/psutil/issues/1674
- debug("skipping %r: %s" % (mountpoint, err))
+ debug(f"skipping {mountpoint!r}: {err}")
continue
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts)
retlist.append(ntuple)
@@ -265,14 +261,6 @@ def net_connections(kind, _pid=-1):
connections (as opposed to connections opened by one process only).
Only INET sockets are returned (UNIX are not).
"""
- cmap = _common.conn_tmap.copy()
- if _pid == -1:
- cmap.pop('unix', 0)
- if kind not in cmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in cmap]))
- )
families, types = _common.conn_tmap[kind]
rawlist = cext.net_connections(_pid)
ret = set()
@@ -346,7 +334,8 @@ def users():
def pids():
"""Returns a list of PIDs currently running on the system."""
- return [int(x) for x in os.listdir(b(get_procfs_path())) if x.isdigit()]
+ path = get_procfs_path().encode(ENCODING)
+ return [int(x) for x in os.listdir(path) if x.isdigit()]
def pid_exists(pid):
@@ -361,24 +350,23 @@ def wrap_exceptions(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
+ pid, ppid, name = self.pid, self._ppid, self._name
try:
return fun(self, *args, **kwargs)
- except (FileNotFoundError, ProcessLookupError):
+ except (FileNotFoundError, ProcessLookupError) as err:
# ENOENT (no such file or directory) gets raised on open().
# ESRCH (no such process) can get raised on read() if
# process is gone in meantime.
- if not pid_exists(self.pid):
- raise NoSuchProcess(self.pid, self._name)
- else:
- raise ZombieProcess(self.pid, self._name, self._ppid)
- except PermissionError:
- raise AccessDenied(self.pid, self._name)
- except OSError:
- if self.pid == 0:
+ if not pid_exists(pid):
+ raise NoSuchProcess(pid, name) from err
+ raise ZombieProcess(pid, name, ppid) from err
+ except PermissionError as err:
+ raise AccessDenied(pid, name) from err
+ except OSError as err:
+ if pid == 0:
if 0 in pids():
- raise AccessDenied(self.pid, self._name)
- else:
- raise
+ raise AccessDenied(pid, name) from err
+ raise
raise
return wrapper
@@ -399,7 +387,7 @@ class Process:
"""Raise NSP if the process disappeared on us."""
# For those C function who do not raise NSP, possibly returning
# incorrect or incomplete result.
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
def oneshot_enter(self):
self._proc_name_and_args.cache_activate(self)
@@ -420,7 +408,7 @@ class Process:
@memoize_when_activated
def _proc_basic_info(self):
if self.pid == 0 and not os.path.exists(
- '%s/%s/psinfo' % (self._procfs_path, self.pid)
+ f"{self._procfs_path}/{self.pid}/psinfo"
):
raise AccessDenied(self.pid)
ret = cext.proc_basic_info(self.pid, self._procfs_path)
@@ -440,9 +428,7 @@ class Process:
@wrap_exceptions
def exe(self):
try:
- return os.readlink(
- "%s/%s/path/a.out" % (self._procfs_path, self.pid)
- )
+ return os.readlink(f"{self._procfs_path}/{self.pid}/path/a.out")
except OSError:
pass # continue and guess the exe name from the cmdline
# Will be guessed later from cmdline but we want to explicitly
@@ -539,9 +525,7 @@ class Process:
if tty != cext.PRNODEV:
for x in (0, 1, 2, 255):
try:
- return os.readlink(
- '%s/%d/path/%d' % (procfs_path, self.pid, x)
- )
+ return os.readlink(f"{procfs_path}/{self.pid}/path/{x}")
except FileNotFoundError:
hit_enoent = True
continue
@@ -553,12 +537,12 @@ class Process:
# /proc/PID/path/cwd may not be resolved by readlink() even if
# it exists (ls shows it). If that's the case and the process
# is still alive return None (we can return None also on BSD).
- # Reference: http://goo.gl/55XgO
+ # Reference: https://groups.google.com/g/comp.unix.solaris/c/tcqvhTNFCAs
procfs_path = self._procfs_path
try:
- return os.readlink("%s/%s/path/cwd" % (procfs_path, self.pid))
+ return os.readlink(f"{procfs_path}/{self.pid}/path/cwd")
except FileNotFoundError:
- os.stat("%s/%s" % (procfs_path, self.pid)) # raise NSP or AD
+ os.stat(f"{procfs_path}/{self.pid}") # raise NSP or AD
return ""
@wrap_exceptions
@@ -580,7 +564,7 @@ class Process:
def threads(self):
procfs_path = self._procfs_path
ret = []
- tids = os.listdir('%s/%d/lwp' % (procfs_path, self.pid))
+ tids = os.listdir(f"{procfs_path}/{self.pid}/lwp")
hit_enoent = False
for tid in tids:
tid = int(tid)
@@ -588,7 +572,7 @@ class Process:
utime, stime = cext.query_process_thread(
self.pid, tid, procfs_path
)
- except EnvironmentError as err:
+ except OSError as err:
if err.errno == errno.EOVERFLOW and not IS_64_BIT:
# We may get here if we attempt to query a 64bit process
# with a 32bit python.
@@ -615,8 +599,8 @@ class Process:
retlist = []
hit_enoent = False
procfs_path = self._procfs_path
- pathdir = '%s/%d/path' % (procfs_path, self.pid)
- for fd in os.listdir('%s/%d/fd' % (procfs_path, self.pid)):
+ pathdir = f"{procfs_path}/{self.pid}/path"
+ for fd in os.listdir(f"{procfs_path}/{self.pid}/fd"):
path = os.path.join(pathdir, fd)
if os.path.islink(path):
try:
@@ -640,16 +624,16 @@ class Process:
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
stdout, stderr = p.communicate()
- if PY3:
- stdout, stderr = (
- x.decode(sys.stdout.encoding) for x in (stdout, stderr)
- )
+ stdout, stderr = (
+ x.decode(sys.stdout.encoding) for x in (stdout, stderr)
+ )
if p.returncode != 0:
if 'permission denied' in stderr.lower():
raise AccessDenied(self.pid, self._name)
if 'no such process' in stderr.lower():
raise NoSuchProcess(self.pid, self._name)
- raise RuntimeError("%r command error\n%s" % (cmd, stderr))
+ msg = f"{cmd!r} command error\n{stderr}"
+ raise RuntimeError(msg)
lines = stdout.split('\n')[2:]
for i, line in enumerate(lines):
@@ -675,7 +659,7 @@ class Process:
# is no longer there.
if not ret:
# will raise NSP if process is gone
- os.stat('%s/%s' % (self._procfs_path, self.pid))
+ os.stat(f"{self._procfs_path}/{self.pid}")
# UNIX sockets
if kind in {'all', 'unix'}:
@@ -691,9 +675,8 @@ class Process:
@wrap_exceptions
def memory_maps(self):
def toaddr(start, end):
- return '%s-%s' % (
- hex(start)[2:].strip('L'),
- hex(end)[2:].strip('L'),
+ return "{}-{}".format(
+ hex(start)[2:].strip('L'), hex(end)[2:].strip('L')
)
procfs_path = self._procfs_path
@@ -718,9 +701,7 @@ class Process:
addr = toaddr(addr, addrsize)
if not name.startswith('['):
try:
- name = os.readlink(
- '%s/%s/path/%s' % (procfs_path, self.pid, name)
- )
+ name = os.readlink(f"{procfs_path}/{self.pid}/path/{name}")
except OSError as err:
if err.errno == errno.ENOENT:
# sometimes the link may not be resolved by
@@ -729,7 +710,7 @@ class Process:
# unresolved link path.
# This seems an inconsistency with /proc similar
# to: http://goo.gl/55XgO
- name = '%s/%s/path/%s' % (procfs_path, self.pid, name)
+ name = f"{procfs_path}/{self.pid}/path/{name}"
hit_enoent = True
else:
raise
@@ -740,7 +721,7 @@ class Process:
@wrap_exceptions
def num_fds(self):
- return len(os.listdir("%s/%s/fd" % (self._procfs_path, self.pid)))
+ return len(os.listdir(f"{self._procfs_path}/{self.pid}/fd"))
@wrap_exceptions
def num_ctx_switches(self):
diff --git a/contrib/python/psutil/py3/psutil/_psutil_common.c b/contrib/python/psutil/py3/psutil/_psutil_common.c
index 941f6bff1b9..2a56ae0f4aa 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_common.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_common.c
@@ -69,15 +69,6 @@ PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type,
return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
}
#endif // !defined(PyErr_SetExcFromWindowsErrWithFilenameObject)
-
-
-// PyPy 2.7
-#if !defined(PyErr_SetFromWindowsErr)
-PyObject *
-PyErr_SetFromWindowsErr(int winerr) {
- return PyErr_SetFromWindowsErrWithFilename(winerr, "");
-}
-#endif // !defined(PyErr_SetFromWindowsErr)
#endif // defined(PSUTIL_WINDOWS) && defined(PYPY_VERSION)
diff --git a/contrib/python/psutil/py3/psutil/_psutil_common.h b/contrib/python/psutil/py3/psutil/_psutil_common.h
index 2cdfa9d4d67..024452630f3 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_common.h
+++ b/contrib/python/psutil/py3/psutil/_psutil_common.h
@@ -23,14 +23,6 @@ static const int PSUTIL_CONN_NONE = 128;
// --- Backward compatibility with missing Python.h APIs
// ====================================================================
-#if PY_MAJOR_VERSION < 3
- // On Python 2 we just return a plain byte string, which is never
- // supposed to raise decoding errors, see:
- // https://github.com/giampaolo/psutil/issues/1040
- #define PyUnicode_DecodeFSDefault PyString_FromString
- #define PyUnicode_DecodeFSDefaultAndSize PyString_FromStringAndSize
-#endif
-
#if defined(PSUTIL_WINDOWS) && defined(PYPY_VERSION)
#if !defined(PyErr_SetFromWindowsErrWithFilename)
PyObject *PyErr_SetFromWindowsErrWithFilename(int ierr,
@@ -45,7 +37,6 @@ static const int PSUTIL_CONN_NONE = 128;
// --- _Py_PARSE_PID
// SIZEOF_INT|LONG is missing on Linux + PyPy (only?).
-// SIZEOF_PID_T is missing on Windows + Python2.
// In this case we guess it from setup.py. It's not 100% bullet proof,
// If wrong we'll probably get compiler warnings.
// FWIW on all UNIX platforms I've seen pid_t is defined as an int.
@@ -60,8 +51,8 @@ static const int PSUTIL_CONN_NONE = 128;
#define SIZEOF_PID_T PSUTIL_SIZEOF_PID_T // set as a macro in setup.py
#endif
-// _Py_PARSE_PID is Python 3 only, but since it's private make sure it's
-// always present.
+// _Py_PARSE_PID was added in Python 3, but since it's private we make
+// sure it's always present.
#ifndef _Py_PARSE_PID
#if SIZEOF_PID_T == SIZEOF_INT
#define _Py_PARSE_PID "i"
@@ -75,14 +66,10 @@ static const int PSUTIL_CONN_NONE = 128;
#endif
#endif
-// Python 2 or PyPy on Windows
+// PyPy on Windows
#ifndef PyLong_FromPid
#if ((SIZEOF_PID_T == SIZEOF_INT) || (SIZEOF_PID_T == SIZEOF_LONG))
- #if PY_MAJOR_VERSION >= 3
- #define PyLong_FromPid PyLong_FromLong
- #else
- #define PyLong_FromPid PyInt_FromLong
- #endif
+ #define PyLong_FromPid PyLong_FromLong
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
#define PyLong_FromPid PyLong_FromLongLong
#else
diff --git a/contrib/python/psutil/py3/psutil/_psutil_linux.c b/contrib/python/psutil/py3/psutil/_psutil_linux.c
index 46244c57920..fcd886bfb61 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_linux.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_linux.c
@@ -19,6 +19,13 @@
#include "arch/linux/proc.h"
#include "arch/linux/users.h"
+// May happen on old RedHat versions, see:
+// https://github.com/giampaolo/psutil/issues/607
+#ifndef DUPLEX_UNKNOWN
+ #define DUPLEX_UNKNOWN 0xff
+#endif
+
+#define INITERR return NULL
static PyMethodDef mod_methods[] = {
// --- per-process functions
@@ -41,40 +48,24 @@ static PyMethodDef mod_methods[] = {
{"set_debug", psutil_set_debug, METH_VARARGS},
{NULL, NULL, 0, NULL}
};
-// May happen on old RedHat versions, see:
-// https://github.com/giampaolo/psutil/issues/607
-#ifndef DUPLEX_UNKNOWN
- #define DUPLEX_UNKNOWN 0xff
-#endif
-
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_linux",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_linux",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
- PyObject *PyInit__psutil_linux(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
- void init_psutil_linux(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+PyObject *
+PyInit__psutil_linux(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_linux", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -91,7 +82,5 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_psutil_osx.c b/contrib/python/psutil/py3/psutil/_psutil_osx.c
index 09fa267a983..b16103379be 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_osx.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_osx.c
@@ -7,6 +7,7 @@
*/
#include <Python.h>
+#include <sys/time.h> // needed for old macOS versions
#include <sys/proc.h>
#include <netinet/tcp_fsm.h>
@@ -20,6 +21,8 @@
#include "arch/osx/sys.h"
+#define INITERR return NULL
+
static PyMethodDef mod_methods[] = {
// --- per-process functions
{"proc_cmdline", psutil_proc_cmdline, METH_VARARGS},
@@ -61,33 +64,22 @@ static PyMethodDef mod_methods[] = {
};
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
-
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_osx",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- PyObject *PyInit__psutil_osx(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
-
- void init_psutil_osx(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_osx",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+PyObject *
+PyInit__psutil_osx(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_osx", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -140,7 +132,5 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_psutil_posix.c b/contrib/python/psutil/py3/psutil/_psutil_posix.c
index 7e6eaac46c0..de10f7854a8 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_posix.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_posix.c
@@ -52,6 +52,9 @@
#include "_psutil_common.h"
+#define INITERR return NULL
+
+
// ====================================================================
// --- Utils
// ====================================================================
@@ -434,11 +437,7 @@ append_flag(PyObject *py_retlist, const char * flag_name)
{
PyObject *py_str = NULL;
-#if PY_MAJOR_VERSION >= 3
py_str = PyUnicode_FromString(flag_name);
-#else
- py_str = PyString_FromString(flag_name);
-#endif
if (! py_str)
return 0;
if (PyList_Append(py_retlist, py_str)) {
@@ -883,33 +882,21 @@ static PyMethodDef mod_methods[] = {
};
-#if PY_MAJOR_VERSION >= 3
- #define INITERR return NULL
-
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_psutil_posix",
- NULL,
- -1,
- mod_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- PyObject *PyInit__psutil_posix(void)
-#else /* PY_MAJOR_VERSION */
- #define INITERR return
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_psutil_posix",
+ NULL,
+ -1,
+ mod_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
- void init_psutil_posix(void)
-#endif /* PY_MAJOR_VERSION */
-{
-#if PY_MAJOR_VERSION >= 3
+PyObject *
+PyInit__psutil_posix(void) {
PyObject *mod = PyModule_Create(&moduledef);
-#else
- PyObject *mod = Py_InitModule("_psutil_posix", mod_methods);
-#endif
if (mod == NULL)
INITERR;
@@ -1022,9 +1009,7 @@ static PyMethodDef mod_methods[] = {
if (mod == NULL)
INITERR;
-#if PY_MAJOR_VERSION >= 3
return mod;
-#endif
}
#ifdef __cplusplus
diff --git a/contrib/python/psutil/py3/psutil/_psutil_windows.c b/contrib/python/psutil/py3/psutil/_psutil_windows.c
index 0c221bdc236..0af18f3e263 100644
--- a/contrib/python/psutil/py3/psutil/_psutil_windows.c
+++ b/contrib/python/psutil/py3/psutil/_psutil_windows.c
@@ -34,6 +34,10 @@
#include "arch/windows/wmi.h"
+#define INITERROR return NULL
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+
+
// ------------------------ Python init ---------------------------
static PyMethodDef
@@ -116,21 +120,15 @@ struct module_state {
PyObject *error;
};
-#if PY_MAJOR_VERSION >= 3
-#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
-#else
-#define GETSTATE(m) (&_state)
-static struct module_state _state;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-static int psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
+static int
+psutil_windows_traverse(PyObject *m, visitproc visit, void *arg) {
Py_VISIT(GETSTATE(m)->error);
return 0;
}
-static int psutil_windows_clear(PyObject *m) {
+static int
+psutil_windows_clear(PyObject *m) {
Py_CLEAR(GETSTATE(m)->error);
return 0;
}
@@ -147,21 +145,12 @@ static struct PyModuleDef moduledef = {
NULL
};
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__psutil_windows(void)
-#else
-#define INITERROR return
-void init_psutil_windows(void)
-#endif
-{
+PyMODINIT_FUNC
+PyInit__psutil_windows(void) {
struct module_state *st = NULL;
-#if PY_MAJOR_VERSION >= 3
+
PyObject *module = PyModule_Create(&moduledef);
-#else
- PyObject *module = Py_InitModule("_psutil_windows", PsutilMethods);
-#endif
if (module == NULL)
INITERROR;
@@ -283,7 +272,5 @@ void init_psutil_windows(void)
PyModule_AddIntConstant(
module, "WINDOWS_10", PSUTIL_WINDOWS_10);
-#if PY_MAJOR_VERSION >= 3
return module;
-#endif
}
diff --git a/contrib/python/psutil/py3/psutil/_pswindows.py b/contrib/python/psutil/py3/psutil/_pswindows.py
index e39ba711fab..e5af3c90f43 100644
--- a/contrib/python/psutil/py3/psutil/_pswindows.py
+++ b/contrib/python/psutil/py3/psutil/_pswindows.py
@@ -5,7 +5,7 @@
"""Windows platform implementation."""
import contextlib
-import errno
+import enum
import functools
import os
import signal
@@ -15,7 +15,6 @@ from collections import namedtuple
from . import _common
from ._common import ENCODING
-from ._common import ENCODING_ERRS
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import TimeoutExpired
@@ -27,11 +26,6 @@ from ._common import memoize
from ._common import memoize_when_activated
from ._common import parse_environ_block
from ._common import usage_percent
-from ._compat import PY3
-from ._compat import long
-from ._compat import lru_cache
-from ._compat import range
-from ._compat import unicode
from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS
from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS
from ._psutil_windows import HIGH_PRIORITY_CLASS
@@ -54,14 +48,10 @@ except ImportError as err:
msg = "this Windows version is too old (< Windows Vista); "
msg += "psutil 3.4.2 is the latest version which supports Windows "
msg += "2000, XP and 2003 server"
- raise RuntimeError(msg)
+ raise RuntimeError(msg) from err
else:
raise
-if PY3:
- import enum
-else:
- enum = None
# process priority constants, import from __init__.py:
# http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
@@ -88,11 +78,8 @@ CONN_DELETE_TCB = "DELETE_TCB"
ERROR_PARTIAL_COPY = 299
PYPY = '__pypy__' in sys.builtin_module_names
-if enum is None:
- AF_LINK = -1
-else:
- AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
- AF_LINK = AddressFamily.AF_LINK
+AddressFamily = enum.IntEnum('AddressFamily', {'AF_LINK': -1})
+AF_LINK = AddressFamily.AF_LINK
TCP_STATUSES = {
cext.MIB_TCP_STATE_ESTAB: _common.CONN_ESTABLISHED,
@@ -110,32 +97,27 @@ TCP_STATUSES = {
cext.PSUTIL_CONN_NONE: _common.CONN_NONE,
}
-if enum is not None:
- class Priority(enum.IntEnum):
- ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
- BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
- HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
- IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
- NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
- REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
+class Priority(enum.IntEnum):
+ ABOVE_NORMAL_PRIORITY_CLASS = ABOVE_NORMAL_PRIORITY_CLASS
+ BELOW_NORMAL_PRIORITY_CLASS = BELOW_NORMAL_PRIORITY_CLASS
+ HIGH_PRIORITY_CLASS = HIGH_PRIORITY_CLASS
+ IDLE_PRIORITY_CLASS = IDLE_PRIORITY_CLASS
+ NORMAL_PRIORITY_CLASS = NORMAL_PRIORITY_CLASS
+ REALTIME_PRIORITY_CLASS = REALTIME_PRIORITY_CLASS
- globals().update(Priority.__members__)
-if enum is None:
+globals().update(Priority.__members__)
+
+
+class IOPriority(enum.IntEnum):
IOPRIO_VERYLOW = 0
IOPRIO_LOW = 1
IOPRIO_NORMAL = 2
IOPRIO_HIGH = 3
-else:
- class IOPriority(enum.IntEnum):
- IOPRIO_VERYLOW = 0
- IOPRIO_LOW = 1
- IOPRIO_NORMAL = 2
- IOPRIO_HIGH = 3
- globals().update(IOPriority.__members__)
+globals().update(IOPriority.__members__)
pinfo_map = dict(
num_handles=0,
@@ -199,7 +181,7 @@ pio = namedtuple('pio', ['read_count', 'write_count',
# =====================================================================
-@lru_cache(maxsize=512)
[email protected]_cache(maxsize=512)
def convert_dos_path(s):
r"""Convert paths using native DOS format like:
"\Device\HarddiskVolume1\Windows\systemew\file.txt"
@@ -212,18 +194,6 @@ def convert_dos_path(s):
return os.path.join(driveletter, remainder)
-def py2_strencode(s):
- """Encode a unicode string to a byte string by using the default fs
- encoding + "replace" error handler.
- """
- if PY3:
- return s
- if isinstance(s, str):
- return s
- else:
- return s.encode(ENCODING, ENCODING_ERRS)
-
-
@memoize
def getpagesize():
return cext.getpagesize()
@@ -282,7 +252,7 @@ disk_io_counters = cext.disk_io_counters
def disk_usage(path):
"""Return disk usage associated with path."""
- if PY3 and isinstance(path, bytes):
+ if isinstance(path, bytes):
# XXX: do we want to use "strict"? Probably yes, in order
# to fail immediately. After all we are accepting input here...
path = path.decode(ENCODING, errors="strict")
@@ -367,7 +337,7 @@ def getloadavg():
# Drop to 2 decimal points which is what Linux does
raw_loads = cext.getloadavg()
- return tuple([round(load, 2) for load in raw_loads])
+ return tuple(round(load, 2) for load in raw_loads)
# =====================================================================
@@ -379,11 +349,6 @@ def net_connections(kind, _pid=-1):
"""Return socket connections. If pid == -1 return system-wide
connections (as opposed to connections opened by one process only).
"""
- if kind not in conn_tmap:
- raise ValueError(
- "invalid %r kind argument; choose between %s"
- % (kind, ', '.join([repr(x) for x in conn_tmap]))
- )
families, types = conn_tmap[kind]
rawlist = cext.net_connections(_pid, families, types)
ret = set()
@@ -408,9 +373,6 @@ def net_if_stats():
ret = {}
rawdict = cext.net_if_stats()
for name, items in rawdict.items():
- if not PY3:
- assert isinstance(name, unicode), type(name)
- name = py2_strencode(name)
isup, duplex, speed, mtu = items
if hasattr(_common, 'NicDuplex'):
duplex = _common.NicDuplex(duplex)
@@ -422,18 +384,12 @@ def net_io_counters():
"""Return network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
"""
- ret = cext.net_io_counters()
- return dict([(py2_strencode(k), v) for k, v in ret.items()])
+ return cext.net_io_counters()
def net_if_addrs():
"""Return the addresses associated to each NIC."""
- ret = []
- for items in cext.net_if_addrs():
- items = list(items)
- items[0] = py2_strencode(items[0])
- ret.append(items)
- return ret
+ return cext.net_if_addrs()
# =====================================================================
@@ -489,7 +445,6 @@ def users():
rawlist = cext.users()
for item in rawlist:
user, hostname, tstamp = item
- user = py2_strencode(user)
nt = _common.suser(user, None, hostname, tstamp, None)
retlist.append(nt)
return retlist
@@ -503,7 +458,7 @@ def users():
def win_service_iter():
"""Yields a list of WindowsService instances."""
for name, display_name in cext.winservice_enumerate():
- yield WindowsService(py2_strencode(name), py2_strencode(display_name))
+ yield WindowsService(name, display_name)
def win_service_get(name):
@@ -521,14 +476,11 @@ class WindowsService: # noqa: PLW1641
self._display_name = display_name
def __str__(self):
- details = "(name=%r, display_name=%r)" % (
- self._name,
- self._display_name,
- )
- return "%s%s" % (self.__class__.__name__, details)
+ details = f"(name={self._name!r}, display_name={self._display_name!r})"
+ return f"{self.__class__.__name__}{details}"
def __repr__(self):
- return "<%s at %s>" % (self.__str__(), id(self))
+ return f"<{self.__str__()} at {id(self)}>"
def __eq__(self, other):
# Test for equality with another WindosService object based
@@ -547,10 +499,10 @@ class WindowsService: # noqa: PLW1641
)
# XXX - update _self.display_name?
return dict(
- display_name=py2_strencode(display_name),
- binpath=py2_strencode(binpath),
- username=py2_strencode(username),
- start_type=py2_strencode(start_type),
+ display_name=display_name,
+ binpath=binpath,
+ username=username,
+ start_type=start_type,
)
def _query_status(self):
@@ -568,18 +520,18 @@ class WindowsService: # noqa: PLW1641
try:
yield
except OSError as err:
+ name = self._name
if is_permission_err(err):
msg = (
- "service %r is not querable (not enough privileges)"
- % self._name
+ f"service {name!r} is not querable (not enough privileges)"
)
- raise AccessDenied(pid=None, name=self._name, msg=msg)
+ raise AccessDenied(pid=None, name=name, msg=msg) from err
elif err.winerror in {
cext.ERROR_INVALID_NAME,
cext.ERROR_SERVICE_DOES_NOT_EXIST,
}:
- msg = "service %r does not exist" % self._name
- raise NoSuchProcess(pid=None, name=self._name, msg=msg)
+ msg = f"service {name!r} does not exist"
+ raise NoSuchProcess(pid=None, name=name, msg=msg) from err
else:
raise
@@ -628,7 +580,7 @@ class WindowsService: # noqa: PLW1641
def description(self):
"""Service long description."""
- return py2_strencode(cext.winservice_query_descr(self.name()))
+ return cext.winservice_query_descr(self.name())
# utils
@@ -696,12 +648,7 @@ ppid_map = cext.ppid_map # used internally by Process.children()
def is_permission_err(exc):
"""Return True if this is a permission error."""
assert isinstance(exc, OSError), exc
- if exc.errno in {errno.EPERM, errno.EACCES}:
- return True
- # On Python 2 OSError doesn't always have 'winerror'. Sometimes
- # it does, in which case the original exception was WindowsError
- # (which is a subclass of OSError).
- return getattr(exc, "winerror", -1) in {
+ return isinstance(exc, PermissionError) or exc.winerror in {
cext.ERROR_ACCESS_DENIED,
cext.ERROR_PRIVILEGE_NOT_HELD,
}
@@ -712,7 +659,7 @@ def convert_oserror(exc, pid=None, name=None):
assert isinstance(exc, OSError), exc
if is_permission_err(exc):
return AccessDenied(pid=pid, name=name)
- if exc.errno == errno.ESRCH:
+ if isinstance(exc, ProcessLookupError):
return NoSuchProcess(pid=pid, name=name)
raise exc
@@ -725,7 +672,7 @@ def wrap_exceptions(fun):
try:
return fun(self, *args, **kwargs)
except OSError as err:
- raise convert_oserror(err, pid=self.pid, name=self._name)
+ raise convert_oserror(err, pid=self.pid, name=self._name) from err
return wrapper
@@ -742,7 +689,7 @@ def retry_error_partial_copy(fun):
for _ in range(times): # retries for roughly 1 second
try:
return fun(self, *args, **kwargs)
- except WindowsError as _:
+ except OSError as _:
err = _
if err.winerror == ERROR_PARTIAL_COPY:
time.sleep(delay)
@@ -750,8 +697,8 @@ def retry_error_partial_copy(fun):
continue
raise
msg = (
- "{} retried {} times, converted to AccessDenied as it's still"
- "returning {}".format(fun, times, err)
+ f"{fun} retried {times} times, converted to AccessDenied as it's "
+ f"still returning {err}"
)
raise AccessDenied(pid=self.pid, name=self._name, msg=msg)
@@ -805,17 +752,15 @@ class Process:
if PYPY:
try:
exe = cext.proc_exe(self.pid)
- except WindowsError as err:
+ except OSError as err:
# 24 = ERROR_TOO_MANY_OPEN_FILES. Not sure why this happens
# (perhaps PyPy's JIT delaying garbage collection of files?).
if err.errno == 24:
- debug("%r translated into AccessDenied" % err)
- raise AccessDenied(self.pid, self._name)
+ debug(f"{err!r} translated into AccessDenied")
+ raise AccessDenied(self.pid, self._name) from err
raise
else:
exe = cext.proc_exe(self.pid)
- if not PY3:
- exe = py2_strencode(exe)
if exe.startswith('\\'):
return convert_dos_path(exe)
return exe # May be "Registry", "MemCompression", ...
@@ -827,32 +772,26 @@ class Process:
# PEB method detects cmdline changes but requires more
# privileges: https://github.com/giampaolo/psutil/pull/1398
try:
- ret = cext.proc_cmdline(self.pid, use_peb=True)
+ return cext.proc_cmdline(self.pid, use_peb=True)
except OSError as err:
if is_permission_err(err):
- ret = cext.proc_cmdline(self.pid, use_peb=False)
+ return cext.proc_cmdline(self.pid, use_peb=False)
else:
raise
else:
- ret = cext.proc_cmdline(self.pid, use_peb=True)
- if PY3:
- return ret
- else:
- return [py2_strencode(s) for s in ret]
+ return cext.proc_cmdline(self.pid, use_peb=True)
@wrap_exceptions
@retry_error_partial_copy
def environ(self):
- ustr = cext.proc_environ(self.pid)
- if ustr and not PY3:
- assert isinstance(ustr, unicode), type(ustr)
- return parse_environ_block(py2_strencode(ustr))
+ s = cext.proc_environ(self.pid)
+ return parse_environ_block(s)
def ppid(self):
try:
return ppid_map()[self.pid]
except KeyError:
- raise NoSuchProcess(self.pid, self._name)
+ raise NoSuchProcess(self.pid, self._name) from None
def _get_raw_meminfo(self):
try:
@@ -900,12 +839,10 @@ class Process:
except OSError as err:
# XXX - can't use wrap_exceptions decorator as we're
# returning a generator; probably needs refactoring.
- raise convert_oserror(err, self.pid, self._name)
+ raise convert_oserror(err, self.pid, self._name) from err
else:
for addr, perm, path, rss in raw:
path = convert_dos_path(path)
- if not PY3:
- path = py2_strencode(path)
addr = hex(addr)
yield (addr, perm, path, rss)
@@ -917,11 +854,7 @@ class Process:
def send_signal(self, sig):
if sig == signal.SIGTERM:
cext.proc_kill(self.pid)
- # py >= 2.7
- elif sig in {
- getattr(signal, "CTRL_C_EVENT", object()),
- getattr(signal, "CTRL_BREAK_EVENT", object()),
- }:
+ elif sig in {signal.CTRL_C_EVENT, signal.CTRL_BREAK_EVENT}:
os.kill(self.pid, sig)
else:
msg = (
@@ -946,9 +879,9 @@ class Process:
# May also be None if OpenProcess() failed with
# ERROR_INVALID_PARAMETER, meaning PID is already gone.
exit_code = cext.proc_wait(self.pid, cext_timeout)
- except cext.TimeoutExpired:
+ except cext.TimeoutExpired as err:
# WaitForSingleObject() returned WAIT_TIMEOUT. Just raise.
- raise TimeoutExpired(timeout, self.pid, self._name)
+ raise TimeoutExpired(timeout, self.pid, self._name) from err
except cext.TimeoutAbandoned:
# WaitForSingleObject() returned WAIT_ABANDONED, see:
# https://github.com/giampaolo/psutil/issues/1224
@@ -978,7 +911,7 @@ class Process:
if self.pid in {0, 4}:
return 'NT AUTHORITY\\SYSTEM'
domain, user = cext.proc_username(self.pid)
- return py2_strencode(domain) + '\\' + py2_strencode(user)
+ return f"{domain}\\{user}"
@wrap_exceptions
def create_time(self, fast_only=False):
@@ -1038,7 +971,7 @@ class Process:
# return a normalized pathname since the native C function appends
# "\\" at the and of the path
path = cext.proc_cwd(self.pid)
- return py2_strencode(os.path.normpath(path))
+ return os.path.normpath(path)
@wrap_exceptions
def open_files(self):
@@ -1050,12 +983,10 @@ class Process:
# Convert the first part in the corresponding drive letter
# (e.g. "C:\") by using Windows's QueryDosDevice()
raw_file_names = cext.proc_open_files(self.pid)
- for _file in raw_file_names:
- _file = convert_dos_path(_file)
- if isfile_strict(_file):
- if not PY3:
- _file = py2_strencode(_file)
- ntuple = _common.popenfile(_file, -1)
+ for file in raw_file_names:
+ file = convert_dos_path(file)
+ if isfile_strict(file):
+ ntuple = _common.popenfile(file, -1)
ret.add(ntuple)
return list(ret)
@@ -1066,8 +997,7 @@ class Process:
@wrap_exceptions
def nice_get(self):
value = cext.proc_priority_get(self.pid)
- if enum is not None:
- value = Priority(value)
+ value = Priority(value)
return value
@wrap_exceptions
@@ -1077,8 +1007,7 @@ class Process:
@wrap_exceptions
def ionice_get(self):
ret = cext.proc_io_priority_get(self.pid)
- if enum is not None:
- ret = IOPriority(ret)
+ ret = IOPriority(ret)
return ret
@wrap_exceptions
@@ -1087,12 +1016,13 @@ class Process:
msg = "value argument not accepted on Windows"
raise TypeError(msg)
if ioclass not in {
- IOPRIO_VERYLOW,
- IOPRIO_LOW,
- IOPRIO_NORMAL,
- IOPRIO_HIGH,
+ IOPriority.IOPRIO_VERYLOW,
+ IOPriority.IOPRIO_LOW,
+ IOPriority.IOPRIO_NORMAL,
+ IOPriority.IOPRIO_HIGH,
}:
- raise ValueError("%s is not a valid priority" % ioclass)
+ msg = f"{ioclass} is not a valid priority"
+ raise ValueError(msg)
cext.proc_io_priority_set(self.pid, ioclass)
@wrap_exceptions
@@ -1134,7 +1064,8 @@ class Process:
def cpu_affinity_set(self, value):
def to_bitmask(ls):
if not ls:
- raise ValueError("invalid argument %r" % ls)
+ msg = f"invalid argument {ls!r}"
+ raise ValueError(msg)
out = 0
for b in ls:
out |= 2**b
@@ -1146,12 +1077,11 @@ class Process:
allcpus = list(range(len(per_cpu_times())))
for cpu in value:
if cpu not in allcpus:
- if not isinstance(cpu, (int, long)):
- raise TypeError(
- "invalid CPU %r; an integer is required" % cpu
- )
- else:
- raise ValueError("invalid CPU %r" % cpu)
+ if not isinstance(cpu, int):
+ msg = f"invalid CPU {cpu!r}; an integer is required"
+ raise TypeError(msg)
+ msg = f"invalid CPU {cpu!r}"
+ raise ValueError(msg)
bitmask = to_bitmask(value)
cext.proc_cpu_affinity_set(self.pid, bitmask)
diff --git a/contrib/python/psutil/py3/psutil/arch/linux/proc.c b/contrib/python/psutil/py3/psutil/arch/linux/proc.c
index b58a3ce2a24..f8230ee75b0 100644
--- a/contrib/python/psutil/py3/psutil/arch/linux/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/linux/proc.c
@@ -118,11 +118,7 @@ psutil_proc_cpu_affinity_get(PyObject *self, PyObject *args) {
cpucount_s = CPU_COUNT_S(setsize, mask);
for (cpu = 0, count = cpucount_s; count; cpu++) {
if (CPU_ISSET_S(cpu, setsize, mask)) {
-#if PY_MAJOR_VERSION >= 3
PyObject *cpu_num = PyLong_FromLong(cpu);
-#else
- PyObject *cpu_num = PyInt_FromLong(cpu);
-#endif
if (cpu_num == NULL)
goto error;
if (PyList_Append(py_list, cpu_num)) {
@@ -159,11 +155,7 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
if (!PySequence_Check(py_cpu_set)) {
return PyErr_Format(
PyExc_TypeError,
-#if PY_MAJOR_VERSION >= 3
"sequence argument expected, got %R", Py_TYPE(py_cpu_set)
-#else
- "sequence argument expected, got %s", Py_TYPE(py_cpu_set)->tp_name
-#endif
);
}
@@ -177,11 +169,7 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
if (!item) {
return NULL;
}
-#if PY_MAJOR_VERSION >= 3
long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
Py_XDECREF(item);
if ((value == -1) || PyErr_Occurred()) {
if (!PyErr_Occurred())
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/disk.c b/contrib/python/psutil/py3/psutil/arch/osx/disk.c
index d02cf794d5d..e1a8f5a4927 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/disk.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/disk.c
@@ -168,7 +168,6 @@ psutil_disk_usage_used(PyObject *self, PyObject *args) {
PyObject *py_mount_point_bytes = NULL;
char* mount_point;
-#if PY_MAJOR_VERSION >= 3
if (!PyArg_ParseTuple(args, "O&O", PyUnicode_FSConverter, &py_mount_point_bytes, &py_default_value)) {
return NULL;
}
@@ -177,11 +176,6 @@ psutil_disk_usage_used(PyObject *self, PyObject *args) {
Py_XDECREF(py_mount_point_bytes);
return NULL;
}
-#else
- if (!PyArg_ParseTuple(args, "sO", &mount_point, &py_default_value)) {
- return NULL;
- }
-#endif
#ifdef ATTR_VOL_SPACEUSED
/* Call getattrlist(ATTR_VOL_SPACEUSED) to get used space info. */
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/mem.c b/contrib/python/psutil/py3/psutil/arch/osx/mem.c
index 53493065c27..8103876070a 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/mem.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/mem.c
@@ -8,6 +8,9 @@
// from psutil/_psutil_osx.c in 2023. This is the GIT blame before the move:
// https://github.com/giampaolo/psutil/blame/efd7ed3/psutil/_psutil_osx.c
+// See:
+// https://github.com/apple-open-source/macos/blob/master/system_cmds/vm_stat/vm_stat.c
+
#include <Python.h>
#include <mach/host_info.h>
#include <sys/sysctl.h>
@@ -17,12 +20,12 @@
static int
-psutil_sys_vminfo(vm_statistics_data_t *vmstat) {
+psutil_sys_vminfo(vm_statistics64_t vmstat) {
kern_return_t ret;
- mach_msg_type_number_t count = sizeof(*vmstat) / sizeof(integer_t);
+ unsigned int count = HOST_VM_INFO64_COUNT;
mach_port_t mport = mach_host_self();
- ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)vmstat, &count);
+ ret = host_statistics64(mport, HOST_VM_INFO64, (host_info64_t)vmstat, &count);
if (ret != KERN_SUCCESS) {
PyErr_Format(
PyExc_RuntimeError,
@@ -46,7 +49,7 @@ psutil_virtual_mem(PyObject *self, PyObject *args) {
int mib[2];
uint64_t total;
size_t len = sizeof(total);
- vm_statistics_data_t vm;
+ vm_statistics64_data_t vm;
long pagesize = psutil_getpagesize();
// physical mem
mib[0] = CTL_HW;
@@ -86,7 +89,7 @@ psutil_swap_mem(PyObject *self, PyObject *args) {
int mib[2];
size_t size;
struct xsw_usage totals;
- vm_statistics_data_t vmstat;
+ vm_statistics64_data_t vmstat;
long pagesize = psutil_getpagesize();
mib[0] = CTL_VM;
diff --git a/contrib/python/psutil/py3/psutil/arch/osx/proc.c b/contrib/python/psutil/py3/psutil/arch/osx/proc.c
index 136311ecee4..681642c3ad9 100644
--- a/contrib/python/psutil/py3/psutil/arch/osx/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/osx/proc.c
@@ -763,7 +763,7 @@ error:
/*
* Return process open files as a Python tuple.
* References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
+ * - lsof source code: https://github.com/apple-opensource/lsof/blob/28/lsof/dialects/darwin/libproc/dproc.c#L342
* - /usr/include/sys/proc_info.h
*/
PyObject *
@@ -854,7 +854,7 @@ error:
* Return process TCP and UDP connections as a list of tuples.
* Raises NSP in case of zombie process.
* References:
- * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
+ * - lsof source code: https://github.com/apple-opensource/lsof/blob/28/lsof/dialects/darwin/libproc/dproc.c#L342
* - /usr/include/sys/proc_info.h
*/
PyObject *
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/disk.c b/contrib/python/psutil/py3/psutil/arch/windows/disk.c
index 88469e3a617..d0405a98f84 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/disk.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/disk.c
@@ -45,33 +45,6 @@ PyObject *
psutil_disk_usage(PyObject *self, PyObject *args) {
BOOL retval;
ULARGE_INTEGER _, total, free;
-
-#if PY_MAJOR_VERSION <= 2
- char *path;
-
- if (PyArg_ParseTuple(args, "u", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceExW((LPCWSTR)path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-
- // on Python 2 we also want to accept plain strings other
- // than Unicode
- PyErr_Clear(); // drop the argument parsing error
- if (PyArg_ParseTuple(args, "s", &path)) {
- Py_BEGIN_ALLOW_THREADS
- retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
- Py_END_ALLOW_THREADS
- goto return_;
- }
-
- return NULL;
-
-return_:
- if (retval == 0)
- return PyErr_SetFromWindowsErrWithFilename(0, path);
-#else
PyObject *py_path;
wchar_t *path;
@@ -92,7 +65,7 @@ return_:
if (retval == 0)
return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 0, py_path);
-#endif
+
return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
}
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/net.c b/contrib/python/psutil/py3/psutil/arch/windows/net.c
index 8d8f7d1c0aa..9a5634b0693 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/net.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/net.c
@@ -255,21 +255,14 @@ psutil_net_if_addrs(PyObject *self, PyObject *args) {
continue;
}
-#if PY_MAJOR_VERSION >= 3
py_address = PyUnicode_FromString(buff_addr);
-#else
- py_address = PyString_FromString(buff_addr);
-#endif
if (py_address == NULL)
goto error;
if (netmaskIntRet != NULL) {
-#if PY_MAJOR_VERSION >= 3
py_netmask = PyUnicode_FromString(buff_netmask);
-#else
- py_netmask = PyString_FromString(buff_netmask);
-#endif
- } else {
+ }
+ else {
Py_INCREF(Py_None);
py_netmask = Py_None;
}
diff --git a/contrib/python/psutil/py3/psutil/arch/windows/proc.c b/contrib/python/psutil/py3/psutil/arch/windows/proc.c
index 05fb5025579..41fa9dda680 100644
--- a/contrib/python/psutil/py3/psutil/arch/windows/proc.c
+++ b/contrib/python/psutil/py3/psutil/arch/windows/proc.c
@@ -192,11 +192,7 @@ psutil_proc_wait(PyObject *self, PyObject *args) {
CloseHandle(hProcess);
-#if PY_MAJOR_VERSION >= 3
return PyLong_FromLong((long) ExitCode);
-#else
- return PyInt_FromLong((long) ExitCode);
-#endif
}
diff --git a/contrib/python/psutil/py3/ya.make b/contrib/python/psutil/py3/ya.make
index c81c1dffb82..fd48170ac2b 100644
--- a/contrib/python/psutil/py3/ya.make
+++ b/contrib/python/psutil/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(6.1.1)
+VERSION(7.0.0)
LICENSE(BSD-3-Clause)
@@ -27,7 +27,7 @@ NO_CHECK_IMPORTS(
NO_UTIL()
CFLAGS(
- -DPSUTIL_VERSION=611
+ -DPSUTIL_VERSION=700
)
SRCS(
@@ -125,7 +125,6 @@ PY_SRCS(
TOP_LEVEL
psutil/__init__.py
psutil/_common.py
- psutil/_compat.py
psutil/_psaix.py
psutil/_psbsd.py
psutil/_pslinux.py