Browse Source

Intermediate changes

robot-piglet 1 year ago
parent
commit
f6c02fde7b

+ 1 - 1
contrib/python/hypothesis/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Metadata-Version: 2.1
 Name: hypothesis
 Name: hypothesis
-Version: 6.98.8
+Version: 6.98.9
 Summary: A library for property-based testing
 Summary: A library for property-based testing
 Home-page: https://hypothesis.works
 Home-page: https://hypothesis.works
 Author: David R. MacIver and Zac Hatfield-Dodds
 Author: David R. MacIver and Zac Hatfield-Dodds

+ 11 - 2
contrib/python/hypothesis/py3/hypothesis/core.py

@@ -834,8 +834,9 @@ class StateForActualGivenExecution:
                     in_drawtime = math.fsum(data.draw_times.values()) - arg_drawtime
                     in_drawtime = math.fsum(data.draw_times.values()) - arg_drawtime
                     runtime = datetime.timedelta(seconds=finish - start - in_drawtime)
                     runtime = datetime.timedelta(seconds=finish - start - in_drawtime)
                     self._timing_features = {
                     self._timing_features = {
-                        "execute_test": finish - start - in_drawtime,
+                        "execute:test": finish - start - in_drawtime,
                         **data.draw_times,
                         **data.draw_times,
+                        **data._stateful_run_times,
                     }
                     }
 
 
                 if (current_deadline := self.settings.deadline) is not None:
                 if (current_deadline := self.settings.deadline) is not None:
@@ -927,6 +928,9 @@ class StateForActualGivenExecution:
                     msg, format_arg = data._sampled_from_all_strategies_elements_message
                     msg, format_arg = data._sampled_from_all_strategies_elements_message
                     add_note(e, msg.format(format_arg))
                     add_note(e, msg.format(format_arg))
                 raise
                 raise
+            finally:
+                if parts := getattr(data, "_stateful_repr_parts", None):
+                    self._string_repr = "\n".join(parts)
 
 
         # self.test_runner can include the execute_example method, or setup/teardown
         # self.test_runner can include the execute_example method, or setup/teardown
         # _example, so it's important to get the PRNG and build context in place first.
         # _example, so it's important to get the PRNG and build context in place first.
@@ -942,7 +946,11 @@ class StateForActualGivenExecution:
         if expected_failure is not None:
         if expected_failure is not None:
             exception, traceback = expected_failure
             exception, traceback = expected_failure
             if isinstance(exception, DeadlineExceeded) and (
             if isinstance(exception, DeadlineExceeded) and (
-                runtime_secs := self._timing_features.get("execute_test")
+                runtime_secs := math.fsum(
+                    v
+                    for k, v in self._timing_features.items()
+                    if k.startswith("execute:")
+                )
             ):
             ):
                 report(
                 report(
                     "Unreliable test timings! On an initial run, this "
                     "Unreliable test timings! On an initial run, this "
@@ -1068,6 +1076,7 @@ class StateForActualGivenExecution:
                     arguments={**self._jsonable_arguments, **data._observability_args},
                     arguments={**self._jsonable_arguments, **data._observability_args},
                     timing=self._timing_features,
                     timing=self._timing_features,
                     coverage=tractable_coverage_report(trace) or None,
                     coverage=tractable_coverage_report(trace) or None,
+                    phase=phase,
                 )
                 )
                 deliver_json_blob(tc)
                 deliver_json_blob(tc)
             self._timing_features = {}
             self._timing_features = {}

+ 3 - 1
contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py

@@ -18,6 +18,7 @@ from typing import (
     TYPE_CHECKING,
     TYPE_CHECKING,
     Any,
     Any,
     Callable,
     Callable,
+    DefaultDict,
     Dict,
     Dict,
     FrozenSet,
     FrozenSet,
     Iterable,
     Iterable,
@@ -1468,6 +1469,7 @@ class ConjectureData:
         self.forced_indices: "Set[int]" = set()
         self.forced_indices: "Set[int]" = set()
         self.interesting_origin: Optional[InterestingOrigin] = None
         self.interesting_origin: Optional[InterestingOrigin] = None
         self.draw_times: "Dict[str, float]" = {}
         self.draw_times: "Dict[str, float]" = {}
+        self._stateful_run_times: "DefaultDict[str, float]" = defaultdict(float)
         self.max_depth = 0
         self.max_depth = 0
         self.has_discards = False
         self.has_discards = False
         self.provider = PrimitiveProvider(self)
         self.provider = PrimitiveProvider(self)
@@ -1752,7 +1754,7 @@ class ConjectureData:
                 try:
                 try:
                     return strategy.do_draw(self)
                     return strategy.do_draw(self)
                 finally:
                 finally:
-                    key = observe_as or f"unlabeled_{len(self.draw_times)}"
+                    key = observe_as or f"generate:unlabeled_{len(self.draw_times)}"
                     self.draw_times[key] = time.perf_counter() - start_time
                     self.draw_times[key] = time.perf_counter() - start_time
         finally:
         finally:
             self.stop_example()
             self.stop_example()

+ 3 - 0
contrib/python/hypothesis/py3/hypothesis/internal/observability.py

@@ -41,9 +41,12 @@ def make_testcase(
     arguments: Optional[dict] = None,
     arguments: Optional[dict] = None,
     timing: Dict[str, float],
     timing: Dict[str, float],
     coverage: Optional[Dict[str, List[int]]] = None,
     coverage: Optional[Dict[str, List[int]]] = None,
+    phase: Optional[str] = None,
 ) -> dict:
 ) -> dict:
     if data.interesting_origin:
     if data.interesting_origin:
         status_reason = str(data.interesting_origin)
         status_reason = str(data.interesting_origin)
+    elif phase == "shrink" and data.status == Status.OVERRUN:
+        status_reason = "exceeded size of current best example"
     else:
     else:
         status_reason = str(data.events.pop("invalid because", ""))
         status_reason = str(data.events.pop("invalid because", ""))
 
 

+ 36 - 19
contrib/python/hypothesis/py3/hypothesis/stateful.py

@@ -20,6 +20,7 @@ import inspect
 from copy import copy
 from copy import copy
 from functools import lru_cache
 from functools import lru_cache
 from io import StringIO
 from io import StringIO
+from time import perf_counter
 from typing import (
 from typing import (
     Any,
     Any,
     Callable,
     Callable,
@@ -48,6 +49,7 @@ from hypothesis.core import TestFunc, given
 from hypothesis.errors import InvalidArgument, InvalidDefinition
 from hypothesis.errors import InvalidArgument, InvalidDefinition
 from hypothesis.internal.conjecture import utils as cu
 from hypothesis.internal.conjecture import utils as cu
 from hypothesis.internal.healthcheck import fail_health_check
 from hypothesis.internal.healthcheck import fail_health_check
+from hypothesis.internal.observability import TESTCASE_CALLBACKS
 from hypothesis.internal.reflection import (
 from hypothesis.internal.reflection import (
     function_digest,
     function_digest,
     get_pretty_function_description,
     get_pretty_function_description,
@@ -121,10 +123,17 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
         print_steps = (
         print_steps = (
             current_build_context().is_final or current_verbosity() >= Verbosity.debug
             current_build_context().is_final or current_verbosity() >= Verbosity.debug
         )
         )
-        try:
+        cd._stateful_repr_parts = []
+
+        def output(s):
             if print_steps:
             if print_steps:
-                report(f"state = {machine.__class__.__name__}()")
-            machine.check_invariants(settings)
+                report(s)
+            if TESTCASE_CALLBACKS:
+                cd._stateful_repr_parts.append(s)
+
+        try:
+            output(f"state = {machine.__class__.__name__}()")
+            machine.check_invariants(settings, output, cd._stateful_run_times)
             max_steps = settings.stateful_step_count
             max_steps = settings.stateful_step_count
             steps_run = 0
             steps_run = 0
 
 
@@ -141,6 +150,8 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
                     must_stop = True
                     must_stop = True
                 elif steps_run <= _min_steps:
                 elif steps_run <= _min_steps:
                     must_stop = False
                     must_stop = False
+
+                start_draw = perf_counter()
                 if cd.draw_boolean(p=2**-16, forced=must_stop):
                 if cd.draw_boolean(p=2**-16, forced=must_stop):
                     break
                     break
                 steps_run += 1
                 steps_run += 1
@@ -156,12 +167,15 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
                     machine._initialize_rules_to_run.remove(rule)
                     machine._initialize_rules_to_run.remove(rule)
                 else:
                 else:
                     rule, data = cd.draw(machine._rules_strategy)
                     rule, data = cd.draw(machine._rules_strategy)
+                draw_label = f"generate:rule:{rule.function.__name__}"
+                cd.draw_times.setdefault(draw_label, 0.0)
+                cd.draw_times[draw_label] += perf_counter() - start_draw
 
 
                 # Pretty-print the values this rule was called with *before* calling
                 # Pretty-print the values this rule was called with *before* calling
                 # _add_result_to_targets, to avoid printing arguments which are also
                 # _add_result_to_targets, to avoid printing arguments which are also
                 # a return value using the variable name they are assigned to.
                 # a return value using the variable name they are assigned to.
                 # See https://github.com/HypothesisWorks/hypothesis/issues/2341
                 # See https://github.com/HypothesisWorks/hypothesis/issues/2341
-                if print_steps:
+                if print_steps or TESTCASE_CALLBACKS:
                     data_to_print = {
                     data_to_print = {
                         k: machine._pretty_print(v) for k, v in data.items()
                         k: machine._pretty_print(v) for k, v in data.items()
                     }
                     }
@@ -173,7 +187,12 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
                     for k, v in list(data.items()):
                     for k, v in list(data.items()):
                         if isinstance(v, VarReference):
                         if isinstance(v, VarReference):
                             data[k] = machine.names_to_values[v.name]
                             data[k] = machine.names_to_values[v.name]
+
+                    label = f"execute:rule:{rule.function.__name__}"
+                    start = perf_counter()
                     result = rule.function(machine, **data)
                     result = rule.function(machine, **data)
+                    cd._stateful_run_times[label] += perf_counter() - start
+
                     if rule.targets:
                     if rule.targets:
                         if isinstance(result, MultipleResults):
                         if isinstance(result, MultipleResults):
                             for single_result in result.values:
                             for single_result in result.values:
@@ -190,16 +209,15 @@ def run_state_machine_as_test(state_machine_factory, *, settings=None, _min_step
                             HealthCheck.return_value,
                             HealthCheck.return_value,
                         )
                         )
                 finally:
                 finally:
-                    if print_steps:
+                    if print_steps or TESTCASE_CALLBACKS:
                         # 'result' is only used if the step has target bundles.
                         # 'result' is only used if the step has target bundles.
                         # If it does, and the result is a 'MultipleResult',
                         # If it does, and the result is a 'MultipleResult',
                         # then 'print_step' prints a multi-variable assignment.
                         # then 'print_step' prints a multi-variable assignment.
-                        machine._print_step(rule, data_to_print, result)
-                machine.check_invariants(settings)
+                        output(machine._repr_step(rule, data_to_print, result))
+                machine.check_invariants(settings, output, cd._stateful_run_times)
                 cd.stop_example()
                 cd.stop_example()
         finally:
         finally:
-            if print_steps:
-                report("state.teardown()")
+            output("state.teardown()")
             machine.teardown()
             machine.teardown()
 
 
     # Use a machine digest to identify stateful tests in the example database
     # Use a machine digest to identify stateful tests in the example database
@@ -338,7 +356,7 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta):
         cls._invariants_per_class[cls] = target
         cls._invariants_per_class[cls] = target
         return cls._invariants_per_class[cls]
         return cls._invariants_per_class[cls]
 
 
-    def _print_step(self, rule, data, result):
+    def _repr_step(self, rule, data, result):
         self.step_count = getattr(self, "step_count", 0) + 1
         self.step_count = getattr(self, "step_count", 0) + 1
         output_assignment = ""
         output_assignment = ""
         if rule.targets:
         if rule.targets:
@@ -350,13 +368,8 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta):
                     output_assignment = ", ".join(output_names) + " = "
                     output_assignment = ", ".join(output_names) + " = "
             else:
             else:
                 output_assignment = self._last_names(1)[0] + " = "
                 output_assignment = self._last_names(1)[0] + " = "
-        report(
-            "{}state.{}({})".format(
-                output_assignment,
-                rule.function.__name__,
-                ", ".join("%s=%s" % kv for kv in data.items()),
-            )
-        )
+        args = ", ".join("%s=%s" % kv for kv in data.items())
+        return f"{output_assignment}state.{rule.function.__name__}({args})"
 
 
     def _add_result_to_targets(self, targets, result):
     def _add_result_to_targets(self, targets, result):
         name = self._new_name()
         name = self._new_name()
@@ -367,18 +380,22 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta):
         for target in targets:
         for target in targets:
             self.bundles.setdefault(target, []).append(VarReference(name))
             self.bundles.setdefault(target, []).append(VarReference(name))
 
 
-    def check_invariants(self, settings):
+    def check_invariants(self, settings, output, runtimes):
         for invar in self.invariants():
         for invar in self.invariants():
             if self._initialize_rules_to_run and not invar.check_during_init:
             if self._initialize_rules_to_run and not invar.check_during_init:
                 continue
                 continue
             if not all(precond(self) for precond in invar.preconditions):
             if not all(precond(self) for precond in invar.preconditions):
                 continue
                 continue
+            name = invar.function.__name__
             if (
             if (
                 current_build_context().is_final
                 current_build_context().is_final
                 or settings.verbosity >= Verbosity.debug
                 or settings.verbosity >= Verbosity.debug
+                or TESTCASE_CALLBACKS
             ):
             ):
-                report(f"state.{invar.function.__name__}()")
+                output(f"state.{name}()")
+            start = perf_counter()
             result = invar.function(self)
             result = invar.function(self)
+            runtimes[f"execute:invariant:{name}"] += perf_counter() - start
             if result is not None:
             if result is not None:
                 fail_health_check(
                 fail_health_check(
                     settings,
                     settings,

+ 1 - 1
contrib/python/hypothesis/py3/hypothesis/version.py

@@ -8,5 +8,5 @@
 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
 # obtain one at https://mozilla.org/MPL/2.0/.
 # obtain one at https://mozilla.org/MPL/2.0/.
 
 
-__version_info__ = (6, 98, 8)
+__version_info__ = (6, 98, 9)
 __version__ = ".".join(map(str, __version_info__))
 __version__ = ".".join(map(str, __version_info__))

+ 1 - 1
contrib/python/hypothesis/py3/ya.make

@@ -2,7 +2,7 @@
 
 
 PY3_LIBRARY()
 PY3_LIBRARY()
 
 
-VERSION(6.98.8)
+VERSION(6.98.9)
 
 
 LICENSE(MPL-2.0)
 LICENSE(MPL-2.0)
 
 

+ 36 - 66
contrib/python/psutil/py3/.dist-info/METADATA

@@ -1,11 +1,11 @@
 Metadata-Version: 2.1
 Metadata-Version: 2.1
 Name: psutil
 Name: psutil
-Version: 5.8.0
+Version: 5.9.8
 Summary: Cross-platform lib for process and system monitoring in Python.
 Summary: Cross-platform lib for process and system monitoring in Python.
 Home-page: https://github.com/giampaolo/psutil
 Home-page: https://github.com/giampaolo/psutil
 Author: Giampaolo Rodola
 Author: Giampaolo Rodola
 Author-email: g.rodola@gmail.com
 Author-email: g.rodola@gmail.com
-License: BSD
+License: BSD-3-Clause
 Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,pstree,monitoring,ulimit,prlimit,smem,performance,metrics,agent,observability
 Keywords: ps,top,kill,free,lsof,netstat,nice,tty,ionice,uptime,taskmgr,process,df,iotop,iostat,ifconfig,taskset,who,pidof,pmap,smem,pstree,monitoring,ulimit,prlimit,smem,performance,metrics,agent,observability
 Platform: Platform Independent
 Platform: Platform Independent
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Development Status :: 5 - Production/Stable
@@ -35,7 +35,6 @@ Classifier: Operating System :: POSIX :: SunOS/Solaris
 Classifier: Operating System :: POSIX
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: C
 Classifier: Programming Language :: C
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -53,19 +52,19 @@ Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Operating System
 Classifier: Topic :: System :: Operating System
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
 Classifier: Topic :: Utilities
-Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*
 Description-Content-Type: text/x-rst
 Description-Content-Type: text/x-rst
+License-File: LICENSE
 Provides-Extra: test
 Provides-Extra: test
 Requires-Dist: ipaddress ; (python_version < "3.0") and extra == 'test'
 Requires-Dist: ipaddress ; (python_version < "3.0") and extra == 'test'
 Requires-Dist: mock ; (python_version < "3.0") and extra == 'test'
 Requires-Dist: mock ; (python_version < "3.0") and extra == 'test'
-Requires-Dist: unittest2 ; (python_version < "3.0") and extra == 'test'
 Requires-Dist: enum34 ; (python_version <= "3.4") and extra == 'test'
 Requires-Dist: enum34 ; (python_version <= "3.4") and extra == 'test'
 Requires-Dist: pywin32 ; (sys_platform == "win32") and extra == 'test'
 Requires-Dist: pywin32 ; (sys_platform == "win32") and extra == 'test'
 Requires-Dist: wmi ; (sys_platform == "win32") and extra == 'test'
 Requires-Dist: wmi ; (sys_platform == "win32") and extra == 'test'
 
 
-|  |downloads| |stars| |forks| |contributors| |coverage| |quality|
+|  |downloads| |stars| |forks| |contributors| |coverage|
 |  |version| |py-versions| |packages| |license|
 |  |version| |py-versions| |packages| |license|
-|  |github-actions| |appveyor| |doc| |twitter| |tidelift|
+|  |github-actions-wheels|  |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
 
 
 .. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
 .. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
     :target: https://pepy.tech/project/psutil
     :target: https://pepy.tech/project/psutil
@@ -83,24 +82,24 @@ Requires-Dist: wmi ; (sys_platform == "win32") and extra == 'test'
     :target: https://github.com/giampaolo/psutil/graphs/contributors
     :target: https://github.com/giampaolo/psutil/graphs/contributors
     :alt: Contributors
     :alt: Contributors
 
 
-.. |quality| image:: https://img.shields.io/codacy/grade/ce63e7f7f69d44b5b59682196e6fbfca.svg
-    :target: https://www.codacy.com/app/g-rodola/psutil?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=giampaolo/psutil&amp;utm_campaign=Badge_Grade
-    :alt: Code quality
+.. |github-actions-wheels| image:: https://img.shields.io/github/actions/workflow/status/giampaolo/psutil/.github/workflows/build.yml?label=Linux%2C%20macOS%2C%20Windows
+    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3Abuild
+    :alt: Linux, macOS, Windows
 
 
-.. |github-actions| image:: https://img.shields.io/github/workflow/status/giampaolo/psutil/CI?label=Linux%2C%20macOS%2C%20FreeBSD
-    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3ACI
-    :alt: Linux, macOS, Windows tests
+.. |github-actions-bsd| image:: https://img.shields.io/github/actions/workflow/status/giampaolo/psutil/.github/workflows/bsd.yml?label=FreeBSD,%20NetBSD,%20OpenBSD
+    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
+    :alt: FreeBSD, NetBSD, OpenBSD
 
 
-.. |appveyor| image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
+.. |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
     :target: https://ci.appveyor.com/project/giampaolo/psutil
-    :alt: Windows tests (Appveyor)
+    :alt: Windows (Appveyor)
 
 
 .. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
 .. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
     :target: https://coveralls.io/github/giampaolo/psutil?branch=master
     :target: https://coveralls.io/github/giampaolo/psutil?branch=master
     :alt: Test coverage (coverall.io)
     :alt: Test coverage (coverall.io)
 
 
 .. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
 .. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
-    :target: http://psutil.readthedocs.io/en/latest/?badge=latest
+    :target: https://psutil.readthedocs.io/en/latest/
     :alt: Documentation Status
     :alt: Documentation Status
 
 
 .. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
 .. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
@@ -108,7 +107,6 @@ Requires-Dist: wmi ; (sys_platform == "win32") and extra == 'test'
     :alt: Latest version
     :alt: Latest version
 
 
 .. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
 .. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
-    :target: https://pypi.org/project/psutil
     :alt: Supported Python versions
     :alt: Supported Python versions
 
 
 .. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
 .. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
@@ -161,7 +159,7 @@ psutil currently supports the following platforms:
 - **Sun Solaris**
 - **Sun Solaris**
 - **AIX**
 - **AIX**
 
 
-Supported Python versions are **2.6**, **2.7**, **3.4+** and
+Supported Python versions are **2.7**, **3.6+** and
 `PyPy <http://pypy.org/>`__.
 `PyPy <http://pypy.org/>`__.
 
 
 Funding
 Funding
@@ -172,7 +170,7 @@ immensely from some funding.
 Keeping up with bug reports and maintenance has become hardly sustainable for
 Keeping up with bug reports and maintenance has become hardly sustainable for
 me alone in terms of time.
 me alone in terms of time.
 If you're a company that's making significant use of psutil you can consider
 If you're a company that's making significant use of psutil you can consider
-becoming a sponsor via `GitHub <https://github.com/sponsors/giampaolo>`__,
+becoming a sponsor via `GitHub Sponsors <https://github.com/sponsors/giampaolo>`__,
 `Open Collective <https://opencollective.com/psutil>`__ or
 `Open Collective <https://opencollective.com/psutil>`__ or
 `PayPal <https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8>`__
 `PayPal <https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8>`__
 and have your logo displayed in here and psutil `doc <https://psutil.readthedocs.io>`__.
 and have your logo displayed in here and psutil `doc <https://psutil.readthedocs.io>`__.
@@ -199,7 +197,7 @@ CPU
     >>> import psutil
     >>> import psutil
     >>>
     >>>
     >>> psutil.cpu_times()
     >>> psutil.cpu_times()
-    scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
+    scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, guest_nice=0.0)
     >>>
     >>>
     >>> for x in range(3):
     >>> for x in range(3):
     ...     psutil.cpu_percent(interval=1)
     ...     psutil.cpu_percent(interval=1)
@@ -254,7 +252,7 @@ Disks
 
 
     >>> psutil.disk_partitions()
     >>> psutil.disk_partitions()
     [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid', maxfile=255, maxpath=4096),
     [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid', maxfile=255, maxpath=4096),
-     sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw', maxfile=255, maxpath=4096)]
+     sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext', opts='rw', maxfile=255, maxpath=4096)]
     >>>
     >>>
     >>> psutil.disk_usage('/')
     >>> psutil.disk_usage('/')
     sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
     sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
@@ -286,8 +284,8 @@ Network
                snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
                snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
     >>>
     >>>
     >>> psutil.net_if_stats()
     >>> psutil.net_if_stats()
-    {'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536),
-     'wlan0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500)}
+    {'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536, flags='up,loopback,running'),
+     'wlan0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500, flags='up,broadcast,running,multicast')}
     >>>
     >>>
 
 
 Sensors
 Sensors
@@ -340,39 +338,38 @@ Process management
     >>> p = psutil.Process(7055)
     >>> p = psutil.Process(7055)
     >>> p
     >>> p
     psutil.Process(pid=7055, name='python3', status='running', started='09:04:44')
     psutil.Process(pid=7055, name='python3', status='running', started='09:04:44')
+    >>> p.pid
+    7055
     >>> p.name()
     >>> p.name()
-    'python'
+    'python3'
     >>> p.exe()
     >>> p.exe()
-    '/usr/bin/python'
+    '/usr/bin/python3'
     >>> p.cwd()
     >>> p.cwd()
     '/home/giampaolo'
     '/home/giampaolo'
     >>> p.cmdline()
     >>> p.cmdline()
-    ['/usr/bin/python', 'main.py']
+    ['/usr/bin/python3', 'main.py']
     >>>
     >>>
-    >>> p.pid
-    7055
     >>> p.ppid()
     >>> p.ppid()
     7054
     7054
-    >>> p.children(recursive=True)
-    [psutil.Process(pid=29835, name='python3', status='sleeping', started='11:45:38'),
-     psutil.Process(pid=29836, name='python3', status='waking', started='11:43:39')]
-    >>>
     >>> p.parent()
     >>> p.parent()
     psutil.Process(pid=4699, name='bash', status='sleeping', started='09:06:44')
     psutil.Process(pid=4699, name='bash', status='sleeping', started='09:06:44')
     >>> p.parents()
     >>> p.parents()
     [psutil.Process(pid=4699, name='bash', started='09:06:44'),
     [psutil.Process(pid=4699, name='bash', started='09:06:44'),
      psutil.Process(pid=4689, name='gnome-terminal-server', status='sleeping', started='0:06:44'),
      psutil.Process(pid=4689, name='gnome-terminal-server', status='sleeping', started='0:06:44'),
      psutil.Process(pid=1, name='systemd', status='sleeping', started='05:56:55')]
      psutil.Process(pid=1, name='systemd', status='sleeping', started='05:56:55')]
+    >>> p.children(recursive=True)
+    [psutil.Process(pid=29835, name='python3', status='sleeping', started='11:45:38'),
+     psutil.Process(pid=29836, name='python3', status='waking', started='11:43:39')]
     >>>
     >>>
     >>> p.status()
     >>> p.status()
     'running'
     'running'
-    >>> p.username()
-    'giampaolo'
     >>> p.create_time()
     >>> p.create_time()
     1267551141.5019531
     1267551141.5019531
     >>> p.terminal()
     >>> p.terminal()
     '/dev/pts/0'
     '/dev/pts/0'
     >>>
     >>>
+    >>> p.username()
+    'giampaolo'
     >>> p.uids()
     >>> p.uids()
     puids(real=1000, effective=1000, saved=1000)
     puids(real=1000, effective=1000, saved=1000)
     >>> p.gids()
     >>> p.gids()
@@ -412,14 +409,14 @@ Process management
     [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
     [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
      pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
      pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
     >>>
     >>>
-    >>> p.num_threads()
-    4
-    >>> p.num_fds()
-    8
     >>> p.threads()
     >>> p.threads()
     [pthread(id=5234, user_time=22.5, system_time=9.2891),
     [pthread(id=5234, user_time=22.5, system_time=9.2891),
      pthread(id=5237, user_time=0.0707, system_time=1.1)]
      pthread(id=5237, user_time=0.0707, system_time=1.1)]
     >>>
     >>>
+    >>> p.num_threads()
+    4
+    >>> p.num_fds()
+    8
     >>> p.num_ctx_switches()
     >>> p.num_ctx_switches()
     pctxsw(voluntary=78, involuntary=19)
     pctxsw(voluntary=78, involuntary=19)
     >>>
     >>>
@@ -486,23 +483,6 @@ Further process APIs
     >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
     >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
     >>>
     >>>
 
 
-Popen wrapper:
-
-.. code-block:: python
-
-    >>> import psutil
-    >>> from subprocess import PIPE
-    >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
-    >>> p.name()
-    'python'
-    >>> p.username()
-    'giampaolo'
-    >>> p.communicate()
-    ('hello\n', None)
-    >>> p.wait(timeout=2)
-    0
-    >>>
-
 Windows services
 Windows services
 ----------------
 ----------------
 
 
@@ -533,6 +513,7 @@ Here's some I find particularly interesting:
 - https://github.com/google/grr
 - https://github.com/google/grr
 - https://github.com/facebook/osquery/
 - https://github.com/facebook/osquery/
 - https://github.com/nicolargo/glances
 - https://github.com/nicolargo/glances
+- https://github.com/aristocratos/bpytop
 - https://github.com/Jahaja/psdash
 - https://github.com/Jahaja/psdash
 - https://github.com/ajenti/ajenti
 - https://github.com/ajenti/ajenti
 - https://github.com/home-assistant/home-assistant/
 - https://github.com/home-assistant/home-assistant/
@@ -545,16 +526,5 @@ Portings
 - Rust: https://github.com/rust-psutil/rust-psutil
 - Rust: https://github.com/rust-psutil/rust-psutil
 - Nim: https://github.com/johnscillieri/psutil-nim
 - Nim: https://github.com/johnscillieri/psutil-nim
 
 
-Security
-========
-
-To report a security vulnerability, please use the `Tidelift security
-contact`_.  Tidelift will coordinate the fix and disclosure.
-
-.. _`Giampaolo Rodola`: https://gmpy.dev/about
-.. _`donation`: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
-.. _Tidelift security contact: https://tidelift.com/security
-.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme
-
 
 
 
 

+ 1 - 1
contrib/python/psutil/py3/LICENSE

@@ -1,6 +1,6 @@
 BSD 3-Clause License
 BSD 3-Clause License
 
 
-Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
+Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use in source and binary forms, with or without modification,
 Redistribution and use in source and binary forms, with or without modification,

+ 56 - 65
contrib/python/psutil/py3/README.rst

@@ -1,6 +1,6 @@
-|  |downloads| |stars| |forks| |contributors| |coverage| |quality|
+|  |downloads| |stars| |forks| |contributors| |coverage|
 |  |version| |py-versions| |packages| |license|
 |  |version| |py-versions| |packages| |license|
-|  |github-actions| |appveyor| |doc| |twitter| |tidelift|
+|  |github-actions-wheels|  |github-actions-bsd| |appveyor| |doc| |twitter| |tidelift|
 
 
 .. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
 .. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
     :target: https://pepy.tech/project/psutil
     :target: https://pepy.tech/project/psutil
@@ -18,24 +18,24 @@
     :target: https://github.com/giampaolo/psutil/graphs/contributors
     :target: https://github.com/giampaolo/psutil/graphs/contributors
     :alt: Contributors
     :alt: Contributors
 
 
-.. |quality| image:: https://img.shields.io/codacy/grade/ce63e7f7f69d44b5b59682196e6fbfca.svg
-    :target: https://www.codacy.com/app/g-rodola/psutil?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=giampaolo/psutil&amp;utm_campaign=Badge_Grade
-    :alt: Code quality
+.. |github-actions-wheels| image:: https://img.shields.io/github/actions/workflow/status/giampaolo/psutil/.github/workflows/build.yml?label=Linux%2C%20macOS%2C%20Windows
+    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3Abuild
+    :alt: Linux, macOS, Windows
 
 
-.. |github-actions| image:: https://img.shields.io/github/workflow/status/giampaolo/psutil/CI?label=Linux%2C%20macOS%2C%20FreeBSD
-    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3ACI
-    :alt: Linux, macOS, Windows tests
+.. |github-actions-bsd| image:: https://img.shields.io/github/actions/workflow/status/giampaolo/psutil/.github/workflows/bsd.yml?label=FreeBSD,%20NetBSD,%20OpenBSD
+    :target: https://github.com/giampaolo/psutil/actions?query=workflow%3Absd-tests
+    :alt: FreeBSD, NetBSD, OpenBSD
 
 
-.. |appveyor| image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
+.. |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
     :target: https://ci.appveyor.com/project/giampaolo/psutil
-    :alt: Windows tests (Appveyor)
+    :alt: Windows (Appveyor)
 
 
 .. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
 .. |coverage| image:: https://coveralls.io/repos/github/giampaolo/psutil/badge.svg?branch=master
     :target: https://coveralls.io/github/giampaolo/psutil?branch=master
     :target: https://coveralls.io/github/giampaolo/psutil?branch=master
     :alt: Test coverage (coverall.io)
     :alt: Test coverage (coverall.io)
 
 
 .. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
 .. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
-    :target: http://psutil.readthedocs.io/en/latest/?badge=latest
+    :target: https://psutil.readthedocs.io/en/latest/
     :alt: Documentation Status
     :alt: Documentation Status
 
 
 .. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
 .. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
@@ -43,7 +43,6 @@
     :alt: Latest version
     :alt: Latest version
 
 
 .. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
 .. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
-    :target: https://pypi.org/project/psutil
     :alt: Supported Python versions
     :alt: Supported Python versions
 
 
 .. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
 .. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
@@ -99,7 +98,7 @@ psutil currently supports the following platforms:
 - **Sun Solaris**
 - **Sun Solaris**
 - **AIX**
 - **AIX**
 
 
-Supported Python versions are **2.6**, **2.7**, **3.4+** and
+Supported Python versions are **2.7**, **3.6+** and
 `PyPy <http://pypy.org/>`__.
 `PyPy <http://pypy.org/>`__.
 
 
 Funding
 Funding
@@ -110,7 +109,7 @@ immensely from some funding.
 Keeping up with bug reports and maintenance has become hardly sustainable for
 Keeping up with bug reports and maintenance has become hardly sustainable for
 me alone in terms of time.
 me alone in terms of time.
 If you're a company that's making significant use of psutil you can consider
 If you're a company that's making significant use of psutil you can consider
-becoming a sponsor via `GitHub <https://github.com/sponsors/giampaolo>`__,
+becoming a sponsor via `GitHub Sponsors <https://github.com/sponsors/giampaolo>`__,
 `Open Collective <https://opencollective.com/psutil>`__ or
 `Open Collective <https://opencollective.com/psutil>`__ or
 `PayPal <https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8>`__
 `PayPal <https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8>`__
 and have your logo displayed in here and psutil `doc <https://psutil.readthedocs.io>`__.
 and have your logo displayed in here and psutil `doc <https://psutil.readthedocs.io>`__.
@@ -122,7 +121,11 @@ Sponsors
 
 
     <div>
     <div>
         <a href="https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme">
         <a href="https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme">
-            <img src="https://github.com/giampaolo/psutil/raw/master/docs/_static/tidelift-logo.png" />
+            <img width="185" src="https://github.com/giampaolo/psutil/raw/master/docs/_static/tidelift-logo.svg" />
+        </a>
+        &nbsp;&nbsp
+        <a href="https://sansec.io/">
+            <img src="https://sansec.io/assets/images/logo.svg" />
         </a>
         </a>
     </div>
     </div>
     <sup><a href="https://github.com/sponsors/giampaolo">add your logo</a></sup>
     <sup><a href="https://github.com/sponsors/giampaolo">add your logo</a></sup>
@@ -130,16 +133,32 @@ Sponsors
 Supporters
 Supporters
 ==========
 ==========
 
 
-None yet.
-
 .. raw:: html
 .. raw:: html
 
 
+    <div>
+      <a href="https://github.com/dbwiddis"><img height="40" width="40" title="Daniel Widdis" src="https://avatars1.githubusercontent.com/u/9291703?s=88&amp;v=4" /></a>
+      <a href="https://github.com/aristocratos"><img height="40" width="40" title="aristocratos" src="https://avatars3.githubusercontent.com/u/59659483?s=96&amp;v=4" /></a>
+      <a href="https://github.com/cybersecgeek"><img height="40" width="40" title="cybersecgeek" src="https://avatars.githubusercontent.com/u/12847926?v=4" /></a>
+      <a href="https://github.com/scoutapm-sponsorships"><img height="40" width="40" title="scoutapm-sponsorships" src="https://avatars.githubusercontent.com/u/71095532?v=4" /></a>
+      <a href="https://opencollective.com/chenyoo-hao"><img height="40" width="40" title="Chenyoo Hao" src="https://images.opencollective.com/chenyoo-hao/avatar/40.png" /></a>
+      <a href="https://opencollective.com/alexey-vazhnov"><img height="40" width="40" title="Alexey Vazhnov" src="https://images.opencollective.com/alexey-vazhnov/daed334/avatar/40.png" /></a>
+      <a href="https://github.com/indeedeng"><img height="40" width="40" title="indeedeng" src="https://avatars.githubusercontent.com/u/2905043?s=200&v=4" /></a>
+      <a href="https://github.com/PySimpleGUI"><img height="40" width="40" title="PySimpleGUI" src="https://avatars.githubusercontent.com/u/46163555?v=4" /></a>
+      <a href="https://github.com/u93"><img height="40" width="40" title="Eugenio E Breijo" src="https://avatars.githubusercontent.com/u/16807302?v=4" /></a>
+      <a href="https://github.com/guilt"><img height="40" width="40" title="Karthik Kumar Viswanathan" src="https://avatars.githubusercontent.com/u/195178?v=4" /></a>
+      <a href="https://github.com/eallrich"><img height="40" width="40" title="Evan Allrich" src="https://avatars.githubusercontent.com/u/17393?v=4" /></a>
+      <a href="https://github.com/robusta-dev"><img height="40" width="40" title="Robusta" src="https://avatars.githubusercontent.com/u/82757710?s=200&v=4" /></a>
+      <a href="https://github.com/JeremyGrosser"><img height="40" width="40" title="JeremyGrosser" src="https://avatars.githubusercontent.com/u/2151?v=4" /></a>
+      <a href="https://github.com/getsentry"><img height="40" width="40" title="getsentry" src="https://avatars.githubusercontent.com/u/1396951?s=200&v=4" /></a>
+
+    </div>
     <sup><a href="https://github.com/sponsors/giampaolo">add your avatar</a></sup>
     <sup><a href="https://github.com/sponsors/giampaolo">add your avatar</a></sup>
 
 
+
 Contributing
 Contributing
 ============
 ============
 
 
-See `CONTRIBUTING.md <https://github.com/giampaolo/psutil/blob/master/CONTRIBUTING.md>`__ guidelines.
+See `contributing guidelines <https://github.com/giampaolo/psutil/blob/master/CONTRIBUTING.md>`__.
 
 
 Example usages
 Example usages
 ==============
 ==============
@@ -154,7 +173,7 @@ CPU
     >>> import psutil
     >>> import psutil
     >>>
     >>>
     >>> psutil.cpu_times()
     >>> psutil.cpu_times()
-    scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
+    scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, guest_nice=0.0)
     >>>
     >>>
     >>> for x in range(3):
     >>> for x in range(3):
     ...     psutil.cpu_percent(interval=1)
     ...     psutil.cpu_percent(interval=1)
@@ -209,7 +228,7 @@ Disks
 
 
     >>> psutil.disk_partitions()
     >>> psutil.disk_partitions()
     [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid', maxfile=255, maxpath=4096),
     [sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid', maxfile=255, maxpath=4096),
-     sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw', maxfile=255, maxpath=4096)]
+     sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext', opts='rw', maxfile=255, maxpath=4096)]
     >>>
     >>>
     >>> psutil.disk_usage('/')
     >>> psutil.disk_usage('/')
     sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
     sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
@@ -241,8 +260,8 @@ Network
                snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
                snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
     >>>
     >>>
     >>> psutil.net_if_stats()
     >>> psutil.net_if_stats()
-    {'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536),
-     'wlan0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500)}
+    {'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536, flags='up,loopback,running'),
+     'wlan0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500, flags='up,broadcast,running,multicast')}
     >>>
     >>>
 
 
 Sensors
 Sensors
@@ -295,39 +314,38 @@ Process management
     >>> p = psutil.Process(7055)
     >>> p = psutil.Process(7055)
     >>> p
     >>> p
     psutil.Process(pid=7055, name='python3', status='running', started='09:04:44')
     psutil.Process(pid=7055, name='python3', status='running', started='09:04:44')
+    >>> p.pid
+    7055
     >>> p.name()
     >>> p.name()
-    'python'
+    'python3'
     >>> p.exe()
     >>> p.exe()
-    '/usr/bin/python'
+    '/usr/bin/python3'
     >>> p.cwd()
     >>> p.cwd()
     '/home/giampaolo'
     '/home/giampaolo'
     >>> p.cmdline()
     >>> p.cmdline()
-    ['/usr/bin/python', 'main.py']
+    ['/usr/bin/python3', 'main.py']
     >>>
     >>>
-    >>> p.pid
-    7055
     >>> p.ppid()
     >>> p.ppid()
     7054
     7054
-    >>> p.children(recursive=True)
-    [psutil.Process(pid=29835, name='python3', status='sleeping', started='11:45:38'),
-     psutil.Process(pid=29836, name='python3', status='waking', started='11:43:39')]
-    >>>
     >>> p.parent()
     >>> p.parent()
     psutil.Process(pid=4699, name='bash', status='sleeping', started='09:06:44')
     psutil.Process(pid=4699, name='bash', status='sleeping', started='09:06:44')
     >>> p.parents()
     >>> p.parents()
     [psutil.Process(pid=4699, name='bash', started='09:06:44'),
     [psutil.Process(pid=4699, name='bash', started='09:06:44'),
      psutil.Process(pid=4689, name='gnome-terminal-server', status='sleeping', started='0:06:44'),
      psutil.Process(pid=4689, name='gnome-terminal-server', status='sleeping', started='0:06:44'),
      psutil.Process(pid=1, name='systemd', status='sleeping', started='05:56:55')]
      psutil.Process(pid=1, name='systemd', status='sleeping', started='05:56:55')]
+    >>> p.children(recursive=True)
+    [psutil.Process(pid=29835, name='python3', status='sleeping', started='11:45:38'),
+     psutil.Process(pid=29836, name='python3', status='waking', started='11:43:39')]
     >>>
     >>>
     >>> p.status()
     >>> p.status()
     'running'
     'running'
-    >>> p.username()
-    'giampaolo'
     >>> p.create_time()
     >>> p.create_time()
     1267551141.5019531
     1267551141.5019531
     >>> p.terminal()
     >>> p.terminal()
     '/dev/pts/0'
     '/dev/pts/0'
     >>>
     >>>
+    >>> p.username()
+    'giampaolo'
     >>> p.uids()
     >>> p.uids()
     puids(real=1000, effective=1000, saved=1000)
     puids(real=1000, effective=1000, saved=1000)
     >>> p.gids()
     >>> p.gids()
@@ -367,14 +385,14 @@ Process management
     [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
     [pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
      pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
      pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
     >>>
     >>>
-    >>> p.num_threads()
-    4
-    >>> p.num_fds()
-    8
     >>> p.threads()
     >>> p.threads()
     [pthread(id=5234, user_time=22.5, system_time=9.2891),
     [pthread(id=5234, user_time=22.5, system_time=9.2891),
      pthread(id=5237, user_time=0.0707, system_time=1.1)]
      pthread(id=5237, user_time=0.0707, system_time=1.1)]
     >>>
     >>>
+    >>> p.num_threads()
+    4
+    >>> p.num_fds()
+    8
     >>> p.num_ctx_switches()
     >>> p.num_ctx_switches()
     pctxsw(voluntary=78, involuntary=19)
     pctxsw(voluntary=78, involuntary=19)
     >>>
     >>>
@@ -441,23 +459,6 @@ Further process APIs
     >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
     >>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
     >>>
     >>>
 
 
-Popen wrapper:
-
-.. code-block:: python
-
-    >>> import psutil
-    >>> from subprocess import PIPE
-    >>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
-    >>> p.name()
-    'python'
-    >>> p.username()
-    'giampaolo'
-    >>> p.communicate()
-    ('hello\n', None)
-    >>> p.wait(timeout=2)
-    0
-    >>>
-
 Windows services
 Windows services
 ----------------
 ----------------
 
 
@@ -488,6 +489,7 @@ Here's some I find particularly interesting:
 - https://github.com/google/grr
 - https://github.com/google/grr
 - https://github.com/facebook/osquery/
 - https://github.com/facebook/osquery/
 - https://github.com/nicolargo/glances
 - https://github.com/nicolargo/glances
+- https://github.com/aristocratos/bpytop
 - https://github.com/Jahaja/psdash
 - https://github.com/Jahaja/psdash
 - https://github.com/ajenti/ajenti
 - https://github.com/ajenti/ajenti
 - https://github.com/home-assistant/home-assistant/
 - https://github.com/home-assistant/home-assistant/
@@ -499,14 +501,3 @@ Portings
 - C: https://github.com/hamon-in/cpslib
 - C: https://github.com/hamon-in/cpslib
 - Rust: https://github.com/rust-psutil/rust-psutil
 - Rust: https://github.com/rust-psutil/rust-psutil
 - Nim: https://github.com/johnscillieri/psutil-nim
 - Nim: https://github.com/johnscillieri/psutil-nim
-
-Security
-========
-
-To report a security vulnerability, please use the `Tidelift security
-contact`_.  Tidelift will coordinate the fix and disclosure.
-
-.. _`Giampaolo Rodola`: https://gmpy.dev/about
-.. _`donation`: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=A9ZS7PKKRM3S8
-.. _Tidelift security contact: https://tidelift.com/security
-.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme

Some files were not shown because too many files changed in this diff