Compare commits
No commits in common. "master" and "pages" have entirely different histories.
|
@ -0,0 +1,4 @@
|
|||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 801d60552fdd793a2274510b414176e3
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
|
@ -1,2 +0,0 @@
|
|||
[run]
|
||||
include=pylspci/*
|
120
.drone.yml
120
.drone.yml
|
@ -1,120 +0,0 @@
|
|||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: pre-commit
|
||||
image: python:3-alpine
|
||||
commands:
|
||||
- apk add --no-cache git gcc musl-dev
|
||||
- pip install .[dev]
|
||||
- pre-commit run -a
|
||||
|
||||
- name: test-py36
|
||||
image: python:3.6-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: test-py37
|
||||
image: python:3.7-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: test-py38
|
||||
image: python:3.8-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: test-py39
|
||||
image: python:3.9-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: test-py310
|
||||
image: python:3.10-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: test-py311
|
||||
image: python:3.11-alpine
|
||||
commands:
|
||||
- pip install .[dev]
|
||||
- coverage run setup.py test
|
||||
- coverage report
|
||||
|
||||
- name: testpypi
|
||||
image: python:3.11-alpine
|
||||
commands:
|
||||
- pip install .[dev] twine setuptools wheel
|
||||
- |
|
||||
echo "[distutils]
|
||||
index-servers = testpypi
|
||||
[testpypi]
|
||||
repository=https://test.pypi.org/legacy/
|
||||
username=$$TESTPYPI_DEPLOY_USERNAME
|
||||
password=$$TESTPYPI_DEPLOY_PASSWORD" > ~/.pypirc
|
||||
- python setup.py sdist bdist_wheel
|
||||
- twine upload dist/* -r testpypi
|
||||
|
||||
when:
|
||||
event:
|
||||
- promote
|
||||
repo:
|
||||
- lucidiot/pylspci
|
||||
|
||||
depends_on:
|
||||
- pre-commit
|
||||
- test-py36
|
||||
- test-py37
|
||||
- test-py38
|
||||
- test-py39
|
||||
- test-py310
|
||||
- test-py311
|
||||
|
||||
environment:
|
||||
TESTPYPI_DEPLOY_USERNAME:
|
||||
from_secret: testpypi_username
|
||||
TESTPYPI_DEPLOY_PASSWORD:
|
||||
from_secret: testpypi_password
|
||||
|
||||
- name: pypi
|
||||
image: python:3.11-alpine
|
||||
commands:
|
||||
- pip install .[dev] twine setuptools wheel
|
||||
- |
|
||||
echo "[distutils]
|
||||
index-servers = pypi
|
||||
[pypi]
|
||||
repository=https://upload.pypi.org/legacy/
|
||||
username=$$PYPI_DEPLOY_USERNAME
|
||||
password=$$PYPI_DEPLOY_PASSWORD" > ~/.pypirc
|
||||
- python setup.py sdist bdist_wheel
|
||||
- twine upload dist/* -r pypi
|
||||
|
||||
when:
|
||||
event:
|
||||
- promote
|
||||
repo:
|
||||
- lucidiot/pylspci
|
||||
branch:
|
||||
- master
|
||||
|
||||
depends_on:
|
||||
- testpypi
|
||||
|
||||
environment:
|
||||
PYPI_DEPLOY_USERNAME:
|
||||
from_secret: pypi_username
|
||||
PYPI_DEPLOY_PASSWORD:
|
||||
from_secret: pypi_password
|
|
@ -1,61 +0,0 @@
|
|||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
docs/_build/
|
||||
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
.ropeproject
|
||||
|
||||
[._]*.s[a-v][a-z]
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
tags
|
||||
[._]*.un~
|
||||
|
||||
.vscode/*
|
|
@ -1,35 +0,0 @@
|
|||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- id: check-merge-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-symlinks
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.2.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
args:
|
||||
- --ignore-missing-imports
|
||||
- --disallow-incomplete-defs
|
||||
- --disallow-untyped-defs
|
||||
- --check-untyped-defs
|
||||
- --no-implicit-optional
|
||||
- repo: https://github.com/PyCQA/doc8
|
||||
rev: v1.1.1
|
||||
hooks:
|
||||
- id: doc8
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
674
LICENSE
674
LICENSE
|
@ -1,674 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
@ -1,6 +0,0 @@
|
|||
include requirements.txt
|
||||
include requirements-dev.txt
|
||||
include VERSION
|
||||
include LICENSE
|
||||
include README.rst
|
||||
include pylspci/py.typed
|
|
@ -1,8 +0,0 @@
|
|||
pylspci
|
||||
=======
|
||||
|
||||
A Python parser for the ``lspci`` command from the pciutils_ package.
|
||||
`Browse documentation`_
|
||||
|
||||
.. _pciutils: http://mj.ucw.cz/sw/pciutils/
|
||||
.. _Browse documentation: https://lucidiot.tildepages.org/pylspci/
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Overview: module code — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../index.html">Documentation overview</a><ul>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>All modules for which code is available</h1>
|
||||
<ul><li><a href="pylspci/command.html">pylspci.command</a></li>
|
||||
<li><a href="pylspci/device.html">pylspci.device</a></li>
|
||||
<li><a href="pylspci/fields.html">pylspci.fields</a></li>
|
||||
<li><a href="pylspci/filters.html">pylspci.filters</a></li>
|
||||
<li><a href="pylspci/parsers/base.html">pylspci.parsers.base</a></li>
|
||||
<li><a href="pylspci/parsers/simple.html">pylspci.parsers.simple</a></li>
|
||||
<li><a href="pylspci/parsers/verbose.html">pylspci.parsers.verbose</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,643 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.command — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.command</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">import</span> <span class="nn">subprocess</span>
|
||||
<span class="kn">from</span> <span class="nn">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
|
||||
<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">Any</span><span class="p">,</span> <span class="n">Iterator</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Mapping</span><span class="p">,</span> <span class="n">MutableMapping</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.device</span> <span class="kn">import</span> <span class="n">Device</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.fields</span> <span class="kn">import</span> <span class="n">PCIAccessParameter</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.filters</span> <span class="kn">import</span> <span class="n">DeviceFilter</span><span class="p">,</span> <span class="n">SlotFilter</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.parsers.base</span> <span class="kn">import</span> <span class="n">Parser</span>
|
||||
|
||||
<span class="n">OptionalPath</span> <span class="o">=</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Path</span><span class="p">]]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="IDResolveOption"><a class="viewcode-back" href="../../command.html#pylspci.command.IDResolveOption">[docs]</a><span class="k">class</span> <span class="nc">IDResolveOption</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> ``lspci`` device, vendor, class names outputting options.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">NameOnly</span> <span class="o">=</span> <span class="s1">''</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Only output the names.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">IDOnly</span> <span class="o">=</span> <span class="s1">'-n'</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Only output the hexadecimal IDs.</span>
|
||||
<span class="sd"> This is the only option that does not require a ``pciids`` file.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">Both</span> <span class="o">=</span> <span class="s1">'-nn'</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Output both the names and hexadecimal IDs, in the format ``Name [ID]``.</span>
|
||||
<span class="sd"> """</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="lspci"><a class="viewcode-back" href="../../command.html#pylspci.command.lspci">[docs]</a><span class="k">def</span> <span class="nf">lspci</span><span class="p">(</span>
|
||||
<span class="n">pciids</span><span class="p">:</span> <span class="n">OptionalPath</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">pcimap</span><span class="p">:</span> <span class="n">OptionalPath</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">access_method</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">pcilib_params</span><span class="p">:</span> <span class="n">Mapping</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">{},</span>
|
||||
<span class="n">file</span><span class="p">:</span> <span class="n">OptionalPath</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">verbose</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||
<span class="n">kernel_drivers</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||
<span class="n">bridge_paths</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span>
|
||||
<span class="n">hide_single_domain</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||||
<span class="n">id_resolve_option</span><span class="p">:</span> <span class="n">IDResolveOption</span> <span class="o">=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">Both</span><span class="p">,</span>
|
||||
<span class="n">slot_filter</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="n">SlotFilter</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">device_filter</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="n">DeviceFilter</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Call the ``lspci`` command with various parameters.</span>
|
||||
|
||||
<span class="sd"> :param pciids: An optional path to a ``pciids`` file,</span>
|
||||
<span class="sd"> to convert hexadecimal class, vendor or device IDs into names.</span>
|
||||
<span class="sd"> :type pciids: str or Path or None</span>
|
||||
<span class="sd"> :param pcimap: An optional path to a ``pcimap`` file,</span>
|
||||
<span class="sd"> linking Linux kernel modules and their supported PCI IDs.</span>
|
||||
<span class="sd"> :type pcimap: str or Path or None</span>
|
||||
<span class="sd"> :param access_method: The access method to use to find devices.</span>
|
||||
<span class="sd"> Set this to ``help`` to list the available access methods in a</span>
|
||||
<span class="sd"> human-readable format. For the machine-readable format, see</span>
|
||||
<span class="sd"> :func:`list_access_methods`.</span>
|
||||
<span class="sd"> :type access_method: str or None</span>
|
||||
<span class="sd"> :param pcilib_params: Parameters passed to pcilib's access methods.</span>
|
||||
<span class="sd"> To list the available parameters with their description and default</span>
|
||||
<span class="sd"> values, see :func:`list_pcilib_params`.</span>
|
||||
<span class="sd"> :type pcilib_params: Mapping[str, Any] or None</span>
|
||||
<span class="sd"> :param file: An hexadecimal dump from ``lspci -x`` to load data from,</span>
|
||||
<span class="sd"> instead of accessing real hardware.</span>
|
||||
<span class="sd"> :type file: str or Path or None</span>
|
||||
<span class="sd"> :param bool verbose: Increase verbosity.</span>
|
||||
<span class="sd"> This radically changes the output format.</span>
|
||||
<span class="sd"> :param bool kernel_drivers: Also include kernel modules and drivers</span>
|
||||
<span class="sd"> in the output. Only has effect with the verbose output.</span>
|
||||
<span class="sd"> :param bool bridge_paths: Add PCI bridge paths to slot numbers.</span>
|
||||
<span class="sd"> :param bool hide_single_domain: If there is a single PCI domain on this</span>
|
||||
<span class="sd"> machine and it is numbered ``0000``, hide it from the slot numbers.</span>
|
||||
<span class="sd"> :param id_resolve_option: Device, vendor or class ID outputting mode.</span>
|
||||
<span class="sd"> See the :class:`IDResolveOption` docs for more details.</span>
|
||||
<span class="sd"> :type id_resolve_option: IDResolveOption</span>
|
||||
<span class="sd"> :param slot_filter: Filter devices by their slot</span>
|
||||
<span class="sd"> (domain, bus, device, function)</span>
|
||||
<span class="sd"> :type slot_filter: SlotFilter or str or None</span>
|
||||
<span class="sd"> :param device_filter: Filter devices by their vendor, device or class ID</span>
|
||||
<span class="sd"> :type device_filter: DeviceFilter or str or None</span>
|
||||
<span class="sd"> :return: Any output from the ``lspci`` command.</span>
|
||||
<span class="sd"> :rtype: str</span>
|
||||
<span class="sd"> :raises subprocess.CalledProcessError:</span>
|
||||
<span class="sd"> ``lspci`` returned a non-zero error code.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'lspci'</span><span class="p">,</span> <span class="s1">'-mm'</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-vvv'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">kernel_drivers</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-k'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">bridge_paths</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-PP'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">hide_single_domain</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-D'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">access_method</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-A</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">access_method</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">slot_filter</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">slot_filter</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">slot_filter</span> <span class="o">=</span> <span class="n">SlotFilter</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">slot_filter</span><span class="p">)</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-s'</span><span class="p">)</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">slot_filter</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">device_filter</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">device_filter</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">device_filter</span> <span class="o">=</span> <span class="n">DeviceFilter</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">device_filter</span><span class="p">)</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-d'</span><span class="p">)</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">device_filter</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">id_resolve_option</span> <span class="o">!=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">NameOnly</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">id_resolve_option</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">pciids</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-i'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pciids</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">pciids</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">pciids</span><span class="p">)</span>
|
||||
<span class="k">assert</span> <span class="n">pciids</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'ID database file not found'</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">pciids</span><span class="o">.</span><span class="n">absolute</span><span class="p">()))</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">pcimap</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-p'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pcimap</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">pcimap</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">pcimap</span><span class="p">)</span>
|
||||
<span class="k">assert</span> <span class="n">pcimap</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'Kernel module mapping file not found'</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">pcimap</span><span class="o">.</span><span class="n">absolute</span><span class="p">()))</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">file</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-F'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">file</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
|
||||
<span class="k">assert</span> <span class="n">file</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'Hex dump file not found'</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">absolute</span><span class="p">()))</span>
|
||||
|
||||
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">pcilib_params</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'-O</span><span class="si">{}</span><span class="s1">=</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">check_output</span><span class="p">(</span>
|
||||
<span class="n">args</span><span class="p">,</span>
|
||||
<span class="n">universal_newlines</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="list_access_methods"><a class="viewcode-back" href="../../command.html#pylspci.command.list_access_methods">[docs]</a><span class="k">def</span> <span class="nf">list_access_methods</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Calls ``lspci(access_method='help')`` to list the PCI access methods</span>
|
||||
<span class="sd"> the underlying ``pcilib`` provides and parses the human-readable list into</span>
|
||||
<span class="sd"> a machine-readable list.</span>
|
||||
|
||||
<span class="sd"> :returns: A list of access methods.</span>
|
||||
<span class="sd"> :rtype: List[str]</span>
|
||||
<span class="sd"> :raises subprocess.CalledProcessError:</span>
|
||||
<span class="sd"> ``lspci`` returned a non-zero error code.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span>
|
||||
<span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="n">line</span> <span class="ow">and</span> <span class="s1">'Known PCI access methods'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">line</span><span class="p">,</span>
|
||||
<span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="o">.</span><span class="n">strip</span><span class="p">,</span> <span class="n">lspci</span><span class="p">(</span><span class="n">access_method</span><span class="o">=</span><span class="s1">'help'</span><span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()),</span>
|
||||
<span class="p">))</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="list_pcilib_params_raw"><a class="viewcode-back" href="../../command.html#pylspci.command.list_pcilib_params_raw">[docs]</a><span class="k">def</span> <span class="nf">list_pcilib_params_raw</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Calls ``lspci -Ohelp`` to list the PCI access parameters the underlying</span>
|
||||
<span class="sd"> ``pcilib`` provides.</span>
|
||||
|
||||
<span class="sd"> :returns: A list of available PCI access parameters.</span>
|
||||
<span class="sd"> :rtype: List[str]</span>
|
||||
<span class="sd"> :raises subprocess.CalledProcessError:</span>
|
||||
<span class="sd"> ``lspci`` returned a non-zero error code.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span>
|
||||
<span class="k">lambda</span> <span class="n">line</span><span class="p">:</span> <span class="n">line</span> <span class="ow">and</span> <span class="s1">'Known PCI access parameters'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">line</span><span class="p">,</span>
|
||||
<span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="o">.</span><span class="n">strip</span><span class="p">,</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">check_output</span><span class="p">(</span>
|
||||
<span class="p">[</span><span class="s1">'lspci'</span><span class="p">,</span> <span class="s1">'-Ohelp'</span><span class="p">],</span>
|
||||
<span class="n">universal_newlines</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">)</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
|
||||
<span class="p">))</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="list_pcilib_params"><a class="viewcode-back" href="../../command.html#pylspci.command.list_pcilib_params">[docs]</a><span class="k">def</span> <span class="nf">list_pcilib_params</span><span class="p">()</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">PCIAccessParameter</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Calls ``lspci -Ohelp`` to list the PCI access parameters the underlying</span>
|
||||
<span class="sd"> ``pcilib`` provides and parse the human-readable list into</span>
|
||||
<span class="sd"> a machine-readable list.</span>
|
||||
|
||||
<span class="sd"> :returns: A list of available PCI access parameters.</span>
|
||||
<span class="sd"> :rtype: List[PCIAccessParameter]</span>
|
||||
<span class="sd"> :raises subprocess.CalledProcessError:</span>
|
||||
<span class="sd"> ``lspci`` returned a non-zero error code.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">PCIAccessParameter</span><span class="p">,</span> <span class="n">list_pcilib_params_raw</span><span class="p">()))</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder">[docs]</a><span class="k">class</span> <span class="nc">CommandBuilder</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Helper class to build a lspci call using a Builder pattern.</span>
|
||||
|
||||
<span class="sd"> Iterating over the builder will result in the command being called,</span>
|
||||
<span class="sd"> and will return strings, devices or pcilib parameters, one at a time,</span>
|
||||
<span class="sd"> depending on the parsing settings.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_list_access_methods</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">_list_pcilib_params</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">_list_pcilib_params_raw</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="n">_params</span><span class="p">:</span> <span class="n">MutableMapping</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="n">_parser</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Parser</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span> <span class="o">=</span> <span class="n">kwargs</span>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.__iter__"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.__iter__">[docs]</a> <span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Iterator</span><span class="p">[</span><span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">PCIAccessParameter</span><span class="p">]]:</span>
|
||||
<span class="n">result</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">PCIAccessParameter</span><span class="p">]]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_list_access_methods</span><span class="p">:</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">list_access_methods</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_list_pcilib_params</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_list_pcilib_params_raw</span><span class="p">:</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">list_pcilib_params_raw</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">list_pcilib_params</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parser</span><span class="p">:</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parser</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">lspci</span><span class="p">(</span><span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">))</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">result</span> <span class="o">=</span> <span class="n">lspci</span><span class="p">(</span><span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">iter</span><span class="p">([</span><span class="n">result</span><span class="p">,</span> <span class="p">])</span>
|
||||
<span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="n">result</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.use_pciids"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.use_pciids">[docs]</a> <span class="k">def</span> <span class="nf">use_pciids</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">path</span><span class="p">:</span> <span class="n">OptionalPath</span><span class="p">,</span>
|
||||
<span class="n">check</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use a PCI IDs file from a given path.</span>
|
||||
|
||||
<span class="sd"> :param path: A string or path-like object pointing to the PCI IDs file</span>
|
||||
<span class="sd"> to use. Set to None to use the default files from lspci.</span>
|
||||
<span class="sd"> :type path: str or Path or None</span>
|
||||
<span class="sd"> :param bool check: Whether to check for the file's existence</span>
|
||||
<span class="sd"> immediately, or delay that to the lspci invocation.</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">path</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">check</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="n">path</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'ID database file not found'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'pciids'</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.use_pcimap"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.use_pcimap">[docs]</a> <span class="k">def</span> <span class="nf">use_pcimap</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">path</span><span class="p">:</span> <span class="n">OptionalPath</span><span class="p">,</span>
|
||||
<span class="n">check</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use a kernel module mapping file from a given path.</span>
|
||||
|
||||
<span class="sd"> :param path: A string or path-like object pointing to the mapping file</span>
|
||||
<span class="sd"> to use. Set to None to use the default files from lspci.</span>
|
||||
<span class="sd"> :type path: str or Path or None</span>
|
||||
<span class="sd"> :param bool check: Whether to check for the file's existence</span>
|
||||
<span class="sd"> immediately, or delay that to the lspci invocation.</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">path</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">check</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="n">path</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'Kernel module mapping file not found'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'pcimap'</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.use_access_method"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.use_access_method">[docs]</a> <span class="k">def</span> <span class="nf">use_access_method</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">])</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use a specific access method to list all devices.</span>
|
||||
|
||||
<span class="sd"> :param method: Name of the access method to use. Set to None to use</span>
|
||||
<span class="sd"> lspci's default method.</span>
|
||||
<span class="sd"> :type method: str or None</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'access_method'</span><span class="p">]</span> <span class="o">=</span> <span class="n">method</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.list_access_methods"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.list_access_methods">[docs]</a> <span class="k">def</span> <span class="nf">list_access_methods</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> List the pcilib access methods instead of listing devices.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to list the access methods.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_list_access_methods</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_list_pcilib_params</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.list_pcilib_params"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.list_pcilib_params">[docs]</a> <span class="k">def</span> <span class="nf">list_pcilib_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||||
<span class="n">raw</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> List the pcilib parameters instead of listing devices.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to list the pcilib parameters.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :param raw: When listing the pcilib parameters, whether to return the</span>
|
||||
<span class="sd"> raw strings or parse them into PCIAccessParameter instances.</span>
|
||||
<span class="sd"> :type raw: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_list_pcilib_params</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_list_pcilib_params_raw</span> <span class="o">=</span> <span class="n">raw</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_list_access_methods</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.with_pcilib_params"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.with_pcilib_params">[docs]</a> <span class="k">def</span> <span class="nf">with_pcilib_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Mapping</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span>
|
||||
<span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Override some pcilib parameters. When given a dict, will rewrite the</span>
|
||||
<span class="sd"> parameters with the new dict. When given keyword arguments, will update</span>
|
||||
<span class="sd"> the existing parameters. Pass ``None`` or ``{}`` to reset all of the</span>
|
||||
<span class="sd"> parameters.</span>
|
||||
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><=</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'Only one positional argument is allowed'</span>
|
||||
<span class="k">assert</span> <span class="ow">not</span> <span class="n">kwargs</span><span class="p">,</span> <span class="s1">'Use either a dict or keyword arguments'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'pcilib_params'</span><span class="p">]</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="bp">self</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s1">'pcilib_params'</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.from_file"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.from_file">[docs]</a> <span class="k">def</span> <span class="nf">from_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">path</span><span class="p">:</span> <span class="n">OptionalPath</span><span class="p">,</span>
|
||||
<span class="n">check</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use a hexadecimal dump from a previous run of lspci instead of</span>
|
||||
<span class="sd"> accessing the host's devices directly.</span>
|
||||
|
||||
<span class="sd"> :param path: A string or path-like object pointing to the hex dump file</span>
|
||||
<span class="sd"> to use. Set to None to not use a dump file.</span>
|
||||
<span class="sd"> :type path: str or Path or None</span>
|
||||
<span class="sd"> :param bool check: Whether to check for the file's existence</span>
|
||||
<span class="sd"> immediately, or delay that to the lspci invocation.</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">path</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">check</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="n">path</span><span class="o">.</span><span class="n">is_file</span><span class="p">(),</span> <span class="s1">'Hex dump file not found'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'file'</span><span class="p">]</span> <span class="o">=</span> <span class="n">path</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.verbose"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.verbose">[docs]</a> <span class="k">def</span> <span class="nf">verbose</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Enable verbose mode.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to use verbose mode.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'verbose'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.include_kernel_drivers"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.include_kernel_drivers">[docs]</a> <span class="k">def</span> <span class="nf">include_kernel_drivers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Under Linux, includes the available kernel modules for each device.</span>
|
||||
<span class="sd"> Implies ``.verbose()``.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to include the available kernel modules</span>
|
||||
<span class="sd"> for each device.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'kernel_drivers'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">verbose</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.include_bridge_paths"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.include_bridge_paths">[docs]</a> <span class="k">def</span> <span class="nf">include_bridge_paths</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Include the PCI bridge paths along with the IDs.</span>
|
||||
<span class="sd"> Implies ``.with_ids()``.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to include the PCI bridge paths.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'bridge_paths'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">with_ids</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.hide_single_domain"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.hide_single_domain">[docs]</a> <span class="k">def</span> <span class="nf">hide_single_domain</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Hide the domain numbers when there is only one domain, numbered zero.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to hide the domain numbers for a single</span>
|
||||
<span class="sd"> domain.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'hide_single_domain'</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.with_ids"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.with_ids">[docs]</a> <span class="k">def</span> <span class="nf">with_ids</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Include PCI device IDs. If disabled, implies ``.with_names()``.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to include the PCI device IDs.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'id_resolve_option'</span><span class="p">)</span> <span class="o">==</span> \
|
||||
<span class="n">IDResolveOption</span><span class="o">.</span><span class="n">NameOnly</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'id_resolve_option'</span><span class="p">]</span> <span class="o">=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">Both</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'id_resolve_option'</span><span class="p">]</span> <span class="o">=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">NameOnly</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.with_names"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.with_names">[docs]</a> <span class="k">def</span> <span class="nf">with_names</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Include PCI device names. If disabled, implies ``.with_ids()``.</span>
|
||||
|
||||
<span class="sd"> :param value: Whether or not to include the PCI device names.</span>
|
||||
<span class="sd"> :type value: bool</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'id_resolve_option'</span><span class="p">)</span> <span class="o">==</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">IDOnly</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'id_resolve_option'</span><span class="p">]</span> <span class="o">=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">Both</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'id_resolve_option'</span><span class="p">]</span> <span class="o">=</span> <span class="n">IDResolveOption</span><span class="o">.</span><span class="n">IDOnly</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.slot_filter"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.slot_filter">[docs]</a> <span class="k">def</span> <span class="nf">slot_filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
|
||||
<span class="n">domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">bus</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">function</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Filter the devices geographically.</span>
|
||||
<span class="sd"> Can be passed a string in lspci's filter syntax, or keyword arguments</span>
|
||||
<span class="sd"> for each portion of the filter.</span>
|
||||
<span class="sd"> See :class:`pylspci.filters.SlotFilter`.</span>
|
||||
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><=</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'Only one positional argument allowed'</span>
|
||||
<span class="k">assert</span> <span class="ow">not</span> <span class="n">domain</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">bus</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">device</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">function</span><span class="p">,</span> \
|
||||
<span class="s1">'Use either a string value or the domain, bus, device '</span> \
|
||||
<span class="s1">'and function keyword arguments'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'slot_filter'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SlotFilter</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'slot_filter'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SlotFilter</span><span class="p">(</span>
|
||||
<span class="n">domain</span><span class="o">=</span><span class="n">domain</span><span class="p">,</span>
|
||||
<span class="n">bus</span><span class="o">=</span><span class="n">bus</span><span class="p">,</span>
|
||||
<span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">,</span>
|
||||
<span class="n">function</span><span class="o">=</span><span class="n">function</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.device_filter"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.device_filter">[docs]</a> <span class="k">def</span> <span class="nf">device_filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||||
<span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
|
||||
<span class="bp">cls</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">vendor</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Filter the devices logically.</span>
|
||||
<span class="sd"> Can be passed a string in lspci's filter syntax, or keyword arguments</span>
|
||||
<span class="sd"> for each portion of the filter.</span>
|
||||
<span class="sd"> See :class:`pylspci.filters.DeviceFilter`.</span>
|
||||
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o"><=</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'Only one positional argument allowed'</span>
|
||||
<span class="k">assert</span> <span class="ow">not</span> <span class="bp">cls</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">vendor</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">device</span><span class="p">,</span> \
|
||||
<span class="s1">'Use either a string value or the cls, vendor and device '</span> \
|
||||
<span class="s1">'keyword arguments'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'device_filter'</span><span class="p">]</span> <span class="o">=</span> <span class="n">DeviceFilter</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="p">[</span><span class="s1">'device_filter'</span><span class="p">]</span> <span class="o">=</span> \
|
||||
<span class="n">DeviceFilter</span><span class="p">(</span><span class="bp">cls</span><span class="o">=</span><span class="bp">cls</span><span class="p">,</span> <span class="n">vendor</span><span class="o">=</span><span class="n">vendor</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.with_parser"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.with_parser">[docs]</a> <span class="k">def</span> <span class="nf">with_parser</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parser</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Parser</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use a pylspci parser to get parsed Device instances instead of strings.</span>
|
||||
|
||||
<span class="sd"> :param parser: The parser to use. Set to None to disable parsing.</span>
|
||||
<span class="sd"> :type parser: pylspci.parsers.Parser</span>
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_parser</span> <span class="o">=</span> <span class="n">parser</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<div class="viewcode-block" id="CommandBuilder.with_default_parser"><a class="viewcode-back" href="../../command.html#pylspci.command.CommandBuilder.with_default_parser">[docs]</a> <span class="k">def</span> <span class="nf">with_default_parser</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'CommandBuilder'</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Use the default parser compatible with the current set of settings.</span>
|
||||
<span class="sd"> Note that this should be used as one of the last instructions of the</span>
|
||||
<span class="sd"> builder, as the default parser can change if the settings are updated.</span>
|
||||
|
||||
<span class="sd"> :returns: The current CommandBuilder instance.</span>
|
||||
<span class="sd"> :rtype: CommandBuilder</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'verbose'</span><span class="p">):</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.parsers</span> <span class="kn">import</span> <span class="n">VerboseParser</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">with_parser</span><span class="p">(</span><span class="n">VerboseParser</span><span class="p">())</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.parsers</span> <span class="kn">import</span> <span class="n">SimpleParser</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">with_parser</span><span class="p">(</span><span class="n">SimpleParser</span><span class="p">())</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.device — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.device</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">NamedTuple</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.fields</span> <span class="kn">import</span> <span class="n">NameWithID</span><span class="p">,</span> <span class="n">NameWithIDDict</span><span class="p">,</span> <span class="n">Slot</span><span class="p">,</span> <span class="n">SlotDict</span>
|
||||
|
||||
<span class="n">DeviceDict</span> <span class="o">=</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Union</span><span class="p">[</span>
|
||||
<span class="nb">int</span><span class="p">,</span>
|
||||
<span class="nb">str</span><span class="p">,</span>
|
||||
<span class="n">SlotDict</span><span class="p">,</span>
|
||||
<span class="n">NameWithIDDict</span><span class="p">,</span>
|
||||
<span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span>
|
||||
<span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">]]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Device"><a class="viewcode-back" href="../../data.html#pylspci.device.Device">[docs]</a><span class="k">class</span> <span class="nc">Device</span><span class="p">(</span><span class="n">NamedTuple</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Describes a device returned by lspci.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">slot</span><span class="p">:</span> <span class="n">Slot</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's slot (domain, bus, number and function).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="bp">cls</span><span class="p">:</span> <span class="n">NameWithID</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's class, with a name and/or an ID.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">vendor</span><span class="p">:</span> <span class="n">NameWithID</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's vendor, with a name and/or an ID.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">NameWithID</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's name and/or ID.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">subsystem_vendor</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">NameWithID</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's subsystem vendor, if found, with a name and/or an ID.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">subsystem_device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">NameWithID</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's subsystem name and/or ID, if found.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">revision</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's revision number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">progif</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's programming interface number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">driver</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's driver (Linux only).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">kernel_modules</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> One or more kernel modules that can handle this device (Linux only).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">numa_node</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> NUMA node this device is connected to (Linux only).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">iommu_group</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> IOMMU group that this device is part of (optional, Linux only).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">physical_slot</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The device's physical slot number (Linux only).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="Device.as_dict"><a class="viewcode-back" href="../../data.html#pylspci.device.Device.as_dict">[docs]</a> <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">DeviceDict</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Serialize this device as a JSON-serializable `dict`.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"slot"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">slot</span><span class="o">.</span><span class="n">as_dict</span><span class="p">(),</span>
|
||||
<span class="s2">"cls"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">cls</span><span class="o">.</span><span class="n">as_dict</span><span class="p">(),</span>
|
||||
<span class="s2">"vendor"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">vendor</span><span class="o">.</span><span class="n">as_dict</span><span class="p">(),</span>
|
||||
<span class="s2">"device"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="o">.</span><span class="n">as_dict</span><span class="p">(),</span>
|
||||
<span class="s2">"subsystem_vendor"</span><span class="p">:</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">subsystem_vendor</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">subsystem_vendor</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">),</span>
|
||||
<span class="s2">"subsystem_device"</span><span class="p">:</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">subsystem_device</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">subsystem_device</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">),</span>
|
||||
<span class="s2">"revision"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">revision</span><span class="p">,</span>
|
||||
<span class="s2">"progif"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">progif</span><span class="p">,</span>
|
||||
<span class="s2">"driver"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="p">,</span>
|
||||
<span class="s2">"kernel_modules"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">kernel_modules</span><span class="p">,</span>
|
||||
<span class="s2">"numa_node"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">numa_node</span><span class="p">,</span>
|
||||
<span class="s2">"iommu_group"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">iommu_group</span><span class="p">,</span>
|
||||
<span class="s2">"physical_slot"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">physical_slot</span><span class="p">,</span>
|
||||
<span class="p">}</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,307 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.fields — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.fields</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">import</span> <span class="nn">re</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">partial</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Union</span>
|
||||
|
||||
<span class="c1"># mypy does not support recursive type definitions</span>
|
||||
<span class="c1"># SlotDict = Dict[str, Union[int, 'SlotDict', None]]</span>
|
||||
<span class="n">SlotDict</span> <span class="o">=</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">],</span> <span class="kc">None</span><span class="p">]]</span>
|
||||
<span class="n">NameWithIDDict</span> <span class="o">=</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="kc">None</span><span class="p">]]</span>
|
||||
|
||||
<span class="n">hexstring</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">base</span><span class="o">=</span><span class="mi">16</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Slot"><a class="viewcode-back" href="../../data.html#pylspci.fields.Slot">[docs]</a><span class="k">class</span> <span class="nc">Slot</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Describes a PCI slot identifier, in the format ``[DDDD:]BB:dd.f``,</span>
|
||||
<span class="sd"> where ``D`` is the domain, ``B`` the bus, ``d`` the device</span>
|
||||
<span class="sd"> and ``f`` the function. The first three are hexadecimal numbers, but</span>
|
||||
<span class="sd"> ``f`` is in octal.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">domain</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mh">0x0000</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's domain, as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> When omitted, defaults to ``0x0000``.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">bus</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's bus, as a two-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">device</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's device, as a two-digit hexadecimal number, up to `0x1f`.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">function</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's function, as a single octal digit.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">parent</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="s2">"Slot"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's parent bridge, if present.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">parent</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">me</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">rpartition</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">parent</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">Slot</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span>
|
||||
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">hexstring</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="sa">r</span><span class="s1">'[:\.]'</span><span class="p">,</span> <span class="n">me</span><span class="p">)))</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
|
||||
<span class="n">data</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">domain</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="k">else</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span> <span class="o">=</span> <span class="n">data</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">></span> <span class="mh">0x1f</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Device numbers cannot be above 0x1f'</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span> <span class="o">></span> <span class="mh">0x7</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Function numbers cannot be above 7'</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="n">output</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s1">'</span><span class="si">{:04x}</span><span class="s1">:</span><span class="si">{:02x}</span><span class="s1">:</span><span class="si">{:02x}</span><span class="s1">.</span><span class="si">{:01x}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{!s}</span><span class="s1">/</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="p">,</span> <span class="n">output</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">output</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">(</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||
|
||||
<div class="viewcode-block" id="Slot.as_dict"><a class="viewcode-back" href="../../data.html#pylspci.fields.Slot.as_dict">[docs]</a> <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">SlotDict</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Serialize this slot as a JSON-serializable `dict`.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"domain"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span>
|
||||
<span class="s2">"bus"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span>
|
||||
<span class="s2">"device"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span>
|
||||
<span class="s2">"function"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">,</span>
|
||||
<span class="s2">"parent"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">as_dict</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">}</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="NameWithID"><a class="viewcode-back" href="../../data.html#pylspci.fields.NameWithID">[docs]</a><span class="k">class</span> <span class="nc">NameWithID</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Describes a device, vendor or class with either</span>
|
||||
<span class="sd"> a name, an hexadecimal PCI ID, or both.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="nb">id</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The PCI ID as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The human-readable name associated with this ID.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_NAME_ID_REGEX</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s1">'^(?P<name>.+)\s\[(?P<id>[0-9a-fA-F]</span><span class="si">{4}</span><span class="s1">)\]$'</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">value</span> <span class="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">']'</span><span class="p">):</span>
|
||||
<span class="c1"># Holds both an ID and a name</span>
|
||||
<span class="n">match</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_NAME_ID_REGEX</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span> <span class="c1"># Except it doesn't</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">value</span>
|
||||
<span class="k">return</span>
|
||||
<span class="n">gd</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">hexstring</span><span class="p">(</span><span class="n">gd</span><span class="p">[</span><span class="s1">'id'</span><span class="p">])</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">gd</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">hexstring</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">value</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1"> [</span><span class="si">{:04x}</span><span class="s1">]'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{:04x}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">''</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">(</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||
|
||||
<div class="viewcode-block" id="NameWithID.as_dict"><a class="viewcode-back" href="../../data.html#pylspci.fields.NameWithID.as_dict">[docs]</a> <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">NameWithIDDict</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Serialize this name and ID as a JSON-serializable `dict`.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"id"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="p">}</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="PCIAccessParameter"><a class="viewcode-back" href="../../data.html#pylspci.fields.PCIAccessParameter">[docs]</a><span class="k">class</span> <span class="nc">PCIAccessParameter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A pcilib access method parameter, as parsed from :func:`list_pcilib_params`</span>
|
||||
<span class="sd"> or ``lspci -Ohelp``, that can be modified using the ``pcilib_params``</span>
|
||||
<span class="sd"> argument of :func:`lspci`, or ``lspci -Oname=value`` in the command line.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The parameter's name.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">description</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A short description of the parameter's use.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">default</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> An optional default value for the parameter.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_PARAM_REGEX</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
|
||||
<span class="sa">r</span><span class="s1">'^(?P<name>\S+)\s+(?P<description>.+)\s\((?P<default>.*)\)$'</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">match</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_PARAM_REGEX</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
||||
<span class="s1">'Could not parse </span><span class="si">{!r}</span><span class="s1"> into a parameter'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
|
||||
<span class="n">gd</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">gd</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">gd</span><span class="p">[</span><span class="s1">'description'</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">default</span> <span class="o">=</span> <span class="n">gd</span><span class="p">[</span><span class="s1">'default'</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="ow">or</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="se">\t</span><span class="si">{}</span><span class="s1"> (</span><span class="si">{}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">default</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{!s}</span><span class="s1">(</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">PCIAccessParameter</span><span class="p">)</span> <span class="ow">and</span> \
|
||||
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">default</span><span class="p">)</span> \
|
||||
<span class="o">==</span> <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">default</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="PCIAccessParameter.as_dict"><a class="viewcode-back" href="../../data.html#pylspci.fields.PCIAccessParameter.as_dict">[docs]</a> <span class="k">def</span> <span class="nf">as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Serialize this PCI access parameter as a JSON-serializable `dict`.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"description"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span>
|
||||
<span class="s2">"default"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">default</span><span class="p">,</span>
|
||||
<span class="p">}</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.filters — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.filters</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">import</span> <span class="nn">re</span>
|
||||
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">ClassVar</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Pattern</span><span class="p">,</span> <span class="n">Type</span><span class="p">,</span> <span class="n">TypeVar</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.fields</span> <span class="kn">import</span> <span class="n">hexstring</span>
|
||||
|
||||
<span class="n">T</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T'</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s1">'Filter'</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Filter"><a class="viewcode-back" href="../../command.html#pylspci.filters.Filter">[docs]</a><span class="k">class</span> <span class="nc">Filter</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
|
||||
|
||||
<span class="n">_REGEX</span><span class="p">:</span> <span class="n">ClassVar</span><span class="p">[</span><span class="n">Pattern</span><span class="p">]</span>
|
||||
|
||||
<div class="viewcode-block" id="Filter.parse"><a class="viewcode-back" href="../../command.html#pylspci.filters.Filter.parse">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">cls</span><span class="p">:</span> <span class="n">Type</span><span class="p">[</span><span class="n">T</span><span class="p">],</span> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">cls</span><span class="p">()</span>
|
||||
<span class="n">match</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_REGEX</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="n">data</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">match</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">v</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">}</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">match</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Value is not a valid filter string'</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">cls</span><span class="p">(</span><span class="o">**</span><span class="p">{</span>
|
||||
<span class="n">k</span><span class="p">:</span> <span class="n">hexstring</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">v</span> <span class="o">!=</span> <span class="s1">''</span> <span class="ow">and</span> <span class="n">v</span> <span class="o">!=</span> <span class="s1">'*'</span>
|
||||
<span class="p">})</span></div>
|
||||
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="s2">"Create a filter."</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="SlotFilter"><a class="viewcode-back" href="../../command.html#pylspci.filters.SlotFilter">[docs]</a><span class="k">class</span> <span class="nc">SlotFilter</span><span class="p">(</span><span class="n">Filter</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Describes a slot filter, to filter devices geographically.</span>
|
||||
|
||||
<span class="sd"> Any field set to ``None`` will remove filtering.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device domain, as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">bus</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device bus, as a two-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device number, as a two-digit hexadecimal number, up to `0x1f`.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">function</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The slot's function, as a single octal digit.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="c1"># [[domain:]bus:][device][.function]</span>
|
||||
<span class="n">_REGEX</span><span class="p">:</span> <span class="n">ClassVar</span><span class="p">[</span><span class="n">Pattern</span><span class="p">]</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
|
||||
<span class="sa">r</span><span class="s1">'^(?:(?:(?P<domain>(?:[0-9a-f]{1,4}|\*?)):)?'</span>
|
||||
<span class="sa">r</span><span class="s1">'(?P<bus>(?:[0-9a-f]{1,2}|\*?)):)?'</span>
|
||||
<span class="sa">r</span><span class="s1">'(?P<device>(?:[01]?[0-9a-f]|\*?))?'</span>
|
||||
<span class="sa">r</span><span class="s1">'(?:\.(?P<function>(?:[0-7]|\*?)))?$'</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span>
|
||||
<span class="n">domain</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">bus</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">function</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">domain</span> <span class="o">=</span> <span class="n">domain</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">bus</span> <span class="o">=</span> <span class="n">bus</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">=</span> <span class="n">device</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">function</span> <span class="o">=</span> <span class="n">function</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">(domain=</span><span class="si">{!r}</span><span class="s1">, bus=</span><span class="si">{!r}</span><span class="s1">, device=</span><span class="si">{!r}</span><span class="s1">, function=</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">:</span><span class="si">{}</span><span class="s1">:</span><span class="si">{}</span><span class="s1">.</span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">*</span><span class="nb">map</span><span class="p">(</span>
|
||||
<span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="s1">'</span><span class="si">{:x}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s1">''</span><span class="p">,</span>
|
||||
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">),</span>
|
||||
<span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">function</span><span class="p">)</span> <span class="o">==</span> \
|
||||
<span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">domain</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">function</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="DeviceFilter"><a class="viewcode-back" href="../../command.html#pylspci.filters.DeviceFilter">[docs]</a><span class="k">class</span> <span class="nc">DeviceFilter</span><span class="p">(</span><span class="n">Filter</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Describes a device filter, to filter devices logically.</span>
|
||||
|
||||
<span class="sd"> Any field set to ``None`` will remove filtering.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="bp">cls</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device class ID, as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">vendor</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device vendor ID, as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Device ID, as a four-digit hexadecimal number.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="c1"># [vendor]:[device][:class]</span>
|
||||
<span class="n">_REGEX</span><span class="p">:</span> <span class="n">ClassVar</span><span class="p">[</span><span class="n">Pattern</span><span class="p">]</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span>
|
||||
<span class="sa">r</span><span class="s1">'^(?P<vendor>(?:[0-9a-f]{1,4}|\*?)):'</span>
|
||||
<span class="sa">r</span><span class="s1">'(?P<device>(?:[0-9a-f]{1,4}|\*?))'</span>
|
||||
<span class="sa">r</span><span class="s1">'(?::(?P<cls>(?:[0-9a-f]{1,4}|\*?))?)?$'</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span>
|
||||
<span class="bp">cls</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">vendor</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">device</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">cls</span> <span class="o">=</span> <span class="bp">cls</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">vendor</span> <span class="o">=</span> <span class="n">vendor</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">device</span> <span class="o">=</span> <span class="n">device</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="si">{}</span><span class="s1">(cls=</span><span class="si">{!r}</span><span class="s1">, vendor=</span><span class="si">{!r}</span><span class="s1">, device=</span><span class="si">{!r}</span><span class="s1">)'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cls</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">vendor</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s1">':'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span>
|
||||
<span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="s1">'</span><span class="si">{:x}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s1">''</span><span class="p">,</span>
|
||||
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vendor</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cls</span><span class="p">),</span>
|
||||
<span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">:</span> <span class="nb">object</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">NotImplemented</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">vendor</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cls</span><span class="p">)</span> <span class="o">==</span> \
|
||||
<span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">vendor</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">device</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">cls</span><span class="p">)</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,155 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.parsers.base — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
|
||||
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.parsers.base</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Union</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.device</span> <span class="kn">import</span> <span class="n">Device</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Parser"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.base.Parser">[docs]</a><span class="k">class</span> <span class="nc">Parser</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
|
||||
|
||||
<span class="n">default_lspci_args</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The default arguments that, when sent to :func:`lspci`, should provide the</span>
|
||||
<span class="sd"> best output for this parser.</span>
|
||||
|
||||
<span class="sd"> See :func:`lspci`'s documentation for a list of available arguments.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="Parser.parse"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.base.Parser.parse">[docs]</a> <span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">data</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">Iterable</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]]</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Parse a string or list of strings as a list of devices.</span>
|
||||
|
||||
<span class="sd"> :param data: A string holding multiple devices,</span>
|
||||
<span class="sd"> a list of strings, one for each device,</span>
|
||||
<span class="sd"> or a list of lists of strings, one list for each device, with</span>
|
||||
<span class="sd"> each list holding each part of the device output.</span>
|
||||
<span class="sd"> :type data: str or Iterable[str] or Iterable[Iterable[str]]</span>
|
||||
<span class="sd"> :returns: A list of parsed devices.</span>
|
||||
<span class="sd"> :rtype: List[Device]</span>
|
||||
<span class="sd"> """</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Parser.run"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.base.Parser.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Run the lspci command with the given arguments, defaulting to the</span>
|
||||
<span class="sd"> parser's default arguments, and parse the result.</span>
|
||||
|
||||
<span class="sd"> :param \\**kwargs: Optional arguments to override the parser's default</span>
|
||||
<span class="sd"> arguments. See :func:`lspci`'s documentation for a list of</span>
|
||||
<span class="sd"> available arguments.</span>
|
||||
<span class="sd"> :type \\**kwargs: Any</span>
|
||||
<span class="sd"> :returns: A list of parsed devices.</span>
|
||||
<span class="sd"> :rtype: List[Device]</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.command</span> <span class="kn">import</span> <span class="n">lspci</span>
|
||||
<span class="n">lspci_kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_lspci_args</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||||
<span class="n">lspci_kwargs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">lspci</span><span class="p">(</span><span class="o">**</span><span class="n">lspci_kwargs</span><span class="p">))</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.parsers.simple — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
|
||||
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.parsers.simple</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">import</span> <span class="nn">argparse</span>
|
||||
<span class="kn">import</span> <span class="nn">shlex</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Union</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">cached_property</span> <span class="kn">import</span> <span class="n">cached_property</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.device</span> <span class="kn">import</span> <span class="n">Device</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.fields</span> <span class="kn">import</span> <span class="n">NameWithID</span><span class="p">,</span> <span class="n">Slot</span><span class="p">,</span> <span class="n">hexstring</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.parsers.base</span> <span class="kn">import</span> <span class="n">Parser</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="SimpleParser"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.simple.SimpleParser">[docs]</a><span class="k">class</span> <span class="nc">SimpleParser</span><span class="p">(</span><span class="n">Parser</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A parser for lspci -mm.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="nd">@cached_property</span>
|
||||
<span class="k">def</span> <span class="nf">_parser</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">:</span>
|
||||
<span class="n">p</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">()</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'slot'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">Slot</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'cls'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'vendor'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'device'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'subsystem_vendor'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'subsystem_device'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'-r'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">hexstring</span><span class="p">,</span>
|
||||
<span class="n">nargs</span><span class="o">=</span><span class="s1">'?'</span><span class="p">,</span>
|
||||
<span class="n">dest</span><span class="o">=</span><span class="s1">'revision'</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span>
|
||||
<span class="s1">'-p'</span><span class="p">,</span>
|
||||
<span class="nb">type</span><span class="o">=</span><span class="n">hexstring</span><span class="p">,</span>
|
||||
<span class="n">nargs</span><span class="o">=</span><span class="s1">'?'</span><span class="p">,</span>
|
||||
<span class="n">dest</span><span class="o">=</span><span class="s1">'progif'</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">p</span>
|
||||
|
||||
<div class="viewcode-block" id="SimpleParser.parse"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.simple.SimpleParser.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">data</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">Iterable</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]],</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Parse a multiline string or a list of single-line strings</span>
|
||||
<span class="sd"> from lspci -mm into devices.</span>
|
||||
|
||||
<span class="sd"> :param data: A string holding multiple devices,</span>
|
||||
<span class="sd"> a list of strings, one for each device,</span>
|
||||
<span class="sd"> or a list of lists of strings, one list for each device, with</span>
|
||||
<span class="sd"> each list holding each part of the device output.</span>
|
||||
<span class="sd"> :type data: str or Iterable[str] or Iterable[Iterable[str]]</span>
|
||||
<span class="sd"> :return: A list of parsed devices.</span>
|
||||
<span class="sd"> :rtype: List[Device]</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">parse_line</span><span class="p">,</span> <span class="n">data</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="SimpleParser.parse_line"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.simple.SimpleParser.parse_line">[docs]</a> <span class="k">def</span> <span class="nf">parse_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]])</span> <span class="o">-></span> <span class="n">Device</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Parse a single line from lspci -mm into a single device, either</span>
|
||||
<span class="sd"> as the line or as a list of fields.</span>
|
||||
|
||||
<span class="sd"> :param args: Line or list of fields to parse from.</span>
|
||||
<span class="sd"> :type args: str or Iterable[str]</span>
|
||||
<span class="sd"> :return: A single parsed device.</span>
|
||||
<span class="sd"> :rtype: Device</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">args</span> <span class="o">=</span> <span class="n">shlex</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">Device</span><span class="p">(</span><span class="o">**</span><span class="nb">vars</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">(</span><span class="n">args</span><span class="p">)))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="SimpleParser.run"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.simple.SimpleParser.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="n">Any</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]:</span>
|
||||
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'verbose'</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
||||
<span class="s1">'Verbose output is unsupported from the SimpleParser. '</span>
|
||||
<span class="s1">'Please use the pylspci.parsers.VerboseParser instead.'</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,229 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>pylspci.parsers.verbose — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
|
||||
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for pylspci.parsers.verbose</h1><div class="highlight"><pre>
|
||||
<span></span><span class="kn">import</span> <span class="nn">warnings</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">NamedTuple</span><span class="p">,</span> <span class="n">Union</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">pylspci.device</span> <span class="kn">import</span> <span class="n">Device</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.fields</span> <span class="kn">import</span> <span class="n">NameWithID</span><span class="p">,</span> <span class="n">Slot</span><span class="p">,</span> <span class="n">hexstring</span>
|
||||
<span class="kn">from</span> <span class="nn">pylspci.parsers.base</span> <span class="kn">import</span> <span class="n">Parser</span>
|
||||
|
||||
<span class="n">UNKNOWN_FIELD_WARNING</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="s1">'Unsupported device field </span><span class="si">{!r}</span><span class="s1"> with value </span><span class="si">{!r}</span><span class="se">\n</span><span class="s1">'</span>
|
||||
<span class="s1">'Please report this, along with the output of `lspci -mmnnvvvk`, at '</span>
|
||||
<span class="s1">'https://tildegit.org/lucidiot/pylspci/issues/new'</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="FieldMapping"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.verbose.FieldMapping">[docs]</a><span class="k">class</span> <span class="nc">FieldMapping</span><span class="p">(</span><span class="n">NamedTuple</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Helper class to map verbose output field names such as ``SVendor`` to</span>
|
||||
<span class="sd"> :class:`Device` fields such as ``subsytem_vendor``.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">field_name</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Field name on the :class:`Device` named tuple.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">field_type</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="nb">str</span><span class="p">],</span> <span class="n">Any</span><span class="p">]</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Field type; a callable to use to parse the string value.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">many</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Whether or not to use a List, if this field can be repeated multiple times</span>
|
||||
<span class="sd"> in the lspci output.</span>
|
||||
<span class="sd"> """</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="VerboseParser"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.verbose.VerboseParser">[docs]</a><span class="k">class</span> <span class="nc">VerboseParser</span><span class="p">(</span><span class="n">Parser</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A parser for lspci -vvvmmk</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">default_lspci_args</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s1">'verbose'</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
|
||||
<span class="s1">'kernel_drivers'</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1"># Maps lspci output fields to Device fields with a type</span>
|
||||
<span class="n">_field_mapping</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s1">'Slot'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'slot'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">Slot</span><span class="p">),</span>
|
||||
<span class="s1">'Class'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'cls'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">),</span>
|
||||
<span class="s1">'Vendor'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'vendor'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">),</span>
|
||||
<span class="s1">'Device'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'device'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">),</span>
|
||||
<span class="s1">'SVendor'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span>
|
||||
<span class="n">field_name</span><span class="o">=</span><span class="s1">'subsystem_vendor'</span><span class="p">,</span>
|
||||
<span class="n">field_type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">),</span>
|
||||
<span class="s1">'SDevice'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span>
|
||||
<span class="n">field_name</span><span class="o">=</span><span class="s1">'subsystem_device'</span><span class="p">,</span>
|
||||
<span class="n">field_type</span><span class="o">=</span><span class="n">NameWithID</span><span class="p">,</span>
|
||||
<span class="p">),</span>
|
||||
<span class="s1">'Rev'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'revision'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">hexstring</span><span class="p">),</span>
|
||||
<span class="s1">'ProgIf'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'progif'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="n">hexstring</span><span class="p">),</span>
|
||||
<span class="s1">'Driver'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'driver'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="nb">str</span><span class="p">),</span>
|
||||
<span class="s1">'Module'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span>
|
||||
<span class="n">field_name</span><span class="o">=</span><span class="s1">'kernel_modules'</span><span class="p">,</span>
|
||||
<span class="n">field_type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span>
|
||||
<span class="n">many</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">),</span>
|
||||
<span class="s1">'NUMANode'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'numa_node'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="nb">int</span><span class="p">),</span>
|
||||
<span class="s1">'IOMMUGroup'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'iommu_group'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="nb">int</span><span class="p">),</span>
|
||||
<span class="s1">'PhySlot'</span><span class="p">:</span> <span class="n">FieldMapping</span><span class="p">(</span><span class="n">field_name</span><span class="o">=</span><span class="s1">'physical_slot'</span><span class="p">,</span> <span class="n">field_type</span><span class="o">=</span><span class="nb">str</span><span class="p">),</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_parse_device</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">device_data</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]])</span> <span class="o">-></span> <span class="n">Device</span><span class="p">:</span>
|
||||
<span class="n">devdict</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">device_data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">device_data</span> <span class="o">=</span> <span class="n">device_data</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
|
||||
|
||||
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">device_data</span><span class="p">:</span>
|
||||
<span class="n">key</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="o">.</span><span class="n">strip</span><span class="p">,</span> <span class="n">line</span><span class="o">.</span><span class="n">partition</span><span class="p">(</span><span class="s1">':'</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_field_mapping</span><span class="p">:</span>
|
||||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
|
||||
<span class="n">UNKNOWN_FIELD_WARNING</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">),</span>
|
||||
<span class="ne">UserWarning</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">continue</span>
|
||||
<span class="n">field</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_field_mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">field</span><span class="o">.</span><span class="n">many</span><span class="p">:</span>
|
||||
<span class="n">devdict</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">field</span><span class="o">.</span><span class="n">field_name</span><span class="p">,</span> <span class="p">[])</span> \
|
||||
<span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">field</span><span class="o">.</span><span class="n">field_type</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">devdict</span><span class="p">[</span><span class="n">field</span><span class="o">.</span><span class="n">field_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">field_type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">Device</span><span class="p">(</span><span class="o">**</span><span class="n">devdict</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="VerboseParser.parse"><a class="viewcode-back" href="../../../low.html#pylspci.parsers.verbose.VerboseParser.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="p">,</span>
|
||||
<span class="n">data</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">],</span> <span class="n">Iterable</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]],</span>
|
||||
<span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Parse an lspci -vvvmm[nnk] output, either as a single string holding</span>
|
||||
<span class="sd"> multiple devices separated by two newlines,</span>
|
||||
<span class="sd"> or as a list of multiline strings holding one device each.</span>
|
||||
|
||||
<span class="sd"> :param data: A string holding multiple devices,</span>
|
||||
<span class="sd"> a list of strings, one for each device,</span>
|
||||
<span class="sd"> or a list of lists of strings, one list for each device, with</span>
|
||||
<span class="sd"> each list holding each part of the device output.</span>
|
||||
<span class="sd"> :type data: str or Iterable[str] or Iterable[Iterable[str]]</span>
|
||||
<span class="sd"> :return: A list of parsed devices.</span>
|
||||
<span class="sd"> :rtype: List[Device]</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span><span class="p">)</span>
|
||||
<span class="n">result</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Device</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="n">line</span> <span class="o">=</span> <span class="nb">str</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span> <span class="c1"># Ignore empty strings and lists</span>
|
||||
<span class="k">continue</span>
|
||||
<span class="n">result</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parse_device</span><span class="p">(</span><span class="n">line</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="n">result</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* _sphinx_javascript_frameworks_compat.js
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* Compatability shim for jQuery and underscores.js.
|
||||
*
|
||||
* WILL BE REMOVED IN Sphinx 6.0
|
||||
* xref RemovedInSphinx60Warning
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* select a different prefix for underscore
|
||||
*/
|
||||
$u = _.noConflict();
|
||||
|
||||
|
||||
/**
|
||||
* small helper function to urldecode strings
|
||||
*
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
|
||||
*/
|
||||
jQuery.urldecode = function(x) {
|
||||
if (!x) {
|
||||
return x
|
||||
}
|
||||
return decodeURIComponent(x.replace(/\+/g, ' '));
|
||||
};
|
||||
|
||||
/**
|
||||
* small helper function to urlencode strings
|
||||
*/
|
||||
jQuery.urlencode = encodeURIComponent;
|
||||
|
||||
/**
|
||||
* This function returns the parsed url parameters of the
|
||||
* current request. Multiple values per key are supported,
|
||||
* it will always return arrays of strings for the value parts.
|
||||
*/
|
||||
jQuery.getQueryParameters = function(s) {
|
||||
if (typeof s === 'undefined')
|
||||
s = document.location.search;
|
||||
var parts = s.substr(s.indexOf('?') + 1).split('&');
|
||||
var result = {};
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var tmp = parts[i].split('=', 2);
|
||||
var key = jQuery.urldecode(tmp[0]);
|
||||
var value = jQuery.urldecode(tmp[1]);
|
||||
if (key in result)
|
||||
result[key].push(value);
|
||||
else
|
||||
result[key] = [value];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a jquery object by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
jQuery.fn.highlightText = function(text, className) {
|
||||
function highlight(node, addItems) {
|
||||
if (node.nodeType === 3) {
|
||||
var val = node.nodeValue;
|
||||
var pos = val.toLowerCase().indexOf(text);
|
||||
if (pos >= 0 &&
|
||||
!jQuery(node.parentNode).hasClass(className) &&
|
||||
!jQuery(node.parentNode).hasClass("nohighlight")) {
|
||||
var span;
|
||||
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.className = className;
|
||||
}
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling));
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
if (isInSVG) {
|
||||
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
||||
var bbox = node.parentElement.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute('class', className);
|
||||
addItems.push({
|
||||
"parent": node.parentNode,
|
||||
"target": rect});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!jQuery(node).is("button, select, textarea")) {
|
||||
jQuery.each(node.childNodes, function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
}
|
||||
}
|
||||
var addItems = [];
|
||||
var result = this.each(function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
for (var i = 0; i < addItems.length; ++i) {
|
||||
jQuery(addItems[i].parent).before(addItems[i].target);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
* backward compatibility for jQuery.browser
|
||||
* This will be supported until firefox bug is fixed.
|
||||
*/
|
||||
if (!jQuery.browser) {
|
||||
jQuery.uaMatch = function(ua) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(msie) ([\w.]+)/.exec(ua) ||
|
||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
browser: match[ 1 ] || "",
|
||||
version: match[ 2 ] || "0"
|
||||
};
|
||||
};
|
||||
jQuery.browser = {};
|
||||
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
|
||||
}
|
|
@ -0,0 +1,707 @@
|
|||
@import url("basic.css");
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: Georgia, serif;
|
||||
font-size: 17px;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
div.document {
|
||||
width: 940px;
|
||||
margin: 30px auto 0 auto;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0 0 0 220px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
width: 220px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #B1B4B6;
|
||||
}
|
||||
|
||||
div.body {
|
||||
background-color: #fff;
|
||||
color: #3E4349;
|
||||
padding: 0 30px 0 30px;
|
||||
}
|
||||
|
||||
div.body > .section {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
width: 940px;
|
||||
margin: 20px auto 30px auto;
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
p.caption {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
|
||||
div.relations {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a:hover {
|
||||
border-bottom: 1px solid #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 18px 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper p.logo {
|
||||
padding: 0;
|
||||
margin: -10px 0 0 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper h1.logo {
|
||||
margin-top: -10px;
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper h1.logo-name {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper p.blurb {
|
||||
margin-top: 0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3,
|
||||
div.sphinxsidebar h4 {
|
||||
font-family: Georgia, serif;
|
||||
color: #444;
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
margin: 0 0 5px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h4 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo a,
|
||||
div.sphinxsidebar h3 a,
|
||||
div.sphinxsidebar p.logo a:hover,
|
||||
div.sphinxsidebar h3 a:hover {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p {
|
||||
color: #555;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul li.toctree-l1 > a {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul li.toctree-l2 > a {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #CCC;
|
||||
font-family: Georgia, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
color: #AAA;
|
||||
background: #AAA;
|
||||
|
||||
text-align: left;
|
||||
margin-left: 0;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar .badge {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar .badge:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* To address an issue with donation coming after search */
|
||||
div.sphinxsidebar h3.donation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
a {
|
||||
color: #004B6B;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #6D4100;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.body h1,
|
||||
div.body h2,
|
||||
div.body h3,
|
||||
div.body h4,
|
||||
div.body h5,
|
||||
div.body h6 {
|
||||
font-family: Georgia, serif;
|
||||
font-weight: normal;
|
||||
margin: 30px 0px 10px 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
|
||||
div.body h2 { font-size: 180%; }
|
||||
div.body h3 { font-size: 150%; }
|
||||
div.body h4 { font-size: 130%; }
|
||||
div.body h5 { font-size: 100%; }
|
||||
div.body h6 { font-size: 100%; }
|
||||
|
||||
a.headerlink {
|
||||
color: #DDD;
|
||||
padding: 0 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.headerlink:hover {
|
||||
color: #444;
|
||||
background: #EAEAEA;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
div.admonition {
|
||||
margin: 20px 0px;
|
||||
padding: 10px 30px;
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
|
||||
background-color: #FBFBFB;
|
||||
border-bottom: 1px solid #fafafa;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title {
|
||||
font-family: Georgia, serif;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.admonition p.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.highlight {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
dt:target, .highlight {
|
||||
background: #FAF3E8;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.danger {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
-moz-box-shadow: 2px 2px 4px #D52C2C;
|
||||
-webkit-box-shadow: 2px 2px 4px #D52C2C;
|
||||
box-shadow: 2px 2px 4px #D52C2C;
|
||||
}
|
||||
|
||||
div.error {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
-moz-box-shadow: 2px 2px 4px #D52C2C;
|
||||
-webkit-box-shadow: 2px 2px 4px #D52C2C;
|
||||
box-shadow: 2px 2px 4px #D52C2C;
|
||||
}
|
||||
|
||||
div.caution {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.attention {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.important {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.note {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.tip {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.hint {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.seealso {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
pre, tt, code {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.hll {
|
||||
background-color: #FFC;
|
||||
margin: 0 -12px;
|
||||
padding: 0 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname, code.descname, code.descclassname {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
tt.descname, code.descname {
|
||||
padding-right: 0.08em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
-moz-box-shadow: 2px 2px 4px #EEE;
|
||||
-webkit-box-shadow: 2px 2px 4px #EEE;
|
||||
box-shadow: 2px 2px 4px #EEE;
|
||||
}
|
||||
|
||||
table.docutils {
|
||||
border: 1px solid #888;
|
||||
-moz-box-shadow: 2px 2px 4px #EEE;
|
||||
-webkit-box-shadow: 2px 2px 4px #EEE;
|
||||
box-shadow: 2px 2px 4px #EEE;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
border: 1px solid #888;
|
||||
padding: 0.25em 0.7em;
|
||||
}
|
||||
|
||||
table.field-list, table.footnote {
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table.footnote {
|
||||
margin: 15px 0;
|
||||
width: 100%;
|
||||
border: 1px solid #EEE;
|
||||
background: #FDFDFD;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
table.footnote + table.footnote {
|
||||
margin-top: -15px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
table.field-list th {
|
||||
padding: 0 0.8em 0 0;
|
||||
}
|
||||
|
||||
table.field-list td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.field-list p {
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
/* Cloned from
|
||||
* https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
|
||||
*/
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
table.footnote td.label {
|
||||
width: .1px;
|
||||
padding: 0.3em 0 0.3em 0.5em;
|
||||
}
|
||||
|
||||
table.footnote td {
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 0 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
/* Matches the 30px from the narrow-screen "li > ul" selector below */
|
||||
margin: 10px 0 10px 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #EEE;
|
||||
padding: 7px 30px;
|
||||
margin: 15px 0px;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
background: #ffd;
|
||||
}
|
||||
|
||||
dl pre, blockquote pre, li pre {
|
||||
margin-left: 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
tt, code {
|
||||
background-color: #ecf0f3;
|
||||
color: #222;
|
||||
/* padding: 1px 2px; */
|
||||
}
|
||||
|
||||
tt.xref, code.xref, a tt {
|
||||
background-color: #FBFBFB;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
a.reference {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
/* Don't put an underline on images */
|
||||
a.image-reference, a.image-reference:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a.reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a.footnote-reference {
|
||||
text-decoration: none;
|
||||
font-size: 0.7em;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
a.footnote-reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a:hover tt, a:hover code {
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 870px) {
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
margin-left: 0;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
li > ul {
|
||||
/* Matches the 30px from the "ul, ol" selector above */
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.github {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media screen and (max-width: 875px) {
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: none;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 102.5%;
|
||||
margin: -20px -30px 20px -30px;
|
||||
padding: 10px 20px;
|
||||
background: #333;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.body {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rtd_doc_footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.github {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 876px) {
|
||||
div.sphinxsidebar {
|
||||
position: fixed;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* misc. */
|
||||
|
||||
.revsys-inline {
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
/* Make nested-list/multi-paragraph items look better in Releases changelog
|
||||
* pages. Without this, docutils' magical list fuckery causes inconsistent
|
||||
* formatting between different release sub-lists.
|
||||
*/
|
||||
div#changelog > div.section > ul > li > p:only-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Hide fugly table cell borders in ..bibliography:: directive output */
|
||||
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
|
||||
border: none;
|
||||
/* Below needed in some edge cases; if not applied, bottom shadows appear */
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/* relbar */
|
||||
|
||||
.related {
|
||||
line-height: 30px;
|
||||
width: 100%;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.related.top {
|
||||
border-bottom: 1px solid #EEE;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.related.bottom {
|
||||
border-top: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.related ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
nav#rellinks {
|
||||
float: right;
|
||||
}
|
||||
|
||||
nav#rellinks li+li:before {
|
||||
content: "|";
|
||||
}
|
||||
|
||||
nav#breadcrumbs li+li:before {
|
||||
content: "\00BB";
|
||||
}
|
||||
|
||||
/* Hide certain items when printing */
|
||||
@media print {
|
||||
div.related {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,900 @@
|
|||
/*
|
||||
* basic.css
|
||||
* ~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- basic theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.section::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap : break-word;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox form.search {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="text"] {
|
||||
float: left;
|
||||
width: 80%;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
||||
float: left;
|
||||
width: 20%;
|
||||
border-left: none;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li p.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
table.indextable > tbody > tr > td > ul {
|
||||
padding-left: 0em;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
div.genindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* -- domain module index --------------------------------------------------- */
|
||||
|
||||
table.modindextable td {
|
||||
padding: 2px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
div.body {
|
||||
min-width: 360px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink,
|
||||
caption:hover > a.headerlink,
|
||||
p.caption:hover > a.headerlink,
|
||||
div.code-block-caption:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.body p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.body td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.align-left, figure.align-left, .figure.align-left, object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
img.align-right, figure.align-right, .figure.align-right, object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
img.align-center, figure.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
img.align-default, figure.align-default, .figure.align-default {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-default {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar,
|
||||
aside.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
clear: right;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
nav.contents,
|
||||
aside.topic,
|
||||
div.admonition, div.topic, blockquote {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
nav.contents,
|
||||
aside.topic,
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.body p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- content of sidebars/topics/admonitions -------------------------------- */
|
||||
|
||||
div.sidebar > :last-child,
|
||||
aside.sidebar > :last-child,
|
||||
nav.contents > :last-child,
|
||||
aside.topic > :last-child,
|
||||
div.topic > :last-child,
|
||||
div.admonition > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sidebar::after,
|
||||
aside.sidebar::after,
|
||||
nav.contents::after,
|
||||
aside.topic::after,
|
||||
div.topic::after,
|
||||
div.admonition::after,
|
||||
blockquote::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-default {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table caption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table caption span.caption-text {
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
table.citation td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
th > :first-child,
|
||||
td > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
th > :last-child,
|
||||
td > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* -- figures --------------------------------------------------------------- */
|
||||
|
||||
div.figure, figure {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div.figure p.caption, figcaption {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-number,
|
||||
figcaption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-text,
|
||||
figcaption span.caption-text {
|
||||
}
|
||||
|
||||
/* -- field list styles ----------------------------------------------------- */
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
/* -- hlist styles ---------------------------------------------------------- */
|
||||
|
||||
table.hlist {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
table.hlist td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -- object description styles --------------------------------------------- */
|
||||
|
||||
.sig {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
}
|
||||
|
||||
.sig-name, code.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sig-name {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
code.descname {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.sig-prename, code.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.sig-paren {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.sig-param.n {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* C++ specific styling */
|
||||
|
||||
.sig-inline.c-texpr,
|
||||
.sig-inline.cpp-texpr {
|
||||
font-family: unset;
|
||||
}
|
||||
|
||||
.sig.c .k, .sig.c .kt,
|
||||
.sig.cpp .k, .sig.cpp .kt {
|
||||
color: #0033B3;
|
||||
}
|
||||
|
||||
.sig.c .m,
|
||||
.sig.cpp .m {
|
||||
color: #1750EB;
|
||||
}
|
||||
|
||||
.sig.c .s, .sig.c .sc,
|
||||
.sig.cpp .s, .sig.cpp .sc {
|
||||
color: #067D17;
|
||||
}
|
||||
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha;
|
||||
}
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha;
|
||||
}
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman;
|
||||
}
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:first-child > :first-child,
|
||||
:not(li) > ul > li:first-child > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:last-child > :last-child,
|
||||
:not(li) > ul > li:last-child > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ol.simple ol p,
|
||||
ol.simple ul p,
|
||||
ul.simple ol p,
|
||||
ul.simple ul p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple > li:not(:first-child) > p,
|
||||
ul.simple > li:not(:first-child) > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple p,
|
||||
ul.simple p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
aside.footnote > span,
|
||||
div.citation > span {
|
||||
float: left;
|
||||
}
|
||||
aside.footnote > span:last-of-type,
|
||||
div.citation > span:last-of-type {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
aside.footnote > p {
|
||||
margin-left: 2em;
|
||||
}
|
||||
div.citation > p {
|
||||
margin-left: 4em;
|
||||
}
|
||||
aside.footnote > p:last-of-type,
|
||||
div.citation > p:last-of-type {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
aside.footnote > p:last-of-type:after,
|
||||
div.citation > p:last-of-type:after {
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
dl.field-list {
|
||||
display: grid;
|
||||
grid-template-columns: fit-content(30%) auto;
|
||||
}
|
||||
|
||||
dl.field-list > dt {
|
||||
font-weight: bold;
|
||||
word-break: break-word;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
dl.field-list > dd {
|
||||
padding-left: 0.5em;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dl > dd:last-child,
|
||||
dl > dd:last-child > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt:target, span.highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
rect.highlighted {
|
||||
fill: #fbe54e;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.guilabel, .menuselection {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.accelerator {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.classifier {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.classifier:before {
|
||||
font-style: normal;
|
||||
margin: 0 0.5em;
|
||||
content: ":";
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
abbr, acronym {
|
||||
border-bottom: dotted 1px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
||||
}
|
||||
|
||||
pre, div[class*="highlight-"] {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
span.pre {
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
hyphens: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div[class*="highlight-"] {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td.code {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.highlight pre,
|
||||
table.highlighttable pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption + div {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption {
|
||||
margin-top: 1em;
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.code-block-caption code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos,
|
||||
span.linenos,
|
||||
div.highlight span.gp { /* gp: Generic.Prompt */
|
||||
user-select: none;
|
||||
-webkit-user-select: text; /* Safari fallback only */
|
||||
-webkit-user-select: none; /* Chrome/Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE10+ */
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-number {
|
||||
padding: 0.1em 0.3em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-text {
|
||||
}
|
||||
|
||||
div.literal-block-wrapper {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
code.xref, a code {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.body div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.eqno a.headerlink {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
div.math:hover a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* -- printout stylesheet --------------------------------------------------- */
|
||||
|
||||
@media print {
|
||||
div.document,
|
||||
div.documentwrapper,
|
||||
div.bodywrapper {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar,
|
||||
div.related,
|
||||
div.footer,
|
||||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/* This file intentionally left blank. */
|
|
@ -0,0 +1,264 @@
|
|||
/*
|
||||
* doctools.js
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* Base JavaScript utilities for all Sphinx HTML documentation.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const _ready = (callback) => {
|
||||
if (document.readyState !== "loading") {
|
||||
callback();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a node by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
const _highlight = (node, addItems, text, className) => {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const val = node.nodeValue;
|
||||
const parent = node.parentNode;
|
||||
const pos = val.toLowerCase().indexOf(text);
|
||||
if (
|
||||
pos >= 0 &&
|
||||
!parent.classList.contains(className) &&
|
||||
!parent.classList.contains("nohighlight")
|
||||
) {
|
||||
let span;
|
||||
|
||||
const closestNode = parent.closest("body, svg, foreignObject");
|
||||
const isInSVG = closestNode && closestNode.matches("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.classList.add(className);
|
||||
}
|
||||
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
parent.insertBefore(
|
||||
span,
|
||||
parent.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling
|
||||
)
|
||||
);
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
|
||||
if (isInSVG) {
|
||||
const rect = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"rect"
|
||||
);
|
||||
const bbox = parent.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute("class", className);
|
||||
addItems.push({ parent: parent, target: rect });
|
||||
}
|
||||
}
|
||||
} else if (node.matches && !node.matches("button, select, textarea")) {
|
||||
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
|
||||
}
|
||||
};
|
||||
const _highlightText = (thisNode, text, className) => {
|
||||
let addItems = [];
|
||||
_highlight(thisNode, addItems, text, className);
|
||||
addItems.forEach((obj) =>
|
||||
obj.parent.insertAdjacentElement("beforebegin", obj.target)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Small JavaScript module for the documentation.
|
||||
*/
|
||||
const Documentation = {
|
||||
init: () => {
|
||||
Documentation.highlightSearchWords();
|
||||
Documentation.initDomainIndexTable();
|
||||
Documentation.initOnKeyListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
* i18n support
|
||||
*/
|
||||
TRANSLATIONS: {},
|
||||
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
|
||||
LOCALE: "unknown",
|
||||
|
||||
// gettext and ngettext don't access this so that the functions
|
||||
// can safely bound to a different name (_ = Documentation.gettext)
|
||||
gettext: (string) => {
|
||||
const translated = Documentation.TRANSLATIONS[string];
|
||||
switch (typeof translated) {
|
||||
case "undefined":
|
||||
return string; // no translation
|
||||
case "string":
|
||||
return translated; // translation exists
|
||||
default:
|
||||
return translated[0]; // (singular, plural) translation tuple exists
|
||||
}
|
||||
},
|
||||
|
||||
ngettext: (singular, plural, n) => {
|
||||
const translated = Documentation.TRANSLATIONS[singular];
|
||||
if (typeof translated !== "undefined")
|
||||
return translated[Documentation.PLURAL_EXPR(n)];
|
||||
return n === 1 ? singular : plural;
|
||||
},
|
||||
|
||||
addTranslations: (catalog) => {
|
||||
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
|
||||
Documentation.PLURAL_EXPR = new Function(
|
||||
"n",
|
||||
`return (${catalog.plural_expr})`
|
||||
);
|
||||
Documentation.LOCALE = catalog.locale;
|
||||
},
|
||||
|
||||
/**
|
||||
* highlight the search words provided in the url in the text
|
||||
*/
|
||||
highlightSearchWords: () => {
|
||||
const highlight =
|
||||
new URLSearchParams(window.location.search).get("highlight") || "";
|
||||
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
|
||||
if (terms.length === 0) return; // nothing to do
|
||||
|
||||
// There should never be more than one element matching "div.body"
|
||||
const divBody = document.querySelectorAll("div.body");
|
||||
const body = divBody.length ? divBody[0] : document.querySelector("body");
|
||||
window.setTimeout(() => {
|
||||
terms.forEach((term) => _highlightText(body, term, "highlighted"));
|
||||
}, 10);
|
||||
|
||||
const searchBox = document.getElementById("searchbox");
|
||||
if (searchBox === null) return;
|
||||
searchBox.appendChild(
|
||||
document
|
||||
.createRange()
|
||||
.createContextualFragment(
|
||||
'<p class="highlight-link">' +
|
||||
'<a href="javascript:Documentation.hideSearchWords()">' +
|
||||
Documentation.gettext("Hide Search Matches") +
|
||||
"</a></p>"
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to hide the search marks again
|
||||
*/
|
||||
hideSearchWords: () => {
|
||||
document
|
||||
.querySelectorAll("#searchbox .highlight-link")
|
||||
.forEach((el) => el.remove());
|
||||
document
|
||||
.querySelectorAll("span.highlighted")
|
||||
.forEach((el) => el.classList.remove("highlighted"));
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.delete("highlight");
|
||||
window.history.replaceState({}, "", url);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to focus on search bar
|
||||
*/
|
||||
focusSearchBar: () => {
|
||||
document.querySelectorAll("input[name=q]")[0]?.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialise the domain index toggle buttons
|
||||
*/
|
||||
initDomainIndexTable: () => {
|
||||
const toggler = (el) => {
|
||||
const idNumber = el.id.substr(7);
|
||||
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
|
||||
if (el.src.substr(-9) === "minus.png") {
|
||||
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = "none"));
|
||||
} else {
|
||||
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = ""));
|
||||
}
|
||||
};
|
||||
|
||||
const togglerElements = document.querySelectorAll("img.toggler");
|
||||
togglerElements.forEach((el) =>
|
||||
el.addEventListener("click", (event) => toggler(event.currentTarget))
|
||||
);
|
||||
togglerElements.forEach((el) => (el.style.display = ""));
|
||||
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
|
||||
},
|
||||
|
||||
initOnKeyListeners: () => {
|
||||
// only install a listener if it is really needed
|
||||
if (
|
||||
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
|
||||
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
|
||||
)
|
||||
return;
|
||||
|
||||
const blacklistedElements = new Set([
|
||||
"TEXTAREA",
|
||||
"INPUT",
|
||||
"SELECT",
|
||||
"BUTTON",
|
||||
]);
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
|
||||
|
||||
if (!event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case "ArrowLeft":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const prevLink = document.querySelector('link[rel="prev"]');
|
||||
if (prevLink && prevLink.href) {
|
||||
window.location.href = prevLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "ArrowRight":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const nextLink = document.querySelector('link[rel="next"]');
|
||||
if (nextLink && nextLink.href) {
|
||||
window.location.href = nextLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.hideSearchWords();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// some keyboard layouts may need Shift to get /
|
||||
switch (event.key) {
|
||||
case "/":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.focusSearchBar();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// quick alias for translations
|
||||
const _ = Documentation.gettext;
|
||||
|
||||
_ready(Documentation.init);
|
|
@ -0,0 +1,14 @@
|
|||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '0.4.3',
|
||||
LANGUAGE: 'en',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
FILE_SUFFIX: '.html',
|
||||
LINK_SUFFIX: '.html',
|
||||
HAS_SOURCE: true,
|
||||
SOURCELINK_SUFFIX: '.txt',
|
||||
NAVIGATION_WITH_KEYS: false,
|
||||
SHOW_SEARCH_SUMMARY: true,
|
||||
ENABLE_SEARCH_SHORTCUTS: true,
|
||||
};
|
Binary file not shown.
After Width: | Height: | Size: 286 B |
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* language_data.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This script contains the language-specific data used by searchtools.js,
|
||||
* namely the list of stopwords, stemmer, scorer and splitter.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
|
||||
|
||||
|
||||
/* Non-minified version is copied as a separate JS file, is available */
|
||||
|
||||
/**
|
||||
* Porter Stemmer
|
||||
*/
|
||||
var Stemmer = function() {
|
||||
|
||||
var step2list = {
|
||||
ational: 'ate',
|
||||
tional: 'tion',
|
||||
enci: 'ence',
|
||||
anci: 'ance',
|
||||
izer: 'ize',
|
||||
bli: 'ble',
|
||||
alli: 'al',
|
||||
entli: 'ent',
|
||||
eli: 'e',
|
||||
ousli: 'ous',
|
||||
ization: 'ize',
|
||||
ation: 'ate',
|
||||
ator: 'ate',
|
||||
alism: 'al',
|
||||
iveness: 'ive',
|
||||
fulness: 'ful',
|
||||
ousness: 'ous',
|
||||
aliti: 'al',
|
||||
iviti: 'ive',
|
||||
biliti: 'ble',
|
||||
logi: 'log'
|
||||
};
|
||||
|
||||
var step3list = {
|
||||
icate: 'ic',
|
||||
ative: '',
|
||||
alize: 'al',
|
||||
iciti: 'ic',
|
||||
ical: 'ic',
|
||||
ful: '',
|
||||
ness: ''
|
||||
};
|
||||
|
||||
var c = "[^aeiou]"; // consonant
|
||||
var v = "[aeiouy]"; // vowel
|
||||
var C = c + "[^aeiouy]*"; // consonant sequence
|
||||
var V = v + "[aeiou]*"; // vowel sequence
|
||||
|
||||
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
|
||||
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
|
||||
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
|
||||
var s_v = "^(" + C + ")?" + v; // vowel in stem
|
||||
|
||||
this.stemWord = function (w) {
|
||||
var stem;
|
||||
var suffix;
|
||||
var firstch;
|
||||
var origword = w;
|
||||
|
||||
if (w.length < 3)
|
||||
return w;
|
||||
|
||||
var re;
|
||||
var re2;
|
||||
var re3;
|
||||
var re4;
|
||||
|
||||
firstch = w.substr(0,1);
|
||||
if (firstch == "y")
|
||||
w = firstch.toUpperCase() + w.substr(1);
|
||||
|
||||
// Step 1a
|
||||
re = /^(.+?)(ss|i)es$/;
|
||||
re2 = /^(.+?)([^s])s$/;
|
||||
|
||||
if (re.test(w))
|
||||
w = w.replace(re,"$1$2");
|
||||
else if (re2.test(w))
|
||||
w = w.replace(re2,"$1$2");
|
||||
|
||||
// Step 1b
|
||||
re = /^(.+?)eed$/;
|
||||
re2 = /^(.+?)(ed|ing)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(fp[1])) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1];
|
||||
re2 = new RegExp(s_v);
|
||||
if (re2.test(stem)) {
|
||||
w = stem;
|
||||
re2 = /(at|bl|iz)$/;
|
||||
re3 = new RegExp("([^aeiouylsz])\\1$");
|
||||
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re2.test(w))
|
||||
w = w + "e";
|
||||
else if (re3.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
else if (re4.test(w))
|
||||
w = w + "e";
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1c
|
||||
re = /^(.+?)y$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(s_v);
|
||||
if (re.test(stem))
|
||||
w = stem + "i";
|
||||
}
|
||||
|
||||
// Step 2
|
||||
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step2list[suffix];
|
||||
}
|
||||
|
||||
// Step 3
|
||||
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step3list[suffix];
|
||||
}
|
||||
|
||||
// Step 4
|
||||
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
|
||||
re2 = /^(.+?)(s|t)(ion)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
if (re.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1] + fp[2];
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re2.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
re = /^(.+?)e$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
re2 = new RegExp(meq1);
|
||||
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
|
||||
w = stem;
|
||||
}
|
||||
re = /ll$/;
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re.test(w) && re2.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
|
||||
// and turn initial Y back to y
|
||||
if (firstch == "y")
|
||||
w = firstch.toLowerCase() + w.substr(1);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 90 B |
Binary file not shown.
After Width: | Height: | Size: 90 B |
|
@ -0,0 +1,74 @@
|
|||
pre { line-height: 125%; }
|
||||
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
|
||||
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
|
||||
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #E40000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #008400 } /* Generic.Inserted */
|
||||
.highlight .go { color: #717171 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #687822 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #767600 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* searchtools.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx JavaScript utilities for the full-text search.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Simple result scoring code.
|
||||
*/
|
||||
if (typeof Scorer === "undefined") {
|
||||
var Scorer = {
|
||||
// Implement the following function to further tweak the score for each result
|
||||
// The function takes a result array [docname, title, anchor, descr, score, filename]
|
||||
// and returns the new score.
|
||||
/*
|
||||
score: result => {
|
||||
const [docname, title, anchor, descr, score, filename] = result
|
||||
return score
|
||||
},
|
||||
*/
|
||||
|
||||
// query matches the full name of an object
|
||||
objNameMatch: 11,
|
||||
// or matches in the last dotted part of the object name
|
||||
objPartialMatch: 6,
|
||||
// Additive scores depending on the priority of the object
|
||||
objPrio: {
|
||||
0: 15, // used to be importantResults
|
||||
1: 5, // used to be objectResults
|
||||
2: -5, // used to be unimportantResults
|
||||
},
|
||||
// Used when the priority is not in the mapping.
|
||||
objPrioDefault: 0,
|
||||
|
||||
// query found in title
|
||||
title: 15,
|
||||
partialTitle: 7,
|
||||
// query found in terms
|
||||
term: 5,
|
||||
partialTerm: 2,
|
||||
};
|
||||
}
|
||||
|
||||
const _removeChildren = (element) => {
|
||||
while (element && element.lastChild) element.removeChild(element.lastChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
||||
*/
|
||||
const _escapeRegExp = (string) =>
|
||||
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
|
||||
const _displayItem = (item, highlightTerms, searchTerms) => {
|
||||
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
|
||||
const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
|
||||
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
|
||||
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
|
||||
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
|
||||
|
||||
const [docName, title, anchor, descr] = item;
|
||||
|
||||
let listItem = document.createElement("li");
|
||||
let requestUrl;
|
||||
let linkUrl;
|
||||
if (docBuilder === "dirhtml") {
|
||||
// dirhtml builder
|
||||
let dirname = docName + "/";
|
||||
if (dirname.match(/\/index\/$/))
|
||||
dirname = dirname.substring(0, dirname.length - 6);
|
||||
else if (dirname === "index/") dirname = "";
|
||||
requestUrl = docUrlRoot + dirname;
|
||||
linkUrl = requestUrl;
|
||||
} else {
|
||||
// normal html builders
|
||||
requestUrl = docUrlRoot + docName + docFileSuffix;
|
||||
linkUrl = docName + docLinkSuffix;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.set("highlight", [...highlightTerms].join(" "));
|
||||
let linkEl = listItem.appendChild(document.createElement("a"));
|
||||
linkEl.href = linkUrl + "?" + params.toString() + anchor;
|
||||
linkEl.innerHTML = title;
|
||||
if (descr)
|
||||
listItem.appendChild(document.createElement("span")).innerHTML =
|
||||
" (" + descr + ")";
|
||||
else if (showSearchSummary)
|
||||
fetch(requestUrl)
|
||||
.then((responseData) => responseData.text())
|
||||
.then((data) => {
|
||||
if (data)
|
||||
listItem.appendChild(
|
||||
Search.makeSearchSummary(data, searchTerms, highlightTerms)
|
||||
);
|
||||
});
|
||||
Search.output.appendChild(listItem);
|
||||
};
|
||||
const _finishSearch = (resultCount) => {
|
||||
Search.stopPulse();
|
||||
Search.title.innerText = _("Search Results");
|
||||
if (!resultCount)
|
||||
Search.status.innerText = Documentation.gettext(
|
||||
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
|
||||
);
|
||||
else
|
||||
Search.status.innerText = _(
|
||||
`Search finished, found ${resultCount} page(s) matching the search query.`
|
||||
);
|
||||
};
|
||||
const _displayNextItem = (
|
||||
results,
|
||||
resultCount,
|
||||
highlightTerms,
|
||||
searchTerms
|
||||
) => {
|
||||
// results left, load the summary and display it
|
||||
// this is intended to be dynamic (don't sub resultsCount)
|
||||
if (results.length) {
|
||||
_displayItem(results.pop(), highlightTerms, searchTerms);
|
||||
setTimeout(
|
||||
() => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
|
||||
5
|
||||
);
|
||||
}
|
||||
// search finished, update title and status message
|
||||
else _finishSearch(resultCount);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
|
||||
* custom function per language.
|
||||
*
|
||||
* The regular expression works by splitting the string on consecutive characters
|
||||
* that are not Unicode letters, numbers, underscores, or emoji characters.
|
||||
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
|
||||
*/
|
||||
if (typeof splitQuery === "undefined") {
|
||||
var splitQuery = (query) => query
|
||||
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
|
||||
.filter(term => term) // remove remaining empty strings
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Module
|
||||
*/
|
||||
const Search = {
|
||||
_index: null,
|
||||
_queued_query: null,
|
||||
_pulse_status: -1,
|
||||
|
||||
htmlToText: (htmlString) => {
|
||||
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
|
||||
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
|
||||
const docContent = htmlElement.querySelector('[role="main"]');
|
||||
if (docContent !== undefined) return docContent.textContent;
|
||||
console.warn(
|
||||
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
|
||||
);
|
||||
return "";
|
||||
},
|
||||
|
||||
init: () => {
|
||||
const query = new URLSearchParams(window.location.search).get("q");
|
||||
document
|
||||
.querySelectorAll('input[name="q"]')
|
||||
.forEach((el) => (el.value = query));
|
||||
if (query) Search.performSearch(query);
|
||||
},
|
||||
|
||||
loadIndex: (url) =>
|
||||
(document.body.appendChild(document.createElement("script")).src = url),
|
||||
|
||||
setIndex: (index) => {
|
||||
Search._index = index;
|
||||
if (Search._queued_query !== null) {
|
||||
const query = Search._queued_query;
|
||||
Search._queued_query = null;
|
||||
Search.query(query);
|
||||
}
|
||||
},
|
||||
|
||||
hasIndex: () => Search._index !== null,
|
||||
|
||||
deferQuery: (query) => (Search._queued_query = query),
|
||||
|
||||
stopPulse: () => (Search._pulse_status = -1),
|
||||
|
||||
startPulse: () => {
|
||||
if (Search._pulse_status >= 0) return;
|
||||
|
||||
const pulse = () => {
|
||||
Search._pulse_status = (Search._pulse_status + 1) % 4;
|
||||
Search.dots.innerText = ".".repeat(Search._pulse_status);
|
||||
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
|
||||
};
|
||||
pulse();
|
||||
},
|
||||
|
||||
/**
|
||||
* perform a search for something (or wait until index is loaded)
|
||||
*/
|
||||
performSearch: (query) => {
|
||||
// create the required interface elements
|
||||
const searchText = document.createElement("h2");
|
||||
searchText.textContent = _("Searching");
|
||||
const searchSummary = document.createElement("p");
|
||||
searchSummary.classList.add("search-summary");
|
||||
searchSummary.innerText = "";
|
||||
const searchList = document.createElement("ul");
|
||||
searchList.classList.add("search");
|
||||
|
||||
const out = document.getElementById("search-results");
|
||||
Search.title = out.appendChild(searchText);
|
||||
Search.dots = Search.title.appendChild(document.createElement("span"));
|
||||
Search.status = out.appendChild(searchSummary);
|
||||
Search.output = out.appendChild(searchList);
|
||||
|
||||
const searchProgress = document.getElementById("search-progress");
|
||||
// Some themes don't use the search progress node
|
||||
if (searchProgress) {
|
||||
searchProgress.innerText = _("Preparing search...");
|
||||
}
|
||||
Search.startPulse();
|
||||
|
||||
// index already loaded, the browser was quick!
|
||||
if (Search.hasIndex()) Search.query(query);
|
||||
else Search.deferQuery(query);
|
||||
},
|
||||
|
||||
/**
|
||||
* execute search (requires search index to be loaded)
|
||||
*/
|
||||
query: (query) => {
|
||||
// stem the search terms and add them to the correct list
|
||||
const stemmer = new Stemmer();
|
||||
const searchTerms = new Set();
|
||||
const excludedTerms = new Set();
|
||||
const highlightTerms = new Set();
|
||||
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
|
||||
splitQuery(query.trim()).forEach((queryTerm) => {
|
||||
const queryTermLower = queryTerm.toLowerCase();
|
||||
|
||||
// maybe skip this "word"
|
||||
// stopwords array is from language_data.js
|
||||
if (
|
||||
stopwords.indexOf(queryTermLower) !== -1 ||
|
||||
queryTerm.match(/^\d+$/)
|
||||
)
|
||||
return;
|
||||
|
||||
// stem the word
|
||||
let word = stemmer.stemWord(queryTermLower);
|
||||
// select the correct list
|
||||
if (word[0] === "-") excludedTerms.add(word.substr(1));
|
||||
else {
|
||||
searchTerms.add(word);
|
||||
highlightTerms.add(queryTermLower);
|
||||
}
|
||||
});
|
||||
|
||||
// console.debug("SEARCH: searching for:");
|
||||
// console.info("required: ", [...searchTerms]);
|
||||
// console.info("excluded: ", [...excludedTerms]);
|
||||
|
||||
// array of [docname, title, anchor, descr, score, filename]
|
||||
let results = [];
|
||||
_removeChildren(document.getElementById("search-progress"));
|
||||
|
||||
// lookup as object
|
||||
objectTerms.forEach((term) =>
|
||||
results.push(...Search.performObjectSearch(term, objectTerms))
|
||||
);
|
||||
|
||||
// lookup as search terms in fulltext
|
||||
results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
|
||||
|
||||
// let the scorer override scores with a custom scoring function
|
||||
if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
|
||||
|
||||
// now sort the results by score (in opposite order of appearance, since the
|
||||
// display function below uses pop() to retrieve items) and then
|
||||
// alphabetically
|
||||
results.sort((a, b) => {
|
||||
const leftScore = a[4];
|
||||
const rightScore = b[4];
|
||||
if (leftScore === rightScore) {
|
||||
// same score: sort alphabetically
|
||||
const leftTitle = a[1].toLowerCase();
|
||||
const rightTitle = b[1].toLowerCase();
|
||||
if (leftTitle === rightTitle) return 0;
|
||||
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
|
||||
}
|
||||
return leftScore > rightScore ? 1 : -1;
|
||||
});
|
||||
|
||||
// remove duplicate search results
|
||||
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
|
||||
let seen = new Set();
|
||||
results = results.reverse().reduce((acc, result) => {
|
||||
let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
|
||||
if (!seen.has(resultStr)) {
|
||||
acc.push(result);
|
||||
seen.add(resultStr);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
results = results.reverse();
|
||||
|
||||
// for debugging
|
||||
//Search.lastresults = results.slice(); // a copy
|
||||
// console.info("search results:", Search.lastresults);
|
||||
|
||||
// print the results
|
||||
_displayNextItem(results, results.length, highlightTerms, searchTerms);
|
||||
},
|
||||
|
||||
/**
|
||||
* search for object names
|
||||
*/
|
||||
performObjectSearch: (object, objectTerms) => {
|
||||
const filenames = Search._index.filenames;
|
||||
const docNames = Search._index.docnames;
|
||||
const objects = Search._index.objects;
|
||||
const objNames = Search._index.objnames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const results = [];
|
||||
|
||||
const objectSearchCallback = (prefix, match) => {
|
||||
const name = match[4]
|
||||
const fullname = (prefix ? prefix + "." : "") + name;
|
||||
const fullnameLower = fullname.toLowerCase();
|
||||
if (fullnameLower.indexOf(object) < 0) return;
|
||||
|
||||
let score = 0;
|
||||
const parts = fullnameLower.split(".");
|
||||
|
||||
// check for different match types: exact matches of full name or
|
||||
// "last name" (i.e. last dotted part)
|
||||
if (fullnameLower === object || parts.slice(-1)[0] === object)
|
||||
score += Scorer.objNameMatch;
|
||||
else if (parts.slice(-1)[0].indexOf(object) > -1)
|
||||
score += Scorer.objPartialMatch; // matches in last name
|
||||
|
||||
const objName = objNames[match[1]][2];
|
||||
const title = titles[match[0]];
|
||||
|
||||
// If more than one term searched for, we require other words to be
|
||||
// found in the name/title/description
|
||||
const otherTerms = new Set(objectTerms);
|
||||
otherTerms.delete(object);
|
||||
if (otherTerms.size > 0) {
|
||||
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
|
||||
if (
|
||||
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
let anchor = match[3];
|
||||
if (anchor === "") anchor = fullname;
|
||||
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
|
||||
|
||||
const descr = objName + _(", in ") + title;
|
||||
|
||||
// add custom score for some objects according to scorer
|
||||
if (Scorer.objPrio.hasOwnProperty(match[2]))
|
||||
score += Scorer.objPrio[match[2]];
|
||||
else score += Scorer.objPrioDefault;
|
||||
|
||||
results.push([
|
||||
docNames[match[0]],
|
||||
fullname,
|
||||
"#" + anchor,
|
||||
descr,
|
||||
score,
|
||||
filenames[match[0]],
|
||||
]);
|
||||
};
|
||||
Object.keys(objects).forEach((prefix) =>
|
||||
objects[prefix].forEach((array) =>
|
||||
objectSearchCallback(prefix, array)
|
||||
)
|
||||
);
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* search for full-text terms in the index
|
||||
*/
|
||||
performTermsSearch: (searchTerms, excludedTerms) => {
|
||||
// prepare search
|
||||
const terms = Search._index.terms;
|
||||
const titleTerms = Search._index.titleterms;
|
||||
const docNames = Search._index.docnames;
|
||||
const filenames = Search._index.filenames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const scoreMap = new Map();
|
||||
const fileMap = new Map();
|
||||
|
||||
// perform the search on the required terms
|
||||
searchTerms.forEach((word) => {
|
||||
const files = [];
|
||||
const arr = [
|
||||
{ files: terms[word], score: Scorer.term },
|
||||
{ files: titleTerms[word], score: Scorer.title },
|
||||
];
|
||||
// add support for partial matches
|
||||
if (word.length > 2) {
|
||||
const escapedWord = _escapeRegExp(word);
|
||||
Object.keys(terms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !terms[word])
|
||||
arr.push({ files: terms[term], score: Scorer.partialTerm });
|
||||
});
|
||||
Object.keys(titleTerms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !titleTerms[word])
|
||||
arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
|
||||
});
|
||||
}
|
||||
|
||||
// no match but word was a required one
|
||||
if (arr.every((record) => record.files === undefined)) return;
|
||||
|
||||
// found search word in contents
|
||||
arr.forEach((record) => {
|
||||
if (record.files === undefined) return;
|
||||
|
||||
let recordFiles = record.files;
|
||||
if (recordFiles.length === undefined) recordFiles = [recordFiles];
|
||||
files.push(...recordFiles);
|
||||
|
||||
// set score for the word in each file
|
||||
recordFiles.forEach((file) => {
|
||||
if (!scoreMap.has(file)) scoreMap.set(file, {});
|
||||
scoreMap.get(file)[word] = record.score;
|
||||
});
|
||||
});
|
||||
|
||||
// create the mapping
|
||||
files.forEach((file) => {
|
||||
if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
|
||||
fileMap.get(file).push(word);
|
||||
else fileMap.set(file, [word]);
|
||||
});
|
||||
});
|
||||
|
||||
// now check if the files don't contain excluded terms
|
||||
const results = [];
|
||||
for (const [file, wordList] of fileMap) {
|
||||
// check if all requirements are matched
|
||||
|
||||
// as search terms with length < 3 are discarded
|
||||
const filteredTermCount = [...searchTerms].filter(
|
||||
(term) => term.length > 2
|
||||
).length;
|
||||
if (
|
||||
wordList.length !== searchTerms.size &&
|
||||
wordList.length !== filteredTermCount
|
||||
)
|
||||
continue;
|
||||
|
||||
// ensure that none of the excluded terms is in the search result
|
||||
if (
|
||||
[...excludedTerms].some(
|
||||
(term) =>
|
||||
terms[term] === file ||
|
||||
titleTerms[term] === file ||
|
||||
(terms[term] || []).includes(file) ||
|
||||
(titleTerms[term] || []).includes(file)
|
||||
)
|
||||
)
|
||||
break;
|
||||
|
||||
// select one (max) score for the file.
|
||||
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
|
||||
// add result to the result list
|
||||
results.push([
|
||||
docNames[file],
|
||||
titles[file],
|
||||
"",
|
||||
null,
|
||||
score,
|
||||
filenames[file],
|
||||
]);
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to return a node containing the
|
||||
* search summary for a given text. keywords is a list
|
||||
* of stemmed words, highlightWords is the list of normal, unstemmed
|
||||
* words. the first one is used to find the occurrence, the
|
||||
* latter for highlighting it.
|
||||
*/
|
||||
makeSearchSummary: (htmlText, keywords, highlightWords) => {
|
||||
const text = Search.htmlToText(htmlText);
|
||||
if (text === "") return null;
|
||||
|
||||
const textLower = text.toLowerCase();
|
||||
const actualStartPosition = [...keywords]
|
||||
.map((k) => textLower.indexOf(k.toLowerCase()))
|
||||
.filter((i) => i > -1)
|
||||
.slice(-1)[0];
|
||||
const startWithContext = Math.max(actualStartPosition - 120, 0);
|
||||
|
||||
const top = startWithContext === 0 ? "" : "...";
|
||||
const tail = startWithContext + 240 < text.length ? "..." : "";
|
||||
|
||||
let summary = document.createElement("p");
|
||||
summary.classList.add("context");
|
||||
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
|
||||
|
||||
highlightWords.forEach((highlightWord) =>
|
||||
_highlightText(summary, highlightWord, "highlighted")
|
||||
);
|
||||
|
||||
return summary;
|
||||
},
|
||||
};
|
||||
|
||||
_ready(Search.init);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,241 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
||||
|
||||
<title>Command-line interface — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="Parsed data" href="data.html" />
|
||||
<link rel="prev" title="Python lspci parser" href="index.html" />
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Command-line interface</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#options">Options</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#filters">Filters</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#device-data">Device data</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#output-modes">Output modes</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#pci-access">PCI access</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
<li>Previous: <a href="index.html" title="previous chapter">Python lspci parser</a></li>
|
||||
<li>Next: <a href="data.html" title="next chapter">Parsed data</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="command-line-interface">
|
||||
<h1>Command-line interface<a class="headerlink" href="#command-line-interface" title="Permalink to this heading">¶</a></h1>
|
||||
<p>Once the package is installed, an executable called <code class="docutils literal notranslate"><span class="pre">pylspci</span></code> should be
|
||||
created by setuptools. You may also use <code class="docutils literal notranslate"><span class="pre">python3</span> <span class="pre">-m</span> <span class="pre">pylspci</span></code> to call the same
|
||||
script. The CLI mimicks some of lspci’s arguments, but due to pylspci’s own
|
||||
behavior and due to some features being not implemented, some arguments have
|
||||
been omitted or modified.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pylspci</span> <span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">i</span> <span class="n">PCIIDS</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">p</span> <span class="n">PCIMAP</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="o">-</span><span class="n">s</span> <span class="p">[[</span><span class="n">domain</span><span class="p">:]</span><span class="n">bus</span><span class="p">:][</span><span class="n">device</span><span class="p">][</span><span class="o">.</span><span class="n">function</span><span class="p">]]</span>
|
||||
<span class="p">[</span><span class="o">-</span><span class="n">d</span> <span class="p">[</span><span class="n">vendor</span><span class="p">]:[</span><span class="n">device</span><span class="p">][:</span><span class="n">class</span><span class="p">]]</span>
|
||||
<span class="p">[</span><span class="o">-</span><span class="n">v</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">k</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span><span class="n">name</span><span class="o">-</span><span class="n">only</span> <span class="o">|</span> <span class="o">-</span><span class="n">n</span> <span class="o">|</span> <span class="o">-</span><span class="n">nn</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="o">-</span><span class="n">A</span> <span class="n">METHOD</span> <span class="o">|</span> <span class="o">-</span><span class="n">F</span> <span class="n">FILE</span> <span class="o">|</span> <span class="o">-</span><span class="n">H1</span> <span class="o">|</span> <span class="o">-</span><span class="n">H2</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="n">O</span> <span class="n">KEY</span><span class="o">=</span><span class="n">VALUE</span><span class="p">]</span>
|
||||
<span class="p">[</span><span class="o">--</span><span class="n">json</span> <span class="o">|</span> <span class="o">--</span><span class="n">raw</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<section id="options">
|
||||
<h2>Options<a class="headerlink" href="#options" title="Permalink to this heading">¶</a></h2>
|
||||
<dl>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-h,</span> <span class="pre">--help</span></code></dt><dd><p>Show a help message and exit.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-i,</span> <span class="pre">--pci-ids</span> <span class="pre"><path></span></code></dt><dd><p>Path to an alternate file to use as the PCI ID list.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">pciids</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-p,</span> <span class="pre">--pci-map</span> <span class="pre"><path></span></code></dt><dd><p>Path to an alternate file to use as the kernel module mapping file.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">pcimap</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<section id="filters">
|
||||
<h3>Filters<a class="headerlink" href="#filters" title="Permalink to this heading">¶</a></h3>
|
||||
<dl>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-s</span> <span class="pre">[[domain:]bus:][device][.function]</span></code></dt><dd><p>Filter devices by their slots.
|
||||
Any value can be omitted or set to <code class="docutils literal notranslate"><span class="pre">*</span></code> to disable filtering.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">slot_filter</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.
|
||||
See <a class="reference internal" href="command.html#pylspci.filters.SlotFilter" title="pylspci.filters.SlotFilter"><code class="xref py py-class docutils literal notranslate"><span class="pre">SlotFilter</span></code></a> for more details.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-d</span> <span class="pre">[vendor]:[device][:class]</span></code></dt><dd><p>Filter devices by their type.
|
||||
Any value can be omitted or set to <code class="docutils literal notranslate"><span class="pre">*</span></code> to disable filtering.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">device_filter</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.
|
||||
See <a class="reference internal" href="command.html#pylspci.filters.DeviceFilter" title="pylspci.filters.DeviceFilter"><code class="xref py py-class docutils literal notranslate"><span class="pre">DeviceFilter</span></code></a> for more details.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section id="device-data">
|
||||
<h3>Device data<a class="headerlink" href="#device-data" title="Permalink to this heading">¶</a></h3>
|
||||
<dl>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-v,</span> <span class="pre">--verbose</span></code></dt><dd><p>Display more details about devices.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">verbose</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-k,</span> <span class="pre">--kernel-modules</span></code></dt><dd><p>On Linux kernels above 2.6, include kernel drivers handling each device and
|
||||
kernel modules able to handle them. Implies <code class="docutils literal notranslate"><span class="pre">-v</span></code>.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">include_kernel_drivers</span></code>
|
||||
in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-P,</span> <span class="pre">-PP,</span> <span class="pre">--bridge-paths</span></code></dt><dd><p>Include PCI bridge paths along with device IDs.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">include_bridge_paths</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">--name-only</span></code></dt><dd><p>Only include device names. This is the default.</p>
|
||||
<p>Maps to <a class="reference internal" href="command.html#pylspci.command.IDResolveOption.NameOnly" title="pylspci.command.IDResolveOption.NameOnly"><code class="xref py py-attr docutils literal notranslate"><span class="pre">NameOnly</span></code></a> as
|
||||
the <code class="docutils literal notranslate"><span class="pre">id_resolve_option</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-n,</span> <span class="pre">--id-only</span></code></dt><dd><p>Only include device IDs, without looking for names in the PCI ID file.</p>
|
||||
<p>Maps to <a class="reference internal" href="command.html#pylspci.command.IDResolveOption.IDOnly" title="pylspci.command.IDResolveOption.IDOnly"><code class="xref py py-attr docutils literal notranslate"><span class="pre">IDOnly</span></code></a> as
|
||||
the <code class="docutils literal notranslate"><span class="pre">id_resolve_option</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-nn,</span> <span class="pre">--name-with-id</span></code></dt><dd><p>Include both device IDs and names.</p>
|
||||
<p>Maps to <a class="reference internal" href="command.html#pylspci.command.IDResolveOption.Both" title="pylspci.command.IDResolveOption.Both"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Both</span></code></a> as
|
||||
the <code class="docutils literal notranslate"><span class="pre">id_resolve_option</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section id="output-modes">
|
||||
<h3>Output modes<a class="headerlink" href="#output-modes" title="Permalink to this heading">¶</a></h3>
|
||||
<dl>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">--json</span></code></dt><dd><p>Parse the lspci output and return a JSON list. This is the default.</p>
|
||||
<p>Will automatically select the best parser depending on the chosen settings:</p>
|
||||
<ul class="simple">
|
||||
<li><p>In verbose mode, uses an instance of
|
||||
<code class="xref py py-class docutils literal notranslate"><span class="pre">VerboseParser</span></code> and returns a list
|
||||
of objects corresponding to <a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><code class="xref py py-class docutils literal notranslate"><span class="pre">Device</span></code></a>
|
||||
instances.</p></li>
|
||||
<li><p>In non-verbose mode, uses an instance of
|
||||
<code class="xref py py-class docutils literal notranslate"><span class="pre">SimpleParser</span></code> and returns a list of
|
||||
objects corresponding to <a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><code class="xref py py-class docutils literal notranslate"><span class="pre">Device</span></code></a> instances.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">-Ahelp</span></code> will always return a list of strings.</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">-Ohelp</span></code> returns a list of objects for each parameter,
|
||||
with its name, description and default values.
|
||||
See <a class="reference internal" href="data.html#pylspci.fields.PCIAccessParameter" title="pylspci.fields.PCIAccessParameter"><code class="xref py py-class docutils literal notranslate"><span class="pre">PCIAccessParameter</span></code></a>.</p></li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">--raw</span></code></dt><dd><p>Return lspci’s output directly, without parsing; the CLI then just becomes a
|
||||
thin layer of argument parsing before lspci.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section id="pci-access">
|
||||
<h3>PCI access<a class="headerlink" href="#pci-access" title="Permalink to this heading">¶</a></h3>
|
||||
<dl>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-O,</span> <span class="pre">--option</span> <span class="pre"><key>=<value></span></code></dt><dd><p>Set PCI library access parameters.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">pcilib_params</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
<p>Use <code class="docutils literal notranslate"><span class="pre">-O</span> <span class="pre">help</span></code> to get a list of available parameters, via
|
||||
<a class="reference internal" href="command.html#pylspci.command.list_pcilib_params" title="pylspci.command.list_pcilib_params"><code class="xref py py-func docutils literal notranslate"><span class="pre">list_pcilib_params()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-A,</span> <span class="pre">--access-method</span> <span class="pre"><method></span></code></dt><dd><p>PCI library access method to use.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">access_method</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
<p>Use <code class="docutils literal notranslate"><span class="pre">-A</span> <span class="pre">help</span></code> to list available access methods, via
|
||||
<a class="reference internal" href="command.html#pylspci.command.list_access_methods" title="pylspci.command.list_access_methods"><code class="xref py py-func docutils literal notranslate"><span class="pre">list_access_methods()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-F,</span> <span class="pre">--file</span> <span class="pre"><path></span></code></dt><dd><p>Use a hex dump file from a previous run of lspci instead of accessing
|
||||
real hardware. Implies <code class="docutils literal notranslate"><span class="pre">-Adump</span></code>.</p>
|
||||
<p>Maps to <code class="docutils literal notranslate"><span class="pre">file</span></code> in <a class="reference internal" href="command.html#pylspci.command.lspci" title="pylspci.command.lspci"><code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code></a>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-H1</span></code></dt><dd><p>Access hardware using Intel configuration mechanism 1.
|
||||
Alias to <code class="docutils literal notranslate"><span class="pre">-A</span> <span class="pre">intel-conf1</span></code>.</p>
|
||||
</dd>
|
||||
<dt><code class="docutils literal notranslate"><span class="pre">-H2</span></code></dt><dd><p>Access hardware using Intel configuration mechanism 2.
|
||||
Alias to <code class="docutils literal notranslate"><span class="pre">-A</span> <span class="pre">intel-conf2</span></code>.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
|
|
||||
<a href="_sources/cli.rst.txt"
|
||||
rel="nofollow">Page source</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,200 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
||||
|
||||
<title>Contributing — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="prev" title="Low-level classes" href="low.html" />
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Contributing</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#bugs-and-suggestions">Bugs and suggestions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#development">Development</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#setup">Setup</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#unit-tests">Unit tests</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#tests-coverage">Tests coverage</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#linting">Linting</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#type-checking">Type checking</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#documentation">Documentation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
<li>Previous: <a href="low.html" title="previous chapter">Low-level classes</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="contributing">
|
||||
<h1>Contributing<a class="headerlink" href="#contributing" title="Permalink to this heading">¶</a></h1>
|
||||
<p>Contributions to the project are greatly appreciated.</p>
|
||||
<section id="bugs-and-suggestions">
|
||||
<h2>Bugs and suggestions<a class="headerlink" href="#bugs-and-suggestions" title="Permalink to this heading">¶</a></h2>
|
||||
<p>You may <a class="reference external" href="https://tildegit.org/lucidiot/pylspci/issues/new">submit an issue</a> to the Gitea repository to warn of any bugs, ask for
|
||||
new features, or ask any questions that are not answered in this documentation.</p>
|
||||
<p>When reporting a bug, do not forget to put in your version of Python and your
|
||||
version of <em>pylspci</em>. This will greatly help when troubleshooting, as most
|
||||
errors often come from version incompatibilities.</p>
|
||||
</section>
|
||||
<section id="development">
|
||||
<h2>Development<a class="headerlink" href="#development" title="Permalink to this heading">¶</a></h2>
|
||||
<section id="setup">
|
||||
<h3>Setup<a class="headerlink" href="#setup" title="Permalink to this heading">¶</a></h3>
|
||||
<p>You will need a virtual envionment to work properly. <a class="reference external" href="https://virtualenvwrapper.readthedocs.io">virtualenvwrapper</a> is
|
||||
recommended:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">clone</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">tildegit</span><span class="o">.</span><span class="n">org</span><span class="o">/</span><span class="n">lucidiot</span><span class="o">/</span><span class="n">pylspci</span><span class="o">.</span><span class="n">git</span>
|
||||
<span class="n">cd</span> <span class="n">pylspci</span>
|
||||
<span class="n">mkvirtualenv</span> <span class="o">-</span><span class="n">a</span> <span class="o">.</span> <span class="n">pylspci</span>
|
||||
<span class="n">pip</span> <span class="n">install</span> <span class="o">-</span><span class="n">e</span> <span class="o">.</span><span class="p">[</span><span class="n">dev</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This will clone the repository, create a virtual environment named
|
||||
<code class="docutils literal notranslate"><span class="pre">pylspci</span></code>, then tell pip to let the package be editable (<code class="docutils literal notranslate"><span class="pre">-e</span></code>).
|
||||
The <code class="docutils literal notranslate"><span class="pre">[dev]</span></code> suffix adds the extra requirements useful for development.</p>
|
||||
</section>
|
||||
<section id="unit-tests">
|
||||
<h3>Unit tests<a class="headerlink" href="#unit-tests" title="Permalink to this heading">¶</a></h3>
|
||||
<p>Unit tests use the standard <code class="docutils literal notranslate"><span class="pre">unittest</span></code> package; you may run them using the
|
||||
standard <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> command:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">./</span><span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">test</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="tests-coverage">
|
||||
<h3>Tests coverage<a class="headerlink" href="#tests-coverage" title="Permalink to this heading">¶</a></h3>
|
||||
<p>I aim for 100% coverage on all of my Python packages whenever I add unit
|
||||
tests to them; this package is no exception. CI checks use the <a class="reference external" href="https://coverage.readthedocs.io/">coverage</a>
|
||||
Python package to get coverage statistics.
|
||||
To get test coverage data locally, run:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">coverage</span> <span class="n">run</span> <span class="n">setup</span><span class="o">.</span><span class="n">py</span> <span class="n">test</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You may then get a short coverage summary in your terminal:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">coverage</span> <span class="n">report</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Or generate an HTML report in a <code class="docutils literal notranslate"><span class="pre">htmlcov</span></code> folder, which can be browsed
|
||||
offline using your favorite web browser and shows line by line coverage:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">coverage</span> <span class="n">html</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If you are having issues reaching 100% coverage, try to still add some tests,
|
||||
and mention your issues when creating a pull request to the
|
||||
<a class="reference external" href="https://tildegit.org/lucidiot/pylspci">Gitea repository</a>.</p>
|
||||
</section>
|
||||
<section id="linting">
|
||||
<h3>Linting<a class="headerlink" href="#linting" title="Permalink to this heading">¶</a></h3>
|
||||
<p>The source code follows the PEP 8 code style and performs CI checks using the
|
||||
<code class="docutils literal notranslate"><span class="pre">flake8</span></code> tool. To perform the same checks locally, run <code class="docutils literal notranslate"><span class="pre">flake8</span></code> on the root
|
||||
directory of this repository.</p>
|
||||
</section>
|
||||
<section id="type-checking">
|
||||
<h3>Type checking<a class="headerlink" href="#type-checking" title="Permalink to this heading">¶</a></h3>
|
||||
<p>The source code uses PEP 484 type hints and type checking is performed in CI
|
||||
using <code class="docutils literal notranslate"><span class="pre">mypy</span></code>. To run those checks locally, run <code class="docutils literal notranslate"><span class="pre">mypy</span> <span class="pre">.</span></code> on the root
|
||||
directory of this repository.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="documentation">
|
||||
<h2>Documentation<a class="headerlink" href="#documentation" title="Permalink to this heading">¶</a></h2>
|
||||
<p>The documentation you are reading is generated by the <a class="reference external" href="http://www.sphinx-doc.org/">Sphinx</a> tool.
|
||||
The text files that hold the documentation’s contents are written in
|
||||
<a class="reference external" href="http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html">reStructuredText</a> and are available under the <code class="docutils literal notranslate"><span class="pre">/docs</span></code> folder of the
|
||||
<a class="reference external" href="https://tildegit.org/lucidiot/pylspci">Gitea repository</a>.
|
||||
They are also subject to linting using the <code class="docutils literal notranslate"><span class="pre">doc8</span></code> tool.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
|
|
||||
<a href="_sources/contributing.rst.txt"
|
||||
rel="nofollow">Page source</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
186
docs/conf.py
186
docs/conf.py
|
@ -1,186 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file does only contain a selection of the most common options. For a
|
||||
# full list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'pylspci'
|
||||
copyright = '2022, Lucidiot and contributors'
|
||||
author = 'Lucidiot and contributors'
|
||||
|
||||
# The short X.Y version
|
||||
version = ''
|
||||
# The full version, including alpha/beta/rc tags
|
||||
release = open('../VERSION').read().strip()
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.viewcode',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = 'en'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'default'
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
html_theme_options = {
|
||||
'description': 'Python lspci parser',
|
||||
'fixed_sidebar': 'true',
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# The default sidebars (for documents that don't match any pattern) are
|
||||
# defined by theme itself. Builtin themes are using these templates by
|
||||
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
||||
# 'searchbox.html']``.
|
||||
#
|
||||
# html_sidebars = {}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ---------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'pylspcidoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
|
||||
# latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
#
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
#
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
#
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
# }
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'pylspci.tex', 'pylspci Documentation',
|
||||
'Lucidiot and contributors', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'pylspci', 'pylspci Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output ----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'pylspci', 'pylspci Documentation',
|
||||
author, 'pylspci', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Epub output -------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = project
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#
|
||||
# epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#
|
||||
# epub_uid = ''
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
|
||||
|
||||
# -- Extension configuration -------------------------------------------------
|
||||
|
||||
# Concatenate the class' and __init__'s docstrings when documenting a class
|
||||
autoclass_content = 'both'
|
|
@ -0,0 +1,523 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Index — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="#" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
|
||||
<h1 id="index">Index</h1>
|
||||
|
||||
<div class="genindex-jumpbox">
|
||||
<a href="#_"><strong>_</strong></a>
|
||||
| <a href="#A"><strong>A</strong></a>
|
||||
| <a href="#B"><strong>B</strong></a>
|
||||
| <a href="#C"><strong>C</strong></a>
|
||||
| <a href="#D"><strong>D</strong></a>
|
||||
| <a href="#F"><strong>F</strong></a>
|
||||
| <a href="#H"><strong>H</strong></a>
|
||||
| <a href="#I"><strong>I</strong></a>
|
||||
| <a href="#K"><strong>K</strong></a>
|
||||
| <a href="#L"><strong>L</strong></a>
|
||||
| <a href="#M"><strong>M</strong></a>
|
||||
| <a href="#N"><strong>N</strong></a>
|
||||
| <a href="#P"><strong>P</strong></a>
|
||||
| <a href="#R"><strong>R</strong></a>
|
||||
| <a href="#S"><strong>S</strong></a>
|
||||
| <a href="#U"><strong>U</strong></a>
|
||||
| <a href="#V"><strong>V</strong></a>
|
||||
| <a href="#W"><strong>W</strong></a>
|
||||
|
||||
</div>
|
||||
<h2 id="_">_</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.__iter__">__iter__() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="A">A</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.device.Device.as_dict">as_dict() (pylspci.device.Device method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="data.html#pylspci.fields.NameWithID.as_dict">(pylspci.fields.NameWithID method)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.PCIAccessParameter.as_dict">(pylspci.fields.PCIAccessParameter method)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.Slot.as_dict">(pylspci.fields.Slot method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="B">B</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.IDResolveOption.Both">Both (pylspci.command.IDResolveOption attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.fields.Slot.bus">bus (pylspci.fields.Slot attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.filters.SlotFilter.bus">(pylspci.filters.SlotFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="C">C</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.device.Device.cls">cls (pylspci.device.Device attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.filters.DeviceFilter.cls">(pylspci.filters.DeviceFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder">CommandBuilder (class in pylspci.command)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="D">D</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.fields.PCIAccessParameter.default">default (pylspci.fields.PCIAccessParameter attribute)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.base.Parser.default_lspci_args">default_lspci_args (pylspci.parsers.base.Parser attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.VerboseParser.default_lspci_args">(pylspci.parsers.verbose.VerboseParser attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="data.html#pylspci.fields.PCIAccessParameter.description">description (pylspci.fields.PCIAccessParameter attribute)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device">Device (class in pylspci.device)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.device">device (pylspci.device.Device attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="data.html#pylspci.fields.Slot.device">(pylspci.fields.Slot attribute)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.filters.DeviceFilter.device">(pylspci.filters.DeviceFilter attribute)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.filters.SlotFilter.device">(pylspci.filters.SlotFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.device_filter">device_filter() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.filters.DeviceFilter">DeviceFilter (class in pylspci.filters)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.Slot.domain">domain (pylspci.fields.Slot attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.filters.SlotFilter.domain">(pylspci.filters.SlotFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="data.html#pylspci.device.Device.driver">driver (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="F">F</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.FieldMapping.field_name">field_name (pylspci.parsers.verbose.FieldMapping attribute)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.FieldMapping.field_type">field_type (pylspci.parsers.verbose.FieldMapping attribute)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.FieldMapping">FieldMapping (class in pylspci.parsers.verbose)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.filters.Filter">Filter (class in pylspci.filters)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.from_file">from_file() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.Slot.function">function (pylspci.fields.Slot attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.filters.SlotFilter.function">(pylspci.filters.SlotFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="H">H</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.hide_single_domain">hide_single_domain() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="I">I</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.fields.NameWithID.id">id (pylspci.fields.NameWithID attribute)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.IDResolveOption.IDOnly">IDOnly (pylspci.command.IDResolveOption attribute)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.IDResolveOption">IDResolveOption (class in pylspci.command)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.include_bridge_paths">include_bridge_paths() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.include_kernel_drivers">include_kernel_drivers() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.iommu_group">iommu_group (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="K">K</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.device.Device.kernel_modules">kernel_modules (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="L">L</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.list_access_methods">list_access_methods() (in module pylspci.command)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.list_access_methods">(pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="command.html#pylspci.command.list_pcilib_params">list_pcilib_params() (in module pylspci.command)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.list_pcilib_params">(pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.list_pcilib_params_raw">list_pcilib_params_raw() (in module pylspci.command)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.lspci">lspci() (in module pylspci.command)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="M">M</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.FieldMapping.many">many (pylspci.parsers.verbose.FieldMapping attribute)</a>
|
||||
</li>
|
||||
<li>
|
||||
module
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#module-pylspci.command">pylspci.command</a>
|
||||
</li>
|
||||
<li><a href="data.html#module-pylspci.device">pylspci.device</a>
|
||||
</li>
|
||||
<li><a href="data.html#module-pylspci.fields">pylspci.fields</a>
|
||||
</li>
|
||||
<li><a href="command.html#module-pylspci.filters">pylspci.filters</a>
|
||||
</li>
|
||||
<li><a href="low.html#module-pylspci.parsers.base">pylspci.parsers.base</a>
|
||||
</li>
|
||||
<li><a href="low.html#module-pylspci.parsers.simple">pylspci.parsers.simple</a>
|
||||
</li>
|
||||
<li><a href="low.html#module-pylspci.parsers.verbose">pylspci.parsers.verbose</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="N">N</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.fields.NameWithID.name">name (pylspci.fields.NameWithID attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="data.html#pylspci.fields.PCIAccessParameter.name">(pylspci.fields.PCIAccessParameter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.IDResolveOption.NameOnly">NameOnly (pylspci.command.IDResolveOption attribute)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.NameWithID">NameWithID (class in pylspci.fields)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.numa_node">numa_node (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="P">P</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.fields.Slot.parent">parent (pylspci.fields.Slot attribute)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.filters.Filter.parse">parse() (pylspci.filters.Filter class method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#pylspci.parsers.base.Parser.parse">(pylspci.parsers.base.Parser method)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.simple.SimpleParser.parse">(pylspci.parsers.simple.SimpleParser method)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.VerboseParser.parse">(pylspci.parsers.verbose.VerboseParser method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="low.html#pylspci.parsers.simple.SimpleParser.parse_line">parse_line() (pylspci.parsers.simple.SimpleParser method)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.base.Parser">Parser (class in pylspci.parsers.base)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.PCIAccessParameter">PCIAccessParameter (class in pylspci.fields)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.physical_slot">physical_slot (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.progif">progif (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
<li>
|
||||
pylspci.command
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#module-pylspci.command">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
pylspci.device
|
||||
|
||||
<ul>
|
||||
<li><a href="data.html#module-pylspci.device">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
pylspci.fields
|
||||
|
||||
<ul>
|
||||
<li><a href="data.html#module-pylspci.fields">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
pylspci.filters
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#module-pylspci.filters">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
pylspci.parsers.base
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#module-pylspci.parsers.base">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
pylspci.parsers.simple
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#module-pylspci.parsers.simple">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
pylspci.parsers.verbose
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#module-pylspci.parsers.verbose">module</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="R">R</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.device.Device.revision">revision (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="low.html#pylspci.parsers.base.Parser.run">run() (pylspci.parsers.base.Parser method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="low.html#pylspci.parsers.simple.SimpleParser.run">(pylspci.parsers.simple.SimpleParser method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="S">S</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="low.html#pylspci.parsers.simple.SimpleParser">SimpleParser (class in pylspci.parsers.simple)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.fields.Slot">Slot (class in pylspci.fields)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.slot">slot (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.slot_filter">slot_filter() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.filters.SlotFilter">SlotFilter (class in pylspci.filters)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.subsystem_device">subsystem_device (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
<li><a href="data.html#pylspci.device.Device.subsystem_vendor">subsystem_vendor (pylspci.device.Device attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="U">U</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.use_access_method">use_access_method() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.use_pciids">use_pciids() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.use_pcimap">use_pcimap() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="V">V</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="data.html#pylspci.device.Device.vendor">vendor (pylspci.device.Device attribute)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="command.html#pylspci.filters.DeviceFilter.vendor">(pylspci.filters.DeviceFilter attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.verbose">verbose() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="low.html#pylspci.parsers.verbose.VerboseParser">VerboseParser (class in pylspci.parsers.verbose)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="W">W</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.with_default_parser">with_default_parser() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.with_ids">with_ids() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.with_names">with_names() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.with_parser">with_parser() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
<li><a href="command.html#pylspci.command.CommandBuilder.with_pcilib_params">with_pcilib_params() (pylspci.command.CommandBuilder method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,206 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
||||
|
||||
<title>Python lspci parser — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="Command-line interface" href="cli.html" />
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="#">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="#">Documentation overview</a><ul>
|
||||
<li>Next: <a href="cli.html" title="next chapter">Command-line interface</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="python-lspci-parser">
|
||||
<h1>Python lspci parser<a class="headerlink" href="#python-lspci-parser" title="Permalink to this heading">¶</a></h1>
|
||||
<p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a> - <a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a> - <a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p>
|
||||
<a class="reference external image-reference" href="https://pypi.org/project/pylspci"><img alt="https://img.shields.io/pypi/v/pylspci.svg" src="https://img.shields.io/pypi/v/pylspci.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://pypi.org/project/pylspci"><img alt="https://img.shields.io/pypi/l/pylspci.svg" src="https://img.shields.io/pypi/l/pylspci.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://pypi.org/project/pylspci"><img alt="https://img.shields.io/pypi/format/pylspci.svg" src="https://img.shields.io/pypi/format/pylspci.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://pypi.org/project/pylspci"><img alt="https://img.shields.io/pypi/pyversions/pylspci.svg" src="https://img.shields.io/pypi/pyversions/pylspci.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://pypi.org/project/pylspci"><img alt="https://img.shields.io/pypi/status/pylspci.svg" src="https://img.shields.io/pypi/status/pylspci.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://drone.tildegit.org/api/badges/lucidiot/pylspci/status.svg"><img alt="https://drone.tildegit.org/api/badges/lucidiot/pylspci/status.svg" src="https://drone.tildegit.org/api/badges/lucidiot/pylspci/status.svg" /></a>
|
||||
<a class="reference external image-reference" href="https://tildegit.org/lucidiot/pylspci"><img alt="https://img.shields.io/badge/badge%20count-7-brightgreen.svg" src="https://img.shields.io/badge/badge%20count-7-brightgreen.svg" /></a>
|
||||
<p>A Python parser for the <code class="docutils literal notranslate"><span class="pre">lspci</span></code> command from the <a class="reference external" href="http://mj.ucw.cz/sw/pciutils/">pciutils</a> package.</p>
|
||||
<section id="command-line-interface">
|
||||
<h2>Command-line interface<a class="headerlink" href="#command-line-interface" title="Permalink to this heading">¶</a></h2>
|
||||
<p>An executable script named <code class="docutils literal notranslate"><span class="pre">pylspci</span></code> is available, and acts as a wrapper
|
||||
around <code class="docutils literal notranslate"><span class="pre">lspci</span></code> that can produce JSON output.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ pylspci -nn
|
||||
[{
|
||||
"slot": {"domain": 0, "bus": 0, "device": 1, "function": 3},
|
||||
"device": {"id": 9248, "name": "Name A"},
|
||||
...
|
||||
}]
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>See <code class="docutils literal notranslate"><span class="pre">pylspci</span> <span class="pre">--help</span></code> and the <a class="reference external" href="cli">CLI docs</a> to learn more.</p>
|
||||
</section>
|
||||
<section id="parsing-in-python">
|
||||
<h2>Parsing in Python<a class="headerlink" href="#parsing-in-python" title="Permalink to this heading">¶</a></h2>
|
||||
<p>To parse <code class="docutils literal notranslate"><span class="pre">lspci</span> <span class="pre">-nnmm</span></code>, use the
|
||||
<a class="reference internal" href="low.html#pylspci.parsers.simple.SimpleParser" title="pylspci.parsers.simple.SimpleParser"><code class="xref py py-class docutils literal notranslate"><span class="pre">SimpleParser</span></code></a>.
|
||||
To parse <code class="docutils literal notranslate"><span class="pre">lspci</span> <span class="pre">-nnmmvvvk</span></code>, use the
|
||||
<a class="reference internal" href="low.html#pylspci.parsers.verbose.VerboseParser" title="pylspci.parsers.verbose.VerboseParser"><code class="xref py py-class docutils literal notranslate"><span class="pre">VerboseParser</span></code></a>.</p>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">pylspci.parsers</span> <span class="kn">import</span> <span class="n">SimpleParser</span>
|
||||
<span class="gp">>>> </span><span class="n">SimpleParser</span><span class="p">()</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
|
||||
<span class="go">[Device(slot=Slot('0000:00:01.3'), name=NameWithID('Name A [2420]'), ...),</span>
|
||||
<span class="go"> Device(slot=Slot('0000:00:01.4'), name=NameWithID('Name B [0e54]'), ...)]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<section id="custom-arguments">
|
||||
<h3>Custom arguments<a class="headerlink" href="#custom-arguments" title="Permalink to this heading">¶</a></h3>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">pylspci.command</span> <span class="kn">import</span> <span class="n">IDResolveOption</span>
|
||||
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">pylspci.parsers</span> <span class="kn">import</span> <span class="n">VerboseParser</span>
|
||||
<span class="gp">>>> </span><span class="n">VerboseParser</span><span class="p">()</span><span class="o">.</span><span class="n">run</span><span class="p">(</span>
|
||||
<span class="gp">... </span> <span class="n">hide_single_domain</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
||||
<span class="gp">... </span> <span class="n">id_resolve_option</span><span class="o">=</span><span class="n">IDResolveOption</span><span class="o">.</span><span class="n">NameOnly</span><span class="p">,</span>
|
||||
<span class="gp">... </span><span class="p">)</span>
|
||||
<span class="go">[Device(slot=Slot('0000:00:01.3'), name=NameWithID('Name A'), ...),</span>
|
||||
<span class="go"> Device(slot=Slot('0000:00:01.4'), name=NameWithID('Name B'), ...)]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="learn-more">
|
||||
<h2>Learn more<a class="headerlink" href="#learn-more" title="Permalink to this heading">¶</a></h2>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="cli.html#options">Options</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#filters">Filters</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#device-data">Device data</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#output-modes">Output modes</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#pci-access">PCI access</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="data.html#module-pylspci.device">The Device</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="data.html#module-pylspci.fields">Device fields</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#command-builder">Command builder</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#module-pylspci.filters">Device selection</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="low.html#module-pylspci.parsers.base">Parsers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="low.html#module-pylspci.parsers.verbose">Implementation details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="contributing.html#bugs-and-suggestions">Bugs and suggestions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="contributing.html#development">Development</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="contributing.html#setup">Setup</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="contributing.html#unit-tests">Unit tests</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="contributing.html#tests-coverage">Tests coverage</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="contributing.html#linting">Linting</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="contributing.html#type-checking">Type checking</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="contributing.html#documentation">Documentation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
|
|
||||
<a href="_sources/index.rst.txt"
|
||||
rel="nofollow">Page source</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,305 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
|
||||
|
||||
<title>Low-level classes — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="Contributing" href="contributing.html" />
|
||||
<link rel="prev" title="Command API" href="command.html" />
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Low-level classes</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#module-pylspci.parsers.base">Parsers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#module-pylspci.parsers.verbose">Implementation details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
<li>Previous: <a href="command.html" title="previous chapter">Command API</a></li>
|
||||
<li>Next: <a href="contributing.html" title="next chapter">Contributing</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="low-level-classes">
|
||||
<h1>Low-level classes<a class="headerlink" href="#low-level-classes" title="Permalink to this heading">¶</a></h1>
|
||||
<section id="module-pylspci.parsers.base">
|
||||
<span id="parsers"></span><h2>Parsers<a class="headerlink" href="#module-pylspci.parsers.base" title="Permalink to this heading">¶</a></h2>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.base.Parser">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pylspci.parsers.base.</span></span><span class="sig-name descname"><span class="pre">Parser</span></span><a class="reference internal" href="_modules/pylspci/parsers/base.html#Parser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.base.Parser" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.base.Parser.default_lspci_args">
|
||||
<span class="sig-name descname"><span class="pre">default_lspci_args</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{}</span></em><a class="headerlink" href="#pylspci.parsers.base.Parser.default_lspci_args" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>The default arguments that, when sent to <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>, should provide the
|
||||
best output for this parser.</p>
|
||||
<p>See <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>’s documentation for a list of available arguments.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.base.Parser.parse">
|
||||
<em class="property"><span class="pre">abstract</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">parse</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/pylspci/parsers/base.html#Parser.parse"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.base.Parser.parse" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Parse a string or list of strings as a list of devices.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>data</strong> (<em>str</em><em> or </em><em>Iterable</em><em>[</em><em>str</em><em>] or </em><em>Iterable</em><em>[</em><em>Iterable</em><em>[</em><em>str</em><em>]</em><em>]</em>) – A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A list of parsed devices.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p>List[<a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a>]</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.base.Parser.run">
|
||||
<span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Any</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/pylspci/parsers/base.html#Parser.run"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.base.Parser.run" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Run the lspci command with the given arguments, defaulting to the
|
||||
parser’s default arguments, and parse the result.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>**kwargs</strong> (<em>Any</em>) – Optional arguments to override the parser’s default
|
||||
arguments. See <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>’s documentation for a list of
|
||||
available arguments.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A list of parsed devices.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p>List[<a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a>]</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<span class="target" id="module-pylspci.parsers.simple"></span><dl class="py class">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.simple.SimpleParser">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pylspci.parsers.simple.</span></span><span class="sig-name descname"><span class="pre">SimpleParser</span></span><a class="reference internal" href="_modules/pylspci/parsers/simple.html#SimpleParser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.simple.SimpleParser" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A parser for lspci -mm.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.simple.SimpleParser.parse">
|
||||
<span class="sig-name descname"><span class="pre">parse</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/pylspci/parsers/simple.html#SimpleParser.parse"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.simple.SimpleParser.parse" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Parse a multiline string or a list of single-line strings
|
||||
from lspci -mm into devices.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>data</strong> (<em>str</em><em> or </em><em>Iterable</em><em>[</em><em>str</em><em>] or </em><em>Iterable</em><em>[</em><em>Iterable</em><em>[</em><em>str</em><em>]</em><em>]</em>) – A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A list of parsed devices.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p>List[<a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a>]</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.simple.SimpleParser.parse_line">
|
||||
<span class="sig-name descname"><span class="pre">parse_line</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">args</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a></span></span><a class="reference internal" href="_modules/pylspci/parsers/simple.html#SimpleParser.parse_line"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.simple.SimpleParser.parse_line" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Parse a single line from lspci -mm into a single device, either
|
||||
as the line or as a list of fields.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>args</strong> (<em>str</em><em> or </em><em>Iterable</em><em>[</em><em>str</em><em>]</em>) – Line or list of fields to parse from.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A single parsed device.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a></p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.simple.SimpleParser.run">
|
||||
<span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="o"><span class="pre">**</span></span><span class="n"><span class="pre">kwargs</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Any</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/pylspci/parsers/simple.html#SimpleParser.run"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.simple.SimpleParser.run" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Run the lspci command with the given arguments, defaulting to the
|
||||
parser’s default arguments, and parse the result.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>**kwargs</strong> (<em>Any</em>) – Optional arguments to override the parser’s default
|
||||
arguments. See <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>’s documentation for a list of
|
||||
available arguments.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A list of parsed devices.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p>List[<a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a>]</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.VerboseParser">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pylspci.parsers.verbose.</span></span><span class="sig-name descname"><span class="pre">VerboseParser</span></span><a class="reference internal" href="_modules/pylspci/parsers/verbose.html#VerboseParser"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.verbose.VerboseParser" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A parser for lspci -vvvmmk</p>
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.VerboseParser.default_lspci_args">
|
||||
<span class="sig-name descname"><span class="pre">default_lspci_args</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></em><em class="property"><span class="w"> </span><span class="p"><span class="pre">=</span></span><span class="w"> </span><span class="pre">{'kernel_drivers':</span> <span class="pre">True,</span> <span class="pre">'verbose':</span> <span class="pre">True}</span></em><a class="headerlink" href="#pylspci.parsers.verbose.VerboseParser.default_lspci_args" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>The default arguments that, when sent to <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>, should provide the
|
||||
best output for this parser.</p>
|
||||
<p>See <code class="xref py py-func docutils literal notranslate"><span class="pre">lspci()</span></code>’s documentation for a list of available arguments.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.VerboseParser.parse">
|
||||
<span class="sig-name descname"><span class="pre">parse</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">Iterable</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device"><span class="pre">Device</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="_modules/pylspci/parsers/verbose.html#VerboseParser.parse"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.verbose.VerboseParser.parse" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Parse an lspci -vvvmm[nnk] output, either as a single string holding
|
||||
multiple devices separated by two newlines,
|
||||
or as a list of multiline strings holding one device each.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p><strong>data</strong> (<em>str</em><em> or </em><em>Iterable</em><em>[</em><em>str</em><em>] or </em><em>Iterable</em><em>[</em><em>Iterable</em><em>[</em><em>str</em><em>]</em><em>]</em>) – A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Returns<span class="colon">:</span></dt>
|
||||
<dd class="field-even"><p>A list of parsed devices.</p>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type<span class="colon">:</span></dt>
|
||||
<dd class="field-odd"><p>List[<a class="reference internal" href="data.html#pylspci.device.Device" title="pylspci.device.Device">Device</a>]</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
<section id="module-pylspci.parsers.verbose">
|
||||
<span id="implementation-details"></span><h2>Implementation details<a class="headerlink" href="#module-pylspci.parsers.verbose" title="Permalink to this heading">¶</a></h2>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.FieldMapping">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">pylspci.parsers.verbose.</span></span><span class="sig-name descname"><span class="pre">FieldMapping</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">field_name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">field_type</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Callable</span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></span></em>, <em class="sig-param"><span class="n"><span class="pre">many</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/pylspci/parsers/verbose.html#FieldMapping"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#pylspci.parsers.verbose.FieldMapping" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Helper class to map verbose output field names such as <code class="docutils literal notranslate"><span class="pre">SVendor</span></code> to
|
||||
<code class="xref py py-class docutils literal notranslate"><span class="pre">Device</span></code> fields such as <code class="docutils literal notranslate"><span class="pre">subsytem_vendor</span></code>.</p>
|
||||
<p>Create new instance of FieldMapping(field_name, field_type, many)</p>
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.FieldMapping.field_name">
|
||||
<span class="sig-name descname"><span class="pre">field_name</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">str</span></em><a class="headerlink" href="#pylspci.parsers.verbose.FieldMapping.field_name" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Field name on the <code class="xref py py-class docutils literal notranslate"><span class="pre">Device</span></code> named tuple.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.FieldMapping.field_type">
|
||||
<span class="sig-name descname"><span class="pre">field_type</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">Callable</span><span class="p"><span class="pre">[</span></span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">Any</span><span class="p"><span class="pre">]</span></span></em><a class="headerlink" href="#pylspci.parsers.verbose.FieldMapping.field_type" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Field type; a callable to use to parse the string value.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="pylspci.parsers.verbose.FieldMapping.many">
|
||||
<span class="sig-name descname"><span class="pre">many</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">bool</span></em><a class="headerlink" href="#pylspci.parsers.verbose.FieldMapping.many" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Whether or not to use a List, if this field can be repeated multiple times
|
||||
in the lspci output.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
|
|
||||
<a href="_sources/low.rst.txt"
|
||||
rel="nofollow">Page source</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
|
@ -0,0 +1,159 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Python Module Index — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>document.getElementById('searchbox').style.display = "block"</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
|
||||
<h1>Python Module Index</h1>
|
||||
|
||||
<div class="modindex-jumpbox">
|
||||
<a href="#cap-p"><strong>p</strong></a>
|
||||
</div>
|
||||
|
||||
<table class="indextable modindextable">
|
||||
<tr class="pcap"><td></td><td> </td><td></td></tr>
|
||||
<tr class="cap" id="cap-p"><td></td><td>
|
||||
<strong>p</strong></td><td></td></tr>
|
||||
<tr>
|
||||
<td><img src="_static/minus.png" class="toggler"
|
||||
id="toggle-1" style="display: none" alt="-" /></td>
|
||||
<td>
|
||||
<code class="xref">pylspci</code></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="command.html#module-pylspci.command"><code class="xref">pylspci.command</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="data.html#module-pylspci.device"><code class="xref">pylspci.device</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="data.html#module-pylspci.fields"><code class="xref">pylspci.fields</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="command.html#module-pylspci.filters"><code class="xref">pylspci.filters</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="low.html#module-pylspci.parsers.base"><code class="xref">pylspci.parsers.base</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="low.html#module-pylspci.parsers.simple"><code class="xref">pylspci.parsers.simple</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
<tr class="cg-1">
|
||||
<td></td>
|
||||
<td>   
|
||||
<a href="low.html#module-pylspci.parsers.verbose"><code class="xref">pylspci.parsers.verbose</code></a></td><td>
|
||||
<em></em></td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,3 +0,0 @@
|
|||
from pylspci.parsers.simple import SimpleParser
|
||||
|
||||
parser = SimpleParser()
|
|
@ -1,205 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from pylspci.command import CommandBuilder, IDResolveOption
|
||||
from pylspci.filters import DeviceFilter, SlotFilter
|
||||
|
||||
|
||||
def get_parser() -> argparse.ArgumentParser:
|
||||
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
||||
description='Python wrapper for lspci',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i', '--pci-ids',
|
||||
help='Path to an alternate file to use as the PCI ID list.',
|
||||
required=False,
|
||||
type=Path,
|
||||
dest='pciids',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-p', '--pci-map',
|
||||
help='Path to an alternate file to use as the '
|
||||
'kernel module mapping file.',
|
||||
required=False,
|
||||
type=Path,
|
||||
dest='pcimap',
|
||||
)
|
||||
|
||||
filter_options = parser.add_argument_group(title='Filters')
|
||||
filter_options.add_argument(
|
||||
'-s',
|
||||
help='Filter devices by their slots. '
|
||||
'Any value can be omitted or set to * to disable filtering.',
|
||||
type=SlotFilter.parse,
|
||||
dest='slot_filter',
|
||||
metavar='[[domain:]bus:][device][.function]',
|
||||
)
|
||||
filter_options.add_argument(
|
||||
'-d',
|
||||
help='Filter devices by their type. '
|
||||
'Any value can be omitted or set to * to disable filtering.',
|
||||
type=DeviceFilter.parse,
|
||||
dest='device_filter',
|
||||
metavar='[vendor]:[device][:class]',
|
||||
)
|
||||
|
||||
output_options = parser.add_argument_group(title='Output options')
|
||||
output_options.add_argument(
|
||||
'-v', '--verbose',
|
||||
help='Display more details about devices.',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='verbose',
|
||||
)
|
||||
output_options.add_argument(
|
||||
'-k', '--kernel-modules',
|
||||
help='On Linux kernels above 2.6, include kernel drivers handling '
|
||||
'each device and kernel modules able to handle them. Implies -v.',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='kernel_drivers',
|
||||
)
|
||||
output_options.add_argument(
|
||||
'-P', '-PP', '--bridge-paths',
|
||||
help='Include PCI bridge paths along with device IDs.',
|
||||
default=False,
|
||||
action='store_true',
|
||||
dest='bridge_paths',
|
||||
)
|
||||
|
||||
output_modes = output_options.add_mutually_exclusive_group()
|
||||
output_modes.add_argument(
|
||||
'--json',
|
||||
help='Parse the lspci output and return JSON data.',
|
||||
action='store_true',
|
||||
default=True,
|
||||
dest='json',
|
||||
)
|
||||
output_modes.add_argument(
|
||||
'--raw',
|
||||
help="Return lspci's output directly, without parsing.",
|
||||
action='store_false',
|
||||
default=True,
|
||||
dest='json',
|
||||
)
|
||||
|
||||
id_resolve_option = output_options.add_mutually_exclusive_group()
|
||||
id_resolve_option.add_argument(
|
||||
'--name-only',
|
||||
help='Only include device names. This is the default.',
|
||||
action='store_const',
|
||||
default=IDResolveOption.NameOnly,
|
||||
const=IDResolveOption.NameOnly,
|
||||
dest='id_resolve_option',
|
||||
)
|
||||
id_resolve_option.add_argument(
|
||||
'-n', '--id-only',
|
||||
help='Only include device IDs, without looking for names '
|
||||
'in the PCI ID file.',
|
||||
action='store_const',
|
||||
const=IDResolveOption.IDOnly,
|
||||
default=IDResolveOption.NameOnly,
|
||||
dest='id_resolve_option',
|
||||
)
|
||||
id_resolve_option.add_argument(
|
||||
'-nn', '--name-with-id',
|
||||
help='Include both device IDs and names.',
|
||||
action='store_const',
|
||||
const=IDResolveOption.Both,
|
||||
default=IDResolveOption.NameOnly,
|
||||
dest='id_resolve_option',
|
||||
)
|
||||
|
||||
access_options = parser.add_argument_group(title='PCI access options')
|
||||
access_options.add_argument(
|
||||
'-O', '--option',
|
||||
help='Set PCI library access parameters. '
|
||||
'Use -O help to get a list of available parameters '
|
||||
'with their descriptions and default values.',
|
||||
action='append',
|
||||
dest='pcilib_params',
|
||||
metavar='KEY=VALUE',
|
||||
)
|
||||
access_exclusive = access_options.add_mutually_exclusive_group()
|
||||
access_exclusive.add_argument(
|
||||
'-A', '--access-method',
|
||||
help='PCI library access method to use. '
|
||||
'Use -A help to list available access methods.',
|
||||
dest='access_method',
|
||||
metavar='METHOD',
|
||||
)
|
||||
access_exclusive.add_argument(
|
||||
'-F', '--file',
|
||||
help='Use a hex dump file from a previous run of lspci instead of '
|
||||
'accessing real hardware.',
|
||||
dest='file',
|
||||
metavar='FILE',
|
||||
)
|
||||
access_exclusive.add_argument(
|
||||
'-H1',
|
||||
help='Access hardware using Intel configuration mechanism 1. '
|
||||
'Alias to -A intel-conf1.',
|
||||
action='store_const',
|
||||
const='intel-conf1',
|
||||
dest='access_method',
|
||||
)
|
||||
access_exclusive.add_argument(
|
||||
'-H2',
|
||||
help='Access hardware using Intel configuration mechanism 2. '
|
||||
'Alias to -A intel-conf2.',
|
||||
action='store_const',
|
||||
const='intel-conf2',
|
||||
dest='access_method',
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser: argparse.ArgumentParser = get_parser()
|
||||
args: Dict[str, Any] = vars(parser.parse_args())
|
||||
|
||||
json_output: bool = args.pop('json', True)
|
||||
kernel_modules: bool = args.pop('kernel_modules', False)
|
||||
access_method: Optional[str] = args.pop('access_method', None)
|
||||
pcilib_params = args.pop('pcilib_params', []) or []
|
||||
|
||||
builder: CommandBuilder = CommandBuilder(**args)
|
||||
if kernel_modules:
|
||||
builder = builder.include_kernel_drivers()
|
||||
|
||||
if access_method:
|
||||
if access_method.strip().lower() == 'help':
|
||||
builder = builder.list_access_methods()
|
||||
else:
|
||||
builder = builder.use_access_method(access_method)
|
||||
|
||||
for param in pcilib_params:
|
||||
if param.strip().lower() == 'help':
|
||||
builder = builder.list_pcilib_params(raw=not json_output)
|
||||
break
|
||||
if '=' not in param:
|
||||
parser.error(
|
||||
'Invalid PCI access parameter syntax for {!r}'.format(param))
|
||||
key, value = map(str.strip, param.split('=', 2))
|
||||
builder = builder.with_pcilib_params(**{key: value})
|
||||
|
||||
if json_output:
|
||||
builder = builder.with_default_parser()
|
||||
|
||||
result = list(builder)
|
||||
if not json_output: # Raw mode
|
||||
for item in result:
|
||||
print(item)
|
||||
return
|
||||
|
||||
print(json.dumps([
|
||||
item if isinstance(item, str) else item.as_dict()
|
||||
for item in result
|
||||
]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,537 +0,0 @@
|
|||
import subprocess
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Any, Iterator, List, Mapping, MutableMapping, Optional, Union
|
||||
)
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.fields import PCIAccessParameter
|
||||
from pylspci.filters import DeviceFilter, SlotFilter
|
||||
from pylspci.parsers.base import Parser
|
||||
|
||||
OptionalPath = Optional[Union[str, Path]]
|
||||
|
||||
|
||||
class IDResolveOption(Enum):
|
||||
"""
|
||||
``lspci`` device, vendor, class names outputting options.
|
||||
"""
|
||||
|
||||
NameOnly = ''
|
||||
"""
|
||||
Only output the names.
|
||||
"""
|
||||
|
||||
IDOnly = '-n'
|
||||
"""
|
||||
Only output the hexadecimal IDs.
|
||||
This is the only option that does not require a ``pciids`` file.
|
||||
"""
|
||||
|
||||
Both = '-nn'
|
||||
"""
|
||||
Output both the names and hexadecimal IDs, in the format ``Name [ID]``.
|
||||
"""
|
||||
|
||||
|
||||
def lspci(
|
||||
pciids: OptionalPath = None,
|
||||
pcimap: OptionalPath = None,
|
||||
access_method: Optional[str] = None,
|
||||
pcilib_params: Mapping[str, Any] = {},
|
||||
file: OptionalPath = None,
|
||||
verbose: bool = False,
|
||||
kernel_drivers: bool = False,
|
||||
bridge_paths: bool = False,
|
||||
hide_single_domain: bool = True,
|
||||
id_resolve_option: IDResolveOption = IDResolveOption.Both,
|
||||
slot_filter: Optional[Union[SlotFilter, str]] = None,
|
||||
device_filter: Optional[Union[DeviceFilter, str]] = None,
|
||||
) -> str:
|
||||
"""
|
||||
Call the ``lspci`` command with various parameters.
|
||||
|
||||
:param pciids: An optional path to a ``pciids`` file,
|
||||
to convert hexadecimal class, vendor or device IDs into names.
|
||||
:type pciids: str or Path or None
|
||||
:param pcimap: An optional path to a ``pcimap`` file,
|
||||
linking Linux kernel modules and their supported PCI IDs.
|
||||
:type pcimap: str or Path or None
|
||||
:param access_method: The access method to use to find devices.
|
||||
Set this to ``help`` to list the available access methods in a
|
||||
human-readable format. For the machine-readable format, see
|
||||
:func:`list_access_methods`.
|
||||
:type access_method: str or None
|
||||
:param pcilib_params: Parameters passed to pcilib's access methods.
|
||||
To list the available parameters with their description and default
|
||||
values, see :func:`list_pcilib_params`.
|
||||
:type pcilib_params: Mapping[str, Any] or None
|
||||
:param file: An hexadecimal dump from ``lspci -x`` to load data from,
|
||||
instead of accessing real hardware.
|
||||
:type file: str or Path or None
|
||||
:param bool verbose: Increase verbosity.
|
||||
This radically changes the output format.
|
||||
:param bool kernel_drivers: Also include kernel modules and drivers
|
||||
in the output. Only has effect with the verbose output.
|
||||
:param bool bridge_paths: Add PCI bridge paths to slot numbers.
|
||||
:param bool hide_single_domain: If there is a single PCI domain on this
|
||||
machine and it is numbered ``0000``, hide it from the slot numbers.
|
||||
:param id_resolve_option: Device, vendor or class ID outputting mode.
|
||||
See the :class:`IDResolveOption` docs for more details.
|
||||
:type id_resolve_option: IDResolveOption
|
||||
:param slot_filter: Filter devices by their slot
|
||||
(domain, bus, device, function)
|
||||
:type slot_filter: SlotFilter or str or None
|
||||
:param device_filter: Filter devices by their vendor, device or class ID
|
||||
:type device_filter: DeviceFilter or str or None
|
||||
:return: Any output from the ``lspci`` command.
|
||||
:rtype: str
|
||||
:raises subprocess.CalledProcessError:
|
||||
``lspci`` returned a non-zero error code.
|
||||
"""
|
||||
args: List[str] = ['lspci', '-mm']
|
||||
if verbose:
|
||||
args.append('-vvv')
|
||||
if kernel_drivers:
|
||||
args.append('-k')
|
||||
if bridge_paths:
|
||||
args.append('-PP')
|
||||
if not hide_single_domain:
|
||||
args.append('-D')
|
||||
if access_method:
|
||||
args.append('-A{}'.format(access_method))
|
||||
if slot_filter:
|
||||
if isinstance(slot_filter, str):
|
||||
slot_filter = SlotFilter.parse(slot_filter)
|
||||
args.append('-s')
|
||||
args.append(str(slot_filter))
|
||||
if device_filter:
|
||||
if isinstance(device_filter, str):
|
||||
device_filter = DeviceFilter.parse(device_filter)
|
||||
args.append('-d')
|
||||
args.append(str(device_filter))
|
||||
if id_resolve_option != IDResolveOption.NameOnly:
|
||||
args.append(id_resolve_option.value)
|
||||
|
||||
if pciids:
|
||||
args.append('-i')
|
||||
if not isinstance(pciids, Path):
|
||||
pciids = Path(pciids)
|
||||
assert pciids.is_file(), 'ID database file not found'
|
||||
args.append(str(pciids.absolute()))
|
||||
|
||||
if pcimap:
|
||||
args.append('-p')
|
||||
if not isinstance(pcimap, Path):
|
||||
pcimap = Path(pcimap)
|
||||
assert pcimap.is_file(), 'Kernel module mapping file not found'
|
||||
args.append(str(pcimap.absolute()))
|
||||
|
||||
if file:
|
||||
args.append('-F')
|
||||
if not isinstance(file, Path):
|
||||
file = Path(file)
|
||||
assert file.is_file(), 'Hex dump file not found'
|
||||
args.append(str(file.absolute()))
|
||||
|
||||
for key, value in pcilib_params.items():
|
||||
args.append('-O{}={}'.format(key, value))
|
||||
|
||||
return subprocess.check_output(
|
||||
args,
|
||||
universal_newlines=True,
|
||||
)
|
||||
|
||||
|
||||
def list_access_methods() -> List[str]:
|
||||
"""
|
||||
Calls ``lspci(access_method='help')`` to list the PCI access methods
|
||||
the underlying ``pcilib`` provides and parses the human-readable list into
|
||||
a machine-readable list.
|
||||
|
||||
:returns: A list of access methods.
|
||||
:rtype: List[str]
|
||||
:raises subprocess.CalledProcessError:
|
||||
``lspci`` returned a non-zero error code.
|
||||
"""
|
||||
return list(filter(
|
||||
lambda line: line and 'Known PCI access methods' not in line,
|
||||
map(str.strip, lspci(access_method='help').splitlines()),
|
||||
))
|
||||
|
||||
|
||||
def list_pcilib_params_raw() -> List[str]:
|
||||
"""
|
||||
Calls ``lspci -Ohelp`` to list the PCI access parameters the underlying
|
||||
``pcilib`` provides.
|
||||
|
||||
:returns: A list of available PCI access parameters.
|
||||
:rtype: List[str]
|
||||
:raises subprocess.CalledProcessError:
|
||||
``lspci`` returned a non-zero error code.
|
||||
"""
|
||||
return list(filter(
|
||||
lambda line: line and 'Known PCI access parameters' not in line,
|
||||
map(str.strip, subprocess.check_output(
|
||||
['lspci', '-Ohelp'],
|
||||
universal_newlines=True,
|
||||
).splitlines())
|
||||
))
|
||||
|
||||
|
||||
def list_pcilib_params() -> List[PCIAccessParameter]:
|
||||
"""
|
||||
Calls ``lspci -Ohelp`` to list the PCI access parameters the underlying
|
||||
``pcilib`` provides and parse the human-readable list into
|
||||
a machine-readable list.
|
||||
|
||||
:returns: A list of available PCI access parameters.
|
||||
:rtype: List[PCIAccessParameter]
|
||||
:raises subprocess.CalledProcessError:
|
||||
``lspci`` returned a non-zero error code.
|
||||
"""
|
||||
return list(map(PCIAccessParameter, list_pcilib_params_raw()))
|
||||
|
||||
|
||||
class CommandBuilder(object):
|
||||
"""
|
||||
Helper class to build a lspci call using a Builder pattern.
|
||||
|
||||
Iterating over the builder will result in the command being called,
|
||||
and will return strings, devices or pcilib parameters, one at a time,
|
||||
depending on the parsing settings.
|
||||
"""
|
||||
|
||||
_list_access_methods: bool = False
|
||||
_list_pcilib_params: bool = False
|
||||
_list_pcilib_params_raw: bool = False
|
||||
_params: MutableMapping[str, Any] = {}
|
||||
_parser: Optional[Parser] = None
|
||||
|
||||
def __init__(self, **kwargs: Any):
|
||||
self._params = kwargs
|
||||
|
||||
def __iter__(self) -> Iterator[Union[str, Device, PCIAccessParameter]]:
|
||||
result: Union[str, List[str], List[Device], List[PCIAccessParameter]]
|
||||
if self._list_access_methods:
|
||||
result = list_access_methods()
|
||||
elif self._list_pcilib_params:
|
||||
if self._list_pcilib_params_raw:
|
||||
result = list_pcilib_params_raw()
|
||||
else:
|
||||
result = list_pcilib_params()
|
||||
elif self._parser:
|
||||
result = self._parser.parse(lspci(**self._params))
|
||||
else:
|
||||
result = lspci(**self._params)
|
||||
|
||||
if isinstance(result, str):
|
||||
return iter([result, ])
|
||||
return iter(result)
|
||||
|
||||
def use_pciids(self,
|
||||
path: OptionalPath,
|
||||
check: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Use a PCI IDs file from a given path.
|
||||
|
||||
:param path: A string or path-like object pointing to the PCI IDs file
|
||||
to use. Set to None to use the default files from lspci.
|
||||
:type path: str or Path or None
|
||||
:param bool check: Whether to check for the file's existence
|
||||
immediately, or delay that to the lspci invocation.
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if path:
|
||||
if not isinstance(path, Path):
|
||||
path = Path(path)
|
||||
if check:
|
||||
assert path.is_file(), 'ID database file not found'
|
||||
self._params['pciids'] = path
|
||||
return self
|
||||
|
||||
def use_pcimap(self,
|
||||
path: OptionalPath,
|
||||
check: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Use a kernel module mapping file from a given path.
|
||||
|
||||
:param path: A string or path-like object pointing to the mapping file
|
||||
to use. Set to None to use the default files from lspci.
|
||||
:type path: str or Path or None
|
||||
:param bool check: Whether to check for the file's existence
|
||||
immediately, or delay that to the lspci invocation.
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if path:
|
||||
if not isinstance(path, Path):
|
||||
path = Path(path)
|
||||
if check:
|
||||
assert path.is_file(), 'Kernel module mapping file not found'
|
||||
self._params['pcimap'] = path
|
||||
return self
|
||||
|
||||
def use_access_method(self, method: Optional[str]) -> 'CommandBuilder':
|
||||
"""
|
||||
Use a specific access method to list all devices.
|
||||
|
||||
:param method: Name of the access method to use. Set to None to use
|
||||
lspci's default method.
|
||||
:type method: str or None
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._params['access_method'] = method
|
||||
return self
|
||||
|
||||
def list_access_methods(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
List the pcilib access methods instead of listing devices.
|
||||
|
||||
:param value: Whether or not to list the access methods.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._list_access_methods = value
|
||||
if value:
|
||||
self._list_pcilib_params = False
|
||||
return self
|
||||
|
||||
def list_pcilib_params(self,
|
||||
value: bool = True,
|
||||
raw: bool = False) -> 'CommandBuilder':
|
||||
"""
|
||||
List the pcilib parameters instead of listing devices.
|
||||
|
||||
:param value: Whether or not to list the pcilib parameters.
|
||||
:type value: bool
|
||||
:param raw: When listing the pcilib parameters, whether to return the
|
||||
raw strings or parse them into PCIAccessParameter instances.
|
||||
:type raw: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._list_pcilib_params = value
|
||||
self._list_pcilib_params_raw = raw
|
||||
if value:
|
||||
self._list_access_methods = False
|
||||
return self
|
||||
|
||||
def with_pcilib_params(self,
|
||||
*args: Mapping[str, Any],
|
||||
**kwargs: Any) -> 'CommandBuilder':
|
||||
"""
|
||||
Override some pcilib parameters. When given a dict, will rewrite the
|
||||
parameters with the new dict. When given keyword arguments, will update
|
||||
the existing parameters. Pass ``None`` or ``{}`` to reset all of the
|
||||
parameters.
|
||||
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if len(args) > 0:
|
||||
assert len(args) <= 1, 'Only one positional argument is allowed'
|
||||
assert not kwargs, 'Use either a dict or keyword arguments'
|
||||
self._params['pcilib_params'] = args[0]
|
||||
return self
|
||||
self._params.setdefault('pcilib_params', {}).update(kwargs)
|
||||
return self
|
||||
|
||||
def from_file(self,
|
||||
path: OptionalPath,
|
||||
check: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Use a hexadecimal dump from a previous run of lspci instead of
|
||||
accessing the host's devices directly.
|
||||
|
||||
:param path: A string or path-like object pointing to the hex dump file
|
||||
to use. Set to None to not use a dump file.
|
||||
:type path: str or Path or None
|
||||
:param bool check: Whether to check for the file's existence
|
||||
immediately, or delay that to the lspci invocation.
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if path:
|
||||
if not isinstance(path, Path):
|
||||
path = Path(path)
|
||||
if check:
|
||||
assert path.is_file(), 'Hex dump file not found'
|
||||
self._params['file'] = path
|
||||
return self
|
||||
|
||||
def verbose(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Enable verbose mode.
|
||||
|
||||
:param value: Whether or not to use verbose mode.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._params['verbose'] = value
|
||||
return self
|
||||
|
||||
def include_kernel_drivers(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Under Linux, includes the available kernel modules for each device.
|
||||
Implies ``.verbose()``.
|
||||
|
||||
:param value: Whether or not to include the available kernel modules
|
||||
for each device.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._params['kernel_drivers'] = value
|
||||
if value:
|
||||
return self.verbose()
|
||||
return self
|
||||
|
||||
def include_bridge_paths(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Include the PCI bridge paths along with the IDs.
|
||||
Implies ``.with_ids()``.
|
||||
|
||||
:param value: Whether or not to include the PCI bridge paths.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._params['bridge_paths'] = value
|
||||
if value:
|
||||
return self.with_ids()
|
||||
return self
|
||||
|
||||
def hide_single_domain(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Hide the domain numbers when there is only one domain, numbered zero.
|
||||
|
||||
:param value: Whether or not to hide the domain numbers for a single
|
||||
domain.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._params['hide_single_domain'] = value
|
||||
return self
|
||||
|
||||
def with_ids(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Include PCI device IDs. If disabled, implies ``.with_names()``.
|
||||
|
||||
:param value: Whether or not to include the PCI device IDs.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if value:
|
||||
if self._params.get('id_resolve_option') == \
|
||||
IDResolveOption.NameOnly:
|
||||
self._params['id_resolve_option'] = IDResolveOption.Both
|
||||
else:
|
||||
self._params['id_resolve_option'] = IDResolveOption.NameOnly
|
||||
return self
|
||||
|
||||
def with_names(self, value: bool = True) -> 'CommandBuilder':
|
||||
"""
|
||||
Include PCI device names. If disabled, implies ``.with_ids()``.
|
||||
|
||||
:param value: Whether or not to include the PCI device names.
|
||||
:type value: bool
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if value:
|
||||
if self._params.get('id_resolve_option') == IDResolveOption.IDOnly:
|
||||
self._params['id_resolve_option'] = IDResolveOption.Both
|
||||
else:
|
||||
self._params['id_resolve_option'] = IDResolveOption.IDOnly
|
||||
return self
|
||||
|
||||
def slot_filter(self,
|
||||
*args: str,
|
||||
domain: Optional[int] = None,
|
||||
bus: Optional[int] = None,
|
||||
device: Optional[int] = None,
|
||||
function: Optional[int] = None) -> 'CommandBuilder':
|
||||
"""
|
||||
Filter the devices geographically.
|
||||
Can be passed a string in lspci's filter syntax, or keyword arguments
|
||||
for each portion of the filter.
|
||||
See :class:`pylspci.filters.SlotFilter`.
|
||||
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if len(args) > 0:
|
||||
assert len(args) <= 1, 'Only one positional argument allowed'
|
||||
assert not domain and not bus and not device and not function, \
|
||||
'Use either a string value or the domain, bus, device ' \
|
||||
'and function keyword arguments'
|
||||
self._params['slot_filter'] = SlotFilter.parse(args[0])
|
||||
else:
|
||||
self._params['slot_filter'] = SlotFilter(
|
||||
domain=domain,
|
||||
bus=bus,
|
||||
device=device,
|
||||
function=function,
|
||||
)
|
||||
return self
|
||||
|
||||
def device_filter(self,
|
||||
*args: str,
|
||||
cls: Optional[int] = None,
|
||||
vendor: Optional[int] = None,
|
||||
device: Optional[int] = None) -> 'CommandBuilder':
|
||||
"""
|
||||
Filter the devices logically.
|
||||
Can be passed a string in lspci's filter syntax, or keyword arguments
|
||||
for each portion of the filter.
|
||||
See :class:`pylspci.filters.DeviceFilter`.
|
||||
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if len(args) > 0:
|
||||
assert len(args) <= 1, 'Only one positional argument allowed'
|
||||
assert not cls and not vendor and not device, \
|
||||
'Use either a string value or the cls, vendor and device ' \
|
||||
'keyword arguments'
|
||||
self._params['device_filter'] = DeviceFilter.parse(args[0])
|
||||
else:
|
||||
self._params['device_filter'] = \
|
||||
DeviceFilter(cls=cls, vendor=vendor, device=device)
|
||||
return self
|
||||
|
||||
def with_parser(self, parser: Optional[Parser] = None) -> 'CommandBuilder':
|
||||
"""
|
||||
Use a pylspci parser to get parsed Device instances instead of strings.
|
||||
|
||||
:param parser: The parser to use. Set to None to disable parsing.
|
||||
:type parser: pylspci.parsers.Parser
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
self._parser = parser
|
||||
return self
|
||||
|
||||
def with_default_parser(self) -> 'CommandBuilder':
|
||||
"""
|
||||
Use the default parser compatible with the current set of settings.
|
||||
Note that this should be used as one of the last instructions of the
|
||||
builder, as the default parser can change if the settings are updated.
|
||||
|
||||
:returns: The current CommandBuilder instance.
|
||||
:rtype: CommandBuilder
|
||||
"""
|
||||
if self._params.get('verbose'):
|
||||
from pylspci.parsers import VerboseParser
|
||||
return self.with_parser(VerboseParser())
|
||||
else:
|
||||
from pylspci.parsers import SimpleParser
|
||||
return self.with_parser(SimpleParser())
|
|
@ -1,111 +0,0 @@
|
|||
from typing import Dict, List, NamedTuple, Optional, Union
|
||||
|
||||
from pylspci.fields import NameWithID, NameWithIDDict, Slot, SlotDict
|
||||
|
||||
DeviceDict = Dict[str, Union[
|
||||
int,
|
||||
str,
|
||||
SlotDict,
|
||||
NameWithIDDict,
|
||||
List[str],
|
||||
None,
|
||||
]]
|
||||
|
||||
|
||||
class Device(NamedTuple):
|
||||
"""
|
||||
Describes a device returned by lspci.
|
||||
"""
|
||||
|
||||
slot: Slot
|
||||
"""
|
||||
The device's slot (domain, bus, number and function).
|
||||
"""
|
||||
|
||||
cls: NameWithID
|
||||
"""
|
||||
The device's class, with a name and/or an ID.
|
||||
"""
|
||||
|
||||
vendor: NameWithID
|
||||
"""
|
||||
The device's vendor, with a name and/or an ID.
|
||||
"""
|
||||
|
||||
device: NameWithID
|
||||
"""
|
||||
The device's name and/or ID.
|
||||
"""
|
||||
|
||||
subsystem_vendor: Optional[NameWithID] = None
|
||||
"""
|
||||
The device's subsystem vendor, if found, with a name and/or an ID.
|
||||
"""
|
||||
|
||||
subsystem_device: Optional[NameWithID] = None
|
||||
"""
|
||||
The device's subsystem name and/or ID, if found.
|
||||
"""
|
||||
|
||||
revision: Optional[int] = None
|
||||
"""
|
||||
The device's revision number.
|
||||
"""
|
||||
|
||||
progif: Optional[int] = None
|
||||
"""
|
||||
The device's programming interface number.
|
||||
"""
|
||||
|
||||
driver: Optional[str] = None
|
||||
"""
|
||||
The device's driver (Linux only).
|
||||
"""
|
||||
|
||||
kernel_modules: List[str] = []
|
||||
"""
|
||||
One or more kernel modules that can handle this device (Linux only).
|
||||
"""
|
||||
|
||||
numa_node: Optional[int] = None
|
||||
"""
|
||||
NUMA node this device is connected to (Linux only).
|
||||
"""
|
||||
|
||||
iommu_group: Optional[int] = None
|
||||
"""
|
||||
IOMMU group that this device is part of (optional, Linux only).
|
||||
"""
|
||||
|
||||
physical_slot: Optional[str] = None
|
||||
"""
|
||||
The device's physical slot number (Linux only).
|
||||
"""
|
||||
|
||||
def as_dict(self) -> DeviceDict:
|
||||
"""
|
||||
Serialize this device as a JSON-serializable `dict`.
|
||||
"""
|
||||
return {
|
||||
"slot": self.slot.as_dict(),
|
||||
"cls": self.cls.as_dict(),
|
||||
"vendor": self.vendor.as_dict(),
|
||||
"device": self.device.as_dict(),
|
||||
"subsystem_vendor": (
|
||||
self.subsystem_vendor.as_dict()
|
||||
if self.subsystem_vendor
|
||||
else None
|
||||
),
|
||||
"subsystem_device": (
|
||||
self.subsystem_device.as_dict()
|
||||
if self.subsystem_device
|
||||
else None
|
||||
),
|
||||
"revision": self.revision,
|
||||
"progif": self.progif,
|
||||
"driver": self.driver,
|
||||
"kernel_modules": self.kernel_modules,
|
||||
"numa_node": self.numa_node,
|
||||
"iommu_group": self.iommu_group,
|
||||
"physical_slot": self.physical_slot,
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
import re
|
||||
from functools import partial
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
# mypy does not support recursive type definitions
|
||||
# SlotDict = Dict[str, Union[int, 'SlotDict', None]]
|
||||
SlotDict = Dict[str, Union[int, Dict[str, Any], None]]
|
||||
NameWithIDDict = Dict[str, Union[int, str, None]]
|
||||
|
||||
hexstring = partial(int, base=16)
|
||||
|
||||
|
||||
class Slot(object):
|
||||
"""
|
||||
Describes a PCI slot identifier, in the format ``[DDDD:]BB:dd.f``,
|
||||
where ``D`` is the domain, ``B`` the bus, ``d`` the device
|
||||
and ``f`` the function. The first three are hexadecimal numbers, but
|
||||
``f`` is in octal.
|
||||
"""
|
||||
|
||||
domain: int = 0x0000
|
||||
"""
|
||||
The slot's domain, as a four-digit hexadecimal number.
|
||||
When omitted, defaults to ``0x0000``.
|
||||
"""
|
||||
|
||||
bus: int
|
||||
"""
|
||||
The slot's bus, as a two-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
device: int
|
||||
"""
|
||||
The slot's device, as a two-digit hexadecimal number, up to `0x1f`.
|
||||
"""
|
||||
|
||||
function: int
|
||||
"""
|
||||
The slot's function, as a single octal digit.
|
||||
"""
|
||||
|
||||
parent: Optional["Slot"] = None
|
||||
"""
|
||||
The slot's parent bridge, if present.
|
||||
"""
|
||||
|
||||
def __init__(self, value: str) -> None:
|
||||
parent, _, me = value.rpartition('/')
|
||||
if parent:
|
||||
self.parent = Slot(parent)
|
||||
|
||||
data = list(map(hexstring, re.split(r'[:\.]', me)))
|
||||
if len(data) == 3:
|
||||
data.insert(0, self.parent.domain if self.parent else 0)
|
||||
self.domain, self.bus, self.device, self.function = data
|
||||
|
||||
if self.device > 0x1f:
|
||||
raise ValueError('Device numbers cannot be above 0x1f')
|
||||
if self.function > 0x7:
|
||||
raise ValueError('Function numbers cannot be above 7')
|
||||
|
||||
def __str__(self) -> str:
|
||||
output: str = '{:04x}:{:02x}:{:02x}.{:01x}'.format(
|
||||
self.domain, self.bus, self.device, self.function,
|
||||
)
|
||||
if self.parent:
|
||||
return '{!s}/{}'.format(self.parent, output)
|
||||
return output
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return '{}({!r})'.format(self.__class__.__name__, str(self))
|
||||
|
||||
def as_dict(self) -> SlotDict:
|
||||
"""
|
||||
Serialize this slot as a JSON-serializable `dict`.
|
||||
"""
|
||||
return {
|
||||
"domain": self.domain,
|
||||
"bus": self.bus,
|
||||
"device": self.device,
|
||||
"function": self.function,
|
||||
"parent": self.parent.as_dict() if self.parent else None,
|
||||
}
|
||||
|
||||
|
||||
class NameWithID(object):
|
||||
"""
|
||||
Describes a device, vendor or class with either
|
||||
a name, an hexadecimal PCI ID, or both.
|
||||
"""
|
||||
|
||||
id: Optional[int]
|
||||
"""
|
||||
The PCI ID as a four-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
name: Optional[str]
|
||||
"""
|
||||
The human-readable name associated with this ID.
|
||||
"""
|
||||
|
||||
_NAME_ID_REGEX = re.compile(r'^(?P<name>.+)\s\[(?P<id>[0-9a-fA-F]{4})\]$')
|
||||
|
||||
def __init__(self, value: Optional[str]) -> None:
|
||||
if value and value.endswith(']'):
|
||||
# Holds both an ID and a name
|
||||
match = self._NAME_ID_REGEX.match(value)
|
||||
if not match: # Except it doesn't
|
||||
self.id = None
|
||||
self.name = value
|
||||
return
|
||||
gd = match.groupdict()
|
||||
self.id = hexstring(gd['id'])
|
||||
self.name = gd['name']
|
||||
return
|
||||
|
||||
try:
|
||||
self.id = hexstring(value)
|
||||
self.name = None
|
||||
except (TypeError, ValueError):
|
||||
self.id = None
|
||||
self.name = value
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.id and self.name:
|
||||
return '{} [{:04x}]'.format(self.name, self.id)
|
||||
elif self.name:
|
||||
return self.name
|
||||
elif self.id:
|
||||
return '{:04x}'.format(self.id)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return '{}({!r})'.format(self.__class__.__name__, str(self))
|
||||
|
||||
def as_dict(self) -> NameWithIDDict:
|
||||
"""
|
||||
Serialize this name and ID as a JSON-serializable `dict`.
|
||||
"""
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
}
|
||||
|
||||
|
||||
class PCIAccessParameter(object):
|
||||
"""
|
||||
A pcilib access method parameter, as parsed from :func:`list_pcilib_params`
|
||||
or ``lspci -Ohelp``, that can be modified using the ``pcilib_params``
|
||||
argument of :func:`lspci`, or ``lspci -Oname=value`` in the command line.
|
||||
"""
|
||||
|
||||
name: str
|
||||
"""
|
||||
The parameter's name.
|
||||
"""
|
||||
|
||||
description: str
|
||||
"""
|
||||
A short description of the parameter's use.
|
||||
"""
|
||||
|
||||
default: Optional[str]
|
||||
"""
|
||||
An optional default value for the parameter.
|
||||
"""
|
||||
|
||||
_PARAM_REGEX = re.compile(
|
||||
r'^(?P<name>\S+)\s+(?P<description>.+)\s\((?P<default>.*)\)$')
|
||||
|
||||
def __init__(self, value: str) -> None:
|
||||
match = self._PARAM_REGEX.match(value)
|
||||
if not match:
|
||||
raise ValueError(
|
||||
'Could not parse {!r} into a parameter'.format(value))
|
||||
gd = match.groupdict()
|
||||
self.name = gd['name'].strip()
|
||||
self.description = gd['description'].strip()
|
||||
self.default = gd['default'].strip() or None
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '{}\t{} ({})'.format(self.name, self.description, self.default)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return '{!s}({!r})'.format(self.__class__.__name__, str(self))
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return isinstance(other, PCIAccessParameter) and \
|
||||
(self.name, self.description, self.default) \
|
||||
== (other.name, other.description, other.default)
|
||||
|
||||
def as_dict(self) -> Dict[str, Optional[str]]:
|
||||
"""
|
||||
Serialize this PCI access parameter as a JSON-serializable `dict`.
|
||||
"""
|
||||
return {
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"default": self.default,
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
import re
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, ClassVar, Dict, Optional, Pattern, Type, TypeVar
|
||||
|
||||
from pylspci.fields import hexstring
|
||||
|
||||
T = TypeVar('T', bound='Filter')
|
||||
|
||||
|
||||
class Filter(ABC):
|
||||
|
||||
_REGEX: ClassVar[Pattern]
|
||||
|
||||
@classmethod
|
||||
def parse(cls: Type[T], value: str) -> T:
|
||||
if not value:
|
||||
return cls()
|
||||
match = cls._REGEX.match(value)
|
||||
data: Dict[str, str] = {}
|
||||
if match:
|
||||
data = {k: v for k, v in match.groupdict().items()
|
||||
if v is not None}
|
||||
if not match or not data:
|
||||
raise ValueError('Value is not a valid filter string')
|
||||
return cls(**{
|
||||
k: hexstring(v)
|
||||
for k, v in data.items()
|
||||
if v != '' and v != '*'
|
||||
})
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
"Create a filter."
|
||||
|
||||
|
||||
class SlotFilter(Filter):
|
||||
"""
|
||||
Describes a slot filter, to filter devices geographically.
|
||||
|
||||
Any field set to ``None`` will remove filtering.
|
||||
"""
|
||||
|
||||
domain: Optional[int] = None
|
||||
"""
|
||||
Device domain, as a four-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
bus: Optional[int] = None
|
||||
"""
|
||||
Device bus, as a two-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
device: Optional[int] = None
|
||||
"""
|
||||
Device number, as a two-digit hexadecimal number, up to `0x1f`.
|
||||
"""
|
||||
|
||||
function: Optional[int] = None
|
||||
"""
|
||||
The slot's function, as a single octal digit.
|
||||
"""
|
||||
|
||||
# [[domain:]bus:][device][.function]
|
||||
_REGEX: ClassVar[Pattern] = re.compile(
|
||||
r'^(?:(?:(?P<domain>(?:[0-9a-f]{1,4}|\*?)):)?'
|
||||
r'(?P<bus>(?:[0-9a-f]{1,2}|\*?)):)?'
|
||||
r'(?P<device>(?:[01]?[0-9a-f]|\*?))?'
|
||||
r'(?:\.(?P<function>(?:[0-7]|\*?)))?$'
|
||||
)
|
||||
|
||||
def __init__(self, *,
|
||||
domain: Optional[int] = None,
|
||||
bus: Optional[int] = None,
|
||||
device: Optional[int] = None,
|
||||
function: Optional[int] = None,
|
||||
):
|
||||
self.domain = domain
|
||||
self.bus = bus
|
||||
self.device = device
|
||||
self.function = function
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return '{}(domain={!r}, bus={!r}, device={!r}, function={!r})'.format(
|
||||
self.__class__.__name__,
|
||||
self.domain, self.bus, self.device, self.function,
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '{}:{}:{}.{}'.format(*map(
|
||||
lambda x: '{:x}'.format(x) if x is not None else '',
|
||||
(self.domain, self.bus, self.device, self.function),
|
||||
))
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
return (self.domain, self.bus, self.device, self.function) == \
|
||||
(other.domain, other.bus, other.device, other.function)
|
||||
|
||||
|
||||
class DeviceFilter(Filter):
|
||||
"""
|
||||
Describes a device filter, to filter devices logically.
|
||||
|
||||
Any field set to ``None`` will remove filtering.
|
||||
"""
|
||||
|
||||
cls: Optional[int] = None
|
||||
"""
|
||||
Device class ID, as a four-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
vendor: Optional[int] = None
|
||||
"""
|
||||
Device vendor ID, as a four-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
device: Optional[int] = None
|
||||
"""
|
||||
Device ID, as a four-digit hexadecimal number.
|
||||
"""
|
||||
|
||||
# [vendor]:[device][:class]
|
||||
_REGEX: ClassVar[Pattern] = re.compile(
|
||||
r'^(?P<vendor>(?:[0-9a-f]{1,4}|\*?)):'
|
||||
r'(?P<device>(?:[0-9a-f]{1,4}|\*?))'
|
||||
r'(?::(?P<cls>(?:[0-9a-f]{1,4}|\*?))?)?$'
|
||||
)
|
||||
|
||||
def __init__(self, *,
|
||||
cls: Optional[int] = None,
|
||||
vendor: Optional[int] = None,
|
||||
device: Optional[int] = None,
|
||||
):
|
||||
self.cls = cls
|
||||
self.vendor = vendor
|
||||
self.device = device
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return '{}(cls={!r}, vendor={!r}, device={!r})'.format(
|
||||
self.__class__.__name__, self.cls, self.vendor, self.device,
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return ':'.join(map(
|
||||
lambda x: '{:x}'.format(x) if x is not None else '',
|
||||
(self.vendor, self.device, self.cls),
|
||||
))
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
if not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
return (self.vendor, self.device, self.cls) == \
|
||||
(other.vendor, other.device, other.cls)
|
|
@ -1,3 +0,0 @@
|
|||
from pylspci.parsers.base import Parser # noqa: F401
|
||||
from pylspci.parsers.simple import SimpleParser # noqa: F401
|
||||
from pylspci.parsers.verbose import VerboseParser # noqa: F401
|
|
@ -1,49 +0,0 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Dict, Iterable, List, Union
|
||||
|
||||
from pylspci.device import Device
|
||||
|
||||
|
||||
class Parser(ABC):
|
||||
|
||||
default_lspci_args: Dict[str, Any] = {}
|
||||
"""
|
||||
The default arguments that, when sent to :func:`lspci`, should provide the
|
||||
best output for this parser.
|
||||
|
||||
See :func:`lspci`'s documentation for a list of available arguments.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def parse(
|
||||
self,
|
||||
data: Union[str, Iterable[str], Iterable[Iterable[str]]]
|
||||
) -> List[Device]:
|
||||
"""
|
||||
Parse a string or list of strings as a list of devices.
|
||||
|
||||
:param data: A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.
|
||||
:type data: str or Iterable[str] or Iterable[Iterable[str]]
|
||||
:returns: A list of parsed devices.
|
||||
:rtype: List[Device]
|
||||
"""
|
||||
|
||||
def run(self, **kwargs: Any) -> List[Device]:
|
||||
"""
|
||||
Run the lspci command with the given arguments, defaulting to the
|
||||
parser's default arguments, and parse the result.
|
||||
|
||||
:param \\**kwargs: Optional arguments to override the parser's default
|
||||
arguments. See :func:`lspci`'s documentation for a list of
|
||||
available arguments.
|
||||
:type \\**kwargs: Any
|
||||
:returns: A list of parsed devices.
|
||||
:rtype: List[Device]
|
||||
"""
|
||||
from pylspci.command import lspci
|
||||
lspci_kwargs = self.default_lspci_args.copy()
|
||||
lspci_kwargs.update(kwargs)
|
||||
return self.parse(lspci(**lspci_kwargs))
|
|
@ -1,98 +0,0 @@
|
|||
import argparse
|
||||
import shlex
|
||||
from typing import Any, Iterable, List, Union
|
||||
|
||||
from cached_property import cached_property
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.fields import NameWithID, Slot, hexstring
|
||||
from pylspci.parsers.base import Parser
|
||||
|
||||
|
||||
class SimpleParser(Parser):
|
||||
"""
|
||||
A parser for lspci -mm.
|
||||
"""
|
||||
|
||||
@cached_property
|
||||
def _parser(self) -> argparse.ArgumentParser:
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument(
|
||||
'slot',
|
||||
type=Slot,
|
||||
)
|
||||
p.add_argument(
|
||||
'cls',
|
||||
type=NameWithID,
|
||||
)
|
||||
p.add_argument(
|
||||
'vendor',
|
||||
type=NameWithID,
|
||||
)
|
||||
p.add_argument(
|
||||
'device',
|
||||
type=NameWithID,
|
||||
)
|
||||
p.add_argument(
|
||||
'subsystem_vendor',
|
||||
type=NameWithID,
|
||||
)
|
||||
p.add_argument(
|
||||
'subsystem_device',
|
||||
type=NameWithID,
|
||||
)
|
||||
p.add_argument(
|
||||
'-r',
|
||||
type=hexstring,
|
||||
nargs='?',
|
||||
dest='revision',
|
||||
)
|
||||
p.add_argument(
|
||||
'-p',
|
||||
type=hexstring,
|
||||
nargs='?',
|
||||
dest='progif',
|
||||
)
|
||||
return p
|
||||
|
||||
def parse(
|
||||
self,
|
||||
data: Union[str, Iterable[str], Iterable[Iterable[str]]],
|
||||
) -> List[Device]:
|
||||
"""
|
||||
Parse a multiline string or a list of single-line strings
|
||||
from lspci -mm into devices.
|
||||
|
||||
:param data: A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.
|
||||
:type data: str or Iterable[str] or Iterable[Iterable[str]]
|
||||
:return: A list of parsed devices.
|
||||
:rtype: List[Device]
|
||||
"""
|
||||
if isinstance(data, str):
|
||||
data = data.splitlines()
|
||||
return list(map(self.parse_line, data))
|
||||
|
||||
def parse_line(self, args: Union[str, Iterable[str]]) -> Device:
|
||||
"""
|
||||
Parse a single line from lspci -mm into a single device, either
|
||||
as the line or as a list of fields.
|
||||
|
||||
:param args: Line or list of fields to parse from.
|
||||
:type args: str or Iterable[str]
|
||||
:return: A single parsed device.
|
||||
:rtype: Device
|
||||
"""
|
||||
if isinstance(args, str):
|
||||
args = shlex.split(args)
|
||||
return Device(**vars(self._parser.parse_args(args)))
|
||||
|
||||
def run(self, **kwargs: Any) -> List[Device]:
|
||||
if kwargs.get('verbose'):
|
||||
raise ValueError(
|
||||
'Verbose output is unsupported from the SimpleParser. '
|
||||
'Please use the pylspci.parsers.VerboseParser instead.'
|
||||
)
|
||||
return super().run(**kwargs)
|
|
@ -1,123 +0,0 @@
|
|||
import warnings
|
||||
from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Union
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.fields import NameWithID, Slot, hexstring
|
||||
from pylspci.parsers.base import Parser
|
||||
|
||||
UNKNOWN_FIELD_WARNING = (
|
||||
'Unsupported device field {!r} with value {!r}\n'
|
||||
'Please report this, along with the output of `lspci -mmnnvvvk`, at '
|
||||
'https://tildegit.org/lucidiot/pylspci/issues/new'
|
||||
)
|
||||
|
||||
|
||||
class FieldMapping(NamedTuple):
|
||||
"""
|
||||
Helper class to map verbose output field names such as ``SVendor`` to
|
||||
:class:`Device` fields such as ``subsytem_vendor``.
|
||||
"""
|
||||
|
||||
field_name: str
|
||||
"""
|
||||
Field name on the :class:`Device` named tuple.
|
||||
"""
|
||||
|
||||
field_type: Callable[[str], Any]
|
||||
"""
|
||||
Field type; a callable to use to parse the string value.
|
||||
"""
|
||||
|
||||
many: bool = False
|
||||
"""
|
||||
Whether or not to use a List, if this field can be repeated multiple times
|
||||
in the lspci output.
|
||||
"""
|
||||
|
||||
|
||||
class VerboseParser(Parser):
|
||||
"""
|
||||
A parser for lspci -vvvmmk
|
||||
"""
|
||||
|
||||
default_lspci_args = {
|
||||
'verbose': True,
|
||||
'kernel_drivers': True,
|
||||
}
|
||||
|
||||
# Maps lspci output fields to Device fields with a type
|
||||
_field_mapping = {
|
||||
'Slot': FieldMapping(field_name='slot', field_type=Slot),
|
||||
'Class': FieldMapping(field_name='cls', field_type=NameWithID),
|
||||
'Vendor': FieldMapping(field_name='vendor', field_type=NameWithID),
|
||||
'Device': FieldMapping(field_name='device', field_type=NameWithID),
|
||||
'SVendor': FieldMapping(
|
||||
field_name='subsystem_vendor',
|
||||
field_type=NameWithID,
|
||||
),
|
||||
'SDevice': FieldMapping(
|
||||
field_name='subsystem_device',
|
||||
field_type=NameWithID,
|
||||
),
|
||||
'Rev': FieldMapping(field_name='revision', field_type=hexstring),
|
||||
'ProgIf': FieldMapping(field_name='progif', field_type=hexstring),
|
||||
'Driver': FieldMapping(field_name='driver', field_type=str),
|
||||
'Module': FieldMapping(
|
||||
field_name='kernel_modules',
|
||||
field_type=str,
|
||||
many=True,
|
||||
),
|
||||
'NUMANode': FieldMapping(field_name='numa_node', field_type=int),
|
||||
'IOMMUGroup': FieldMapping(field_name='iommu_group', field_type=int),
|
||||
'PhySlot': FieldMapping(field_name='physical_slot', field_type=str),
|
||||
}
|
||||
|
||||
def _parse_device(self, device_data: Union[str, Iterable[str]]) -> Device:
|
||||
devdict: Dict[str, Any] = {}
|
||||
if isinstance(device_data, str):
|
||||
device_data = device_data.splitlines()
|
||||
|
||||
for line in device_data:
|
||||
key, _, value = map(str.strip, line.partition(':'))
|
||||
if key not in self._field_mapping:
|
||||
warnings.warn(
|
||||
UNKNOWN_FIELD_WARNING.format(key, value),
|
||||
UserWarning,
|
||||
)
|
||||
continue
|
||||
field = self._field_mapping[key]
|
||||
if field.many:
|
||||
devdict.setdefault(field.field_name, []) \
|
||||
.append(field.field_type(value))
|
||||
else:
|
||||
devdict[field.field_name] = field.field_type(value)
|
||||
|
||||
return Device(**devdict)
|
||||
|
||||
def parse(
|
||||
self,
|
||||
data: Union[str, Iterable[str], Iterable[Iterable[str]]],
|
||||
) -> List[Device]:
|
||||
"""
|
||||
Parse an lspci -vvvmm[nnk] output, either as a single string holding
|
||||
multiple devices separated by two newlines,
|
||||
or as a list of multiline strings holding one device each.
|
||||
|
||||
:param data: A string holding multiple devices,
|
||||
a list of strings, one for each device,
|
||||
or a list of lists of strings, one list for each device, with
|
||||
each list holding each part of the device output.
|
||||
:type data: str or Iterable[str] or Iterable[Iterable[str]]
|
||||
:return: A list of parsed devices.
|
||||
:rtype: List[Device]
|
||||
"""
|
||||
if isinstance(data, str):
|
||||
data = data.split('\n\n')
|
||||
result: List[Device] = []
|
||||
for line in data:
|
||||
if isinstance(line, str):
|
||||
line = str.strip(line)
|
||||
if not line: # Ignore empty strings and lists
|
||||
continue
|
||||
result.append(self._parse_device(line))
|
||||
return result
|
|
@ -1,381 +0,0 @@
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from pylspci.command import CommandBuilder, IDResolveOption
|
||||
from pylspci.parsers import SimpleParser, VerboseParser
|
||||
|
||||
|
||||
class TestCommandBuilder(TestCase):
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_default(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
self.assertListEqual(list(CommandBuilder()), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call())
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_iter_str(self, lspci_mock: MagicMock) -> None:
|
||||
"""
|
||||
Test iterating the CommandBuilder when lspci returns a single string
|
||||
returns an iterator for a list made of a single string, not an iterator
|
||||
for each character of the string
|
||||
"""
|
||||
lspci_mock.return_value = 'a\nb'
|
||||
self.assertListEqual(list(CommandBuilder()), ['a\nb', ])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call())
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pciids(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = True
|
||||
builder = CommandBuilder().use_pciids('somefile')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pciids=Path('somefile')))
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pciids_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
with self.assertRaisesRegex(AssertionError, 'not found'):
|
||||
CommandBuilder().use_pciids('somefile')
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pciids_no_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
builder = CommandBuilder().use_pciids('somefile', check=False)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pciids=Path('somefile')))
|
||||
self.assertFalse(isfile_mock.called)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pcimap(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = True
|
||||
builder = CommandBuilder().use_pcimap('somefile')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pcimap=Path('somefile')))
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pcimap_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
with self.assertRaisesRegex(AssertionError, 'not found'):
|
||||
CommandBuilder().use_pcimap('somefile')
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_pcimap_no_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
builder = CommandBuilder().use_pcimap('somefile', check=False)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pcimap=Path('somefile')))
|
||||
self.assertFalse(isfile_mock.called)
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_use_access_method(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder() \
|
||||
.use_access_method('one') \
|
||||
.use_access_method('two')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(access_method='two'))
|
||||
|
||||
@patch('pylspci.command.list_access_methods')
|
||||
def test_list_access_methods(self, list_mock: MagicMock) -> None:
|
||||
list_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().list_pcilib_params().list_access_methods()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(list_mock.call_count, 1)
|
||||
self.assertEqual(list_mock.call_args, call())
|
||||
|
||||
@patch('pylspci.command.list_pcilib_params')
|
||||
def test_list_pcilib_params(self, list_mock: MagicMock) -> None:
|
||||
list_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().list_access_methods().list_pcilib_params()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(list_mock.call_count, 1)
|
||||
self.assertEqual(list_mock.call_args, call())
|
||||
|
||||
@patch('pylspci.command.list_pcilib_params_raw')
|
||||
def test_list_pcilib_params_raw(self, list_mock: MagicMock) -> None:
|
||||
list_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder() \
|
||||
.list_access_methods() \
|
||||
.list_pcilib_params(raw=True)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(list_mock.call_count, 1)
|
||||
self.assertEqual(list_mock.call_args, call())
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_with_pcilib_params_dict(self, lspci_mock: MagicMock) -> None:
|
||||
with self.assertRaisesRegex(AssertionError, 'dict or keyword'):
|
||||
CommandBuilder().with_pcilib_params({'a': 'b'}, c='d')
|
||||
with self.assertRaisesRegex(AssertionError, 'Only one positional'):
|
||||
CommandBuilder().with_pcilib_params({'a': 'b'}, {'c': 'd'})
|
||||
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().with_pcilib_params({'a': 'b'})
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pcilib_params={'a': 'b'}))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_with_pcilib_params_kwargs(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder() \
|
||||
.with_pcilib_params(a='1', b='2') \
|
||||
.with_pcilib_params(b='3', c='4')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(pcilib_params={
|
||||
'a': '1', 'b': '3', 'c': '4',
|
||||
}))
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_from_file(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = True
|
||||
builder = CommandBuilder().from_file('somefile')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(file=Path('somefile')))
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_from_file_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
with self.assertRaisesRegex(AssertionError, 'not found'):
|
||||
CommandBuilder().from_file('somefile')
|
||||
self.assertEqual(isfile_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_from_file_no_check(self,
|
||||
lspci_mock: MagicMock,
|
||||
isfile_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
isfile_mock.return_value = False
|
||||
builder = CommandBuilder().from_file('somefile', check=False)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(file=Path('somefile')))
|
||||
self.assertFalse(isfile_mock.called)
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_verbose(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().verbose()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(verbose=True))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_include_kernel_drivers(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder() \
|
||||
.include_kernel_drivers(False) \
|
||||
.include_kernel_drivers()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
verbose=True,
|
||||
kernel_drivers=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_include_bridge_paths(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder() \
|
||||
.include_bridge_paths(False) \
|
||||
.include_bridge_paths()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
bridge_paths=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_hide_single_domain(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().hide_single_domain()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(hide_single_domain=True))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_with_ids(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().with_ids(False)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
id_resolve_option=IDResolveOption.NameOnly,
|
||||
))
|
||||
|
||||
lspci_mock.reset_mock()
|
||||
builder = builder.with_ids()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
id_resolve_option=IDResolveOption.Both,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_with_names(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().with_names(False)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
id_resolve_option=IDResolveOption.IDOnly,
|
||||
))
|
||||
|
||||
lspci_mock.reset_mock()
|
||||
builder = builder.with_names()
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(
|
||||
id_resolve_option=IDResolveOption.Both,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.SlotFilter')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_slot_filter_str(self,
|
||||
lspci_mock: MagicMock,
|
||||
filter_mock: MagicMock) -> None:
|
||||
with self.assertRaisesRegex(AssertionError, 'Only one positional'):
|
||||
CommandBuilder().slot_filter('something', 'something else')
|
||||
with self.assertRaisesRegex(AssertionError, 'Use either'):
|
||||
CommandBuilder().slot_filter('something', domain=0xa)
|
||||
|
||||
filter_mock.parse.return_value = 'lefilter'
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().slot_filter('something')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(slot_filter='lefilter'))
|
||||
self.assertEqual(filter_mock.parse.call_count, 1)
|
||||
self.assertEqual(filter_mock.parse.call_args, call('something'))
|
||||
|
||||
@patch('pylspci.command.SlotFilter')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_slot_filter_kwargs(self,
|
||||
lspci_mock: MagicMock,
|
||||
filter_mock: MagicMock) -> None:
|
||||
filter_mock.return_value = 'lefilter'
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().slot_filter(
|
||||
domain=0xa,
|
||||
bus=0xb,
|
||||
device=0xc,
|
||||
function=0xd,
|
||||
)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(slot_filter='lefilter'))
|
||||
self.assertEqual(filter_mock.call_count, 1)
|
||||
self.assertEqual(filter_mock.call_args, call(
|
||||
domain=0xa,
|
||||
bus=0xb,
|
||||
device=0xc,
|
||||
function=0xd,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.DeviceFilter')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_device_filter_str(self,
|
||||
lspci_mock: MagicMock,
|
||||
filter_mock: MagicMock) -> None:
|
||||
with self.assertRaisesRegex(AssertionError, 'Only one positional'):
|
||||
CommandBuilder().device_filter('something', 'something else')
|
||||
with self.assertRaisesRegex(AssertionError, 'Use either'):
|
||||
CommandBuilder().device_filter('something', vendor=0xb)
|
||||
|
||||
filter_mock.parse.return_value = 'lefilter'
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().device_filter('something')
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(device_filter='lefilter'))
|
||||
self.assertEqual(filter_mock.parse.call_count, 1)
|
||||
self.assertEqual(filter_mock.parse.call_args, call('something'))
|
||||
|
||||
@patch('pylspci.command.DeviceFilter')
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_device_filter_kwargs(self,
|
||||
lspci_mock: MagicMock,
|
||||
filter_mock: MagicMock) -> None:
|
||||
filter_mock.return_value = 'lefilter'
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
builder = CommandBuilder().device_filter(
|
||||
cls=0xa,
|
||||
vendor=0xb,
|
||||
device=0xc,
|
||||
)
|
||||
self.assertListEqual(list(builder), ['a', 'b'])
|
||||
self.assertEqual(lspci_mock.call_count, 1)
|
||||
self.assertEqual(lspci_mock.call_args, call(device_filter='lefilter'))
|
||||
self.assertEqual(filter_mock.call_count, 1)
|
||||
self.assertEqual(filter_mock.call_args, call(
|
||||
cls=0xa,
|
||||
vendor=0xb,
|
||||
device=0xc,
|
||||
))
|
||||
|
||||
def test_with_default_parser(self) -> None:
|
||||
builder = CommandBuilder()
|
||||
self.assertIsNone(builder._parser)
|
||||
|
||||
builder = CommandBuilder().with_default_parser()
|
||||
self.assertIsInstance(builder._parser, SimpleParser)
|
||||
|
||||
builder = CommandBuilder().verbose().with_default_parser()
|
||||
self.assertIsInstance(builder._parser, VerboseParser)
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_with_parser(self, lspci_mock: MagicMock) -> None:
|
||||
lspci_mock.return_value = ['a', 'b']
|
||||
parser_mock = MagicMock(spec=SimpleParser)
|
||||
parser_mock.parse.return_value = ('parsed_a', 'parsed_b')
|
||||
builder = CommandBuilder().with_parser(parser_mock)
|
||||
self.assertListEqual(list(builder), ['parsed_a', 'parsed_b'])
|
||||
self.assertEqual(parser_mock.parse.call_count, 1)
|
||||
self.assertEqual(parser_mock.parse.call_args, call(['a', 'b']))
|
|
@ -1,292 +0,0 @@
|
|||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from pylspci.command import (
|
||||
IDResolveOption, list_access_methods, list_pcilib_params, lspci
|
||||
)
|
||||
from pylspci.fields import PCIAccessParameter
|
||||
|
||||
|
||||
class TestCommand(TestCase):
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_default(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-nn'], universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_pciids(self,
|
||||
cmd_mock: MagicMock,
|
||||
is_file_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
is_file_mock.return_value = True
|
||||
self.assertEqual(lspci(pciids='/somewhere'), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-nn', '-i', '/somewhere'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
def test_pciids_missing(self, is_file_mock: MagicMock) -> None:
|
||||
is_file_mock.return_value = False
|
||||
with self.assertRaises(AssertionError):
|
||||
lspci(pciids='/nowhere')
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_pcimap(self,
|
||||
cmd_mock: MagicMock,
|
||||
is_file_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
is_file_mock.return_value = True
|
||||
self.assertEqual(lspci(pcimap='/somewhere'), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-nn', '-p', '/somewhere'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
def test_pcimap_missing(self, is_file_mock: MagicMock) -> None:
|
||||
is_file_mock.return_value = False
|
||||
with self.assertRaises(AssertionError):
|
||||
lspci(pcimap='/nowhere')
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_access_method(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(access_method='somemethod'), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-Asomemethod', '-nn'], universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_pcilib_params(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(pcilib_params={'a': 'b', 'c': 2}), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-nn', '-Oa=b', '-Oc=2'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_file(self, cmd_mock: MagicMock, is_file_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
is_file_mock.return_value = True
|
||||
self.assertEqual(lspci(file='/somewhere'), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-nn', '-F', '/somewhere'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
def test_file_missing(self, is_file_mock: MagicMock) -> None:
|
||||
is_file_mock.return_value = False
|
||||
with self.assertRaises(AssertionError):
|
||||
lspci(file='/nowhere')
|
||||
self.assertEqual(is_file_mock.call_count, 1)
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_verbose(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(verbose=True), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-vvv', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_kernel_drivers(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(kernel_drivers=True), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-k', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_bridge_paths(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(bridge_paths=True), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-PP', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_hide_single_domain(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(lspci(hide_single_domain=False), 'something')
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-D', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_id_resolve_option_id_only(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(
|
||||
lspci(id_resolve_option=IDResolveOption.IDOnly),
|
||||
'something',
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-n'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_id_resolve_option_name_only(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(
|
||||
lspci(id_resolve_option=IDResolveOption.NameOnly),
|
||||
'something',
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_slot_filter(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(
|
||||
lspci(slot_filter='13'),
|
||||
'something',
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-s', '::13.', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_device_filter(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
self.assertEqual(
|
||||
lspci(device_filter=':13'),
|
||||
'something',
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-d', ':13:', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.Path.is_file')
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_everything(self,
|
||||
cmd_mock: MagicMock,
|
||||
is_file_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = 'something'
|
||||
is_file_mock.return_value = True
|
||||
|
||||
self.assertEqual(lspci(
|
||||
pciids='/pciids',
|
||||
pcimap='/pcimap',
|
||||
access_method='somemethod',
|
||||
pcilib_params={'a': 'b', 'c': 42},
|
||||
file='/file',
|
||||
verbose=True,
|
||||
kernel_drivers=True,
|
||||
bridge_paths=True,
|
||||
hide_single_domain=False,
|
||||
id_resolve_option=IDResolveOption.IDOnly,
|
||||
slot_filter='c0fe:e:e',
|
||||
device_filter='c0fe::eeee',
|
||||
), 'something')
|
||||
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci',
|
||||
'-mm',
|
||||
'-vvv',
|
||||
'-k',
|
||||
'-PP',
|
||||
'-D',
|
||||
'-Asomemethod',
|
||||
'-s',
|
||||
'c0fe:e:e.',
|
||||
'-d',
|
||||
'c0fe::eeee',
|
||||
'-n',
|
||||
'-i', '/pciids',
|
||||
'-p', '/pcimap',
|
||||
'-F', '/file',
|
||||
'-Oa=b',
|
||||
'-Oc=42'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
self.assertEqual(is_file_mock.call_count, 3)
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_list_access_methods(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = """
|
||||
Known PCI access methods:
|
||||
|
||||
linux-sysfs
|
||||
linux-proc
|
||||
intel-conf1
|
||||
intel-conf2
|
||||
dump
|
||||
"""
|
||||
self.assertListEqual(
|
||||
list_access_methods(),
|
||||
['linux-sysfs', 'linux-proc', 'intel-conf1', 'intel-conf2', 'dump']
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-mm', '-Ahelp', '-nn'],
|
||||
universal_newlines=True,
|
||||
))
|
||||
|
||||
@patch('pylspci.command.subprocess.check_output')
|
||||
def test_list_pcilib_params(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = """
|
||||
Known PCI access parameters:
|
||||
|
||||
dump.name Name of the bus dump file to read from ()
|
||||
proc.path Path to the procfs bus tree (/proc/bus/pci)
|
||||
sysfs.path Path to the sysfs device tree (/sys/bus/pci)
|
||||
hwdb.disable Do not look up names in UDEV's HWDB if non-zero (0)
|
||||
net.cache_name Name of the ID cache file (~/.pciids-cache)
|
||||
net.domain DNS domain used for resolving of ID's (pci.id.ucw.cz)
|
||||
"""
|
||||
self.assertListEqual(
|
||||
list_pcilib_params(),
|
||||
list(map(PCIAccessParameter, [
|
||||
"dump.name Name of the bus dump file to read from ()",
|
||||
"proc.path Path to the procfs bus tree (/proc/bus/pci)",
|
||||
"sysfs.path Path to the sysfs device tree (/sys/bus/pci)",
|
||||
"hwdb.disable Do not look up names "
|
||||
"in UDEV's HWDB if non-zero (0)",
|
||||
"net.cache_name Name of the ID cache file (~/.pciids-cache)",
|
||||
"net.domain DNS domain used for "
|
||||
"resolving of ID's (pci.id.ucw.cz)",
|
||||
]))
|
||||
)
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call(
|
||||
['lspci', '-Ohelp'],
|
||||
universal_newlines=True,
|
||||
))
|
|
@ -1,110 +0,0 @@
|
|||
from typing import List
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.parsers import SimpleParser
|
||||
|
||||
|
||||
class TestSimpleParser(TestCase):
|
||||
|
||||
parser: SimpleParser
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
super().setUpClass()
|
||||
cls.parser = SimpleParser()
|
||||
|
||||
def _check_device(self, dev: Device) -> None:
|
||||
self.assertIsInstance(dev, Device)
|
||||
self.assertEqual(dev.slot.domain, 0x0000)
|
||||
self.assertEqual(dev.slot.bus, 0x00)
|
||||
self.assertEqual(dev.slot.device, 0x1c)
|
||||
self.assertEqual(dev.slot.function, 0x3)
|
||||
self.assertEqual(dev.cls.id, 0x0604)
|
||||
self.assertEqual(dev.cls.name, 'PCI bridge')
|
||||
self.assertEqual(dev.vendor.id, 0x8086)
|
||||
self.assertEqual(dev.vendor.name, 'Intel Corporation')
|
||||
self.assertEqual(dev.device.id, 0x244e)
|
||||
self.assertEqual(dev.device.name, '82801 PCI Bridge')
|
||||
assert dev.subsystem_vendor is not None
|
||||
self.assertEqual(dev.subsystem_vendor.id, 0x8086)
|
||||
self.assertEqual(dev.subsystem_vendor.name, 'Intel Corporation')
|
||||
assert dev.subsystem_device is not None
|
||||
self.assertEqual(dev.subsystem_device.id, 0x244e)
|
||||
self.assertEqual(dev.subsystem_device.name, '82801 PCI Bridge')
|
||||
self.assertEqual(dev.revision, 0xd5)
|
||||
self.assertEqual(dev.progif, 0x01)
|
||||
|
||||
def test_parse_str(self) -> None:
|
||||
dev_list: List[Device] = self.parser.parse(
|
||||
'00:1c.3 "PCI bridge [0604]" "Intel Corporation [8086]" '
|
||||
'"82801 PCI Bridge [244e]" -rd5 -p01 "Intel Corporation [8086]" '
|
||||
'"82801 PCI Bridge [244e]"'
|
||||
)
|
||||
self.assertEqual(len(dev_list), 1)
|
||||
self._check_device(dev_list[0])
|
||||
|
||||
def test_parse_list(self) -> None:
|
||||
dev_list: List[Device] = self.parser.parse([
|
||||
[
|
||||
'00:1c.3',
|
||||
'PCI bridge [0604]',
|
||||
'Intel Corporation [8086]',
|
||||
'82801 PCI Bridge [244e]',
|
||||
'-rd5',
|
||||
'-p01',
|
||||
'Intel Corporation [8086]',
|
||||
'82801 PCI Bridge [244e]',
|
||||
]
|
||||
])
|
||||
self.assertEqual(len(dev_list), 1)
|
||||
self._check_device(dev_list[0])
|
||||
|
||||
def test_parse_nothing(self) -> None:
|
||||
dev_list: List[Device] = self.parser.parse('00:00.0 "" "" "" "" ""')
|
||||
self.assertEqual(len(dev_list), 1)
|
||||
dev: Device = dev_list[0]
|
||||
self.assertIsInstance(dev, Device)
|
||||
self.assertEqual(dev.slot.domain, 0x0000)
|
||||
self.assertEqual(dev.slot.bus, 0x00)
|
||||
self.assertEqual(dev.slot.device, 0x00)
|
||||
self.assertEqual(dev.slot.function, 0x0)
|
||||
self.assertIsNone(dev.cls.id)
|
||||
self.assertEqual(dev.cls.name, '')
|
||||
self.assertIsNone(dev.vendor.id)
|
||||
self.assertEqual(dev.vendor.name, '')
|
||||
self.assertIsNone(dev.device.id)
|
||||
self.assertEqual(dev.device.name, '')
|
||||
assert dev.subsystem_vendor is not None
|
||||
self.assertIsNone(dev.subsystem_vendor.id)
|
||||
self.assertEqual(dev.subsystem_vendor.name, '')
|
||||
assert dev.subsystem_device is not None
|
||||
self.assertIsNone(dev.subsystem_device.id)
|
||||
self.assertEqual(dev.subsystem_device.name, '')
|
||||
self.assertIsNone(dev.revision)
|
||||
self.assertIsNone(dev.progif)
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_command(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = \
|
||||
'00:1c.3 "PCI bridge [0604]" "Intel Corporation [8086]" ' \
|
||||
'"82801 PCI Bridge [244e]" -rd5 -p01 "Intel Corporation [8086]" ' \
|
||||
'"82801 PCI Bridge [244e]"\n' * 2
|
||||
|
||||
devices: List[Device] = self.parser.run()
|
||||
self.assertEqual(len(devices), 2)
|
||||
self._check_device(devices[0])
|
||||
self._check_device(devices[1])
|
||||
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args, call())
|
||||
|
||||
def test_verbose_error(self) -> None:
|
||||
with self.assertRaises(ValueError) as ctx:
|
||||
self.parser.run(verbose=True)
|
||||
self.assertEqual(
|
||||
ctx.exception.args[0],
|
||||
'Verbose output is unsupported from the SimpleParser. '
|
||||
'Please use the pylspci.parsers.VerboseParser instead.'
|
||||
)
|
|
@ -1,95 +0,0 @@
|
|||
from typing import List
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.parsers import VerboseParser
|
||||
|
||||
SAMPLE_DEVICE: str = """
|
||||
Slot: 00:1c.3
|
||||
Class: PCI bridge [0604]
|
||||
Vendor: Intel Corporation [8086]
|
||||
Device: 82801 PCI Bridge [244e]
|
||||
SVendor: Intel Corporation [8086]
|
||||
SDevice: 82801 PCI Bridge [244e]
|
||||
Rev: d5
|
||||
ProgIf: 01
|
||||
Driver: pcieport
|
||||
Module: nouveau
|
||||
Module: nvidia
|
||||
NUMANode: 0
|
||||
IOMMUGroup: 1
|
||||
PhySlot: 4
|
||||
"""
|
||||
|
||||
|
||||
class TestVerboseParser(TestCase):
|
||||
|
||||
parser: VerboseParser
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
super().setUpClass()
|
||||
cls.parser = VerboseParser()
|
||||
|
||||
def _check_device(self, dev: Device) -> None:
|
||||
self.assertIsInstance(dev, Device)
|
||||
self.assertEqual(dev.slot.domain, 0x0000)
|
||||
self.assertEqual(dev.slot.bus, 0x00)
|
||||
self.assertEqual(dev.slot.device, 0x1c)
|
||||
self.assertEqual(dev.slot.function, 0x3)
|
||||
self.assertEqual(dev.cls.id, 0x0604)
|
||||
self.assertEqual(dev.cls.name, 'PCI bridge')
|
||||
self.assertEqual(dev.vendor.id, 0x8086)
|
||||
self.assertEqual(dev.vendor.name, 'Intel Corporation')
|
||||
self.assertEqual(dev.device.id, 0x244e)
|
||||
self.assertEqual(dev.device.name, '82801 PCI Bridge')
|
||||
assert dev.subsystem_vendor is not None
|
||||
self.assertEqual(dev.subsystem_vendor.id, 0x8086)
|
||||
self.assertEqual(dev.subsystem_vendor.name, 'Intel Corporation')
|
||||
assert dev.subsystem_device is not None
|
||||
self.assertEqual(dev.subsystem_device.id, 0x244e)
|
||||
self.assertEqual(dev.subsystem_device.name, '82801 PCI Bridge')
|
||||
self.assertEqual(dev.revision, 0xd5)
|
||||
self.assertEqual(dev.progif, 0x01)
|
||||
self.assertEqual(dev.driver, 'pcieport')
|
||||
self.assertListEqual(dev.kernel_modules, ['nouveau', 'nvidia'])
|
||||
self.assertEqual(dev.numa_node, 0)
|
||||
self.assertEqual(dev.iommu_group, 1)
|
||||
self.assertEqual(dev.physical_slot, '4')
|
||||
|
||||
def test_parse_str(self) -> None:
|
||||
devices: List[Device] = self.parser.parse(SAMPLE_DEVICE)
|
||||
self.assertEqual(len(devices), 1)
|
||||
self._check_device(devices[0])
|
||||
|
||||
def test_parse_list(self) -> None:
|
||||
devices: List[Device] = self.parser.parse([SAMPLE_DEVICE, ])
|
||||
self.assertEqual(len(devices), 1)
|
||||
self._check_device(devices[0])
|
||||
|
||||
@patch('pylspci.command.lspci')
|
||||
def test_command(self, cmd_mock: MagicMock) -> None:
|
||||
cmd_mock.return_value = '{0}\n\n{0}'.format(SAMPLE_DEVICE)
|
||||
|
||||
devices: List[Device] = self.parser.run()
|
||||
self.assertEqual(len(devices), 2)
|
||||
self._check_device(devices[0])
|
||||
self._check_device(devices[1])
|
||||
|
||||
self.assertEqual(cmd_mock.call_count, 1)
|
||||
self.assertEqual(cmd_mock.call_args,
|
||||
call(verbose=True, kernel_drivers=True))
|
||||
|
||||
def test_unknown_field(self) -> None:
|
||||
with self.assertWarns(
|
||||
UserWarning,
|
||||
msg="Unsupported device field 'NewField' with value 'Value'\n"
|
||||
"Please report this, along with the output of"
|
||||
"`lspci -mmnnvvvk`, at "
|
||||
"https://tildegit.org/lucidiot/pylspci/issues/new"):
|
||||
devices: List[Device] = \
|
||||
self.parser.parse(SAMPLE_DEVICE + 'NewField\tValue')
|
||||
|
||||
self.assertEqual(len(devices), 1)
|
||||
self._check_device(devices[0])
|
|
@ -1,60 +0,0 @@
|
|||
from unittest import TestCase
|
||||
|
||||
from pylspci.device import Device
|
||||
from pylspci.fields import NameWithID, Slot
|
||||
|
||||
|
||||
class TestDevice(TestCase):
|
||||
|
||||
def test_as_dict(self) -> None:
|
||||
d = Device(
|
||||
slot=Slot('cafe:13:07.2'),
|
||||
cls=NameWithID('Something [caf3]'),
|
||||
vendor=NameWithID('Something [caf3]'),
|
||||
device=NameWithID('Something [caf3]'),
|
||||
subsystem_vendor=NameWithID('Something [caf3]'),
|
||||
subsystem_device=NameWithID('Something [caf3]'),
|
||||
revision=20,
|
||||
progif=1,
|
||||
driver='self_driving',
|
||||
kernel_modules=['snd-pcsp'],
|
||||
numa_node=0,
|
||||
iommu_group=1,
|
||||
physical_slot='4-2',
|
||||
)
|
||||
self.assertDictEqual(d.as_dict(), {
|
||||
'slot': {
|
||||
'bus': 0x13,
|
||||
'device': 0x07,
|
||||
'domain': 0xcafe,
|
||||
'function': 0x2,
|
||||
'parent': None
|
||||
},
|
||||
'cls': {
|
||||
'id': 0xcaf3,
|
||||
'name': 'Something'
|
||||
},
|
||||
'vendor': {
|
||||
'id': 0xcaf3,
|
||||
'name': 'Something'
|
||||
},
|
||||
'device': {
|
||||
'id': 0xcaf3,
|
||||
'name': 'Something'
|
||||
},
|
||||
'subsystem_vendor': {
|
||||
'id': 0xcaf3,
|
||||
'name': 'Something'
|
||||
},
|
||||
'subsystem_device': {
|
||||
'id': 0xcaf3,
|
||||
'name': 'Something'
|
||||
},
|
||||
'revision': 20,
|
||||
'progif': 1,
|
||||
'driver': 'self_driving',
|
||||
'kernel_modules': ['snd-pcsp'],
|
||||
'numa_node': 0,
|
||||
'iommu_group': 1,
|
||||
'physical_slot': '4-2',
|
||||
})
|
|
@ -1,186 +0,0 @@
|
|||
from unittest import TestCase
|
||||
|
||||
from pylspci.fields import NameWithID, PCIAccessParameter, Slot
|
||||
|
||||
|
||||
class TestSlot(TestCase):
|
||||
|
||||
def test_full_slot(self) -> None:
|
||||
s = Slot('cafe:13:07.2')
|
||||
self.assertEqual(s.domain, 0xcafe)
|
||||
self.assertEqual(s.bus, 0x13)
|
||||
self.assertEqual(s.device, 0x07)
|
||||
self.assertEqual(s.function, 0x2)
|
||||
|
||||
def test_optional_domain(self) -> None:
|
||||
"""
|
||||
lspci can hide the domain ID when there is only one domain
|
||||
on the system, numbered 0. Ensure Slot defaults the domain to 0.
|
||||
"""
|
||||
s = Slot('13:07.2')
|
||||
self.assertEqual(s.domain, 0x0)
|
||||
self.assertEqual(s.bus, 0x13)
|
||||
self.assertEqual(s.device, 0x07)
|
||||
self.assertEqual(s.function, 0x2)
|
||||
|
||||
def test_device_limit_32(self) -> None:
|
||||
"""
|
||||
There cannot be more than 32 devices on each bus
|
||||
"""
|
||||
with self.assertRaises(ValueError):
|
||||
Slot('0000:00:20.0')
|
||||
|
||||
def test_function_limit_8(self) -> None:
|
||||
"""
|
||||
Function numbers are from 0 to 7
|
||||
"""
|
||||
with self.assertRaises(ValueError):
|
||||
Slot('0000:00:01.f')
|
||||
|
||||
def test_repr(self) -> None:
|
||||
self.assertEqual(
|
||||
repr(Slot('13:37:04.2')),
|
||||
"Slot('0013:37:04.2')",
|
||||
)
|
||||
|
||||
def test_str(self) -> None:
|
||||
self.assertEqual(
|
||||
str(Slot('13:37:04.2')),
|
||||
'0013:37:04.2',
|
||||
)
|
||||
|
||||
def test_parent(self) -> None:
|
||||
s = Slot('abcd:13:07.2/cafe:c0:0f.3/66:06.6')
|
||||
self.assertEqual(str(s), 'abcd:13:07.2/cafe:c0:0f.3/cafe:66:06.6')
|
||||
self.assertEqual(
|
||||
repr(s),
|
||||
"Slot('abcd:13:07.2/cafe:c0:0f.3/cafe:66:06.6')",
|
||||
)
|
||||
self.assertEqual(s.domain, 0xcafe)
|
||||
self.assertEqual(s.bus, 0x66)
|
||||
self.assertEqual(s.device, 0x06)
|
||||
self.assertEqual(s.function, 0x6)
|
||||
self.assertIsInstance(s.parent, Slot)
|
||||
assert s.parent is not None # Required for type checks
|
||||
self.assertEqual(s.parent.domain, 0xcafe)
|
||||
self.assertEqual(s.parent.bus, 0xc0)
|
||||
self.assertEqual(s.parent.device, 0x0f)
|
||||
self.assertEqual(s.parent.function, 0x3)
|
||||
self.assertIsInstance(s.parent.parent, Slot)
|
||||
assert s.parent.parent is not None # Required for type checks
|
||||
self.assertEqual(s.parent.parent.domain, 0xabcd)
|
||||
self.assertEqual(s.parent.parent.bus, 0x13)
|
||||
self.assertEqual(s.parent.parent.device, 0x07)
|
||||
self.assertEqual(s.parent.parent.function, 0x2)
|
||||
|
||||
def test_as_dict(self) -> None:
|
||||
s = Slot('cafe:13:07.2')
|
||||
self.assertDictEqual(s.as_dict(), {
|
||||
"domain": 0xcafe,
|
||||
"bus": 0x13,
|
||||
"device": 0x07,
|
||||
"function": 0x2,
|
||||
"parent": None,
|
||||
})
|
||||
|
||||
|
||||
class TestNameWithID(TestCase):
|
||||
|
||||
def test_full(self) -> None:
|
||||
n = NameWithID('Something [caf3]')
|
||||
self.assertEqual(n.id, 0xcaf3)
|
||||
self.assertEqual(n.name, 'Something')
|
||||
self.assertEqual(str(n), 'Something [caf3]')
|
||||
self.assertEqual(repr(n), "NameWithID('Something [caf3]')")
|
||||
|
||||
def test_only_id(self) -> None:
|
||||
"""
|
||||
Depending on the lspci arguments, we might only have an hexadecimal ID
|
||||
"""
|
||||
n = NameWithID('caf3')
|
||||
self.assertEqual(n.id, 0xcaf3)
|
||||
self.assertIsNone(n.name)
|
||||
self.assertEqual(str(n), 'caf3')
|
||||
self.assertEqual(repr(n), "NameWithID('caf3')")
|
||||
|
||||
def test_only_name(self) -> None:
|
||||
"""
|
||||
Depending on the lspci arguments, we might only have a name
|
||||
"""
|
||||
n = NameWithID('Something')
|
||||
self.assertIsNone(n.id)
|
||||
self.assertEqual(n.name, 'Something')
|
||||
self.assertEqual(str(n), 'Something')
|
||||
self.assertEqual(repr(n), "NameWithID('Something')")
|
||||
|
||||
def test_double_brackets(self) -> None:
|
||||
"""
|
||||
Some device names have extra info in brackets
|
||||
"""
|
||||
n = NameWithID('Something [with brackets] [caf3]')
|
||||
self.assertEqual(n.id, 0xcaf3)
|
||||
self.assertEqual(n.name, 'Something [with brackets]')
|
||||
self.assertEqual(str(n), 'Something [with brackets] [caf3]')
|
||||
self.assertEqual(
|
||||
repr(n),
|
||||
"NameWithID('Something [with brackets] [caf3]')",
|
||||
)
|
||||
|
||||
def test_none(self) -> None:
|
||||
n = NameWithID(None)
|
||||
self.assertIsNone(n.id)
|
||||
self.assertIsNone(n.name)
|
||||
self.assertEqual(str(n), '')
|
||||
self.assertEqual(repr(n), "NameWithID('')")
|
||||
|
||||
def test_bad_format(self) -> None:
|
||||
n = NameWithID('Something [hexa]')
|
||||
self.assertIsNone(n.id)
|
||||
self.assertEqual(n.name, 'Something [hexa]')
|
||||
|
||||
def test_as_dict(self) -> None:
|
||||
n = NameWithID('Something [caf3]')
|
||||
self.assertDictEqual(n.as_dict(), {
|
||||
"id": 0xcaf3,
|
||||
"name": "Something",
|
||||
})
|
||||
|
||||
|
||||
class TestPCIAccessParameter(TestCase):
|
||||
|
||||
def test_normal(self) -> None:
|
||||
p = PCIAccessParameter('param.name Some description (default value)')
|
||||
self.assertEqual(p.name, 'param.name')
|
||||
self.assertEqual(p.description, 'Some description')
|
||||
self.assertEqual(p.default, 'default value')
|
||||
self.assertEqual(str(p),
|
||||
'param.name\tSome description (default value)')
|
||||
self.assertEqual(repr(p),
|
||||
"PCIAccessParameter('param.name\\tSome description"
|
||||
" (default value)')")
|
||||
|
||||
def test_no_default(self) -> None:
|
||||
p = PCIAccessParameter('param.name Some description ()')
|
||||
self.assertEqual(p.name, 'param.name')
|
||||
self.assertEqual(p.description, 'Some description')
|
||||
self.assertIsNone(p.default)
|
||||
|
||||
def test_bad_format(self) -> None:
|
||||
with self.assertRaises(ValueError):
|
||||
PCIAccessParameter('nope')
|
||||
with self.assertRaises(ValueError):
|
||||
PCIAccessParameter('nope (nope)')
|
||||
|
||||
def test_equal(self) -> None:
|
||||
p1 = PCIAccessParameter('param.name Some description (default value)')
|
||||
p2 = PCIAccessParameter('param.name Some description ()')
|
||||
self.assertEqual(p1, p1)
|
||||
self.assertNotEqual(p1, p2)
|
||||
|
||||
def test_as_dict(self) -> None:
|
||||
p = PCIAccessParameter('param.name Some description (default value)')
|
||||
self.assertDictEqual(p.as_dict(), {
|
||||
"name": "param.name",
|
||||
"description": "Some description",
|
||||
"default": "default value",
|
||||
})
|
|
@ -1,109 +0,0 @@
|
|||
from unittest import TestCase
|
||||
|
||||
from pylspci.filters import DeviceFilter, SlotFilter
|
||||
|
||||
|
||||
class TestSlotFilter(TestCase):
|
||||
|
||||
def test_empty(self) -> None:
|
||||
f = SlotFilter()
|
||||
self.assertIsNone(f.domain)
|
||||
self.assertIsNone(f.bus)
|
||||
self.assertIsNone(f.device)
|
||||
self.assertIsNone(f.function)
|
||||
self.assertEqual(
|
||||
repr(f),
|
||||
'SlotFilter(domain=None, bus=None, device=None, function=None)',
|
||||
)
|
||||
|
||||
def test_str(self) -> None:
|
||||
self.assertEqual(str(SlotFilter()), '::.')
|
||||
self.assertEqual(str(SlotFilter(domain=0xcafe)), 'cafe::.')
|
||||
self.assertEqual(
|
||||
str(SlotFilter(domain=0xc0ff, bus=0xe, device=0xe, function=7)),
|
||||
'c0ff:e:e.7',
|
||||
)
|
||||
|
||||
def test_parse(self) -> None:
|
||||
self.assertEqual(SlotFilter.parse(''), SlotFilter())
|
||||
self.assertEqual(SlotFilter.parse('::.'), SlotFilter())
|
||||
self.assertEqual(SlotFilter.parse('*:*:*.*'), SlotFilter())
|
||||
self.assertEqual(SlotFilter.parse('4'), SlotFilter(device=4))
|
||||
self.assertEqual(SlotFilter.parse('4:'), SlotFilter(bus=4))
|
||||
self.assertEqual(SlotFilter.parse('4::'), SlotFilter(domain=4))
|
||||
self.assertEqual(SlotFilter.parse('.4'), SlotFilter(function=4))
|
||||
self.assertEqual(
|
||||
SlotFilter.parse('c0ff:e:e.7'),
|
||||
SlotFilter(domain=0xc0ff, bus=0xe, device=0xe, function=7),
|
||||
)
|
||||
with self.assertRaises(ValueError):
|
||||
SlotFilter.parse(':::::')
|
||||
with self.assertRaises(ValueError):
|
||||
SlotFilter.parse('g')
|
||||
|
||||
def test_eq(self) -> None:
|
||||
self.assertEqual(
|
||||
SlotFilter(domain=0xc0ff, bus=0xe, device=0xe, function=7),
|
||||
SlotFilter(domain=0xc0ff, bus=0xe, device=0xe, function=7),
|
||||
)
|
||||
self.assertNotEqual(
|
||||
SlotFilter(domain=0xc0ff, bus=0xf, device=0xe, function=7),
|
||||
SlotFilter(domain=0xc0ff, bus=0xe, device=0xe, function=7),
|
||||
)
|
||||
self.assertNotEqual(
|
||||
SlotFilter(domain=0xc0ff, bus=0xf, device=0xe, function=7),
|
||||
'not a filter',
|
||||
)
|
||||
|
||||
|
||||
class TestDeviceFilter(TestCase):
|
||||
|
||||
def test_empty(self) -> None:
|
||||
f = DeviceFilter()
|
||||
self.assertIsNone(f.vendor)
|
||||
self.assertIsNone(f.device)
|
||||
self.assertIsNone(f.cls)
|
||||
self.assertEqual(
|
||||
repr(f),
|
||||
'DeviceFilter(cls=None, vendor=None, device=None)',
|
||||
)
|
||||
|
||||
def test_str(self) -> None:
|
||||
self.assertEqual(str(DeviceFilter()), '::')
|
||||
self.assertEqual(str(DeviceFilter(vendor=0xcafe)), 'cafe::')
|
||||
self.assertEqual(
|
||||
str(DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe)),
|
||||
'c0ff:e:e',
|
||||
)
|
||||
|
||||
def test_parse(self) -> None:
|
||||
self.assertEqual(DeviceFilter.parse(''), DeviceFilter())
|
||||
self.assertEqual(DeviceFilter.parse('::'), DeviceFilter())
|
||||
self.assertEqual(DeviceFilter.parse('*:*:*'), DeviceFilter())
|
||||
self.assertEqual(DeviceFilter.parse('4:'), DeviceFilter(vendor=4))
|
||||
self.assertEqual(DeviceFilter.parse(':4'), DeviceFilter(device=4))
|
||||
self.assertEqual(DeviceFilter.parse('::4'), DeviceFilter(cls=4))
|
||||
self.assertEqual(
|
||||
DeviceFilter.parse('c0ff:e:e'),
|
||||
DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe),
|
||||
)
|
||||
with self.assertRaises(ValueError):
|
||||
DeviceFilter.parse(':::::')
|
||||
with self.assertRaises(ValueError):
|
||||
DeviceFilter.parse('4')
|
||||
with self.assertRaises(ValueError):
|
||||
DeviceFilter.parse('g')
|
||||
|
||||
def test_eq(self) -> None:
|
||||
self.assertEqual(
|
||||
DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe),
|
||||
DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe),
|
||||
)
|
||||
self.assertNotEqual(
|
||||
DeviceFilter(vendor=0xc0ff, device=0xf, cls=0xe),
|
||||
DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe),
|
||||
)
|
||||
self.assertNotEqual(
|
||||
DeviceFilter(vendor=0xc0ff, device=0xe, cls=0xe),
|
||||
'not a filter',
|
||||
)
|
|
@ -1,4 +0,0 @@
|
|||
doc8>=0.8.0
|
||||
Sphinx>=1.8.1
|
||||
coverage>=4.5
|
||||
pre-commit>=2.9.2
|
|
@ -1 +0,0 @@
|
|||
cached-property>=1.5.1
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Search — pylspci 0.4.3 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||
|
||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||
<script src="_static/jquery.js"></script>
|
||||
<script src="_static/underscore.js"></script>
|
||||
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="_static/doctools.js"></script>
|
||||
<script src="_static/searchtools.js"></script>
|
||||
<script src="_static/language_data.js"></script>
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="#" />
|
||||
<script src="searchindex.js" defer></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
|
||||
</head><body>
|
||||
<div class="document">
|
||||
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="index.html">pylspci</a></h1>
|
||||
|
||||
|
||||
|
||||
<p class="blurb">Python lspci parser</p>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command-line interface</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="data.html">Parsed data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Command API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="low.html">Low-level classes</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="index.html">Documentation overview</a><ul>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1 id="search-documentation">Search</h1>
|
||||
|
||||
<noscript>
|
||||
<div class="admonition warning">
|
||||
<p>
|
||||
Please activate JavaScript to enable the search
|
||||
functionality.
|
||||
</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
|
||||
<p>
|
||||
Searching for multiple words only shows matches that contain
|
||||
all words.
|
||||
</p>
|
||||
|
||||
|
||||
<form action="" method="get">
|
||||
<input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="search" />
|
||||
<span id="search-progress" style="padding-left: 10px"></span>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<div id="search-results">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2022, Lucidiot and contributors.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 5.1.1</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
15
setup.cfg
15
setup.cfg
|
@ -1,15 +0,0 @@
|
|||
[flake8]
|
||||
exclude=.git,__pycache__,docs,*.pyc,venv
|
||||
|
||||
[doc8]
|
||||
ignore-path=**/*.txt,*.txt,*.egg-info,docs/_build,venv,.git
|
||||
|
||||
[mypy]
|
||||
ignore_missing_imports=True
|
||||
disallow_incomplete_defs=True
|
||||
disallow_untyped_defs=True
|
||||
check_untyped_defs=True
|
||||
no_implicit_optional=True
|
||||
|
||||
[isort]
|
||||
multi_line_output=5
|
70
setup.py
70
setup.py
|
@ -1,70 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
from typing import List
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
|
||||
def read_requirements(filename: str) -> List[str]:
|
||||
return [req.strip() for req in open(filename)]
|
||||
|
||||
|
||||
requirements = read_requirements('requirements.txt')
|
||||
dev_requirements = read_requirements('requirements-dev.txt')
|
||||
|
||||
setup(
|
||||
name='pylspci',
|
||||
version=open('VERSION').read().strip(),
|
||||
author='Lucidiot',
|
||||
packages=find_packages(
|
||||
exclude=["*.tests", "*.tests.*", "tests.*", "tests"],
|
||||
),
|
||||
entry_points={
|
||||
'console_scripts': ['pylspci=pylspci.__main__:main'],
|
||||
},
|
||||
package_data={
|
||||
'': [
|
||||
'VERSION',
|
||||
'LICENSE',
|
||||
'README.rst',
|
||||
'requirements.txt',
|
||||
'requirements-dev.txt',
|
||||
],
|
||||
'pylspci': ['py.typed'],
|
||||
},
|
||||
python_requires='>=3.6',
|
||||
install_requires=requirements,
|
||||
extras_require={
|
||||
'dev': dev_requirements,
|
||||
},
|
||||
test_suite='pylspci.tests',
|
||||
license='GNU General Public License 3',
|
||||
description="Simple parser for lspci -mmnn.",
|
||||
long_description=open('README.rst').read(),
|
||||
long_description_content_type='text/x-rst',
|
||||
keywords="lspci parser",
|
||||
url="https://tildegit.org/lucidiot/pylspci",
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
"Natural Language :: English",
|
||||
"Intended Audience :: Developers",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Topic :: Software Development :: Libraries",
|
||||
"Topic :: System :: Hardware",
|
||||
"Topic :: Utilities",
|
||||
"Typing :: Typed",
|
||||
],
|
||||
project_urls={
|
||||
"Homepage": "https://tildegit.org/lucidiot/pylspci",
|
||||
"Changelog": "https://tildegit.org/lucidiot/pylspci/releases",
|
||||
"Documentation": "https://lucidiot.tildepages.org/pylspci/",
|
||||
"Issue tracker": "https://tildegit.org/lucidiot/pylspci/issues",
|
||||
}
|
||||
)
|
Loading…
Reference in New Issue