增加JAVA环境配置
增加VC运行库安装
增加检测升级功能
更新PY模块
This commit is contained in:
shileiye 2022-01-05 03:12:34 +08:00
parent f3ce17779b
commit 3ece9fa803
55 changed files with 827 additions and 1776 deletions

2
.idea/misc.xml generated
View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (onekey)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

2
.idea/onekey.iml generated
View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
dist/config.ini vendored
View File

@ -52,7 +52,7 @@ gm_url = http://${domain_name}:${web_port}/gm
gm_code = 123456
gm_user = test
gm_pass = test
game_back = http://${domain_name}:${web_port}/gameback
game_url = http://${domain_name}:${web_port}/gameback
game_code = 123456
game_user = test
game_pass = test
@ -79,11 +79,11 @@ android_name_file = ${android_path}game\
tmp_android_name = ${android_path}game_tmp.apk
new_android_name = ${android_path}game_signed.apk
[pc]
[PC]
pc_path = ${GAME:client_path}pc\
pc_name = ${pc_path}pc\bin.exe
[ios]
[IOS]
ios_path = ${GAME:client_path}ios\
ios_name = ${android_path}game.ipa
@ -92,6 +92,8 @@ apktool_path = ${GAME:tool_path}apktool\
heidisql_path = ${GAME:tool_path}HeidiSQL\heidisql.exe
notepad3_path = ${GAME:tool_path}Notepad3\Notepad3.exe
composer_path = ${GAME:tool_path}Composer\
java_path = ${GAME:tool_path}jdk-8\
msvbcrt_path = ${GAME:tool_path}Other\MSVBCRT.exe
[OTHER]
about = shileiye

BIN
dist/main.exe vendored

Binary file not shown.

View File

@ -5,7 +5,7 @@ block_cipher = None
a = Analysis(['main.py'],
pathex=['D:\\soft\\Python\\Python39\\Lib\\site-packages', 'D:\\soft\\Python\\Python39\\Lib', 'D:\\soft\\Python\\Python39\\Lib\\site-packages\\PyQt5\\Qt\\bin', 'D:\\Code\\python\\onekey\\venv\\Lib\\site-packages', ''],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],

View File

@ -2,5 +2,5 @@
### 打包命令
```python
pyinstaller -F -w -p D:\soft\Python\Python39\Lib\site-packages;D:\soft\Python\Python39\Lib;D:\soft\Python\Python39\Lib\site-packages\PyQt5\Qt\bin;D:\Code\python\onekey\venv\Lib\site-packages; main.py
pyinstaller -F -w -p D:\soft\Python\Python39\Lib\site-packages;D:\soft\Python\Python39\Lib;D:\soft\Python\Python39\Lib\site-packages\PyQt5\Qt\bin;D:\Code\python\onekey\venv\Lib\site-packages; .\main.py
```

View File

@ -3,6 +3,7 @@ import os
import re
import importlib
import warnings
import contextlib
is_pypy = '__pypy__' in sys.builtin_module_names
@ -52,9 +53,8 @@ def ensure_local_distutils():
# With the DistutilsMetaFinder in place,
# perform an import to cause distutils to be
# loaded from setuptools._distutils. Ref #2906.
add_shim()
importlib.import_module('distutils')
remove_shim()
with shim():
importlib.import_module('distutils')
# check that submodules load as expected
core = importlib.import_module('distutils.core')
@ -86,10 +86,23 @@ class DistutilsMetaFinder:
import importlib.abc
import importlib.util
try:
mod = importlib.import_module('setuptools._distutils')
except Exception:
# There are a couple of cases where setuptools._distutils
# may not be present:
# - An older Setuptools without a local distutils is
# taking precedence. Ref #2957.
# - Path manipulation during sitecustomize removes
# setuptools from the path but only after the hook
# has been loaded. Ref #2980.
# In either case, fall back to stdlib behavior.
return
class DistutilsLoader(importlib.abc.Loader):
def create_module(self, spec):
return importlib.import_module('setuptools._distutils')
return mod
def exec_module(self, module):
pass
@ -130,6 +143,19 @@ DISTUTILS_FINDER = DistutilsMetaFinder()
def add_shim():
DISTUTILS_FINDER in sys.meta_path or insert_shim()
@contextlib.contextmanager
def shim():
insert_shim()
try:
yield
finally:
remove_shim()
def insert_shim():
sys.meta_path.insert(0, DISTUTILS_FINDER)

View File

@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola'
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the psutil authors nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,560 +0,0 @@
Metadata-Version: 2.1
Name: psutil
Version: 5.8.0
Summary: Cross-platform lib for process and system monitoring in Python.
Home-page: https://github.com/giampaolo/psutil
Author: Giampaolo Rodola
Author-email: g.rodola@gmail.com
License: BSD
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
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Environment :: Win32 (MS Windows)
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
Classifier: Operating System :: Microsoft :: Windows :: Windows 7
Classifier: Operating System :: Microsoft :: Windows :: Windows 8
Classifier: Operating System :: Microsoft :: Windows :: Windows 8.1
Classifier: Operating System :: Microsoft :: Windows :: Windows Server 2003
Classifier: Operating System :: Microsoft :: Windows :: Windows Server 2008
Classifier: Operating System :: Microsoft :: Windows :: Windows Vista
Classifier: Operating System :: Microsoft
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: AIX
Classifier: Operating System :: POSIX :: BSD :: FreeBSD
Classifier: Operating System :: POSIX :: BSD :: NetBSD
Classifier: Operating System :: POSIX :: BSD :: OpenBSD
Classifier: Operating System :: POSIX :: BSD
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.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Benchmark
Classifier: Topic :: System :: Hardware :: Hardware Drivers
Classifier: Topic :: System :: Hardware
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: System :: Networking :: Monitoring :: Hardware Watchdog
Classifier: Topic :: System :: Networking :: Monitoring
Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Operating System
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
Description-Content-Type: text/x-rst
Provides-Extra: test
Requires-Dist: ipaddress ; (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: pywin32 ; (sys_platform == "win32") and extra == 'test'
Requires-Dist: wmi ; (sys_platform == "win32") and extra == 'test'
| |downloads| |stars| |forks| |contributors| |coverage| |quality|
| |version| |py-versions| |packages| |license|
| |github-actions| |appveyor| |doc| |twitter| |tidelift|
.. |downloads| image:: https://img.shields.io/pypi/dm/psutil.svg
:target: https://pepy.tech/project/psutil
:alt: Downloads
.. |stars| image:: https://img.shields.io/github/stars/giampaolo/psutil.svg
:target: https://github.com/giampaolo/psutil/stargazers
:alt: Github stars
.. |forks| image:: https://img.shields.io/github/forks/giampaolo/psutil.svg
:target: https://github.com/giampaolo/psutil/network/members
:alt: Github forks
.. |contributors| image:: https://img.shields.io/github/contributors/giampaolo/psutil.svg
:target: https://github.com/giampaolo/psutil/graphs/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| 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
.. |appveyor| image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
:target: https://ci.appveyor.com/project/giampaolo/psutil
:alt: Windows tests (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)
.. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
:target: http://psutil.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
:target: https://pypi.org/project/psutil
:alt: Latest version
.. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
:target: https://pypi.org/project/psutil
:alt: Supported Python versions
.. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
:target: https://repology.org/metapackage/python:psutil/versions
:alt: Binary packages
.. |license| image:: https://img.shields.io/pypi/l/psutil.svg
:target: https://github.com/giampaolo/psutil/blob/master/LICENSE
:alt: License
.. |twitter| image:: https://img.shields.io/twitter/follow/grodola.svg?label=follow&style=flat&logo=twitter&logoColor=4FADFF
:target: https://twitter.com/grodola
:alt: Twitter Follow
.. |tidelift| image:: https://tidelift.com/badges/github/giampaolo/psutil?style=flat
:target: https://tidelift.com/subscription/pkg/pypi-psutil?utm_source=pypi-psutil&utm_medium=referral&utm_campaign=readme
:alt: Tidelift
-----
Quick links
===========
- `Home page <https://github.com/giampaolo/psutil>`_
- `Install <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
- `Documentation <http://psutil.readthedocs.io>`_
- `Download <https://pypi.org/project/psutil/#files>`_
- `Forum <http://groups.google.com/group/psutil/topics>`_
- `StackOverflow <https://stackoverflow.com/questions/tagged/psutil>`_
- `Blog <https://gmpy.dev/tags/psutil>`_
- `What's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst>`_
Summary
=======
psutil (process and system utilities) is a cross-platform library for
retrieving information on **running processes** and **system utilization**
(CPU, memory, disks, network, sensors) in Python.
It is useful mainly for **system monitoring**, **profiling and limiting process
resources** and **management of running processes**.
It implements many functionalities offered by classic UNIX command line tools
such as *ps, top, iotop, lsof, netstat, ifconfig, free* and others.
psutil currently supports the following platforms:
- **Linux**
- **Windows**
- **macOS**
- **FreeBSD, OpenBSD**, **NetBSD**
- **Sun Solaris**
- **AIX**
Supported Python versions are **2.6**, **2.7**, **3.4+** and
`PyPy <http://pypy.org/>`__.
Funding
=======
While psutil is free software and will always be, the project would benefit
immensely from some funding.
Keeping up with bug reports and maintenance has become hardly sustainable for
me alone in terms of time.
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>`__,
`Open Collective <https://opencollective.com/psutil>`__ or
`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>`__.
Sponsors
========
.. image:: https://github.com/giampaolo/psutil/raw/master/docs/_static/tidelift-logo.png
:width: 200
:alt: Alternative text
`Add your logo <https://github.com/sponsors/giampaolo>`__.
Example usages
==============
This represents pretty much the whole psutil API.
CPU
---
.. code-block:: python
>>> import psutil
>>>
>>> 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)
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1)
...
4.0
5.9
3.8
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1, percpu=True)
...
[4.0, 6.9, 3.7, 9.2]
[7.0, 8.5, 2.4, 2.1]
[1.2, 9.0, 9.9, 7.2]
>>>
>>> for x in range(3):
... psutil.cpu_times_percent(interval=1, percpu=False)
...
scputimes(user=1.5, nice=0.0, system=0.5, idle=96.5, iowait=1.5, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=1.0, nice=0.0, system=0.0, idle=99.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=2.0, nice=0.0, system=0.0, idle=98.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
>>>
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
>>>
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
>>>
>>> psutil.cpu_freq()
scpufreq(current=931.42925, min=800.0, max=3500.0)
>>>
>>> psutil.getloadavg() # also on Windows (emulated)
(3.14, 3.89, 4.67)
Memory
------
.. code-block:: python
>>> psutil.virtual_memory()
svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304)
>>> psutil.swap_memory()
sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
>>>
Disks
-----
.. code-block:: python
>>> psutil.disk_partitions()
[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)]
>>>
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>>
>>> psutil.disk_io_counters(perdisk=False)
sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568, read_merged_count=619166, write_merged_count=812396, busy_time=4523412)
>>>
Network
-------
.. code-block:: python
>>> psutil.net_io_counters(pernic=True)
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>>
>>> psutil.net_connections(kind='tcp')
[sconn(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', pid=1254),
sconn(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', pid=2987),
...]
>>>
>>> psutil.net_if_addrs()
{'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
'wlan0': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, 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()
{'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)}
>>>
Sensors
-------
.. code-block:: python
>>> import psutil
>>> psutil.sensors_temperatures()
{'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0)]}
>>>
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
>>>
>>> psutil.sensors_battery()
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>>
Other system info
-----------------
.. code-block:: python
>>> import psutil
>>> psutil.users()
[suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
>>>
>>> psutil.boot_time()
1365519115.0
>>>
Process management
------------------
.. code-block:: python
>>> import psutil
>>> psutil.pids()
[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, 268, 1215,
1216, 1220, 1221, 1243, 1244, 1301, 1601, 2237, 2355, 2637, 2774, 3932,
4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4263, 4282, 4306, 4311,
4312, 4313, 4314, 4337, 4339, 4357, 4358, 4363, 4383, 4395, 4408, 4433,
4443, 4445, 4446, 5167, 5234, 5235, 5252, 5318, 5424, 5644, 6987, 7054,
7055, 7071]
>>>
>>> p = psutil.Process(7055)
>>> p
psutil.Process(pid=7055, name='python3', status='running', started='09:04:44')
>>> p.name()
'python'
>>> p.exe()
'/usr/bin/python'
>>> p.cwd()
'/home/giampaolo'
>>> p.cmdline()
['/usr/bin/python', 'main.py']
>>>
>>> p.pid
7055
>>> p.ppid()
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()
psutil.Process(pid=4699, name='bash', status='sleeping', started='09:06:44')
>>> p.parents()
[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=1, name='systemd', status='sleeping', started='05:56:55')]
>>>
>>> p.status()
'running'
>>> p.username()
'giampaolo'
>>> p.create_time()
1267551141.5019531
>>> p.terminal()
'/dev/pts/0'
>>>
>>> p.uids()
puids(real=1000, effective=1000, saved=1000)
>>> p.gids()
pgids(real=1000, effective=1000, saved=1000)
>>>
>>> p.cpu_times()
pcputimes(user=1.02, system=0.31, children_user=0.32, children_system=0.1, iowait=0.0)
>>> p.cpu_percent(interval=1.0)
12.1
>>> p.cpu_affinity()
[0, 1, 2, 3]
>>> p.cpu_affinity([0, 1]) # set
>>> p.cpu_num()
1
>>>
>>> p.memory_info()
pmem(rss=10915840, vms=67608576, shared=3313664, text=2310144, lib=0, data=7262208, dirty=0)
>>> p.memory_full_info() # "real" USS memory usage (Linux, macOS, Win only)
pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
>>> p.memory_percent()
0.7823
>>> p.memory_maps()
[pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
pmmap_grouped(path='[heap]', rss=32768, size=139264, pss=32768, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=32768, referenced=32768, anonymous=32768, swap=0),
pmmap_grouped(path='[stack]', rss=2465792, size=2494464, pss=2465792, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=2465792, referenced=2277376, anonymous=2465792, swap=0),
...]
>>>
>>> p.io_counters()
pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632, read_chars=456232, write_chars=517543)
>>>
>>> p.open_files()
[popenfile(path='/home/giampaolo/monit.py', fd=3, position=0, mode='r', flags=32768),
popenfile(path='/var/log/monit.log', fd=4, position=235542, mode='a', flags=33793)]
>>>
>>> p.connections(kind='tcp')
[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')]
>>>
>>> p.num_threads()
4
>>> p.num_fds()
8
>>> p.threads()
[pthread(id=5234, user_time=22.5, system_time=9.2891),
pthread(id=5237, user_time=0.0707, system_time=1.1)]
>>>
>>> p.num_ctx_switches()
pctxsw(voluntary=78, involuntary=19)
>>>
>>> p.nice()
0
>>> p.nice(10) # set
>>>
>>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # IO priority (Win and Linux only)
>>> p.ionice()
pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
>>>
>>> p.rlimit(psutil.RLIMIT_NOFILE, (5, 5)) # set resource limits (Linux only)
>>> p.rlimit(psutil.RLIMIT_NOFILE)
(5, 5)
>>>
>>> p.environ()
{'LC_PAPER': 'it_IT.UTF-8', 'SHELL': '/bin/bash', 'GREP_OPTIONS': '--color=auto',
'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg',
...}
>>>
>>> p.as_dict()
{'status': 'running', 'num_ctx_switches': pctxsw(voluntary=63, involuntary=1), 'pid': 5457, ...}
>>> p.is_running()
True
>>> p.suspend()
>>> p.resume()
>>>
>>> p.terminate()
>>> p.kill()
>>> p.wait(timeout=3)
<Exitcode.EX_OK: 0>
>>>
>>> psutil.test()
USER PID %CPU %MEM VSZ RSS TTY START TIME COMMAND
root 1 0.0 0.0 24584 2240 Jun17 00:00 init
root 2 0.0 0.0 0 0 Jun17 00:00 kthreadd
...
giampaolo 31475 0.0 0.0 20760 3024 /dev/pts/0 Jun19 00:00 python2.4
giampaolo 31721 0.0 2.2 773060 181896 00:04 10:30 chrome
root 31763 0.0 0.0 0 0 00:05 00:00 kworker/0:1
>>>
Further process APIs
--------------------
.. code-block:: python
>>> import psutil
>>> for proc in psutil.process_iter(['pid', 'name']):
... print(proc.info)
...
{'pid': 1, 'name': 'systemd'}
{'pid': 2, 'name': 'kthreadd'}
{'pid': 3, 'name': 'ksoftirqd/0'}
...
>>>
>>> psutil.pid_exists(3)
True
>>>
>>> def on_terminate(proc):
... print("process {} terminated".format(proc))
...
>>> # waits for multiple processes to 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
----------------
.. code-block:: python
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
Projects using psutil
=====================
Here's some I find particularly interesting:
- https://github.com/google/grr
- https://github.com/facebook/osquery/
- https://github.com/nicolargo/glances
- https://github.com/Jahaja/psdash
- https://github.com/ajenti/ajenti
- https://github.com/home-assistant/home-assistant/
Portings
========
- Go: https://github.com/shirou/gopsutil
- C: https://github.com/hamon-in/cpslib
- Rust: https://github.com/rust-psutil/rust-psutil
- 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

View File

@ -1,64 +0,0 @@
psutil-5.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
psutil-5.8.0.dist-info/LICENSE,sha256=JMEphFAMqgf_3OGe68BjlsXm0kS1c7xsQ49KbvjlbBs,1549
psutil-5.8.0.dist-info/METADATA,sha256=Bphj_aWaN0I3HJ9grSaLCwTHYKWVx9Gh3lV9WQvyBeY,22626
psutil-5.8.0.dist-info/RECORD,,
psutil-5.8.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
psutil-5.8.0.dist-info/WHEEL,sha256=jr7ubY0Lkz_yXH9FfFe9PTtLhGOsf62dZkNvTYrJINE,100
psutil-5.8.0.dist-info/top_level.txt,sha256=gCNhn57wzksDjSAISmgMJ0aiXzQulk0GJhb2-BAyYgw,7
psutil/__init__.py,sha256=kBgynYzuxNXqFVpCNdTr0RqSmR-TqcHraDedB2ycPak,86749
psutil/__pycache__/__init__.cpython-39.pyc,,
psutil/__pycache__/_common.cpython-39.pyc,,
psutil/__pycache__/_compat.cpython-39.pyc,,
psutil/__pycache__/_psaix.cpython-39.pyc,,
psutil/__pycache__/_psbsd.cpython-39.pyc,,
psutil/__pycache__/_pslinux.cpython-39.pyc,,
psutil/__pycache__/_psosx.cpython-39.pyc,,
psutil/__pycache__/_psposix.cpython-39.pyc,,
psutil/__pycache__/_pssunos.cpython-39.pyc,,
psutil/__pycache__/_pswindows.cpython-39.pyc,,
psutil/_common.py,sha256=Iej9ua0_H4c-lgmKx3xBWDHRP-Pb4szU-QNb8cN6d8M,26218
psutil/_compat.py,sha256=wiGTaLFqCNUrCFvFfRXp4Y3gn5FiqzLUFVTCp6GA3tY,14474
psutil/_psaix.py,sha256=0tYwysbZZOZshzh5Jlrmgh7yZBj9mARdKpfIEtSB2CM,18555
psutil/_psbsd.py,sha256=wciWlLRNUfukUjld8xO-6MpO5D0q-3WxFQbeC9OKmlw,31069
psutil/_pslinux.py,sha256=5YfU-zmscLdqxrm481q3_PFyrY8z0iQnRHjbLmY0nJ0,82101
psutil/_psosx.py,sha256=SLUzYazQXOdIJ0yZjm-UqlDF-hJHy8yaDR4sljDeMCc,17494
psutil/_psposix.py,sha256=IcXJTdU6osTJwjB2uDohCLnuGPl5BGQYD6vDg0sOJ8c,8045
psutil/_pssunos.py,sha256=u3wVhSnBLtQFtCfhND1rxD2KHWB4zKaNIpmeCG5z5Mc,25495
psutil/_psutil_windows.cp39-win_amd64.pyd,sha256=959nMupaNnUxLvS5UGvtjhWqLZxyLTDQyWJ0Z1qp3Gg,76288
psutil/_pswindows.py,sha256=JyffHx0PmRJY-4FnL0eevPdmrnB7d96AuV6mTvUavPc,36841
psutil/tests/__init__.py,sha256=6SFK_zga_qUnJOnKF6AIWasKGIYwd6XXqXg3KxJiX1Y,57568
psutil/tests/__main__.py,sha256=bBfMPu_gPzyiA4gfAFSZLk7LyLSPTUIHQFU1kFcj_Ok,291
psutil/tests/__pycache__/__init__.cpython-39.pyc,,
psutil/tests/__pycache__/__main__.cpython-39.pyc,,
psutil/tests/__pycache__/runner.cpython-39.pyc,,
psutil/tests/__pycache__/test_aix.cpython-39.pyc,,
psutil/tests/__pycache__/test_bsd.cpython-39.pyc,,
psutil/tests/__pycache__/test_connections.cpython-39.pyc,,
psutil/tests/__pycache__/test_contracts.cpython-39.pyc,,
psutil/tests/__pycache__/test_linux.cpython-39.pyc,,
psutil/tests/__pycache__/test_memleaks.cpython-39.pyc,,
psutil/tests/__pycache__/test_misc.cpython-39.pyc,,
psutil/tests/__pycache__/test_osx.cpython-39.pyc,,
psutil/tests/__pycache__/test_posix.cpython-39.pyc,,
psutil/tests/__pycache__/test_process.cpython-39.pyc,,
psutil/tests/__pycache__/test_sunos.cpython-39.pyc,,
psutil/tests/__pycache__/test_system.cpython-39.pyc,,
psutil/tests/__pycache__/test_testutils.cpython-39.pyc,,
psutil/tests/__pycache__/test_unicode.cpython-39.pyc,,
psutil/tests/__pycache__/test_windows.cpython-39.pyc,,
psutil/tests/runner.py,sha256=aWiBnzMuH42dGAeofRuOgmDPcyKI9Yr0u1PI4HLDPOE,11332
psutil/tests/test_aix.py,sha256=r78PBazMdlagip3tnWdZIS6HxQNTirE9c8GWqPkcKTw,4526
psutil/tests/test_bsd.py,sha256=3tTFVIkmXZFkHyaFydsmJH_-lsAEk1HuAAi3-LgBGJM,20695
psutil/tests/test_connections.py,sha256=-4pjxtJGWobjidWEkuEFIS7SHA5eXvEcrj2MG51Fqb8,21434
psutil/tests/test_contracts.py,sha256=ID5_K_GwlQLYJZdl3BbZcV-ZcnptwlfNx42mM7a58Kk,27097
psutil/tests/test_linux.py,sha256=jEiPD5gSCrUiFOvau-sRncPO3StetoIlxPJcYzarTas,89802
psutil/tests/test_memleaks.py,sha256=tDP4poPQeCdXcD5DayQ0uLb71Yy_bk0QlIYNdBl-ems,14796
psutil/tests/test_misc.py,sha256=KyB__5fP8Lwt57ZirpFkWtPa3psX9S5D9zJQIR2dFl8,28584
psutil/tests/test_osx.py,sha256=PAQf49HUiN8n0DKmUWCXCaEV-2h20m1jeuLX85pxsg8,7550
psutil/tests/test_posix.py,sha256=qN0W3r760F5c6dGFTYKVsyNjG16wX_fpVs2k1K8CqSE,15143
psutil/tests/test_process.py,sha256=bCcCqfc2JxKI9PvuW7mpFY599rxoMZKzkxDRT-Oms0k,59703
psutil/tests/test_sunos.py,sha256=tosB6-4boM6ZlIVaeJZh6YbBY8gVGRm0YIXgb_Z69GU,1351
psutil/tests/test_system.py,sha256=dT0v3X4ZZl1RO0ARYU_AkvNAzsGt21CIIQ9-_VvbQa4,35596
psutil/tests/test_testutils.py,sha256=A9nneh29Z9rN7wM4ekBg4QdXL5diD4mCUI1Uw6B5jec,14420
psutil/tests/test_unicode.py,sha256=cPwy2YUW8XV0U9oIsMCBFhS2SMu5htdFD3DTimmRtic,12459
psutil/tests/test_windows.py,sha256=dkEkbFEUaI2L5syFte9vok42n_r_DsTjbFu6IZ6SzvQ,32589

View File

@ -1,5 +0,0 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: false
Tag: cp39-cp39-win_amd64

View File

@ -21,6 +21,7 @@ Works with Python versions from 2.6 to 3.4+.
"""
from __future__ import division
import collections
import contextlib
import datetime
@ -31,24 +32,16 @@ import subprocess
import sys
import threading
import time
try:
import pwd
except ImportError:
pwd = None
from . import _common
from ._common import AccessDenied
from ._common import Error
from ._common import memoize_when_activated
from ._common import NoSuchProcess
from ._common import TimeoutExpired
from ._common import wrap_numbers as _wrap_numbers
from ._common import ZombieProcess
from ._compat import long
from ._compat import PermissionError
from ._compat import ProcessLookupError
from ._compat import PY3 as _PY3
from ._common import AIX
from ._common import BSD
from ._common import CONN_CLOSE
from ._common import CONN_CLOSE_WAIT
from ._common import CONN_CLOSING
@ -61,9 +54,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 LINUX
from ._common import MACOS
from ._common import NETBSD # NOQA
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 OSX # deprecated alias
from ._common import POSIX # NOQA
from ._common import POWER_TIME_UNKNOWN
from ._common import POWER_TIME_UNLIMITED
from ._common import STATUS_DEAD
@ -78,18 +78,21 @@ from ._common import STATUS_TRACING_STOP
from ._common import STATUS_WAITING
from ._common import STATUS_WAKING
from ._common import STATUS_ZOMBIE
from ._common import AIX
from ._common import BSD
from ._common import FREEBSD # NOQA
from ._common import LINUX
from ._common import MACOS
from ._common import NETBSD # NOQA
from ._common import OPENBSD # NOQA
from ._common import OSX # deprecated alias
from ._common import POSIX # NOQA
from ._common import SUNOS
from ._common import WINDOWS
from ._common import AccessDenied
from ._common import Error
from ._common import NoSuchProcess
from ._common import TimeoutExpired
from ._common import ZombieProcess
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:
# This is public API and it will be retrieved from _pslinux.py
@ -97,7 +100,6 @@ 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
@ -112,10 +114,10 @@ elif WINDOWS:
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_VERYLOW # NOQA
from ._pswindows import IOPRIO_HIGH # NOQA
from ._pswindows import IOPRIO_LOW # NOQA
from ._pswindows import IOPRIO_NORMAL # NOQA
from ._pswindows import IOPRIO_HIGH # NOQA
from ._pswindows import IOPRIO_VERYLOW # NOQA
elif MACOS:
from . import _psosx as _psplatform
@ -209,7 +211,7 @@ if hasattr(_psplatform.Process, "rlimit"):
AF_LINK = _psplatform.AF_LINK
__author__ = "Giampaolo Rodola'"
__version__ = "5.8.0"
__version__ = "5.9.0"
version_info = tuple([int(num) for num in __version__.split('.')])
_timer = getattr(time, 'monotonic', time.time)
@ -268,7 +270,11 @@ def _assert_pid_not_reused(fun):
@functools.wraps(fun)
def wrapper(self, *args, **kwargs):
if not self.is_running():
raise NoSuchProcess(self.pid, self._name)
if self._pid_reused:
msg = "process no longer exists and its PID has been reused"
else:
msg = None
raise NoSuchProcess(self.pid, self._name, msg=msg)
return fun(self, *args, **kwargs)
return wrapper
@ -339,6 +345,7 @@ class Process(object):
self._exe = None
self._create_time = None
self._gone = False
self._pid_reused = False
self._hash = None
self._lock = threading.RLock()
# used for caching on Windows only (on POSIX ppid may change)
@ -363,8 +370,7 @@ class Process(object):
pass
except NoSuchProcess:
if not _ignore_nsp:
msg = 'no process found with pid %s' % pid
raise NoSuchProcess(pid, None, msg)
raise NoSuchProcess(pid, msg='process PID not found')
else:
self._gone = True
# This pair is supposed to indentify a Process instance
@ -570,7 +576,7 @@ class Process(object):
It also checks if PID has been reused by another process in
which case return False.
"""
if self._gone:
if self._gone or self._pid_reused:
return False
try:
# Checking if PID is alive is not enough as the PID might
@ -578,7 +584,8 @@ class Process(object):
# verify process identity.
# Process identity / uniqueness over time is guaranteed by
# (PID + creation time) and that is verified in __eq__.
return self == Process(self.pid)
self._pid_reused = self != Process(self.pid)
return not self._pid_reused
except ZombieProcess:
# We should never get here as it's already handled in
# Process.__init__; here just for extra safety.
@ -1386,7 +1393,6 @@ def pid_exists(pid):
_pmap = {}
_lock = threading.Lock()
def process_iter(attrs=None, ad_value=None):
@ -1410,58 +1416,59 @@ def process_iter(attrs=None, ad_value=None):
If *attrs* is an empty list it will retrieve all process info
(slow).
"""
global _pmap
def add(pid):
proc = Process(pid)
if attrs is not None:
proc.info = proc.as_dict(attrs=attrs, ad_value=ad_value)
with _lock:
_pmap[proc.pid] = proc
pmap[proc.pid] = proc
return proc
def remove(pid):
with _lock:
_pmap.pop(pid, None)
pmap.pop(pid, None)
pmap = _pmap.copy()
a = set(pids())
b = set(_pmap.keys())
b = set(pmap.keys())
new_pids = a - b
gone_pids = b - a
for pid in gone_pids:
remove(pid)
with _lock:
ls = sorted(list(_pmap.items()) +
list(dict.fromkeys(new_pids).items()))
for pid, proc in ls:
try:
if proc is None: # new process
yield add(pid)
else:
# use is_running() to check whether PID has been reused by
# another process in which case yield a new Process instance
if proc.is_running():
if attrs is not None:
proc.info = proc.as_dict(
attrs=attrs, ad_value=ad_value)
yield proc
else:
try:
ls = sorted(list(pmap.items()) + list(dict.fromkeys(new_pids).items()))
for pid, proc in ls:
try:
if proc is None: # new process
yield add(pid)
except NoSuchProcess:
remove(pid)
except AccessDenied:
# Process creation time can't be determined hence there's
# no way to tell whether the pid of the cached process
# has been reused. Just return the cached version.
if proc is None and pid in _pmap:
try:
yield _pmap[pid]
except KeyError:
# If we get here it is likely that 2 threads were
# using process_iter().
pass
else:
raise
else:
# use is_running() to check whether PID has been
# reused by another process in which case yield a
# new Process instance
if proc.is_running():
if attrs is not None:
proc.info = proc.as_dict(
attrs=attrs, ad_value=ad_value)
yield proc
else:
yield add(pid)
except NoSuchProcess:
remove(pid)
except AccessDenied:
# Process creation time can't be determined hence there's
# no way to tell whether the pid of the cached process
# has been reused. Just return the cached version.
if proc is None and pid in pmap:
try:
yield pmap[pid]
except KeyError:
# If we get here it is likely that 2 threads were
# using process_iter().
pass
else:
raise
finally:
_pmap = pmap
def wait_procs(procs, timeout=None, callback=None):
@ -1505,6 +1512,8 @@ def wait_procs(procs, timeout=None, callback=None):
returncode = proc.wait(timeout=timeout)
except TimeoutExpired:
pass
except _SubprocessTimeoutExpired:
pass
else:
if returncode is not None or not proc.is_running():
# Set new Process instance attribute.
@ -1575,7 +1584,7 @@ def cpu_count(logical=True):
if logical:
ret = _psplatform.cpu_count_logical()
else:
ret = _psplatform.cpu_count_physical()
ret = _psplatform.cpu_count_cores()
if ret is not None and ret < 1:
ret = None
return ret
@ -1721,7 +1730,6 @@ def cpu_percent(interval=None, percpu=False):
def calculate(t1, t2):
times_delta = _cpu_times_deltas(t1, t2)
all_delta = _cpu_tot_time(times_delta)
busy_delta = _cpu_busy_time(times_delta)
@ -1849,7 +1857,7 @@ def cpu_stats():
if hasattr(_psplatform, "cpu_freq"):
def cpu_freq(percpu=False):
"""Return CPU frequency as a nameduple including current,
"""Return CPU frequency as a namedtuple including current,
min and max frequency expressed in Mhz.
If *percpu* is True and the system supports per-cpu frequency
@ -2338,6 +2346,15 @@ if WINDOWS:
# =====================================================================
def _set_debug(value):
"""Enable or disable PSUTIL_DEBUG option, which prints debugging
messages to stderr.
"""
import psutil._common
psutil._common.PSUTIL_DEBUG = bool(value)
_psplatform.cext.set_debug(bool(value))
def test(): # pragma: no cover
from ._common import bytes2human
from ._compat import get_terminal_size

View File

@ -7,8 +7,10 @@
# Note: this module is imported by setup.py so it should not import
# psutil or third-party modules.
from __future__ import division, print_function
from __future__ import division
from __future__ import print_function
import collections
import contextlib
import errno
import functools
@ -18,12 +20,12 @@ import stat
import sys
import threading
import warnings
from collections import defaultdict
from collections import namedtuple
from socket import AF_INET
from socket import SOCK_DGRAM
from socket import SOCK_STREAM
try:
from socket import AF_INET6
except ImportError:
@ -41,6 +43,7 @@ else:
# can't take it from _common.py as this script is imported by setup.py
PY3 = sys.version_info[0] == 3
PSUTIL_DEBUG = bool(os.getenv('PSUTIL_DEBUG', 0))
__all__ = [
# OS constants
@ -83,7 +86,7 @@ WINDOWS = os.name == "nt"
LINUX = sys.platform.startswith("linux")
MACOS = sys.platform.startswith("darwin")
OSX = MACOS # deprecated alias
FREEBSD = sys.platform.startswith("freebsd")
FREEBSD = sys.platform.startswith(("freebsd", "midnightbsd"))
OPENBSD = sys.platform.startswith("openbsd")
NETBSD = sys.platform.startswith("netbsd")
BSD = FREEBSD or OPENBSD or NETBSD
@ -275,15 +278,32 @@ class Error(Exception):
"""
__module__ = 'psutil'
def __init__(self, msg=""):
Exception.__init__(self, msg)
self.msg = msg
def _infodict(self, attrs):
try:
info = collections.OrderedDict()
except AttributeError: # pragma: no cover
info = {} # Python 2.6
for name in attrs:
value = getattr(self, name, None)
if value:
info[name] = value
return info
def __str__(self):
# 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()])
else:
details = None
return " ".join([x for x in (self.msg, details) if x])
def __repr__(self):
ret = "psutil.%s %s" % (self.__class__.__name__, self.msg)
return ret.strip()
__str__ = __repr__
# 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)
class NoSuchProcess(Error):
@ -293,16 +313,10 @@ class NoSuchProcess(Error):
__module__ = 'psutil'
def __init__(self, pid, name=None, msg=None):
Error.__init__(self, msg)
Error.__init__(self)
self.pid = pid
self.name = name
self.msg = msg
if msg is None:
if name:
details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
else:
details = "(pid=%s)" % self.pid
self.msg = "process no longer exists " + details
self.msg = msg or "process no longer exists"
class ZombieProcess(NoSuchProcess):
@ -315,19 +329,9 @@ class ZombieProcess(NoSuchProcess):
__module__ = 'psutil'
def __init__(self, pid, name=None, ppid=None, msg=None):
NoSuchProcess.__init__(self, msg)
self.pid = pid
NoSuchProcess.__init__(self, pid, name, msg)
self.ppid = ppid
self.name = name
self.msg = msg
if msg is None:
args = ["pid=%s" % pid]
if name:
args.append("name=%s" % repr(self.name))
if ppid:
args.append("ppid=%s" % self.ppid)
details = "(%s)" % ", ".join(args)
self.msg = "process still exists but it's a zombie " + details
self.msg = msg or "PID still exists but it's a zombie"
class AccessDenied(Error):
@ -335,17 +339,10 @@ class AccessDenied(Error):
__module__ = 'psutil'
def __init__(self, pid=None, name=None, msg=None):
Error.__init__(self, msg)
Error.__init__(self)
self.pid = pid
self.name = name
self.msg = msg
if msg is None:
if (pid is not None) and (name is not None):
self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
elif (pid is not None):
self.msg = "(pid=%s)" % self.pid
else:
self.msg = ""
self.msg = msg or ""
class TimeoutExpired(Error):
@ -355,14 +352,11 @@ class TimeoutExpired(Error):
__module__ = 'psutil'
def __init__(self, seconds, pid=None, name=None):
Error.__init__(self, "timeout after %s seconds" % seconds)
Error.__init__(self)
self.seconds = seconds
self.pid = pid
self.name = name
if (pid is not None) and (name is not None):
self.msg += " (pid=%s, name=%s)" % (pid, repr(name))
elif (pid is not None):
self.msg += " (pid=%s)" % self.pid
self.msg = "timeout after %s seconds" % seconds
# ===================================================================
@ -451,7 +445,13 @@ def memoize_when_activated(fun):
except KeyError:
# case 3: we entered oneshot() ctx but there's no cache
# for this entry yet
ret = self._cache[fun] = fun(self)
ret = fun(self)
try:
self._cache[fun] = ret
except AttributeError:
# multi-threading race condition, see:
# https://github.com/giampaolo/psutil/issues/1948
pass
return ret
def cache_activate(proc):
@ -622,8 +622,8 @@ class _WrapNumbers:
assert name not in self.reminders
assert name not in self.reminder_keys
self.cache[name] = input_dict
self.reminders[name] = defaultdict(int)
self.reminder_keys[name] = defaultdict(set)
self.reminders[name] = collections.defaultdict(int)
self.reminder_keys[name] = collections.defaultdict(set)
def _remove_dead_reminders(self, input_dict, name):
"""In case the number of keys changed between calls (e.g. a
@ -832,15 +832,17 @@ def print_color(
SetConsoleTextAttribute(handle, DEFAULT_COLOR)
if bool(os.getenv('PSUTIL_DEBUG', 0)):
import inspect
def debug(msg):
"""If PSUTIL_DEBUG env var is set, print a debug message to stderr."""
def debug(msg):
"""If PSUTIL_DEBUG env var is set, print a debug message to stderr."""
if PSUTIL_DEBUG:
import inspect
fname, lineno, func_name, lines, index = inspect.getframeinfo(
inspect.currentframe().f_back)
if isinstance(msg, Exception):
if isinstance(msg, (OSError, IOError, EnvironmentError)):
# ...because str(exc) may contain info about the file name
msg = "ignoring %s" % msg
else:
msg = "ignoring %r" % msg
print("psutil-debug [%s:%s]> %s" % (fname, lineno, msg), # NOQA
file=sys.stderr)
else:
def debug(msg):
pass

View File

@ -8,12 +8,14 @@ Python 3 way of doing things).
"""
import collections
import contextlib
import errno
import functools
import os
import sys
import types
__all__ = [
# constants
"PY3",
@ -25,6 +27,8 @@ __all__ = [
"lru_cache",
# shutil module
"which", "get_terminal_size",
# contextlib module
"redirect_stderr",
# python 3 exceptions
"FileNotFoundError", "PermissionError", "ProcessLookupError",
"InterruptedError", "ChildProcessError", "FileExistsError"]
@ -410,8 +414,8 @@ except ImportError:
def get_terminal_size(fallback=(80, 24)):
try:
import fcntl
import termios
import struct
import termios
except ImportError:
return fallback
else:
@ -422,3 +426,25 @@ except ImportError:
return (res[1], res[0])
except Exception:
return fallback
# python 3.3
try:
from subprocess import TimeoutExpired as SubprocessTimeoutExpired
except ImportError:
class SubprocessTimeoutExpired:
pass
# python 3.5
try:
from contextlib import redirect_stderr
except ImportError:
@contextlib.contextmanager
def redirect_stderr(new_target):
original = getattr(sys, "stderr")
try:
setattr(sys, "stderr", new_target)
yield new_target
finally:
setattr(sys, "stderr", original)

View File

@ -18,20 +18,20 @@ from . import _common
from . import _psposix
from . import _psutil_aix as cext
from . import _psutil_posix as cext_posix
from ._common import AccessDenied
from ._common import conn_to_ntuple
from ._common import get_procfs_path
from ._common import memoize_when_activated
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import usage_percent
from ._common import ZombieProcess
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
from ._compat import PY3
__extra__all__ = ["PROCFS_PATH"]
@ -143,7 +143,7 @@ def cpu_count_logical():
return None
def cpu_count_physical():
def cpu_count_cores():
cmd = "lsdev -Cc processor"
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)

View File

@ -9,24 +9,24 @@ import errno
import functools
import os
import xml.etree.ElementTree as ET
from collections import namedtuple
from collections import defaultdict
from collections import namedtuple
from . import _common
from . import _psposix
from . import _psutil_bsd as cext
from . import _psutil_posix as cext_posix
from ._common import FREEBSD
from ._common import NETBSD
from ._common import OPENBSD
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
from ._common import conn_tmap
from ._common import conn_to_ntuple
from ._common import FREEBSD
from ._common import memoize
from ._common import memoize_when_activated
from ._common import NETBSD
from ._common import NoSuchProcess
from ._common import OPENBSD
from ._common import usage_percent
from ._common import ZombieProcess
from ._compat import FileNotFoundError
from ._compat import PermissionError
from ._compat import ProcessLookupError
@ -249,19 +249,19 @@ def cpu_count_logical():
if OPENBSD or NETBSD:
def cpu_count_physical():
def cpu_count_cores():
# OpenBSD and NetBSD do not implement this.
return 1 if cpu_count_logical() == 1 else None
else:
def cpu_count_physical():
"""Return the number of physical CPUs in the system."""
def cpu_count_cores():
"""Return the number of CPU cores in the system."""
# From the C module we'll get an XML string similar to this:
# http://manpages.ubuntu.com/manpages/precise/man4/smp.4freebsd.html
# We may get None in case "sysctl kern.sched.topology_spec"
# is not supported on this BSD version, in which case we'll mimic
# os.cpu_count() and return None.
ret = None
s = cext.cpu_count_phys()
s = cext.cpu_topology()
if s is not None:
# get rid of padding chars appended at the end of the string
index = s.rfind("</groups>")
@ -274,8 +274,7 @@ else:
# needed otherwise it will memleak
root.clear()
if not ret:
# If logical CPUs are 1 it's obvious we'll have only 1
# physical CPU.
# If logical CPUs == 1 it's obvious we' have only 1 core.
if cpu_count_logical() == 1:
return 1
return ret

View File

@ -25,30 +25,31 @@ from . import _common
from . import _psposix
from . import _psutil_linux as cext
from . import _psutil_posix as cext_posix
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
from ._common import debug
from ._common import decode
from ._common import get_procfs_path
from ._common import isfile_strict
from ._common import memoize
from ._common import memoize_when_activated
from ._common import NIC_DUPLEX_FULL
from ._common import NIC_DUPLEX_HALF
from ._common import NIC_DUPLEX_UNKNOWN
from ._common import NoSuchProcess
from ._common import open_binary
from ._common import open_text
from ._common import parse_environ_block
from ._common import path_exists_strict
from ._common import supports_ipv6
from ._common import usage_percent
from ._common import ZombieProcess
from ._compat import b
from ._compat import basestring
from ._compat import PY3
from ._compat import FileNotFoundError
from ._compat import PermissionError
from ._compat import ProcessLookupError
from ._compat import PY3
from ._compat import b
from ._compat import basestring
if sys.version_info >= (3, 4):
import enum
@ -656,8 +657,8 @@ def cpu_count_logical():
return num
def cpu_count_physical():
"""Return the number of physical cores in the system."""
def cpu_count_cores():
"""Return the number of CPU cores in the system."""
# Method #1
ls = set()
# These 2 files are the same but */core_cpus_list is newer while
@ -719,6 +720,17 @@ def cpu_stats():
ctx_switches, interrupts, soft_interrupts, syscalls)
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
if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq"):
def cpu_freq():
@ -726,20 +738,20 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
Contrarily to other OSes, Linux updates these values in
real-time.
"""
def get_path(num):
for p in ("/sys/devices/system/cpu/cpufreq/policy%s" % num,
"/sys/devices/system/cpu/cpu%s/cpufreq" % num):
if os.path.exists(p):
return p
cpuinfo_freqs = _cpu_get_cpuinfo_freq()
paths = \
glob.glob("/sys/devices/system/cpu/cpufreq/policy[0-9]*") or \
glob.glob("/sys/devices/system/cpu/cpu[0-9]*/cpufreq")
paths.sort(key=lambda x: int(re.search(r"[0-9]+", x).group()))
ret = []
for n in range(cpu_count_logical()):
path = get_path(n)
if not path:
continue
pjoin = os.path.join
curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
pjoin = os.path.join
for i, path in enumerate(paths):
if len(paths) == len(cpuinfo_freqs):
# take cached value from cpuinfo if available, see:
# https://github.com/giampaolo/psutil/issues/1851
curr = cpuinfo_freqs[i]
else:
curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
if curr is None:
# Likely an old RedHat, see:
# https://github.com/giampaolo/psutil/issues/1071
@ -753,24 +765,12 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
ret.append(_common.scpufreq(curr, min_, max_))
return ret
elif os.path.exists("/proc/cpuinfo"):
else:
def cpu_freq():
"""Alternate implementation using /proc/cpuinfo.
min and max frequencies are not available and are set to None.
"""
ret = []
with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
for line in f:
if line.lower().startswith(b'cpu mhz'):
key, value = line.split(b':', 1)
ret.append(_common.scpufreq(float(value), 0., 0.))
return ret
else:
def cpu_freq():
"""Dummy implementation when none of the above files are present.
"""
return []
return [_common.scpufreq(x, 0., 0.) for x in _cpu_get_cpuinfo_freq()]
# =====================================================================
@ -834,6 +834,10 @@ class Connections:
if err.errno == errno.EINVAL:
# not a link
continue
if err.errno == errno.ENAMETOOLONG:
# file name too long
debug(err)
continue
raise
else:
if inode.startswith('socket:['):
@ -1080,6 +1084,8 @@ def net_if_stats():
# https://github.com/giampaolo/psutil/issues/1279
if err.errno != errno.ENODEV:
raise
else:
debug(err)
else:
ret[name] = _common.snicstats(isup, duplex_map[duplex], speed, mtu)
return ret
@ -1188,6 +1194,80 @@ def disk_io_counters(perdisk=False):
return retdict
class RootFsDeviceFinder:
"""disk_partitions() may return partitions with device == "/dev/root"
or "rootfs". This container class uses different strategies to try to
obtain the real device path. Resources:
https://bootlin.com/blog/find-root-device/
https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/
"""
__slots__ = ['major', 'minor']
def __init__(self):
dev = os.stat("/").st_dev
self.major = os.major(dev)
self.minor = os.minor(dev)
def ask_proc_partitions(self):
with open_text("%s/partitions" % get_procfs_path()) as f:
for line in f.readlines()[2:]:
fields = line.split()
if len(fields) < 4: # just for extra safety
continue
major = int(fields[0]) if fields[0].isdigit() else None
minor = int(fields[1]) if fields[1].isdigit() else None
name = fields[3]
if major == self.major and minor == self.minor:
if name: # just for extra safety
return "/dev/%s" % name
def ask_sys_dev_block(self):
path = "/sys/dev/block/%s:%s/uevent" % (self.major, self.minor)
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
def ask_sys_class_block(self):
needle = "%s:%s" % (self.major, self.minor)
files = glob.iglob("/sys/class/block/*/dev")
for file in files:
try:
f = open_text(file)
except FileNotFoundError: # race condition
continue
else:
with f:
data = f.read().strip()
if data == needle:
name = os.path.basename(os.path.dirname(file))
return "/dev/%s" % name
def find(self):
path = None
if path is None:
try:
path = self.ask_proc_partitions()
except (IOError, OSError) as err:
debug(err)
if path is None:
try:
path = self.ask_sys_dev_block()
except (IOError, OSError) as err:
debug(err)
if path is None:
try:
path = self.ask_sys_class_block()
except (IOError, OSError) as err:
debug(err)
# We use exists() because the "/dev/*" part of the path is hard
# coded, so we want to be sure.
if path is not None and os.path.exists(path):
return path
def disk_partitions(all=False):
"""Return mounted disk partitions as a list of namedtuples."""
fstypes = set()
@ -1215,6 +1295,8 @@ def disk_partitions(all=False):
device, mountpoint, fstype, opts = partition
if device == 'none':
device = ''
if device in ("/dev/root", "rootfs"):
device = RootFsDeviceFinder().find() or device
if not all:
if device == '' or fstype not in fstypes:
continue
@ -1310,7 +1392,7 @@ def sensors_temperatures():
path = os.path.join(base, 'type')
unit_name = cat(path, binary=False)
except (IOError, OSError, ValueError) as err:
debug("ignoring %r for file %r" % (err, path))
debug(err)
continue
trip_paths = glob.glob(base + '/trip_point*')
@ -1366,7 +1448,7 @@ def sensors_fans():
try:
current = int(cat(base + '_input'))
except (IOError, OSError) as err:
warnings.warn("ignoring %r" % err, RuntimeWarning)
debug(err)
continue
unit_name = cat(os.path.join(os.path.dirname(base), 'name'),
binary=False)
@ -1392,7 +1474,10 @@ def sensors_battery():
for path in paths:
ret = cat(path, fallback=null)
if ret != null:
return int(ret) if ret.isdigit() else ret
try:
return int(ret)
except ValueError:
return ret
return None
bats = [x for x in os.listdir(POWER_SUPPLY_PATH) if x.startswith('BAT') or
@ -2100,6 +2185,10 @@ class Process(object):
if err.errno == errno.EINVAL:
# not a link
continue
if err.errno == errno.ENAMETOOLONG:
# file name too long
debug(err)
continue
raise
else:
# If path is not an absolute there's no way to tell

View File

@ -4,7 +4,6 @@
"""macOS platform implementation."""
import contextlib
import errno
import functools
import os
@ -15,14 +14,14 @@ from . import _psposix
from . import _psutil_osx as cext
from . import _psutil_posix as cext_posix
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
from ._common import conn_tmap
from ._common import conn_to_ntuple
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import NoSuchProcess
from ._common import parse_environ_block
from ._common import usage_percent
from ._common import ZombieProcess
from ._compat import PermissionError
from ._compat import ProcessLookupError
@ -159,9 +158,9 @@ def cpu_count_logical():
return cext.cpu_count_logical()
def cpu_count_physical():
"""Return the number of physical CPUs in the system."""
return cext.cpu_count_phys()
def cpu_count_cores():
"""Return the number of CPU cores in the system."""
return cext.cpu_count_cores()
def cpu_stats():
@ -354,32 +353,6 @@ def wrap_exceptions(fun):
return wrapper
@contextlib.contextmanager
def catch_zombie(proc):
"""There are some poor C APIs which incorrectly raise ESRCH when
the process is still alive or it's a zombie, or even RuntimeError
(those who don't set errno). This is here in order to solve:
https://github.com/giampaolo/psutil/issues/1044
"""
try:
yield
except (OSError, RuntimeError) as err:
if isinstance(err, RuntimeError) or err.errno == errno.ESRCH:
try:
# status() is not supposed to lie and correctly detect
# zombies so if it raises ESRCH it's true.
status = proc.status()
except NoSuchProcess:
raise err
else:
if status == _common.STATUS_ZOMBIE:
raise ZombieProcess(proc.pid, proc._name, proc._ppid)
else:
raise AccessDenied(proc.pid, proc._name)
else:
raise
class Process(object):
"""Wrapper class around underlying C implementation."""
@ -402,8 +375,7 @@ class Process(object):
@memoize_when_activated
def _get_pidtaskinfo(self):
# Note: should work for PIDs owned by user only.
with catch_zombie(self):
ret = cext.proc_pidtaskinfo_oneshot(self.pid)
ret = cext.proc_pidtaskinfo_oneshot(self.pid)
assert len(ret) == len(pidtaskinfo_map)
return ret
@ -422,18 +394,15 @@ class Process(object):
@wrap_exceptions
def exe(self):
with catch_zombie(self):
return cext.proc_exe(self.pid)
return cext.proc_exe(self.pid)
@wrap_exceptions
def cmdline(self):
with catch_zombie(self):
return cext.proc_cmdline(self.pid)
return cext.proc_cmdline(self.pid)
@wrap_exceptions
def environ(self):
with catch_zombie(self):
return parse_environ_block(cext.proc_environ(self.pid))
return parse_environ_block(cext.proc_environ(self.pid))
@wrap_exceptions
def ppid(self):
@ -442,8 +411,7 @@ class Process(object):
@wrap_exceptions
def cwd(self):
with catch_zombie(self):
return cext.proc_cwd(self.pid)
return cext.proc_cwd(self.pid)
@wrap_exceptions
def uids(self):
@ -516,8 +484,7 @@ class Process(object):
if self.pid == 0:
return []
files = []
with catch_zombie(self):
rawlist = cext.proc_open_files(self.pid)
rawlist = cext.proc_open_files(self.pid)
for path, fd in rawlist:
if isfile_strict(path):
ntuple = _common.popenfile(path, fd)
@ -530,8 +497,7 @@ class Process(object):
raise ValueError("invalid %r kind argument; choose between %s"
% (kind, ', '.join([repr(x) for x in conn_tmap])))
families, types = conn_tmap[kind]
with catch_zombie(self):
rawlist = cext.proc_connections(self.pid, families, types)
rawlist = cext.proc_connections(self.pid, families, types)
ret = []
for item in rawlist:
fd, fam, type, laddr, raddr, status = item
@ -544,8 +510,7 @@ class Process(object):
def num_fds(self):
if self.pid == 0:
return 0
with catch_zombie(self):
return cext.proc_num_fds(self.pid)
return cext.proc_num_fds(self.pid)
@wrap_exceptions
def wait(self, timeout=None):
@ -553,13 +518,11 @@ class Process(object):
@wrap_exceptions
def nice_get(self):
with catch_zombie(self):
return cext_posix.getpriority(self.pid)
return cext_posix.getpriority(self.pid)
@wrap_exceptions
def nice_set(self, value):
with catch_zombie(self):
return cext_posix.setpriority(self.pid, value)
return cext_posix.setpriority(self.pid, value)
@wrap_exceptions
def status(self):

View File

@ -10,18 +10,19 @@ import signal
import sys
import time
from ._common import TimeoutExpired
from ._common import memoize
from ._common import sdiskusage
from ._common import TimeoutExpired
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 PY3
from ._compat import unicode
if sys.version_info >= (3, 4):
import enum
else:

View File

@ -17,22 +17,22 @@ from . import _common
from . import _psposix
from . import _psutil_posix as cext_posix
from . import _psutil_sunos as cext
from ._common import AccessDenied
from ._common import AF_INET6
from ._common import AccessDenied
from ._common import NoSuchProcess
from ._common import ZombieProcess
from ._common import debug
from ._common import get_procfs_path
from ._common import isfile_strict
from ._common import memoize_when_activated
from ._common import NoSuchProcess
from ._common import sockfam_to_enum
from ._common import socktype_to_enum
from ._common import usage_percent
from ._common import ZombieProcess
from ._compat import b
from ._compat import PY3
from ._compat import FileNotFoundError
from ._compat import PermissionError
from ._compat import ProcessLookupError
from ._compat import PY3
from ._compat import b
__extra__all__ = ["CONN_IDLE", "CONN_BOUND", "PROCFS_PATH"]
@ -155,7 +155,7 @@ def swap_memory():
total = free = 0
for line in lines:
line = line.split()
t, f = line[3:4]
t, f = line[3:5]
total += int(int(t) * 512)
free += int(int(f) * 512)
used = total - free
@ -190,9 +190,9 @@ def cpu_count_logical():
return None
def cpu_count_physical():
"""Return the number of physical CPUs in the system."""
return cext.cpu_count_phys()
def cpu_count_cores():
"""Return the number of CPU cores in the system."""
return cext.cpu_count_cores()
def cpu_stats():
@ -231,7 +231,7 @@ def disk_partitions(all=False):
continue
except OSError as err:
# https://github.com/giampaolo/psutil/issues/1674
debug("skipping %r: %r" % (mountpoint, err))
debug("skipping %r: %s" % (mountpoint, err))
continue
maxfile = maxpath = None # set later
ntuple = _common.sdiskpart(device, mountpoint, fstype, opts,

View File

@ -14,22 +14,22 @@ import time
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
from ._common import conn_tmap
from ._common import conn_to_ntuple
from ._common import debug
from ._common import ENCODING
from ._common import ENCODING_ERRS
from ._common import isfile_strict
from ._common import memoize
from ._common import memoize_when_activated
from ._common import NoSuchProcess
from ._common import parse_environ_block
from ._common import TimeoutExpired
from ._common import usage_percent
from ._compat import PY3
from ._compat import long
from ._compat import lru_cache
from ._compat import PY3
from ._compat import range
from ._compat import unicode
from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS
@ -39,6 +39,7 @@ from ._psutil_windows import IDLE_PRIORITY_CLASS
from ._psutil_windows import NORMAL_PRIORITY_CLASS
from ._psutil_windows import REALTIME_PRIORITY_CLASS
try:
from . import _psutil_windows as cext
except ImportError as err:
@ -197,7 +198,7 @@ def convert_dos_path(s):
"C:\Windows\systemew\file.txt"
"""
rawdrive = '\\'.join(s.split('\\')[:3])
driveletter = cext.win32_QueryDosDevice(rawdrive)
driveletter = cext.QueryDosDevice(rawdrive)
remainder = s[len(rawdrive):]
return os.path.join(driveletter, remainder)
@ -241,8 +242,16 @@ def virtual_memory():
def swap_memory():
"""Swap system memory as a (total, used, free, sin, sout) tuple."""
mem = cext.virtual_mem()
total = mem[2]
free = mem[3]
total_phys = mem[0]
free_phys = mem[1]
total_system = mem[2]
free_system = mem[3]
# Despite the name PageFile refers to total system memory here
# thus physical memory values need to be substracted to get swap values
total = total_system - total_phys
free = min(total, free_system - free_phys)
used = total - free
percent = usage_percent(used, total, round_=1)
return _common.sswap(total, used, free, percent, 0, 0)
@ -304,9 +313,9 @@ def cpu_count_logical():
return cext.cpu_count_logical()
def cpu_count_physical():
"""Return the number of physical CPU cores in the system."""
return cext.cpu_count_phys()
def cpu_count_cores():
"""Return the number of CPU cores in the system."""
return cext.cpu_count_cores()
def cpu_stats():
@ -759,7 +768,7 @@ class Process(object):
# 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 forced into AccessDenied" % err)
debug("%r translated into AccessDenied" % err)
raise AccessDenied(self.pid, self._name)
raise
else:

View File

@ -9,6 +9,7 @@ Test utilities.
"""
from __future__ import print_function
import atexit
import contextlib
import ctypes
@ -46,15 +47,16 @@ from psutil import WINDOWS
from psutil._common import bytes2human
from psutil._common import print_color
from psutil._common import supports_ipv6
from psutil._compat import PY3
from psutil._compat import FileExistsError
from psutil._compat import FileNotFoundError
from psutil._compat import PY3
from psutil._compat import range
from psutil._compat import super
from psutil._compat import u
from psutil._compat import unicode
from psutil._compat import which
if PY3:
import unittest
else:
@ -72,6 +74,9 @@ if sys.version_info >= (3, 4):
else:
enum = None
if POSIX:
from psutil._psposix import wait_pid
__all__ = [
# constants
@ -482,9 +487,6 @@ def terminate(proc_or_pid, sig=signal.SIGTERM, wait_timeout=GLOBAL_TIMEOUT):
Does nothing if the process does not exist.
Return process exit status.
"""
if POSIX:
from psutil._psposix import wait_pid
def wait(proc, timeout):
if isinstance(proc, subprocess.Popen) and not PY3:
proc.wait()
@ -952,6 +954,15 @@ class TestMemoryLeak(PsutilTestCase):
retries = 10 if CI_TESTING else 5
verbose = True
_thisproc = psutil.Process()
_psutil_debug_orig = bool(os.getenv('PSUTIL_DEBUG', 0))
@classmethod
def setUpClass(cls):
psutil._set_debug(False) # avoid spamming to stderr
@classmethod
def tearDownClass(cls):
psutil._set_debug(cls._psutil_debug_orig)
def _get_mem(self):
# USS is the closest thing we have to "real" memory usage and it
@ -1724,8 +1735,8 @@ else:
in memory via ctypes.
Return the new absolutized, normcased path.
"""
from ctypes import wintypes
from ctypes import WinError
from ctypes import wintypes
ext = ".dll"
dst = get_testfn(suffix=suffix + ext)
libs = [x.path for x in psutil.Process().memory_maps() if

View File

@ -10,4 +10,6 @@ $ python -m psutil.tests
"""
from .runner import main
main()

View File

@ -21,6 +21,7 @@ Parallel:
"""
from __future__ import print_function
import atexit
import optparse
import os
@ -28,6 +29,8 @@ import sys
import textwrap
import time
import unittest
try:
import ctypes
except ImportError:
@ -298,16 +301,15 @@ def get_runner(parallel=False):
# Used by test_*,py modules.
def run_from_name(name):
if CI_TESTING:
print_sysinfo()
suite = TestLoader().from_name(name)
runner = get_runner()
runner.run(suite)
def setup():
# Note: doc states that altering os.environment may cause memory
# leaks on some platforms.
# Sets PSUTIL_TESTING and PSUTIL_DEBUG in the C module.
psutil._psplatform.cext.set_testing()
psutil._set_debug(True)
def main():

View File

@ -10,11 +10,11 @@
import re
import psutil
from psutil import AIX
from psutil.tests import PsutilTestCase
from psutil.tests import sh
from psutil.tests import unittest
import psutil
@unittest.skipIf(not AIX, "AIX only")

View File

@ -20,12 +20,12 @@ from psutil import BSD
from psutil import FREEBSD
from psutil import NETBSD
from psutil import OPENBSD
from psutil.tests import spawn_testproc
from psutil.tests import HAS_BATTERY
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import PsutilTestCase
from psutil.tests import retry_on_failure
from psutil.tests import sh
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import spawn_testproc
from psutil.tests import terminate
from psutil.tests import unittest
from psutil.tests import which

View File

@ -8,7 +8,6 @@
import os
import socket
import sys
import textwrap
from contextlib import closing
from socket import AF_INET
@ -28,17 +27,17 @@ from psutil import WINDOWS
from psutil._common import supports_ipv6
from psutil._compat import PY3
from psutil.tests import AF_UNIX
from psutil.tests import HAS_CONNECTIONS_UNIX
from psutil.tests import SKIP_SYSCONS
from psutil.tests import PsutilTestCase
from psutil.tests import bind_socket
from psutil.tests import bind_unix_socket
from psutil.tests import check_connection_ntuple
from psutil.tests import create_sockets
from psutil.tests import HAS_CONNECTIONS_UNIX
from psutil.tests import PsutilTestCase
from psutil.tests import reap_children
from psutil.tests import retry_on_failure
from psutil.tests import serialrun
from psutil.tests import skip_on_access_denied
from psutil.tests import SKIP_SYSCONS
from psutil.tests import tcp_socketpair
from psutil.tests import unittest
from psutil.tests import unix_socketpair
@ -47,7 +46,6 @@ from psutil.tests import wait_for_file
thisproc = psutil.Process()
SOCK_SEQPACKET = getattr(socket, "SOCK_SEQPACKET", object())
PYTHON_39 = sys.version_info[:2] == (3, 9)
@serialrun

View File

@ -18,6 +18,7 @@ import sys
import time
import traceback
import psutil
from psutil import AIX
from psutil import BSD
from psutil import FREEBSD
@ -33,25 +34,24 @@ from psutil._compat import FileNotFoundError
from psutil._compat import long
from psutil._compat import range
from psutil.tests import APPVEYOR
from psutil.tests import check_connection_ntuple
from psutil.tests import CI_TESTING
from psutil.tests import create_sockets
from psutil.tests import enum
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import HAS_CPU_FREQ
from psutil.tests import HAS_NET_IO_COUNTERS
from psutil.tests import HAS_SENSORS_FANS
from psutil.tests import HAS_SENSORS_TEMPERATURES
from psutil.tests import PYPY
from psutil.tests import SKIP_SYSCONS
from psutil.tests import VALID_PROC_STATUSES
from psutil.tests import PsutilTestCase
from psutil.tests import check_connection_ntuple
from psutil.tests import create_sockets
from psutil.tests import enum
from psutil.tests import is_namedtuple
from psutil.tests import kernel_version
from psutil.tests import process_namespace
from psutil.tests import PsutilTestCase
from psutil.tests import PYPY
from psutil.tests import serialrun
from psutil.tests import SKIP_SYSCONS
from psutil.tests import unittest
from psutil.tests import VALID_PROC_STATUSES
import psutil
# ===================================================================
@ -360,7 +360,6 @@ def proc_info(pid):
elif isinstance(exc, psutil.NoSuchProcess):
tcase.assertProcessGone(proc)
str(exc)
assert exc.msg
def do_wait():
if pid != 0:

View File

@ -7,6 +7,7 @@
"""Linux specific tests."""
from __future__ import division
import collections
import contextlib
import errno
@ -23,31 +24,39 @@ import warnings
import psutil
from psutil import LINUX
from psutil._compat import basestring
from psutil._compat import FileNotFoundError
from psutil._compat import PY3
from psutil._compat import FileNotFoundError
from psutil._compat import basestring
from psutil._compat import u
from psutil.tests import call_until
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import GLOBAL_TIMEOUT
from psutil.tests import HAS_BATTERY
from psutil.tests import HAS_CPU_FREQ
from psutil.tests import HAS_GETLOADAVG
from psutil.tests import HAS_RLIMIT
from psutil.tests import mock
from psutil.tests import PsutilTestCase
from psutil.tests import PYPY
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import PsutilTestCase
from psutil.tests import ThreadTask
from psutil.tests import call_until
from psutil.tests import mock
from psutil.tests import reload_module
from psutil.tests import retry_on_failure
from psutil.tests import safe_rmpath
from psutil.tests import sh
from psutil.tests import skip_on_not_implemented
from psutil.tests import ThreadTask
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import unittest
from psutil.tests import which
if LINUX:
from psutil._pslinux import CLOCK_TICKS
from psutil._pslinux import RootFsDeviceFinder
from psutil._pslinux import calculate_avail_vmem
from psutil._pslinux import open_binary
HERE = os.path.abspath(os.path.dirname(__file__))
SIOCGIFADDR = 0x8915
SIOCGIFCONF = 0x8912
@ -58,6 +67,7 @@ if LINUX:
SECTOR_SIZE = 512
EMPTY_TEMPERATURES = not glob.glob('/sys/class/hwmon/hwmon*')
# =====================================================================
# --- utils
# =====================================================================
@ -141,7 +151,7 @@ def free_swap():
"""Parse 'free' cmd and return swap memory's s total, used and free
values.
"""
out = sh('free -b', env={"LANG": "C.UTF-8"})
out = sh(["free", "-b"], env={"LANG": "C.UTF-8"})
lines = out.split('\n')
for line in lines:
if line.startswith('Swap'):
@ -160,7 +170,7 @@ def free_physmem():
# and 'cached' memory which may have different positions so we
# do not return them.
# https://github.com/giampaolo/psutil/issues/538#issuecomment-57059946
out = sh('free -b', env={"LANG": "C.UTF-8"})
out = sh(["free", "-b"], env={"LANG": "C.UTF-8"})
lines = out.split('\n')
for line in lines:
if line.startswith('Mem'):
@ -174,7 +184,7 @@ def free_physmem():
def vmstat(stat):
out = sh("vmstat -s", env={"LANG": "C.UTF-8"})
out = sh(["vmstat", "-s"], env={"LANG": "C.UTF-8"})
for line in out.split("\n"):
line = line.strip()
if stat in line:
@ -183,7 +193,7 @@ def vmstat(stat):
def get_free_version_info():
out = sh("free -V").strip()
out = sh(["free", "-V"]).strip()
if 'UNKNOWN' in out:
raise unittest.SkipTest("can't determine free version")
return tuple(map(int, out.split()[-1].split('.')))
@ -243,7 +253,8 @@ class TestSystemVirtualMemory(PsutilTestCase):
# self.assertEqual(free_value, psutil_value)
vmstat_value = vmstat('total memory') * 1024
psutil_value = psutil.virtual_memory().total
self.assertAlmostEqual(vmstat_value, psutil_value)
self.assertAlmostEqual(
vmstat_value, psutil_value, delta=TOLERANCE_SYS_MEM)
@retry_on_failure()
def test_used(self):
@ -303,7 +314,7 @@ class TestSystemVirtualMemory(PsutilTestCase):
def test_available(self):
# "free" output format has changed at some point:
# https://github.com/giampaolo/psutil/issues/538#issuecomment-147192098
out = sh("free -b")
out = sh(["free", "-b"])
lines = out.split('\n')
if 'available' not in lines[0]:
raise unittest.SkipTest("free does not support 'available' column")
@ -357,9 +368,6 @@ class TestSystemVirtualMemory(PsutilTestCase):
def test_avail_old_percent(self):
# Make sure that our calculation of avail mem for old kernels
# is off by max 15%.
from psutil._pslinux import calculate_avail_vmem
from psutil._pslinux import open_binary
mems = {}
with open_binary('/proc/meminfo') as f:
for line in f:
@ -715,7 +723,7 @@ class TestSystemCPUCountLogical(PsutilTestCase):
@unittest.skipIf(not LINUX, "LINUX only")
class TestSystemCPUCountPhysical(PsutilTestCase):
class TestSystemCPUCountCores(PsutilTestCase):
@unittest.skipIf(not which("lscpu"), "lscpu utility not available")
def test_against_lscpu(self):
@ -728,9 +736,9 @@ class TestSystemCPUCountPhysical(PsutilTestCase):
self.assertEqual(psutil.cpu_count(logical=False), len(core_ids))
def test_method_2(self):
meth_1 = psutil._pslinux.cpu_count_physical()
meth_1 = psutil._pslinux.cpu_count_cores()
with mock.patch('glob.glob', return_value=[]) as m:
meth_2 = psutil._pslinux.cpu_count_physical()
meth_2 = psutil._pslinux.cpu_count_cores()
assert m.called
if meth_1 is not None:
self.assertEqual(meth_1, meth_2)
@ -738,7 +746,7 @@ class TestSystemCPUCountPhysical(PsutilTestCase):
def test_emulate_none(self):
with mock.patch('glob.glob', return_value=[]) as m1:
with mock.patch('psutil._common.open', create=True) as m2:
self.assertIsNone(psutil._pslinux.cpu_count_physical())
self.assertIsNone(psutil._pslinux.cpu_count_cores())
assert m1.called
assert m2.called
@ -768,18 +776,14 @@ class TestSystemCPUFrequency(PsutilTestCase):
if path.startswith('/sys/devices/system/cpu/'):
return False
else:
if path == "/proc/cpuinfo":
flags.append(None)
return os_path_exists(path)
flags = []
os_path_exists = os.path.exists
try:
with mock.patch("os.path.exists", side_effect=path_exists_mock):
reload_module(psutil._pslinux)
ret = psutil.cpu_freq()
assert ret
assert flags
self.assertEqual(ret.max, 0.0)
self.assertEqual(ret.min, 0.0)
for freq in psutil.cpu_freq(percpu=True):
@ -1263,6 +1267,68 @@ class TestSystemDiskIoCounters(PsutilTestCase):
self.assertRaises(NotImplementedError, psutil.disk_io_counters)
@unittest.skipIf(not LINUX, "LINUX only")
class TestRootFsDeviceFinder(PsutilTestCase):
def setUp(self):
dev = os.stat("/").st_dev
self.major = os.major(dev)
self.minor = os.minor(dev)
def test_call_methods(self):
finder = RootFsDeviceFinder()
if os.path.exists("/proc/partitions"):
finder.ask_proc_partitions()
else:
self.assertRaises(FileNotFoundError, finder.ask_proc_partitions)
if os.path.exists("/sys/dev/block/%s:%s/uevent" % (
self.major, self.minor)):
finder.ask_sys_dev_block()
else:
self.assertRaises(FileNotFoundError, finder.ask_sys_dev_block)
finder.ask_sys_class_block()
@unittest.skipIf(GITHUB_ACTIONS, "unsupported on GITHUB_ACTIONS")
def test_comparisons(self):
finder = RootFsDeviceFinder()
self.assertIsNotNone(finder.find())
a = b = c = None
if os.path.exists("/proc/partitions"):
a = finder.ask_proc_partitions()
if os.path.exists("/sys/dev/block/%s:%s/uevent" % (
self.major, self.minor)):
b = finder.ask_sys_class_block()
c = finder.ask_sys_dev_block()
base = a or b or c
if base and a:
self.assertEqual(base, a)
if base and b:
self.assertEqual(base, b)
if base and c:
self.assertEqual(base, c)
@unittest.skipIf(not which("findmnt"), "findmnt utility not available")
@unittest.skipIf(GITHUB_ACTIONS, "unsupported on GITHUB_ACTIONS")
def test_against_findmnt(self):
psutil_value = RootFsDeviceFinder().find()
findmnt_value = sh("findmnt -o SOURCE -rn /")
self.assertEqual(psutil_value, findmnt_value)
def test_disk_partitions_mocked(self):
with mock.patch(
'psutil._pslinux.cext.disk_partitions',
return_value=[('/dev/root', '/', 'ext4', 'rw')]) as m:
part = psutil.disk_partitions()[0]
assert m.called
if not GITHUB_ACTIONS:
self.assertNotEqual(part.device, "/dev/root")
self.assertEqual(part.device, RootFsDeviceFinder().find())
else:
self.assertEqual(part.device, "/dev/root")
# =====================================================================
# --- misc
# =====================================================================
@ -1431,9 +1497,7 @@ class TestMisc(PsutilTestCase):
# - Process(tid) is supposed to work
# - pids() should not return the TID
# See: https://github.com/giampaolo/psutil/issues/687
t = ThreadTask()
t.start()
try:
with ThreadTask():
p = psutil.Process()
threads = p.threads()
self.assertEqual(len(threads), 2)
@ -1442,8 +1506,6 @@ class TestMisc(PsutilTestCase):
pt = psutil.Process(tid)
pt.as_dict()
self.assertNotIn(tid, psutil.pids())
finally:
t.stop()
def test_pid_exists_no_proc_status(self):
# Internally pid_exists relies on /proc/{pid}/status.
@ -1837,6 +1899,22 @@ class TestProcess(PsutilTestCase):
assert not files
assert m.called
def test_open_files_enametoolong(self):
# Simulate a case where /proc/{pid}/fd/{fd} symlink
# points to a file with full path longer than PATH_MAX, see:
# https://github.com/giampaolo/psutil/issues/1940
p = psutil.Process()
files = p.open_files()
with open(self.get_testfn(), 'w'):
# give the kernel some time to see the new file
call_until(p.open_files, "len(ret) != %i" % len(files))
patch_point = 'psutil._pslinux.os.readlink'
with mock.patch(patch_point,
side_effect=OSError(errno.ENAMETOOLONG, "")) as m:
files = p.open_files()
assert not files
assert m.called
# --- mocked tests
def test_terminal_mocked(self):
@ -1985,8 +2063,6 @@ class TestProcess(PsutilTestCase):
self.assertEqual(exc.exception.name, p.name())
def test_stat_file_parsing(self):
from psutil._pslinux import CLOCK_TICKS
args = [
"0", # pid
"(cat)", # name
@ -2072,6 +2148,16 @@ class TestProcess(PsutilTestCase):
self.assertEqual(gids.saved, 1006)
self.assertEqual(p._proc._get_eligible_cpus(), list(range(0, 8)))
def test_connections_enametoolong(self):
# Simulate a case where /proc/{pid}/fd/{fd} symlink points to
# a file with full path longer than PATH_MAX, see:
# https://github.com/giampaolo/psutil/issues/1940
with mock.patch('psutil._pslinux.os.readlink',
side_effect=OSError(errno.ENAMETOOLONG, "")) as m:
p = psutil.Process()
assert not p.connections()
assert m.called
@unittest.skipIf(not LINUX, "LINUX only")
class TestProcessAgainstStatus(PsutilTestCase):

View File

@ -16,6 +16,7 @@ because of how its JIT handles memory, so tests are skipped.
"""
from __future__ import print_function
import functools
import os
@ -29,8 +30,6 @@ from psutil import SUNOS
from psutil import WINDOWS
from psutil._compat import ProcessLookupError
from psutil._compat import super
from psutil.tests import create_sockets
from psutil.tests import get_testfn
from psutil.tests import HAS_CPU_AFFINITY
from psutil.tests import HAS_CPU_FREQ
from psutil.tests import HAS_ENVIRON
@ -43,12 +42,14 @@ from psutil.tests import HAS_RLIMIT
from psutil.tests import HAS_SENSORS_BATTERY
from psutil.tests import HAS_SENSORS_FANS
from psutil.tests import HAS_SENSORS_TEMPERATURES
from psutil.tests import TestMemoryLeak
from psutil.tests import create_sockets
from psutil.tests import get_testfn
from psutil.tests import process_namespace
from psutil.tests import skip_on_access_denied
from psutil.tests import spawn_testproc
from psutil.tests import system_namespace
from psutil.tests import terminate
from psutil.tests import TestMemoryLeak
from psutil.tests import unittest
@ -347,7 +348,7 @@ class TestModuleFunctionsLeaks(TestMemoryLeak):
self.execute(lambda: psutil.cpu_count(logical=True))
@fewtimes_if_linux()
def test_cpu_count_physical(self):
def test_cpu_count_cores(self):
self.execute(lambda: psutil.cpu_count(logical=False))
@fewtimes_if_linux()
@ -456,6 +457,9 @@ class TestModuleFunctionsLeaks(TestMemoryLeak):
def test_users(self):
self.execute(psutil.users)
def test_set_debug(self):
self.execute(lambda: psutil._set_debug(False))
if WINDOWS:
# --- win services

View File

@ -17,16 +17,19 @@ import os
import pickle
import socket
import stat
import sys
import psutil
import psutil.tests
from psutil import LINUX
from psutil import POSIX
from psutil import WINDOWS
from psutil._common import debug
from psutil._common import memoize
from psutil._common import memoize_when_activated
from psutil._common import supports_ipv6
from psutil._common import wrap_numbers
from psutil._compat import PY3
from psutil._compat import redirect_stderr
from psutil.tests import APPVEYOR
from psutil.tests import CI_TESTING
from psutil.tests import HAS_BATTERY
@ -35,20 +38,15 @@ from psutil.tests import HAS_NET_IO_COUNTERS
from psutil.tests import HAS_SENSORS_BATTERY
from psutil.tests import HAS_SENSORS_FANS
from psutil.tests import HAS_SENSORS_TEMPERATURES
from psutil.tests import import_module_by_path
from psutil.tests import mock
from psutil.tests import PsutilTestCase
from psutil.tests import PYTHON_EXE
from psutil.tests import reload_module
from psutil.tests import ROOT_DIR
from psutil.tests import SCRIPTS_DIR
from psutil.tests import PsutilTestCase
from psutil.tests import import_module_by_path
from psutil.tests import mock
from psutil.tests import reload_module
from psutil.tests import sh
from psutil.tests import unittest
import psutil
import psutil.tests
PYTHON_39 = sys.version_info[:2] == (3, 9)
# ===================================================================
@ -97,57 +95,71 @@ class TestMisc(PsutilTestCase):
def test_process__str__(self):
self.test_process__repr__(func=str)
def test_no_such_process__repr__(self, func=repr):
def test_no_such_process__repr__(self):
self.assertEqual(
repr(psutil.NoSuchProcess(321)),
"psutil.NoSuchProcess process no longer exists (pid=321)")
"psutil.NoSuchProcess(pid=321, msg='process no longer exists')")
self.assertEqual(
repr(psutil.NoSuchProcess(321, name='foo')),
"psutil.NoSuchProcess process no longer exists (pid=321, "
"name='foo')")
self.assertEqual(
repr(psutil.NoSuchProcess(321, msg='foo')),
"psutil.NoSuchProcess foo")
repr(psutil.NoSuchProcess(321, name="name", msg="msg")),
"psutil.NoSuchProcess(pid=321, name='name', msg='msg')")
def test_zombie_process__repr__(self, func=repr):
def test_no_such_process__str__(self):
self.assertEqual(
str(psutil.NoSuchProcess(321)),
"process no longer exists (pid=321)")
self.assertEqual(
str(psutil.NoSuchProcess(321, name="name", msg="msg")),
"msg (pid=321, name='name')")
def test_zombie_process__repr__(self):
self.assertEqual(
repr(psutil.ZombieProcess(321)),
"psutil.ZombieProcess process still exists but it's a zombie "
"(pid=321)")
'psutil.ZombieProcess(pid=321, msg="PID still '
'exists but it\'s a zombie")')
self.assertEqual(
repr(psutil.ZombieProcess(321, name='foo')),
"psutil.ZombieProcess process still exists but it's a zombie "
"(pid=321, name='foo')")
self.assertEqual(
repr(psutil.ZombieProcess(321, name='foo', ppid=1)),
"psutil.ZombieProcess process still exists but it's a zombie "
"(pid=321, name='foo', ppid=1)")
self.assertEqual(
repr(psutil.ZombieProcess(321, msg='foo')),
"psutil.ZombieProcess foo")
repr(psutil.ZombieProcess(321, name="name", ppid=320, msg="foo")),
"psutil.ZombieProcess(pid=321, ppid=320, name='name', msg='foo')")
def test_access_denied__repr__(self, func=repr):
def test_zombie_process__str__(self):
self.assertEqual(
str(psutil.ZombieProcess(321)),
"PID still exists but it's a zombie (pid=321)")
self.assertEqual(
str(psutil.ZombieProcess(321, name="name", ppid=320, msg="foo")),
"foo (pid=321, ppid=320, name='name')")
def test_access_denied__repr__(self):
self.assertEqual(
repr(psutil.AccessDenied(321)),
"psutil.AccessDenied (pid=321)")
"psutil.AccessDenied(pid=321)")
self.assertEqual(
repr(psutil.AccessDenied(321, name='foo')),
"psutil.AccessDenied (pid=321, name='foo')")
self.assertEqual(
repr(psutil.AccessDenied(321, msg='foo')),
"psutil.AccessDenied foo")
repr(psutil.AccessDenied(321, name="name", msg="msg")),
"psutil.AccessDenied(pid=321, name='name', msg='msg')")
def test_timeout_expired__repr__(self, func=repr):
def test_access_denied__str__(self):
self.assertEqual(
repr(psutil.TimeoutExpired(321)),
"psutil.TimeoutExpired timeout after 321 seconds")
str(psutil.AccessDenied(321)),
"(pid=321)")
self.assertEqual(
repr(psutil.TimeoutExpired(321, pid=111)),
"psutil.TimeoutExpired timeout after 321 seconds (pid=111)")
str(psutil.AccessDenied(321, name="name", msg="msg")),
"msg (pid=321, name='name')")
def test_timeout_expired__repr__(self):
self.assertEqual(
repr(psutil.TimeoutExpired(321, pid=111, name='foo')),
"psutil.TimeoutExpired timeout after 321 seconds "
"(pid=111, name='foo')")
repr(psutil.TimeoutExpired(5)),
"psutil.TimeoutExpired(seconds=5, msg='timeout after 5 seconds')")
self.assertEqual(
repr(psutil.TimeoutExpired(5, pid=321, name="name")),
"psutil.TimeoutExpired(pid=321, name='name', seconds=5, "
"msg='timeout after 5 seconds')")
def test_timeout_expired__str__(self):
self.assertEqual(
str(psutil.TimeoutExpired(5)),
"timeout after 5 seconds")
self.assertEqual(
str(psutil.TimeoutExpired(5, pid=321, name="name")),
"timeout after 5 seconds (pid=321, name='name')")
def test_process__eq__(self):
p1 = psutil.Process()
@ -354,6 +366,8 @@ class TestMisc(PsutilTestCase):
check(psutil.disk_usage(os.getcwd()))
check(psutil.users())
# XXX: https://github.com/pypa/setuptools/pull/2896
@unittest.skipIf(APPVEYOR, "temporarily disabled due to setuptools bug")
def test_setup_script(self):
setup_py = os.path.join(ROOT_DIR, 'setup.py')
if CI_TESTING and not os.path.exists(setup_py):
@ -387,6 +401,35 @@ class TestMisc(PsutilTestCase):
reload_module(psutil)
self.assertIn("version conflict", str(cm.exception).lower())
def test_debug(self):
if PY3:
from io import StringIO
else:
from StringIO import StringIO
with redirect_stderr(StringIO()) as f:
debug("hello")
msg = f.getvalue()
assert msg.startswith("psutil-debug"), msg
self.assertIn("hello", msg)
self.assertIn(__file__.replace('.pyc', '.py'), msg)
# supposed to use repr(exc)
with redirect_stderr(StringIO()) as f:
debug(ValueError("this is an error"))
msg = f.getvalue()
self.assertIn("ignoring ValueError", msg)
self.assertIn("'this is an error'", msg)
# supposed to use str(exc), because of extra info about file name
with redirect_stderr(StringIO()) as f:
exc = OSError(2, "no such file")
exc.filename = "/foo"
debug(exc)
msg = f.getvalue()
self.assertIn("no such file", msg)
self.assertIn("/foo", msg)
# ===================================================================
# --- Tests for wrap_numbers() function.
@ -679,11 +722,12 @@ class TestScripts(PsutilTestCase):
@unittest.skipIf(not POSIX, "POSIX only")
def test_executable(self):
for name in os.listdir(SCRIPTS_DIR):
if name.endswith('.py'):
path = os.path.join(SCRIPTS_DIR, name)
if not stat.S_IXUSR & os.stat(path)[stat.ST_MODE]:
self.fail('%r is not executable' % path)
for root, dirs, files in os.walk(SCRIPTS_DIR):
for file in files:
if file.endswith('.py'):
path = os.path.join(root, file)
if not stat.S_IXUSR & os.stat(path)[stat.ST_MODE]:
raise self.fail('%r is not executable' % path)
def test_disk_usage(self):
self.assert_stdout('disk_usage.py')

View File

@ -11,17 +11,22 @@ import time
import psutil
from psutil import MACOS
from psutil import POSIX
from psutil.tests import HAS_BATTERY
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import PsutilTestCase
from psutil.tests import retry_on_failure
from psutil.tests import sh
from psutil.tests import spawn_testproc
from psutil.tests import terminate
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import TOLERANCE_SYS_MEM
from psutil.tests import unittest
if POSIX:
from psutil._psutil_posix import getpagesize
def sysctl(cmdline):
"""Expects a sysctl command with an argument and parse the result
returning only the value of interest.
@ -36,8 +41,6 @@ def sysctl(cmdline):
def vm_stat(field):
"""Wrapper around 'vm_stat' cmdline utility."""
from psutil._psutil_posix import getpagesize
out = sh('vm_stat')
for line in out.split('\n'):
if field in line:
@ -137,7 +140,7 @@ class TestSystemAPIs(PsutilTestCase):
num = sysctl("sysctl hw.logicalcpu")
self.assertEqual(num, psutil.cpu_count(logical=True))
def test_cpu_count_physical(self):
def test_cpu_count_cores(self):
num = sysctl("sysctl hw.physicalcpu")
self.assertEqual(num, psutil.cpu_count(logical=False))

View File

@ -23,18 +23,19 @@ from psutil import OPENBSD
from psutil import POSIX
from psutil import SUNOS
from psutil.tests import CI_TESTING
from psutil.tests import spawn_testproc
from psutil.tests import HAS_NET_IO_COUNTERS
from psutil.tests import mock
from psutil.tests import PsutilTestCase
from psutil.tests import PYTHON_EXE
from psutil.tests import PsutilTestCase
from psutil.tests import mock
from psutil.tests import retry_on_failure
from psutil.tests import sh
from psutil.tests import skip_on_access_denied
from psutil.tests import spawn_testproc
from psutil.tests import terminate
from psutil.tests import unittest
from psutil.tests import which
if POSIX:
import mmap
import resource

View File

@ -21,7 +21,6 @@ import time
import types
import psutil
from psutil import AIX
from psutil import BSD
from psutil import LINUX
@ -33,15 +32,12 @@ from psutil import POSIX
from psutil import SUNOS
from psutil import WINDOWS
from psutil._common import open_text
from psutil._compat import PY3
from psutil._compat import FileNotFoundError
from psutil._compat import long
from psutil._compat import PY3
from psutil._compat import super
from psutil.tests import APPVEYOR
from psutil.tests import call_until
from psutil.tests import CI_TESTING
from psutil.tests import copyload_shared_lib
from psutil.tests import create_exe
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import GLOBAL_TIMEOUT
from psutil.tests import HAS_CPU_AFFINITY
@ -52,17 +48,20 @@ from psutil.tests import HAS_PROC_CPU_NUM
from psutil.tests import HAS_PROC_IO_COUNTERS
from psutil.tests import HAS_RLIMIT
from psutil.tests import HAS_THREADS
from psutil.tests import mock
from psutil.tests import process_namespace
from psutil.tests import PsutilTestCase
from psutil.tests import PYPY
from psutil.tests import PYTHON_EXE
from psutil.tests import PsutilTestCase
from psutil.tests import ThreadTask
from psutil.tests import call_until
from psutil.tests import copyload_shared_lib
from psutil.tests import create_exe
from psutil.tests import mock
from psutil.tests import process_namespace
from psutil.tests import reap_children
from psutil.tests import retry_on_failure
from psutil.tests import sh
from psutil.tests import skip_on_access_denied
from psutil.tests import skip_on_not_implemented
from psutil.tests import ThreadTask
from psutil.tests import unittest
from psutil.tests import wait_for_pid
@ -718,6 +717,12 @@ class TestProcess(PsutilTestCase):
if NETBSD or OPENBSD or AIX:
self.assertEqual(p.cmdline()[0], PYTHON_EXE)
else:
if MACOS and CI_TESTING:
pyexe = p.cmdline()[0]
if pyexe != PYTHON_EXE:
self.assertEqual(' '.join(p.cmdline()[1:]),
' '.join(cmdline[1:]))
return
self.assertEqual(' '.join(p.cmdline()), ' '.join(cmdline))
@unittest.skipIf(PYPY, "broken on PYPY")
@ -1326,6 +1331,20 @@ class TestProcess(PsutilTestCase):
self.assertEqual(p.status(), psutil.STATUS_ZOMBIE)
assert m.called
def test_reused_pid(self):
# Emulate a case where PID has been reused by another process.
subp = self.spawn_testproc()
p = psutil.Process(subp.pid)
p._ident = (p.pid, p.create_time() + 100)
assert not p.is_running()
assert p != psutil.Process(subp.pid)
msg = "process no longer exists and its PID has been reused"
self.assertRaisesRegex(psutil.NoSuchProcess, msg, p.suspend)
self.assertRaisesRegex(psutil.NoSuchProcess, msg, p.resume)
self.assertRaisesRegex(psutil.NoSuchProcess, msg, p.terminate)
self.assertRaisesRegex(psutil.NoSuchProcess, msg, p.kill)
self.assertRaisesRegex(psutil.NoSuchProcess, msg, p.children)
def test_pid_0(self):
# Process(0) is supposed to work on all platforms except Linux
if 0 not in psutil.pids():
@ -1369,7 +1388,6 @@ class TestProcess(PsutilTestCase):
def test_environ(self):
def clean_dict(d):
# Most of these are problematic on Travis.
d.pop("PSUTIL_TESTING", None)
d.pop("PLAT", None)
d.pop("HOME", None)
if MACOS:
@ -1395,11 +1413,13 @@ class TestProcess(PsutilTestCase):
code = textwrap.dedent("""
#include <unistd.h>
#include <fcntl.h>
char * const argv[] = {"cat", 0};
char * const envp[] = {"A=1", "X", "C=3", 0};
int main(void) {
/* Close stderr on exec so parent can wait for the execve to
* finish. */
// Close stderr on exec so parent can wait for the
// execve to finish.
if (fcntl(2, F_SETFD, FD_CLOEXEC) != 0)
return 0;
return execve("/bin/cat", argv, envp);

View File

@ -31,10 +31,9 @@ from psutil import WINDOWS
from psutil._compat import FileNotFoundError
from psutil._compat import long
from psutil.tests import ASCII_FS
from psutil.tests import check_net_address
from psutil.tests import CI_TESTING
from psutil.tests import DEVNULL
from psutil.tests import enum
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import GLOBAL_TIMEOUT
from psutil.tests import HAS_BATTERY
from psutil.tests import HAS_CPU_FREQ
@ -44,12 +43,13 @@ from psutil.tests import HAS_SENSORS_BATTERY
from psutil.tests import HAS_SENSORS_FANS
from psutil.tests import HAS_SENSORS_TEMPERATURES
from psutil.tests import IS_64BIT
from psutil.tests import mock
from psutil.tests import PsutilTestCase
from psutil.tests import PYPY
from psutil.tests import retry_on_failure
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import UNICODE_SUFFIX
from psutil.tests import PsutilTestCase
from psutil.tests import check_net_address
from psutil.tests import enum
from psutil.tests import mock
from psutil.tests import retry_on_failure
from psutil.tests import unittest
@ -316,16 +316,16 @@ class TestCpuAPIs(PsutilTestCase):
if "physical id" not in cpuinfo_data:
raise unittest.SkipTest("cpuinfo doesn't include physical id")
def test_cpu_count_physical(self):
def test_cpu_count_cores(self):
logical = psutil.cpu_count()
physical = psutil.cpu_count(logical=False)
if physical is None:
raise self.skipTest("physical cpu_count() is None")
cores = psutil.cpu_count(logical=False)
if cores is None:
raise self.skipTest("cpu_count_cores() is None")
if WINDOWS and sys.getwindowsversion()[:2] <= (6, 1): # <= Vista
self.assertIsNone(physical)
self.assertIsNone(cores)
else:
self.assertGreaterEqual(physical, 1)
self.assertGreaterEqual(logical, physical)
self.assertGreaterEqual(cores, 1)
self.assertGreaterEqual(logical, cores)
def test_cpu_count_none(self):
# https://github.com/giampaolo/psutil/issues/1085
@ -334,7 +334,7 @@ class TestCpuAPIs(PsutilTestCase):
return_value=val) as m:
self.assertIsNone(psutil.cpu_count())
assert m.called
with mock.patch('psutil._psplatform.cpu_count_physical',
with mock.patch('psutil._psplatform.cpu_count_cores',
return_value=val) as m:
self.assertIsNone(psutil.cpu_count(logical=False))
assert m.called

View File

@ -17,25 +17,28 @@ import socket
import stat
import subprocess
import psutil
import psutil.tests
from psutil import FREEBSD
from psutil import NETBSD
from psutil import POSIX
from psutil._common import open_binary
from psutil._common import open_text
from psutil._common import supports_ipv6
from psutil.tests import CI_TESTING
from psutil.tests import HAS_CONNECTIONS_UNIX
from psutil.tests import PYTHON_EXE
from psutil.tests import PsutilTestCase
from psutil.tests import TestMemoryLeak
from psutil.tests import bind_socket
from psutil.tests import bind_unix_socket
from psutil.tests import call_until
from psutil.tests import chdir
from psutil.tests import CI_TESTING
from psutil.tests import create_sockets
from psutil.tests import get_free_port
from psutil.tests import HAS_CONNECTIONS_UNIX
from psutil.tests import is_namedtuple
from psutil.tests import mock
from psutil.tests import process_namespace
from psutil.tests import PsutilTestCase
from psutil.tests import PYTHON_EXE
from psutil.tests import reap_children
from psutil.tests import retry
from psutil.tests import retry_on_failure
@ -45,13 +48,11 @@ from psutil.tests import serialrun
from psutil.tests import system_namespace
from psutil.tests import tcp_socketpair
from psutil.tests import terminate
from psutil.tests import TestMemoryLeak
from psutil.tests import unittest
from psutil.tests import unix_socketpair
from psutil.tests import wait_for_file
from psutil.tests import wait_for_pid
import psutil
import psutil.tests
# ===================================================================
# --- Unit tests for test utilities.
@ -350,6 +351,7 @@ class TestNetUtils(PsutilTestCase):
@serialrun
class TestMemLeakClass(TestMemoryLeak):
@retry_on_failure()
def test_times(self):
def fun():
cnt['cnt'] += 1

View File

@ -79,6 +79,7 @@ import traceback
import warnings
from contextlib import closing
import psutil
from psutil import BSD
from psutil import OPENBSD
from psutil import POSIX
@ -87,28 +88,27 @@ from psutil._compat import PY3
from psutil._compat import u
from psutil.tests import APPVEYOR
from psutil.tests import ASCII_FS
from psutil.tests import bind_unix_socket
from psutil.tests import chdir
from psutil.tests import CI_TESTING
from psutil.tests import copyload_shared_lib
from psutil.tests import create_exe
from psutil.tests import get_testfn
from psutil.tests import HAS_CONNECTIONS_UNIX
from psutil.tests import HAS_ENVIRON
from psutil.tests import HAS_MEMORY_MAPS
from psutil.tests import INVALID_UNICODE_SUFFIX
from psutil.tests import PsutilTestCase
from psutil.tests import PYPY
from psutil.tests import TESTFN_PREFIX
from psutil.tests import UNICODE_SUFFIX
from psutil.tests import PsutilTestCase
from psutil.tests import bind_unix_socket
from psutil.tests import chdir
from psutil.tests import copyload_shared_lib
from psutil.tests import create_exe
from psutil.tests import get_testfn
from psutil.tests import safe_mkdir
from psutil.tests import safe_rmpath
from psutil.tests import serialrun
from psutil.tests import skip_on_access_denied
from psutil.tests import spawn_testproc
from psutil.tests import terminate
from psutil.tests import TESTFN_PREFIX
from psutil.tests import UNICODE_SUFFIX
from psutil.tests import unittest
import psutil
if APPVEYOR:

View File

@ -27,15 +27,15 @@ from psutil.tests import APPVEYOR
from psutil.tests import GITHUB_ACTIONS
from psutil.tests import HAS_BATTERY
from psutil.tests import IS_64BIT
from psutil.tests import mock
from psutil.tests import PsutilTestCase
from psutil.tests import PY3
from psutil.tests import PYPY
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import PsutilTestCase
from psutil.tests import mock
from psutil.tests import retry_on_failure
from psutil.tests import sh
from psutil.tests import spawn_testproc
from psutil.tests import terminate
from psutil.tests import TOLERANCE_DISK_USAGE
from psutil.tests import unittest
@ -47,24 +47,13 @@ if WINDOWS and not PYPY:
import win32process
import wmi # requires "pip install wmi" / "make setup-dev-env"
if WINDOWS:
from psutil._pswindows import convert_oserror
cext = psutil._psplatform.cext
def wrap_exceptions(fun):
def wrapper(self, *args, **kwargs):
try:
return fun(self, *args, **kwargs)
except OSError as err:
from psutil._pswindows import ACCESS_DENIED_SET
if err.errno in ACCESS_DENIED_SET:
raise psutil.AccessDenied(None, None)
if err.errno == errno.ESRCH:
raise psutil.NoSuchProcess(None, None)
raise
return wrapper
@unittest.skipIf(not WINDOWS, "WINDOWS only")
@unittest.skipIf(PYPY, "pywin32 not available on PYPY")
# https://github.com/giampaolo/psutil/pull/1762#issuecomment-632892692
@ -100,7 +89,7 @@ class TestCpuAPIs(WindowsTestCase):
proc = w.Win32_Processor()[0]
self.assertEqual(psutil.cpu_count(), proc.NumberOfLogicalProcessors)
def test_cpu_count_phys_vs_wmi(self):
def test_cpu_count_cores_vs_wmi(self):
w = wmi.WMI()
proc = w.Win32_Processor()[0]
self.assertEqual(psutil.cpu_count(logical=False), proc.NumberOfCores)
@ -633,7 +622,6 @@ class TestDualProcessImplementation(PsutilTestCase):
assert fun.called
def test_cmdline(self):
from psutil._pswindows import convert_oserror
for pid in psutil.pids():
try:
a = cext.proc_cmdline(pid, use_peb=True)
@ -725,7 +713,7 @@ class RemoteProcessTestCase(PsutilTestCase):
p = psutil.Process(self.proc32.pid)
e = p.environ()
self.assertIn("THINK_OF_A_NUMBER", e)
self.assertEquals(e["THINK_OF_A_NUMBER"], str(os.getpid()))
self.assertEqual(e["THINK_OF_A_NUMBER"], str(os.getpid()))
def test_environ_64(self):
p = psutil.Process(self.proc64.pid)

View File

@ -1,19 +0,0 @@
Copyright Jason R. Coombs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View File

@ -1,124 +0,0 @@
Metadata-Version: 2.1
Name: setuptools
Version: 60.0.3
Summary: Easily download, build, install, upgrade, and uninstall Python packages
Home-page: https://github.com/pypa/setuptools
Author: Python Packaging Authority
Author-email: distutils-sig@python.org
License: UNKNOWN
Project-URL: Documentation, https://setuptools.pypa.io/
Keywords: CPAN PyPI distutils eggs package management
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Archiving :: Packaging
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=3.7
License-File: LICENSE
Provides-Extra: certs
Provides-Extra: docs
Requires-Dist: sphinx ; extra == 'docs'
Requires-Dist: jaraco.packaging (>=8.2) ; extra == 'docs'
Requires-Dist: rst.linker (>=1.9) ; extra == 'docs'
Requires-Dist: jaraco.tidelift (>=1.4) ; extra == 'docs'
Requires-Dist: pygments-github-lexers (==0.0.5) ; extra == 'docs'
Requires-Dist: sphinx-inline-tabs ; extra == 'docs'
Requires-Dist: sphinxcontrib-towncrier ; extra == 'docs'
Requires-Dist: furo ; extra == 'docs'
Provides-Extra: ssl
Provides-Extra: testing
Requires-Dist: pytest (>=6) ; extra == 'testing'
Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing'
Requires-Dist: pytest-flake8 ; extra == 'testing'
Requires-Dist: pytest-cov ; extra == 'testing'
Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing'
Requires-Dist: mock ; extra == 'testing'
Requires-Dist: flake8-2020 ; extra == 'testing'
Requires-Dist: virtualenv (>=13.0.0) ; extra == 'testing'
Requires-Dist: pytest-virtualenv (>=1.2.7) ; extra == 'testing'
Requires-Dist: wheel ; extra == 'testing'
Requires-Dist: paver ; extra == 'testing'
Requires-Dist: pip (>=19.1) ; extra == 'testing'
Requires-Dist: jaraco.envs (>=2.2) ; extra == 'testing'
Requires-Dist: pytest-xdist ; extra == 'testing'
Requires-Dist: sphinx ; extra == 'testing'
Requires-Dist: jaraco.path (>=3.2.0) ; extra == 'testing'
Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing'
Requires-Dist: pytest-mypy ; (platform_python_implementation != "PyPy") and extra == 'testing'
.. image:: https://raw.githubusercontent.com/pypa/setuptools/main/docs/images/banner-640x320.svg
:align: center
|
.. image:: https://img.shields.io/pypi/v/setuptools.svg
:target: `PyPI link`_
.. image:: https://img.shields.io/pypi/pyversions/setuptools.svg
:target: `PyPI link`_
.. _PyPI link: https://pypi.org/project/setuptools
.. image:: https://github.com/pypa/setuptools/workflows/tests/badge.svg
:target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22
:alt: tests
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/psf/black
:alt: Code style: Black
.. image:: https://img.shields.io/readthedocs/setuptools/latest.svg
:target: https://setuptools.pypa.io
.. image:: https://img.shields.io/badge/skeleton-2021-informational
:target: https://blog.jaraco.com/skeleton
.. image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white
:target: https://codecov.io/gh/pypa/setuptools
.. image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat
:target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme
See the `Installation Instructions
<https://packaging.python.org/installing/>`_ in the Python Packaging
User's Guide for instructions on installing, upgrading, and uninstalling
Setuptools.
Questions and comments should be directed to the `distutils-sig
mailing list <http://mail.python.org/pipermail/distutils-sig/>`_.
Bug reports and especially tested patches may be
submitted directly to the `bug tracker
<https://github.com/pypa/setuptools/issues>`_.
Code of Conduct
===============
Everyone interacting in the setuptools project's codebases, issue trackers,
chat rooms, and mailing lists is expected to follow the
`PSF Code of Conduct <https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md>`_.
For Enterprise
==============
Available as part of the Tidelift Subscription.
Setuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
`Learn more <https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=referral&utm_campaign=github>`_.
Security Contact
================
To report a security vulnerability, please use the
`Tidelift security contact <https://tidelift.com/security>`_.
Tidelift will coordinate the fix and disclosure.

View File

@ -1,297 +0,0 @@
_distutils_hack/__init__.py,sha256=8AFtsXYDw0MMp6RE4osVd0Rdnaf38y90btaCDDRCoH0,4014
_distutils_hack/__pycache__/__init__.cpython-39.pyc,,
_distutils_hack/__pycache__/override.cpython-39.pyc,,
_distutils_hack/override.py,sha256=Eu_s-NF6VIZ4Cqd0tbbA5wtWky2IZPNd8et6GLt1mzo,44
distutils-precedence.pth,sha256=JjjOniUA5XKl4N5_rtZmHrVp0baW_LoHsN0iPaX10iQ,151
pkg_resources/__init__.py,sha256=uAnPq8FsTXHAEHFWK7UU9AhdNjE4o5Skfk8CyfbztO8,108573
pkg_resources/__pycache__/__init__.cpython-39.pyc,,
pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pkg_resources/_vendor/__pycache__/__init__.cpython-39.pyc,,
pkg_resources/_vendor/__pycache__/appdirs.cpython-39.pyc,,
pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc,,
pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701
pkg_resources/_vendor/packaging/__about__.py,sha256=IIRHpOsJlJSgkjq1UoeBoMTqhvNp3gN9FyMb5Kf8El4,661
pkg_resources/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497
pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/tags.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/utils.cpython-39.pyc,,
pkg_resources/_vendor/packaging/__pycache__/version.cpython-39.pyc,,
pkg_resources/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488
pkg_resources/_vendor/packaging/_musllinux.py,sha256=z5yeG1ygOPx4uUyLdqj-p8Dk5UBb5H_b0NIjW9yo8oA,4378
pkg_resources/_vendor/packaging/_structures.py,sha256=TMiAgFbdUOPmIfDIfiHc3KFhSJ8kMjof2QS5I-2NyQ8,1629
pkg_resources/_vendor/packaging/markers.py,sha256=gFSKoBTb0sKDw1v_apJy15lPr0v2mEvuEkfooTtcWx4,8496
pkg_resources/_vendor/packaging/requirements.py,sha256=uJ4cjwm3_nrfHJLCcGU9mT5aw8SXfw8v1aBUD7OFuVs,4706
pkg_resources/_vendor/packaging/specifiers.py,sha256=MZ-fYcNL3u7pNrt-6g2EQO7AbRXkjc-SPEYwXMQbLmc,30964
pkg_resources/_vendor/packaging/tags.py,sha256=vGybAUQYlPKMcukzX_2e65fmafnFFuMbD25naYTEwtc,15710
pkg_resources/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200
pkg_resources/_vendor/packaging/version.py,sha256=_fLRNrFrxYcHVfyo8vk9j8s6JM8N_xsSxVFr6RJyco8,14665
pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055
pkg_resources/extern/__init__.py,sha256=3PixaT9Tzzd4NoyV6CVhGd7S_9Z-U5yvMWAftZKvC6k,2362
pkg_resources/extern/__pycache__/__init__.cpython-39.pyc,,
pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-39.pyc,,
pkg_resources/tests/data/my-test-package-source/setup.py,sha256=Mrezl3nqxkYkjCYpIxmjhhg4AR8hgi4QZdEYmk-I7R8,104
setuptools-60.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
setuptools-60.0.3.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050
setuptools-60.0.3.dist-info/METADATA,sha256=mGuu7DhncmGsqzGoOzN0s1FZ7ydotAT7_hVg2x2veRQ,4963
setuptools-60.0.3.dist-info/RECORD,,
setuptools-60.0.3.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
setuptools-60.0.3.dist-info/entry_points.txt,sha256=wpnhLrbtyk4hZ1qCCw48cCSxoQPzULMhIuaFqsB7GxQ,2636
setuptools-60.0.3.dist-info/top_level.txt,sha256=d9yL39v_W7qmKDDSH6sT4bE0j_Ls1M3P161OGgdsm4g,41
setuptools/__init__.py,sha256=l7ULo8jGk-4-8jbacmJ58cYpSRX4swS1ccbJaJVAGdM,7448
setuptools/__pycache__/__init__.cpython-39.pyc,,
setuptools/__pycache__/_deprecation_warning.cpython-39.pyc,,
setuptools/__pycache__/_imp.cpython-39.pyc,,
setuptools/__pycache__/archive_util.cpython-39.pyc,,
setuptools/__pycache__/build_meta.cpython-39.pyc,,
setuptools/__pycache__/config.cpython-39.pyc,,
setuptools/__pycache__/dep_util.cpython-39.pyc,,
setuptools/__pycache__/depends.cpython-39.pyc,,
setuptools/__pycache__/dist.cpython-39.pyc,,
setuptools/__pycache__/errors.cpython-39.pyc,,
setuptools/__pycache__/extension.cpython-39.pyc,,
setuptools/__pycache__/glob.cpython-39.pyc,,
setuptools/__pycache__/installer.cpython-39.pyc,,
setuptools/__pycache__/launch.cpython-39.pyc,,
setuptools/__pycache__/monkey.cpython-39.pyc,,
setuptools/__pycache__/msvc.cpython-39.pyc,,
setuptools/__pycache__/namespaces.cpython-39.pyc,,
setuptools/__pycache__/package_index.cpython-39.pyc,,
setuptools/__pycache__/py34compat.cpython-39.pyc,,
setuptools/__pycache__/sandbox.cpython-39.pyc,,
setuptools/__pycache__/unicode_utils.cpython-39.pyc,,
setuptools/__pycache__/version.cpython-39.pyc,,
setuptools/__pycache__/wheel.cpython-39.pyc,,
setuptools/__pycache__/windows_support.cpython-39.pyc,,
setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218
setuptools/_distutils/__init__.py,sha256=3YtkfadGoU57VMEQFk2TNyMZVud1kDkakWQLhWg2Fm8,536
setuptools/_distutils/__pycache__/__init__.cpython-39.pyc,,
setuptools/_distutils/__pycache__/_msvccompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/archive_util.cpython-39.pyc,,
setuptools/_distutils/__pycache__/bcppcompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/ccompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/cmd.cpython-39.pyc,,
setuptools/_distutils/__pycache__/config.cpython-39.pyc,,
setuptools/_distutils/__pycache__/core.cpython-39.pyc,,
setuptools/_distutils/__pycache__/cygwinccompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/debug.cpython-39.pyc,,
setuptools/_distutils/__pycache__/dep_util.cpython-39.pyc,,
setuptools/_distutils/__pycache__/dir_util.cpython-39.pyc,,
setuptools/_distutils/__pycache__/dist.cpython-39.pyc,,
setuptools/_distutils/__pycache__/errors.cpython-39.pyc,,
setuptools/_distutils/__pycache__/extension.cpython-39.pyc,,
setuptools/_distutils/__pycache__/fancy_getopt.cpython-39.pyc,,
setuptools/_distutils/__pycache__/file_util.cpython-39.pyc,,
setuptools/_distutils/__pycache__/filelist.cpython-39.pyc,,
setuptools/_distutils/__pycache__/log.cpython-39.pyc,,
setuptools/_distutils/__pycache__/msvc9compiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/msvccompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/py35compat.cpython-39.pyc,,
setuptools/_distutils/__pycache__/py38compat.cpython-39.pyc,,
setuptools/_distutils/__pycache__/spawn.cpython-39.pyc,,
setuptools/_distutils/__pycache__/sysconfig.cpython-39.pyc,,
setuptools/_distutils/__pycache__/text_file.cpython-39.pyc,,
setuptools/_distutils/__pycache__/unixccompiler.cpython-39.pyc,,
setuptools/_distutils/__pycache__/util.cpython-39.pyc,,
setuptools/_distutils/__pycache__/version.cpython-39.pyc,,
setuptools/_distutils/__pycache__/versionpredicate.cpython-39.pyc,,
setuptools/_distutils/_msvccompiler.py,sha256=jR0JM5A1JMnZ6xMDicQzhXWgXTVXs1lWAeUexC1z198,20813
setuptools/_distutils/archive_util.py,sha256=qW-uiGwYexTvK5e-iSel_31Dshx-CqTanNPK6snwf98,8572
setuptools/_distutils/bcppcompiler.py,sha256=OJDVpCUmX6H8v_7lV1zifV1fcx92Cr2dhiUh6989UJI,14894
setuptools/_distutils/ccompiler.py,sha256=YbernlpGZZqKnfzZSfJ814fINca8cicZiUlBjyUPyaM,47644
setuptools/_distutils/cmd.py,sha256=eco6LAGUtobLuPafuhmgKgkwRRL_WY8KJ4YeDCHpcls,18079
setuptools/_distutils/command/__init__.py,sha256=2TA-rlNDlzeI-csbWHXFjGD8uOYqALMfyWOhT49nC6g,799
setuptools/_distutils/command/__pycache__/__init__.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/bdist.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/bdist_msi.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/build.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/build_clib.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/build_ext.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/build_py.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/build_scripts.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/check.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/clean.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/config.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install_data.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install_egg_info.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install_headers.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install_lib.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/install_scripts.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/py37compat.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/register.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/sdist.cpython-39.pyc,,
setuptools/_distutils/command/__pycache__/upload.cpython-39.pyc,,
setuptools/_distutils/command/bdist.py,sha256=2z4eudRl_n7m3lG9leL0IYqes4bsm8c0fxfZuiafjMg,5562
setuptools/_distutils/command/bdist_dumb.py,sha256=BTur9jcIppyP7Piavjfsk7YjElqvxeYO2npUyPPOekc,4913
setuptools/_distutils/command/bdist_msi.py,sha256=EVFQYN_X-ExeeP8gmdV9JcINsuUGsLJUz9afMU0Rt8c,35579
setuptools/_distutils/command/bdist_rpm.py,sha256=gjOw22GhDSbcq0bdq25cTb-n6HWWm0bShLQad_mkJ4k,21537
setuptools/_distutils/command/bdist_wininst.py,sha256=iGlaI-VfElHOneeczKHWnSN5a10-7IMcJaXuR1mdS3c,16030
setuptools/_distutils/command/build.py,sha256=1AF-dxN_NlOEyoydBz19AwpeWYPSYCZvOLJSN_PdatY,5773
setuptools/_distutils/command/build_clib.py,sha256=bgVTHh28eLQA2Gkw68amApd_j7qQBX4MTI-zTvAK_J4,8022
setuptools/_distutils/command/build_ext.py,sha256=KgxpopuD6sqep0LsumMH15joWih0VdbnXpYm-ETNjoE,31612
setuptools/_distutils/command/build_py.py,sha256=hXesMrH_epNj6K8SUtJdipgEis3EdICKeZ8VWe_ndck,16495
setuptools/_distutils/command/build_scripts.py,sha256=urdn6wPxPMW5dLqpqFkZ8dqaFG1tf9TiAao6U9LCoEI,5963
setuptools/_distutils/command/check.py,sha256=5qDtI75ccZg3sAItQWeaIu8y3FR314O4rr9Smz4HsEo,5637
setuptools/_distutils/command/clean.py,sha256=2TCt47ru4hZZM0RfVfUYj5bbpicpGLP4Qhw5jBtvp9k,2776
setuptools/_distutils/command/config.py,sha256=2aTjww3PwjMB8-ZibCe4P7B-qG1hM1gn_rJXYyxRz6c,13117
setuptools/_distutils/command/install.py,sha256=wpaYPr38D55ZL9JCLqHKuTIUdhwX9K3LyQ_4T2E2n8w,29704
setuptools/_distutils/command/install_data.py,sha256=YhGOAwh3gJPqF7em5XA0rmpR42z1bLh80ooElzDyUvk,2822
setuptools/_distutils/command/install_egg_info.py,sha256=WijZ7cHMAkNMMCwrZ--KoqV9M2RtLouU4-qSbiCwv70,2753
setuptools/_distutils/command/install_headers.py,sha256=XQ6idkbIDfr1ljXCOznuVUMvOFpHBn6cK0Wz9gIM2b4,1298
setuptools/_distutils/command/install_lib.py,sha256=9AofR-MO9lAtjwwuukCptepOaJEKMZW2VHiyR5hU7HA,8397
setuptools/_distutils/command/install_scripts.py,sha256=_CLUeQwGJRcY2kik7azPMn5IdtDCrjWdUvZ1khlG6ck,2017
setuptools/_distutils/command/py37compat.py,sha256=qzRhhvTihqx_PZZt2ZYECxh1X3Oj255VqatzelYFAKw,671
setuptools/_distutils/command/register.py,sha256=2jaq9968rt2puRVDBx1HbNiXv27uOk8idE_4lPf_3VM,11712
setuptools/_distutils/command/sdist.py,sha256=qotJjAOzyhJjq2-oDImjNFrOtaSneEFDJTB-sEk1wnU,19005
setuptools/_distutils/command/upload.py,sha256=BLO1w7eSAqsCjCLXtf_CRVSjwF1WmyOByGVGNdcQ8oY,7597
setuptools/_distutils/config.py,sha256=dtHgblx9JhfyrKx1-J7Jlxw_f7s8ZbPFQii2UWMTZpY,4827
setuptools/_distutils/core.py,sha256=0v7Emh9y0AW9o4AEjfVMhDxKzTFWFxUQn46spFSL56g,9282
setuptools/_distutils/cygwinccompiler.py,sha256=oZh-mbF-3ClAsZBplFrxt4ck9iXXNIK3ipFNNfdnGIk,17357
setuptools/_distutils/debug.py,sha256=N6MrTAqK6l9SVk6tWweR108PM8Ol7qNlfyV-nHcLhsY,139
setuptools/_distutils/dep_util.py,sha256=GuR9Iw_jzZRkyemJ5HX8rB_wRGxkIBcBm1qh54r7zhk,3491
setuptools/_distutils/dir_util.py,sha256=UwhBOUTcV65GTwce4SPuTXR8Z8q3LYEcmttqcGb0bYo,7778
setuptools/_distutils/dist.py,sha256=Biuf6ca8uiFfMScRFsYUKtb5neMPtxKxRtXn50_1f3U,50421
setuptools/_distutils/errors.py,sha256=Yr6tKZGdzBoNi53vBtiq0UJ__X05CmxSdQJqOWaw6SY,3577
setuptools/_distutils/extension.py,sha256=bTb3Q0CoevGKYv5dX1ls--Ln8tlB0-UEOsi9BwzlZ-s,10515
setuptools/_distutils/fancy_getopt.py,sha256=OPxp2CxHi1Yp_d1D8JxW4Ueq9fC71tegQFaafh58GGU,17784
setuptools/_distutils/file_util.py,sha256=0hUqfItN_x2DVihR0MHdA4KCMVCOO8VoByaFp_a6MDg,8148
setuptools/_distutils/filelist.py,sha256=Z9f5hvepZnpniZ2IFmCnWIjdviWozs8sbARBhWajwoM,13407
setuptools/_distutils/log.py,sha256=hWBmdUC2K927QcVv3REMW3HMPclxccPQngxLSuUXQl0,1969
setuptools/_distutils/msvc9compiler.py,sha256=23cxMWGk2i8iFEvr5xdAXThlGM4LDuhQcM0175psc7A,30483
setuptools/_distutils/msvccompiler.py,sha256=qruALeGRq8-CjtjE2tLQ8W26QnchcYedWzFme8AxZ4Q,23540
setuptools/_distutils/py35compat.py,sha256=-sk1vBIsOgH-AobjIYbK_OEjdJF_54Ul_D1EiE9XM_c,455
setuptools/_distutils/py38compat.py,sha256=II7ddBxOijC7uNN4z_46HYUjwYTJYMNiLJoGTormZm0,212
setuptools/_distutils/spawn.py,sha256=4uE9k3VZWijxy7E_Rlcmh1MoamaPJ8rajdNBagKxjgU,3498
setuptools/_distutils/sysconfig.py,sha256=k3fzINx3-qjge0udI6fC1UQSDPYpMGrxeSuV9cY4rmU,22151
setuptools/_distutils/text_file.py,sha256=PsuAJeWdKJoLSV_6N6IpB5-0Pa84KzLUucJMFRazw3I,12483
setuptools/_distutils/unixccompiler.py,sha256=u2Sfs6LRmqQux4nZW08GwDtoFMded6wYnkiaO2TvKC4,14538
setuptools/_distutils/util.py,sha256=0v7B6nIsAXP11A7xqS6FC6lFAdaIqzxz_C-at4aMcgs,20655
setuptools/_distutils/version.py,sha256=syRvPxuMQxnftpuIKeRE-2ELQ_ZMCwMJ-o8ie-lxdZo,13015
setuptools/_distutils/versionpredicate.py,sha256=vx4ND3BtMgxFR9iZ4_t3WFa-NdIKxO8vtOd0twBppxc,5277
setuptools/_imp.py,sha256=HmF91IbitRfsD5z-g4_wmcuH-RahyIONbPgiCOFgtzA,2392
setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
setuptools/_vendor/__pycache__/__init__.cpython-39.pyc,,
setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc,,
setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc,,
setuptools/_vendor/more_itertools/__init__.py,sha256=C7sXffHTXM3P-iaLPPfqfmDoxOflQMJLcM7ed9p3jak,82
setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-39.pyc,,
setuptools/_vendor/more_itertools/__pycache__/more.cpython-39.pyc,,
setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-39.pyc,,
setuptools/_vendor/more_itertools/more.py,sha256=DlZa8v6JihVwfQ5zHidOA-xDE0orcQIUyxVnCaUoDKE,117968
setuptools/_vendor/more_itertools/recipes.py,sha256=UkNkrsZyqiwgLHANBTmvMhCvaNSvSNYhyOpz_Jc55DY,16256
setuptools/_vendor/ordered_set.py,sha256=dbaCcs27dyN9gnMWGF5nA_BrVn6Q-NrjKYJpV9_fgBs,15130
setuptools/_vendor/packaging/__about__.py,sha256=IIRHpOsJlJSgkjq1UoeBoMTqhvNp3gN9FyMb5Kf8El4,661
setuptools/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497
setuptools/_vendor/packaging/__pycache__/__about__.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/__init__.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/_structures.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/requirements.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/utils.cpython-39.pyc,,
setuptools/_vendor/packaging/__pycache__/version.cpython-39.pyc,,
setuptools/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488
setuptools/_vendor/packaging/_musllinux.py,sha256=z5yeG1ygOPx4uUyLdqj-p8Dk5UBb5H_b0NIjW9yo8oA,4378
setuptools/_vendor/packaging/_structures.py,sha256=TMiAgFbdUOPmIfDIfiHc3KFhSJ8kMjof2QS5I-2NyQ8,1629
setuptools/_vendor/packaging/markers.py,sha256=lihRgqpZjLM-JW-vxlLPqU3kmVe79g9vypy1kxmTRuQ,8493
setuptools/_vendor/packaging/requirements.py,sha256=Opd0FjqgdEiWkzBLyo1oLU0Dj01uIFwTAnAJQrr6j2A,4700
setuptools/_vendor/packaging/specifiers.py,sha256=MZ-fYcNL3u7pNrt-6g2EQO7AbRXkjc-SPEYwXMQbLmc,30964
setuptools/_vendor/packaging/tags.py,sha256=vGybAUQYlPKMcukzX_2e65fmafnFFuMbD25naYTEwtc,15710
setuptools/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200
setuptools/_vendor/packaging/version.py,sha256=_fLRNrFrxYcHVfyo8vk9j8s6JM8N_xsSxVFr6RJyco8,14665
setuptools/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055
setuptools/archive_util.py,sha256=maJDbozRbDeSPw53VT0cb_IS3W0Ap73lJR8tX8RZDx0,7077
setuptools/build_meta.py,sha256=hCU742vjgXHY6oKPYttBkie-n4DVNAJrUOgn0O_V3nc,10536
setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536
setuptools/cli-64.exe,sha256=KLABu5pyrnokJCv6skjXZ6GsXeyYHGcqOUT3oHI3Xpo,74752
setuptools/cli-arm64.exe,sha256=o9amxowudZ98NvNWh_a2DRY8LhoIRqTAekxABqltiMc,137216
setuptools/cli.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536
setuptools/command/__init__.py,sha256=e-8TJOikUe3St0fw2b2p9u5EDdSxl5zHUBJJKifbcQ8,217
setuptools/command/__pycache__/__init__.cpython-39.pyc,,
setuptools/command/__pycache__/alias.cpython-39.pyc,,
setuptools/command/__pycache__/bdist_egg.cpython-39.pyc,,
setuptools/command/__pycache__/bdist_rpm.cpython-39.pyc,,
setuptools/command/__pycache__/build_clib.cpython-39.pyc,,
setuptools/command/__pycache__/build_ext.cpython-39.pyc,,
setuptools/command/__pycache__/build_py.cpython-39.pyc,,
setuptools/command/__pycache__/develop.cpython-39.pyc,,
setuptools/command/__pycache__/dist_info.cpython-39.pyc,,
setuptools/command/__pycache__/easy_install.cpython-39.pyc,,
setuptools/command/__pycache__/egg_info.cpython-39.pyc,,
setuptools/command/__pycache__/install.cpython-39.pyc,,
setuptools/command/__pycache__/install_egg_info.cpython-39.pyc,,
setuptools/command/__pycache__/install_lib.cpython-39.pyc,,
setuptools/command/__pycache__/install_scripts.cpython-39.pyc,,
setuptools/command/__pycache__/py36compat.cpython-39.pyc,,
setuptools/command/__pycache__/register.cpython-39.pyc,,
setuptools/command/__pycache__/rotate.cpython-39.pyc,,
setuptools/command/__pycache__/saveopts.cpython-39.pyc,,
setuptools/command/__pycache__/sdist.cpython-39.pyc,,
setuptools/command/__pycache__/setopt.cpython-39.pyc,,
setuptools/command/__pycache__/test.cpython-39.pyc,,
setuptools/command/__pycache__/upload.cpython-39.pyc,,
setuptools/command/__pycache__/upload_docs.cpython-39.pyc,,
setuptools/command/alias.py,sha256=1sLQxZcNh6dDQpDmm4G7UGGTol83nY1NTPmNBbm2siI,2381
setuptools/command/bdist_egg.py,sha256=-upiB6fFtm8cQSQj1LRDVpG1-T143DsXCvV0fh03u7U,16604
setuptools/command/bdist_rpm.py,sha256=PxrgoHPNaw2Pw2qNjjHDPC-Ay_IaDbCqP3d_5N-cj2A,1182
setuptools/command/build_clib.py,sha256=fWHSFGkk10VCddBWCszvNhowbG9Z9CZXVjQ2uSInoOs,4415
setuptools/command/build_ext.py,sha256=SNK042HfB2ezlDQbSVRGFqI1IM5A4AsjU1wpV3fgskE,13212
setuptools/command/build_py.py,sha256=c90V1nVPEtYkdye-xvo-B48V5RLvSgD8JBMfPtUbtYw,8751
setuptools/command/develop.py,sha256=5_Ss7ENd1_B_jVMY1tF5UV_y1Xu6jbVzAPG8oKeluGA,7012
setuptools/command/dist_info.py,sha256=5t6kOfrdgALT-P3ogss6PF9k-Leyesueycuk3dUyZnI,960
setuptools/command/easy_install.py,sha256=gapK3GqeIhiT1DEXX46orMxWC6bJRa8lxp9usbBD1Ts,85791
setuptools/command/egg_info.py,sha256=0Y3BXOaQ5tftvCet6LA4lD4A_K9igTKfl-wUJmvs84A,26126
setuptools/command/install.py,sha256=UynjFBgRyyHrDZRVAmXrXG0vChJAMx-sxnOO3JoAzVo,4906
setuptools/command/install_egg_info.py,sha256=bMgeIeRiXzQ4DAGPV1328kcjwQjHjOWU4FngAWLV78Q,2203
setuptools/command/install_lib.py,sha256=Uz42McsyHZAjrB6cw9E7Bz0xsaTbzxnM1PI9CBhiPtE,3875
setuptools/command/install_scripts.py,sha256=o0jN_ex7yYYk8W5clymTFOXwkFMKzW9q_zd9Npcex7M,2593
setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628
setuptools/command/py36compat.py,sha256=7yLWzQj179Enx3pJ8V1cDDCzeLMFMd9XJXlK-iZTq5Y,4946
setuptools/command/register.py,sha256=kk3DxXCb5lXTvqnhfwx2g6q7iwbUmgTyXUCaBooBOUk,468
setuptools/command/rotate.py,sha256=SvsQPasezIojPjvMnfkqzh8P0U0tCj0daczF8uc3NQM,2128
setuptools/command/saveopts.py,sha256=za7QCBcQimKKriWcoCcbhxPjUz30gSB74zuTL47xpP4,658
setuptools/command/sdist.py,sha256=2onJidYBPFpUgcX6J4KjZX5ilwciHPRB8VkID5YVaL0,6413
setuptools/command/setopt.py,sha256=okxhqD1NM1nQlbSVDCNv6P7Y7g680sc2r-tUW7wPH1Y,5086
setuptools/command/test.py,sha256=qGY-Hx1RPCndlVh2rsrEs5479CgmxRsrEflVLr98jVA,8088
setuptools/command/upload.py,sha256=XT3YFVfYPAmA5qhGg0euluU98ftxRUW-PzKcODMLxUs,462
setuptools/command/upload_docs.py,sha256=ba5kOyedD_u62weinrxqqnvpuQvBIuamXehJG6tAvO0,7218
setuptools/config.py,sha256=O-T_28163qkEeaX8bLgqJLuOLYur15cC2_xpA0RENfM,23153
setuptools/dep_util.py,sha256=BDx1BkzNQntvAB4alypHbW5UVBzjqths000PrUL4Zqc,949
setuptools/depends.py,sha256=QYQIadr5DwLxPzkErhNt5hmRhvGhWxoXZMRXCm_jcQ0,5499
setuptools/dist.py,sha256=y3gQZbodbqOTG_cXFXuQ2OnTwciIlpZpIciapxOIfBc,43154
setuptools/errors.py,sha256=t4Rm85eXm71Ti0-PO1gAQMRK3V7NN3x1tcbcw0-xGSI,1555
setuptools/extension.py,sha256=NMM46XjNdVelWemc0x8CyVKA5Ks6Zm3xTWSA2SS6xZM,1684
setuptools/extern/__init__.py,sha256=Hhf9W73WAitw9TdRJfDIb6YFjmK56CF61afds1Mg0HY,2407
setuptools/extern/__pycache__/__init__.cpython-39.pyc,,
setuptools/glob.py,sha256=1oZjbfjAHSXbgdhSuR6YGU8jKob9L8NtEmBYqcPTLYk,4873
setuptools/gui-32.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536
setuptools/gui-64.exe,sha256=aYKMhX1IJLn4ULHgWX0sE0yREUt6B3TEHf_jOw6yNyE,75264
setuptools/gui-arm64.exe,sha256=TEFnOKDi-mq3ZszxqbCoCXTnM_lhUWjdIqBpr6fVs40,137728
setuptools/gui.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536
setuptools/installer.py,sha256=s6DQfsoICBJxbUqbduhOJtl1oG0S4yegRCg3EAs0i3M,3824
setuptools/launch.py,sha256=TyPT-Ic1T2EnYvGO26gfNRP4ysBlrhpbRjQxWsiO414,812
setuptools/monkey.py,sha256=0e3HdVKXHL415O7np-AUqhEFXPPuDdJKbI47chQ_DE4,5217
setuptools/msvc.py,sha256=3LLt938e6OR7wWPzIvCQu7LCWZSIKqoKV6w3r8jV3kY,50561
setuptools/namespaces.py,sha256=PMqGVPXPYQgjUTvEg9bGccRAkIODrQ6NmsDg_fwErwI,3093
setuptools/package_index.py,sha256=SV0gUvX5-uEsnjDJYCS5IRiWs-zEqN5H_vYJcuaq7-A,40092
setuptools/py34compat.py,sha256=KYOd6ybRxjBW8NJmYD8t_UyyVmysppFXqHpFLdslGXU,245
setuptools/sandbox.py,sha256=mR83i-mu-ZUU_7TaMgYCeRSyzkqv8loJ_GR9xhS2DDw,14348
setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218
setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138
setuptools/unicode_utils.py,sha256=aOOFo4JGwAsiBttGYDsqFS7YqWQeZ2j6DWiCuctR_00,941
setuptools/version.py,sha256=og_cuZQb0QI6ukKZFfZWPlr1HgJBPPn2vO2m_bI9ZTE,144
setuptools/wheel.py,sha256=0P8tSk105uF_Ub-30N2HU2X2v7MKDSdjpeQlRRW3SkI,8288
setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714

View File

@ -1,5 +0,0 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.37.0)
Root-Is-Purelib: true
Tag: py3-none-any

View File

@ -1,56 +0,0 @@
[distutils.commands]
alias = setuptools.command.alias:alias
bdist_egg = setuptools.command.bdist_egg:bdist_egg
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
build_clib = setuptools.command.build_clib:build_clib
build_ext = setuptools.command.build_ext:build_ext
build_py = setuptools.command.build_py:build_py
develop = setuptools.command.develop:develop
dist_info = setuptools.command.dist_info:dist_info
easy_install = setuptools.command.easy_install:easy_install
egg_info = setuptools.command.egg_info:egg_info
install = setuptools.command.install:install
install_egg_info = setuptools.command.install_egg_info:install_egg_info
install_lib = setuptools.command.install_lib:install_lib
install_scripts = setuptools.command.install_scripts:install_scripts
rotate = setuptools.command.rotate:rotate
saveopts = setuptools.command.saveopts:saveopts
sdist = setuptools.command.sdist:sdist
setopt = setuptools.command.setopt:setopt
test = setuptools.command.test:test
upload_docs = setuptools.command.upload_docs:upload_docs
[distutils.setup_keywords]
dependency_links = setuptools.dist:assert_string_list
eager_resources = setuptools.dist:assert_string_list
entry_points = setuptools.dist:check_entry_points
exclude_package_data = setuptools.dist:check_package_data
extras_require = setuptools.dist:check_extras
include_package_data = setuptools.dist:assert_bool
install_requires = setuptools.dist:check_requirements
namespace_packages = setuptools.dist:check_nsp
package_data = setuptools.dist:check_package_data
packages = setuptools.dist:check_packages
python_requires = setuptools.dist:check_specifier
setup_requires = setuptools.dist:check_requirements
test_loader = setuptools.dist:check_importable
test_runner = setuptools.dist:check_importable
test_suite = setuptools.dist:check_test_suite
tests_require = setuptools.dist:check_requirements
use_2to3 = setuptools.dist:invalid_unless_false
zip_safe = setuptools.dist:assert_bool
[egg_info.writers]
PKG-INFO = setuptools.command.egg_info:write_pkg_info
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
depends.txt = setuptools.command.egg_info:warn_depends_obsolete
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
entry_points.txt = setuptools.command.egg_info:write_entries
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
requires.txt = setuptools.command.egg_info:write_requirements
top_level.txt = setuptools.command.egg_info:write_toplevel_names
[setuptools.finalize_distribution_options]
keywords = setuptools.dist:Distribution._finalize_setup_keywords
parent_finalize = setuptools.dist:_Distribution.finalize_options

View File

@ -1,3 +0,0 @@
_distutils_hack
pkg_resources
setuptools

View File

@ -18,6 +18,7 @@ from setuptools.extension import Extension
from setuptools.dist import Distribution
from setuptools.depends import Require
from . import monkey
from . import logging
__all__ = [
@ -149,6 +150,7 @@ def _install_setup_requires(attrs):
def setup(**attrs):
# Make sure we have any requirements needed to interpret 'attrs'.
logging.configure()
_install_setup_requires(attrs)
return distutils.core.setup(**attrs)

View File

@ -527,7 +527,7 @@ class MSVCCompiler(CCompiler) :
return
warnings.warn(
"Fallback spawn triggered. Please update distutils monkeypatch.")
with unittest.mock.patch('os.environ', env):
with unittest.mock.patch.dict('os.environ', env):
bag.value = super().spawn(cmd)
# -- Miscellaneous methods -----------------------------------------

View File

@ -81,11 +81,6 @@ if HAS_USER_SITE:
'data' : '{userbase}',
}
INSTALL_SCHEMES['osx_framework_user'] = {
'headers':
'{userbase}/include/{implementation_lower}{py_version_short}{abiflags}/{dist_name}',
}
# The keys to an installation scheme; if any new types of files are to be
# installed, be sure to add an entry to every installation scheme above,
# and to SCHEME_KEYS here.
@ -124,7 +119,8 @@ def _get_implementation():
def _select_scheme(ob, name):
vars(ob).update(_remove_set(ob, _scheme_attrs(_resolve_scheme(name))))
scheme = _inject_headers(name, _load_scheme(_resolve_scheme(name)))
vars(ob).update(_remove_set(ob, _scheme_attrs(scheme)))
def _remove_set(ob, attrs):
@ -147,9 +143,26 @@ def _resolve_scheme(name):
return resolved
def _scheme_attrs(name):
def _load_scheme(name):
return _load_schemes()[name]
def _inject_headers(name, scheme):
"""
Given a scheme name and the resolved scheme,
if the scheme does not include headers, resolve
the fallback scheme for the name and use headers
from it. pypa/distutils#88
"""
# Bypass the preferred scheme, which may not
# have defined headers.
fallback = _load_scheme(_pypy_hack(name))
scheme.setdefault('headers', fallback['headers'])
return scheme
def _scheme_attrs(scheme):
"""Resolve install directories by applying the install schemes."""
scheme = _load_schemes()[name]
return {
f'install_{key}': scheme[key]
for key in SCHEME_KEYS
@ -395,6 +408,7 @@ class install(Command):
'platlibdir': getattr(sys, 'platlibdir', 'lib'),
'implementation_lower': _get_implementation().lower(),
'implementation': _get_implementation(),
'platsubdir': sysconfig.get_config_var('platsubdir'),
}
if HAS_USER_SITE:
@ -635,7 +649,7 @@ class install(Command):
return
home = convert_path(os.path.expanduser("~"))
for name, path in self.config_vars.items():
if path.startswith(home) and not os.path.isdir(path):
if str(path).startswith(home) and not os.path.isdir(path):
self.debug_print("os.makedirs('%s', 0o700)" % path)
os.makedirs(path, 0o700)

View File

@ -51,16 +51,14 @@ import os
import sys
import copy
import shlex
from subprocess import Popen, PIPE, check_output
import re
import warnings
from subprocess import check_output
import distutils.version
from distutils.unixccompiler import UnixCCompiler
from distutils.file_util import write_file
from distutils.errors import (DistutilsExecError, CCompilerError,
CompileError, UnknownFileError)
from distutils.version import LooseVersion
from distutils.spawn import find_executable
from distutils.version import LooseVersion, suppress_known_deprecation
def get_msvcr():
"""Include the appropriate MSVC runtime library if Python was built
@ -125,33 +123,8 @@ class CygwinCCompiler(UnixCCompiler):
self.cc = os.environ.get('CC', 'gcc')
self.cxx = os.environ.get('CXX', 'g++')
if ('gcc' in self.cc): # Start gcc workaround
self.gcc_version, self.ld_version, self.dllwrap_version = \
get_versions()
self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" %
(self.gcc_version,
self.ld_version,
self.dllwrap_version) )
# ld_version >= "2.10.90" and < "2.13" should also be able to use
# gcc -mdll instead of dllwrap
# Older dllwraps had own version numbers, newer ones use the
# same as the rest of binutils ( also ld )
# dllwrap 2.10.90 is buggy
if self.ld_version >= "2.10.90":
self.linker_dll = self.cc
else:
self.linker_dll = "dllwrap"
# ld_version >= "2.13" support -shared so use it instead of
# -mdll -static
if self.ld_version >= "2.13":
shared_option = "-shared"
else:
shared_option = "-mdll -static"
else: # Assume linker is up to date
self.linker_dll = self.cc
shared_option = "-shared"
self.linker_dll = self.cc
shared_option = "-shared"
self.set_executables(compiler='%s -mcygwin -O -Wall' % self.cc,
compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc,
@ -160,17 +133,24 @@ class CygwinCCompiler(UnixCCompiler):
linker_so=('%s -mcygwin %s' %
(self.linker_dll, shared_option)))
# cygwin and mingw32 need different sets of libraries
if ('gcc' in self.cc and self.gcc_version == "2.91.57"):
# cygwin shouldn't need msvcrt, but without the dlls will crash
# (gcc version 2.91.57) -- perhaps something about initialization
self.dll_libraries=["msvcrt"]
self.warn(
"Consider upgrading to a newer version of gcc")
else:
# Include the appropriate MSVC runtime library if Python was built
# with MSVC 7.0 or later.
self.dll_libraries = get_msvcr()
# Include the appropriate MSVC runtime library if Python was built
# with MSVC 7.0 or later.
self.dll_libraries = get_msvcr()
@property
def gcc_version(self):
# Older numpy dependend on this existing to check for ancient
# gcc versions. This doesn't make much sense with clang etc so
# just hardcode to something recent.
# https://github.com/numpy/numpy/pull/20333
warnings.warn(
"gcc_version attribute of CygwinCCompiler is deprecated. "
"Instead of returning actual gcc version a fixed value 11.2.0 is returned.",
DeprecationWarning,
stacklevel=2,
)
with suppress_known_deprecation():
return LooseVersion("11.2.0")
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
"""Compiles the source by spawning GCC and windres if needed."""
@ -232,24 +212,17 @@ class CygwinCCompiler(UnixCCompiler):
# next add options for def-file and to creating import libraries
# dllwrap uses different options than gcc/ld
if self.linker_dll == "dllwrap":
extra_preargs.extend(["--output-lib", lib_file])
# for dllwrap we have to use a special option
extra_preargs.extend(["--def", def_file])
# we use gcc/ld here and can be sure ld is >= 2.9.10
else:
# doesn't work: bfd_close build\...\libfoo.a: Invalid operation
#extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
# for gcc/ld the def-file is specified as any object files
objects.append(def_file)
# doesn't work: bfd_close build\...\libfoo.a: Invalid operation
#extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
# for gcc/ld the def-file is specified as any object files
objects.append(def_file)
#end: if ((export_symbols is not None) and
# (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
# who wants symbols and a many times larger output file
# should explicitly switch the debug mode on
# otherwise we let dllwrap/ld strip the output file
# otherwise we let ld strip the output file
# (On my machine: 10KiB < stripped_file < ??100KiB
# unstripped_file = stripped_file + XXX KiB
# ( XXX=254 for a typical python extension))
@ -297,19 +270,7 @@ class Mingw32CCompiler(CygwinCCompiler):
CygwinCCompiler.__init__ (self, verbose, dry_run, force)
# ld_version >= "2.13" support -shared so use it instead of
# -mdll -static
if ('gcc' in self.cc and self.ld_version < "2.13"):
shared_option = "-mdll -static"
else:
shared_option = "-shared"
# A real mingw32 doesn't need to specify a different entry point,
# but cygwin 2.91.57 in no-cygwin-mode needs it.
if ('gcc' in self.cc and self.gcc_version <= "2.91.57"):
entry_point = '--entry _DllMain@12'
else:
entry_point = ''
shared_option = "-shared"
if is_cygwincc(self.cc):
raise CCompilerError(
@ -319,9 +280,9 @@ class Mingw32CCompiler(CygwinCCompiler):
compiler_so='%s -mdll -O -Wall' % self.cc,
compiler_cxx='%s -O -Wall' % self.cxx,
linker_exe='%s' % self.cc,
linker_so='%s %s %s'
% (self.linker_dll, shared_option,
entry_point))
linker_so='%s %s'
% (self.linker_dll, shared_option))
# Maybe we should also append -mthreads, but then the finished
# dlls need another dll (mingwm10.dll see Mingw32 docs)
# (-mthreads: Support thread-safe exception handling on `Mingw32')
@ -388,39 +349,14 @@ def check_config_h():
return (CONFIG_H_UNCERTAIN,
"couldn't read '%s': %s" % (fn, exc.strerror))
RE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)')
def _find_exe_version(cmd):
"""Find the version of an executable by running `cmd` in the shell.
If the command is not found, or the output does not match
`RE_VERSION`, returns None.
"""
executable = cmd.split()[0]
if find_executable(executable) is None:
return None
out = Popen(cmd, shell=True, stdout=PIPE).stdout
try:
out_string = out.read()
finally:
out.close()
result = RE_VERSION.search(out_string)
if result is None:
return None
# LooseVersion works with strings; decode
ver_str = result.group(1).decode()
with distutils.version.suppress_known_deprecation():
return LooseVersion(ver_str)
def get_versions():
""" Try to find out the versions of gcc, ld and dllwrap.
If not possible it returns None for it.
"""
commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version']
return tuple([_find_exe_version(cmd) for cmd in commands])
def is_cygwincc(cc):
'''Try to determine if the compiler that would be used is from cygwin.'''
out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
return out_string.strip().endswith(b'cygwin')
get_versions = None
"""
A stand-in for the previous get_versions() function to prevent failures
when monkeypatched. See pypa/setuptools#2969.
"""

View File

@ -3,13 +3,14 @@
# The class here is styled after PEP 282 so that it could later be
# replaced with a standard Python logging implementation.
import sys
DEBUG = 1
INFO = 2
WARN = 3
ERROR = 4
FATAL = 5
import sys
class Log:
@ -54,6 +55,7 @@ class Log:
def fatal(self, msg, *args):
self._log(FATAL, msg, args)
_global_log = Log()
log = _global_log.log
debug = _global_log.debug
@ -62,12 +64,14 @@ warn = _global_log.warn
error = _global_log.error
fatal = _global_log.fatal
def set_threshold(level):
# return the old threshold for use from tests
old = _global_log.threshold
_global_log.threshold = level
return old
def set_verbosity(v):
if v <= 0:
set_threshold(WARN)

View File

@ -13,6 +13,7 @@ import _imp
import os
import re
import sys
import sysconfig
from .errors import DistutilsPlatformError
@ -274,31 +275,15 @@ def get_config_h_filename():
inc_dir = os.path.join(_sys_home or project_base, "PC")
else:
inc_dir = _sys_home or project_base
return os.path.join(inc_dir, 'pyconfig.h')
else:
inc_dir = get_python_inc(plat_specific=1)
return sysconfig.get_config_h_filename()
return os.path.join(inc_dir, 'pyconfig.h')
# Allow this value to be patched by pkgsrc. Ref pypa/distutils#16.
_makefile_tmpl = 'config-{python_ver}{build_flags}{multiarch}'
def get_makefile_filename():
"""Return full pathname of installed Makefile from the Python build."""
if python_build:
return os.path.join(_sys_home or project_base, "Makefile")
lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
multiarch = (
'-%s' % sys.implementation._multiarch
if hasattr(sys.implementation, '_multiarch') else ''
)
config_file = _makefile_tmpl.format(
python_ver=get_python_version(),
build_flags=build_flags,
multiarch=multiarch,
)
return os.path.join(lib_dir, config_file, 'Makefile')
return sysconfig.get_makefile_filename()
def parse_config_h(fp, g=None):
@ -308,26 +293,7 @@ def parse_config_h(fp, g=None):
optional dictionary is passed in as the second argument, it is
used instead of a new dictionary.
"""
if g is None:
g = {}
define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
#
while True:
line = fp.readline()
if not line:
break
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try: v = int(v)
except ValueError: pass
g[n] = v
else:
m = undef_rx.match(line)
if m:
g[m.group(1)] = 0
return g
return sysconfig.parse_config_h(fp, vars=g)
# Regexes needed for parsing Makefile (and similar syntaxes,