Initial Python 3.7 drop
This commit is contained in:
parent
b9855b9104
commit
93c7fdd60c
2
.flake8
2
.flake8
|
|
@ -58,7 +58,7 @@ ignore =
|
||||||
PT004,
|
PT004,
|
||||||
PT011,
|
PT011,
|
||||||
PT012
|
PT012
|
||||||
min-version = 3.7.0
|
min-version = 3.8.0
|
||||||
max-complexity = 12
|
max-complexity = 12
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
qutebrowser/api/hook.py : N801
|
qutebrowser/api/hook.py : N801
|
||||||
|
|
|
||||||
|
|
@ -128,10 +128,10 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
### PyQt 5.15.2 (Python 3.7)
|
### PyQt 5.15.2 (Python 3.8)
|
||||||
- testenv: py37-pyqt5152
|
- testenv: py37-pyqt5152
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
python: "3.7"
|
python: "3.8"
|
||||||
### PyQt 5.15 (Python 3.10, with coverage)
|
### PyQt 5.15 (Python 3.10, with coverage)
|
||||||
# FIXME:qt6
|
# FIXME:qt6
|
||||||
# - testenv: py310-pyqt515-cov
|
# - testenv: py310-pyqt515-cov
|
||||||
|
|
@ -141,10 +141,10 @@ jobs:
|
||||||
- testenv: py311-pyqt515
|
- testenv: py311-pyqt515
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
python: "3.11"
|
python: "3.11"
|
||||||
### PyQt 6.2 (Python 3.7)
|
### PyQt 6.2 (Python 3.8)
|
||||||
- testenv: py37-pyqt62
|
- testenv: py37-pyqt62
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
python: "3.7"
|
python: "3.8"
|
||||||
### PyQt 6.3 (Python 3.8)
|
### PyQt 6.3 (Python 3.8)
|
||||||
- testenv: py38-pyqt63
|
- testenv: py38-pyqt63
|
||||||
os: ubuntu-20.04
|
os: ubuntu-20.04
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Set up Python 3.7
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: '3.7'
|
|
||||||
- name: Set up Python 3.8
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[mypy]
|
[mypy]
|
||||||
python_version = 3.7
|
python_version = 3.8
|
||||||
|
|
||||||
### --strict
|
### --strict
|
||||||
warn_unused_configs = True
|
warn_unused_configs = True
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ load-plugins=qute_pylint.config,
|
||||||
pylint.extensions.dunder
|
pylint.extensions.dunder
|
||||||
|
|
||||||
persistent=n
|
persistent=n
|
||||||
py-version=3.7
|
py-version=3.8
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
enable=all
|
enable=all
|
||||||
|
|
@ -52,6 +52,7 @@ disable=locally-disabled,
|
||||||
too-few-public-methods,
|
too-few-public-methods,
|
||||||
import-outside-toplevel,
|
import-outside-toplevel,
|
||||||
consider-using-f-string,
|
consider-using-f-string,
|
||||||
|
consider-using-assignment-expr,
|
||||||
logging-fstring-interpolation,
|
logging-fstring-interpolation,
|
||||||
raise-missing-from,
|
raise-missing-from,
|
||||||
consider-using-tuple,
|
consider-using-tuple,
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ Requirements
|
||||||
|
|
||||||
The following software and libraries are required to run qutebrowser:
|
The following software and libraries are required to run qutebrowser:
|
||||||
|
|
||||||
* https://www.python.org/[Python] 3.7 or newer
|
* https://www.python.org/[Python] 3.8 or newer
|
||||||
* https://www.qt.io/[Qt], either 6.2.0 or newer, or 5.15.0 or newer, with the following modules:
|
* https://www.qt.io/[Qt], either 6.2.0 or newer, or 5.15.0 or newer, with the following modules:
|
||||||
- QtCore / qtbase
|
- QtCore / qtbase
|
||||||
- QtQuick (part of qtbase or qtdeclarative in some distributions)
|
- QtQuick (part of qtbase or qtdeclarative in some distributions)
|
||||||
|
|
@ -103,7 +103,7 @@ websites and using it for transmission of sensitive data._
|
||||||
* https://palletsprojects.com/p/jinja/[jinja2]
|
* https://palletsprojects.com/p/jinja/[jinja2]
|
||||||
* https://github.com/yaml/pyyaml[PyYAML]
|
* https://github.com/yaml/pyyaml[PyYAML]
|
||||||
|
|
||||||
On older Python versions (3.7/3.8), the following backports are also required:
|
On Python 3.8, the following backport is also required:
|
||||||
|
|
||||||
* https://importlib-resources.readthedocs.io/[importlib_resources]
|
* https://importlib-resources.readthedocs.io/[importlib_resources]
|
||||||
|
|
||||||
|
|
@ -119,10 +119,6 @@ The following libraries are optional:
|
||||||
QtWebEngine backend.
|
QtWebEngine backend.
|
||||||
* On Windows, https://pypi.python.org/pypi/colorama/[colorama] for colored log
|
* On Windows, https://pypi.python.org/pypi/colorama/[colorama] for colored log
|
||||||
output.
|
output.
|
||||||
* https://importlib-metadata.readthedocs.io/[importlib_metadata] on Python 3.7,
|
|
||||||
to improve QtWebEngine version detection when PyQtWebEngine is
|
|
||||||
installed via pip (thus, this dependency usually isn't relevant for
|
|
||||||
packagers).
|
|
||||||
* https://asciidoc.org/[asciidoc] to generate the documentation for the `:help`
|
* https://asciidoc.org/[asciidoc] to generate the documentation for the `:help`
|
||||||
command, when using the git repository (rather than a release).
|
command, when using the git repository (rather than a release).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,9 @@ Added
|
||||||
Removed
|
Removed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
- Support for Python 3.6 is dropped, as it's been
|
- Python 3.8.0 or newer is now required.
|
||||||
https://discuss.python.org/t/python-3-6-rides-into-the-sunset/12964[end-of-life upstream]
|
- Support for Python 3.6 and 3.7 is dropped, as they both reached
|
||||||
since December 2021. Python 3.7.0 or newer is now required.
|
their [end of life] in December 2021 and June 2023, respectively.
|
||||||
- Support for Qt/PyQt before 5.15.0 and QtWebEngine before 5.15.2 are now
|
- Support for Qt/PyQt before 5.15.0 and QtWebEngine before 5.15.2 are now
|
||||||
dropped, as older Qt versions are
|
dropped, as older Qt versions are
|
||||||
https://endoflife.date/qt[end-of-life upstream] since mid/late 2020
|
https://endoflife.date/qt[end-of-life upstream] since mid/late 2020
|
||||||
|
|
|
||||||
|
|
@ -111,9 +111,9 @@ unittests and several linters/checkers.
|
||||||
Currently, the following tox environments are available:
|
Currently, the following tox environments are available:
|
||||||
|
|
||||||
* Tests using https://www.pytest.org[pytest]:
|
* Tests using https://www.pytest.org[pytest]:
|
||||||
- `py37`, `py38`, ...: Run pytest for python 3.7/3.8/... with the system-wide PyQt.
|
- `py38`, `py39`, ...: Run pytest for python 3.8/3.9/... with the system-wide PyQt.
|
||||||
- `py37-pyqt512`, ..., `py37-pyqt515`: Run pytest with the given PyQt version (`py37-*` also works).
|
- `py38-pyqt515`, ..., `py38-pyqt65`: Run pytest with the given PyQt version (`py39-*` etc. also works).
|
||||||
- `py37-pyqt515-cov`: Run with coverage support (other Python/PyQt versions work too).
|
- `py38-pyqt515-cov`: Run with coverage support (other Python/PyQt versions work too).
|
||||||
* `flake8`: Run various linting checks via https://pypi.python.org/pypi/flake8[flake8].
|
* `flake8`: Run various linting checks via https://pypi.python.org/pypi/flake8[flake8].
|
||||||
* `vulture`: Run https://pypi.python.org/pypi/vulture[vulture] to find
|
* `vulture`: Run https://pypi.python.org/pypi/vulture[vulture] to find
|
||||||
unused code portions.
|
unused code portions.
|
||||||
|
|
@ -171,16 +171,16 @@ Examples:
|
||||||
|
|
||||||
----
|
----
|
||||||
# run only pytest tests which failed in last run:
|
# run only pytest tests which failed in last run:
|
||||||
tox -e py37 -- --lf
|
tox -e py38 -- --lf
|
||||||
|
|
||||||
# run only the end2end feature tests:
|
# run only the end2end feature tests:
|
||||||
tox -e py37 -- tests/end2end/features
|
tox -e py38 -- tests/end2end/features
|
||||||
|
|
||||||
# run everything with undo in the generated name, based on the scenario text
|
# run everything with undo in the generated name, based on the scenario text
|
||||||
tox -e py37 -- tests/end2end/features/test_tabs_bdd.py -k undo
|
tox -e py38 -- tests/end2end/features/test_tabs_bdd.py -k undo
|
||||||
|
|
||||||
# run coverage test for specific file (updates htmlcov/index.html)
|
# run coverage test for specific file (updates htmlcov/index.html)
|
||||||
tox -e py37-cov -- tests/unit/browser/test_webelem.py
|
tox -e py38-cov -- tests/unit/browser/test_webelem.py
|
||||||
----
|
----
|
||||||
|
|
||||||
Specifying the backend for tests
|
Specifying the backend for tests
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ version (Qt 5.7, based on a Chromium from March 2016). Furthermore, it packages
|
||||||
Ubuntu 16.04 doesn't come with an up-to-date engine (a new enough QtWebKit, or
|
Ubuntu 16.04 doesn't come with an up-to-date engine (a new enough QtWebKit, or
|
||||||
QtWebEngine) and also comes with Python 3.5.
|
QtWebEngine) and also comes with Python 3.5.
|
||||||
|
|
||||||
You should be able to install a newer Python (3.7+) using the
|
You should be able to install a newer Python (3.8+) using the
|
||||||
https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa[deadsnakes PPA] or
|
https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa[deadsnakes PPA] or
|
||||||
https://github.com/pyenv/pyenv[pyenv], and then proceed to
|
https://github.com/pyenv/pyenv[pyenv], and then proceed to
|
||||||
<<tox,install qutebrowser in a virtualenv>>. However, this is currently untested. If you
|
<<tox,install qutebrowser in a virtualenv>>. However, this is currently untested. If you
|
||||||
|
|
@ -452,7 +452,7 @@ This installs all needed Python dependencies in a `.venv` subfolder
|
||||||
This comes with an up-to-date Qt/PyQt including a pre-compiled QtWebEngine
|
This comes with an up-to-date Qt/PyQt including a pre-compiled QtWebEngine
|
||||||
binary, but has a few caveats:
|
binary, but has a few caveats:
|
||||||
|
|
||||||
- Make sure your `python3` is Python 3.7 or newer, otherwise you'll get a "No
|
- Make sure your `python3` is Python 3.8 or newer, otherwise you'll get a "No
|
||||||
matching distribution found" error and/or qutebrowser will not run.
|
matching distribution found" error and/or qutebrowser will not run.
|
||||||
- It only works on 64-bit x86 systems, with other architectures you'll get the
|
- It only works on 64-bit x86 systems, with other architectures you'll get the
|
||||||
same error.
|
same error.
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,3 @@ types-PyYAML
|
||||||
|
|
||||||
# So stubs are available even on newer Python versions
|
# So stubs are available even on newer Python versions
|
||||||
importlib_resources
|
importlib_resources
|
||||||
importlib_metadata
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ cryptography==41.0.1
|
||||||
dill==0.3.6
|
dill==0.3.6
|
||||||
github3.py==4.0.1
|
github3.py==4.0.1
|
||||||
idna==3.4
|
idna==3.4
|
||||||
isort==5.11.5
|
isort==5.12.0
|
||||||
lazy-object-proxy==1.9.0
|
lazy-object-proxy==1.9.0
|
||||||
mccabe==0.7.0
|
mccabe==0.7.0
|
||||||
pefile==2023.2.7
|
pefile==2023.2.7
|
||||||
|
|
@ -20,10 +20,7 @@ python-dateutil==2.8.2
|
||||||
./scripts/dev/pylint_checkers
|
./scripts/dev/pylint_checkers
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
tomli==2.0.1
|
|
||||||
tomlkit==0.11.8
|
tomlkit==0.11.8
|
||||||
typed-ast==1.5.4 ; python_version<"3.8"
|
|
||||||
typing_extensions==4.6.3
|
|
||||||
uritemplate==4.1.1
|
uritemplate==4.1.1
|
||||||
# urllib3==2.0.3
|
# urllib3==2.0.3
|
||||||
wrapt==1.15.0
|
wrapt==1.15.0
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,4 @@ Pygments # For :view-source --pygments or on QtWebKit
|
||||||
colorama # Colored log output on Windows
|
colorama # Colored log output on Windows
|
||||||
adblock # Improved adblocking
|
adblock # Improved adblocking
|
||||||
|
|
||||||
# Optional, only relevant when installing PyQt5/PyQtWebEngine via pip.
|
#@ markers: importlib-resources python_version=="3.8.*"
|
||||||
importlib-metadata # Determining PyQt version
|
|
||||||
typing_extensions # from importlib-metadata
|
|
||||||
|
|
||||||
#@ markers: importlib-resources python_version=="3.7.*" or python_version=="3.8.*"
|
|
||||||
#@ markers: importlib-metadata python_version=="3.7.*"
|
|
||||||
#@ markers: typing_extensions python_version<"3.8"
|
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,15 @@ charset-normalizer==3.1.0
|
||||||
cheroot==10.0.0
|
cheroot==10.0.0
|
||||||
click==8.1.3
|
click==8.1.3
|
||||||
coverage==7.2.7
|
coverage==7.2.7
|
||||||
exceptiongroup==1.1.1
|
|
||||||
execnet==1.9.0
|
execnet==1.9.0
|
||||||
filelock==3.12.2
|
filelock==3.12.2
|
||||||
Flask==2.3.2 ; python_version>="3.8"
|
Flask==2.3.2
|
||||||
hunter==3.6.1
|
hunter==3.6.1
|
||||||
hypothesis==6.79.3
|
hypothesis==6.79.3
|
||||||
idna==3.4
|
idna==3.4
|
||||||
importlib-metadata==6.7.0
|
|
||||||
iniconfig==2.0.0
|
iniconfig==2.0.0
|
||||||
itsdangerous==2.1.2
|
itsdangerous==2.1.2
|
||||||
jaraco.functools==3.8.0 ; python_version>="3.8"
|
jaraco.functools==3.8.0
|
||||||
# Jinja2==3.1.2
|
# Jinja2==3.1.2
|
||||||
Mako==1.2.4
|
Mako==1.2.4
|
||||||
manhole==1.8.0
|
manhole==1.8.0
|
||||||
|
|
@ -49,12 +47,7 @@ sortedcontainers==2.4.0
|
||||||
soupsieve==2.4.1
|
soupsieve==2.4.1
|
||||||
tldextract==3.4.4
|
tldextract==3.4.4
|
||||||
toml==0.10.2
|
toml==0.10.2
|
||||||
tomli==2.0.1
|
|
||||||
typing_extensions==4.6.3
|
typing_extensions==4.6.3
|
||||||
urllib3==2.0.3
|
urllib3==2.0.3
|
||||||
vulture==2.7
|
vulture==2.7
|
||||||
Werkzeug==2.3.6 ; python_version>="3.8"
|
Werkzeug==2.3.6
|
||||||
zipp==3.15.0
|
|
||||||
Flask==2.2.5 ; python_version=="3.7.*"
|
|
||||||
Werkzeug==2.2.3 ; python_version=="3.7.*"
|
|
||||||
jaraco.functools<3.8.0 ; python_version=="3.7.*"
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,3 @@ pytest-xdist
|
||||||
tldextract
|
tldextract
|
||||||
|
|
||||||
#@ ignore: Jinja2, MarkupSafe, colorama
|
#@ ignore: Jinja2, MarkupSafe, colorama
|
||||||
# Python 3.7
|
|
||||||
#@ markers: Flask python_version>="3.8"
|
|
||||||
#@ add: Flask==2.2.5 ; python_version=="3.7.*"
|
|
||||||
#@ markers: Werkzeug python_version>="3.8"
|
|
||||||
#@ add: Werkzeug==2.2.3 ; python_version=="3.7.*"
|
|
||||||
#@ markers: jaraco.functools python_version>="3.8"
|
|
||||||
#@ add: jaraco.functools<3.8.0 ; python_version=="3.7.*"
|
|
||||||
|
|
|
||||||
|
|
@ -403,21 +403,12 @@ class Command:
|
||||||
raise TypeError("{}: Legacy tuple type annotation!".format(
|
raise TypeError("{}: Legacy tuple type annotation!".format(
|
||||||
self.name))
|
self.name))
|
||||||
|
|
||||||
try:
|
origin = typing.get_origin(typ)
|
||||||
origin = typing.get_origin(typ) # type: ignore[attr-defined]
|
|
||||||
except AttributeError:
|
|
||||||
# typing.get_origin was added in Python 3.8
|
|
||||||
origin = getattr(typ, '__origin__', None)
|
|
||||||
|
|
||||||
if origin is Union:
|
if origin is Union:
|
||||||
try:
|
types = list(typing.get_args(typ))
|
||||||
types = list(typing.get_args(typ)) # type: ignore[attr-defined]
|
|
||||||
except AttributeError:
|
|
||||||
# typing.get_args was added in Python 3.8
|
|
||||||
types = list(typ.__args__)
|
|
||||||
|
|
||||||
if param.default is not inspect.Parameter.empty:
|
if param.default is not inspect.Parameter.empty:
|
||||||
types.append(type(param.default))
|
types.append(type(param.default))
|
||||||
|
|
||||||
choices = self.get_arg_info(param).choices
|
choices = self.get_arg_info(param).choices
|
||||||
value = argparser.multitype_conv(param, types, value,
|
value = argparser.multitype_conv(param, types, value,
|
||||||
str_choices=choices)
|
str_choices=choices)
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ except ImportError: # pragma: no cover
|
||||||
# to stderr.
|
# to stderr.
|
||||||
def check_python_version():
|
def check_python_version():
|
||||||
"""Check if correct python version is run."""
|
"""Check if correct python version is run."""
|
||||||
if sys.hexversion < 0x03070000:
|
if sys.hexversion < 0x03080000:
|
||||||
# We don't use .format() and print_function here just in case someone
|
# We don't use .format() and print_function here just in case someone
|
||||||
# still has < 2.6 installed.
|
# still has < 2.6 installed.
|
||||||
version_str = '.'.join(map(str, sys.version_info[:3]))
|
version_str = '.'.join(map(str, sys.version_info[:3]))
|
||||||
text = ("At least Python 3.7 is required to run qutebrowser, but " +
|
text = ("At least Python 3.8 is required to run qutebrowser, but " +
|
||||||
"it's running with " + version_str + ".\n")
|
"it's running with " + version_str + ".\n")
|
||||||
|
|
||||||
show_errors = '--no-err-windows' not in sys.argv
|
show_errors = '--no-err-windows' not in sys.argv
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
"""Things which need to be done really early (e.g. before importing Qt).
|
"""Things which need to be done really early (e.g. before importing Qt).
|
||||||
|
|
||||||
At this point we can be sure we have all python 3.7 features available.
|
At this point we can be sure we have all python 3.8 features available.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import pathlib
|
||||||
from typing import Iterator, Iterable, Union
|
from typing import Iterator, Iterable, Union
|
||||||
|
|
||||||
|
|
||||||
# We cannot use the stdlib version on 3.7-3.8 because we need the files() API.
|
# We cannot use the stdlib version on 3.8 because we need the files() API.
|
||||||
if sys.version_info >= (3, 11): # pragma: no cover
|
if sys.version_info >= (3, 11): # pragma: no cover
|
||||||
# https://github.com/python/cpython/issues/90276
|
# https://github.com/python/cpython/issues/90276
|
||||||
import importlib.resources as importlib_resources
|
import importlib.resources as importlib_resources
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ import datetime
|
||||||
import getpass
|
import getpass
|
||||||
import functools
|
import functools
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import importlib.metadata
|
||||||
from typing import (Mapping, Optional, Sequence, Tuple, ClassVar, Dict, cast,
|
from typing import (Mapping, Optional, Sequence, Tuple, ClassVar, Dict, cast,
|
||||||
TYPE_CHECKING)
|
TYPE_CHECKING)
|
||||||
|
|
||||||
|
|
@ -520,19 +521,9 @@ def _get_pyqt_webengine_qt_version() -> Optional[str]:
|
||||||
PyQtWebEngine 5.15.4 renamed it to PyQtWebEngine-Qt5...:
|
PyQtWebEngine 5.15.4 renamed it to PyQtWebEngine-Qt5...:
|
||||||
https://www.riverbankcomputing.com/pipermail/pyqt/2021-March/043699.html
|
https://www.riverbankcomputing.com/pipermail/pyqt/2021-March/043699.html
|
||||||
|
|
||||||
Here, we try to use importlib.metadata or its backport (optional dependency) to
|
Here, we try to use importlib.metadata to figure out that version number.
|
||||||
figure out that version number. If PyQtWebEngine is installed via pip, this will
|
If PyQtWebEngine is installed via pip, this will give us an accurate answer.
|
||||||
give us an accurate answer.
|
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
import importlib.metadata as importlib_metadata # type: ignore[import]
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
import importlib_metadata
|
|
||||||
except ImportError:
|
|
||||||
log.misc.debug("Neither importlib.metadata nor backport available")
|
|
||||||
return None
|
|
||||||
|
|
||||||
names = (
|
names = (
|
||||||
['PyQt6-WebEngine-Qt6']
|
['PyQt6-WebEngine-Qt6']
|
||||||
if machinery.IS_QT6 else
|
if machinery.IS_QT6 else
|
||||||
|
|
@ -541,8 +532,8 @@ def _get_pyqt_webengine_qt_version() -> Optional[str]:
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
try:
|
try:
|
||||||
return importlib_metadata.version(name)
|
return importlib.metadata.version(name)
|
||||||
except importlib_metadata.PackageNotFoundError:
|
except importlib.metadata.PackageNotFoundError:
|
||||||
log.misc.debug(f"{name} not found")
|
log.misc.debug(f"{name} not found")
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,11 @@
|
||||||
|
|
||||||
adblock==0.6.0
|
adblock==0.6.0
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
importlib-metadata==6.7.0 ; python_version=="3.7.*"
|
importlib-resources==5.12.0 ; python_version=="3.8.*"
|
||||||
importlib-resources==5.12.0 ; python_version=="3.7.*" or python_version=="3.8.*"
|
|
||||||
Jinja2==3.1.2
|
Jinja2==3.1.2
|
||||||
MarkupSafe==2.1.3
|
MarkupSafe==2.1.3
|
||||||
Pygments==2.15.1
|
Pygments==2.15.1
|
||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
typing_extensions==4.6.3 ; python_version<"3.8"
|
|
||||||
zipp==3.15.0
|
|
||||||
# Unpinned due to recompile_requirements.py limitations
|
# Unpinned due to recompile_requirements.py limitations
|
||||||
pyobjc-core ; sys_platform=="darwin"
|
pyobjc-core ; sys_platform=="darwin"
|
||||||
pyobjc-framework-Cocoa ; sys_platform=="darwin"
|
pyobjc-framework-Cocoa ; sys_platform=="darwin"
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
"Flask": "https://flask.palletsprojects.com/en/latest/changes/",
|
"Flask": "https://flask.palletsprojects.com/en/latest/changes/",
|
||||||
"Mako": "https://docs.makotemplates.org/en/latest/changelog.html",
|
"Mako": "https://docs.makotemplates.org/en/latest/changelog.html",
|
||||||
"hypothesis": "https://hypothesis.readthedocs.io/en/latest/changes.html",
|
"hypothesis": "https://hypothesis.readthedocs.io/en/latest/changes.html",
|
||||||
"exceptiongroup": "https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst",
|
|
||||||
"mypy": "https://mypy-lang.blogspot.com/",
|
"mypy": "https://mypy-lang.blogspot.com/",
|
||||||
"types-PyYAML": "https://github.com/python/typeshed/commits/main/stubs/PyYAML",
|
"types-PyYAML": "https://github.com/python/typeshed/commits/main/stubs/PyYAML",
|
||||||
"pytest": "https://docs.pytest.org/en/latest/changelog.html",
|
"pytest": "https://docs.pytest.org/en/latest/changelog.html",
|
||||||
|
|
@ -84,7 +83,6 @@
|
||||||
"pyinstaller": "https://pyinstaller.readthedocs.io/en/stable/CHANGES.html",
|
"pyinstaller": "https://pyinstaller.readthedocs.io/en/stable/CHANGES.html",
|
||||||
"pyinstaller-hooks-contrib": "https://github.com/pyinstaller/pyinstaller-hooks-contrib/blob/master/CHANGELOG.rst",
|
"pyinstaller-hooks-contrib": "https://github.com/pyinstaller/pyinstaller-hooks-contrib/blob/master/CHANGELOG.rst",
|
||||||
"pytest-benchmark": "https://pytest-benchmark.readthedocs.io/en/stable/changelog.html",
|
"pytest-benchmark": "https://pytest-benchmark.readthedocs.io/en/stable/changelog.html",
|
||||||
"typed-ast": "https://github.com/python/typed_ast/commits/master",
|
|
||||||
"docutils": "https://docutils.sourceforge.io/RELEASE-NOTES.html",
|
"docutils": "https://docutils.sourceforge.io/RELEASE-NOTES.html",
|
||||||
"bump2version": "https://github.com/c4urself/bump2version/blob/master/CHANGELOG.md",
|
"bump2version": "https://github.com/c4urself/bump2version/blob/master/CHANGELOG.md",
|
||||||
"six": "https://github.com/benjaminp/six/blob/master/CHANGES",
|
"six": "https://github.com/benjaminp/six/blob/master/CHANGES",
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,11 @@ def run_pip(venv_dir, *args, quiet=False, **kwargs):
|
||||||
return subprocess.run([venv_python, '-m', 'pip'] + args, check=True, **kwargs)
|
return subprocess.run([venv_python, '-m', 'pip'] + args, check=True, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def init_venv(host_python, venv_dir, requirements, pre=False, pip_args=None):
|
def init_venv(venv_dir, requirements, pre=False, pip_args=None):
|
||||||
"""Initialize a new virtualenv and install the given packages."""
|
"""Initialize a new virtualenv and install the given packages."""
|
||||||
with utils.gha_group('Creating virtualenv'):
|
with utils.gha_group('Creating virtualenv'):
|
||||||
utils.print_col('$ python3 -m venv {}'.format(venv_dir), 'blue')
|
utils.print_col('$ python3 -m venv {}'.format(venv_dir), 'blue')
|
||||||
subprocess.run([host_python, '-m', 'venv', venv_dir], check=True)
|
subprocess.run([sys.executable, '-m', 'venv', venv_dir], check=True)
|
||||||
|
|
||||||
run_pip(venv_dir, 'install', '-U', 'pip', quiet=not utils.ON_CI)
|
run_pip(venv_dir, 'install', '-U', 'pip', quiet=not utils.ON_CI)
|
||||||
run_pip(venv_dir, 'install', '-U', 'setuptools', 'wheel', quiet=not utils.ON_CI)
|
run_pip(venv_dir, 'install', '-U', 'setuptools', 'wheel', quiet=not utils.ON_CI)
|
||||||
|
|
@ -347,17 +347,6 @@ def print_changed_files():
|
||||||
print('::set-output name=diff::' + diff_table)
|
print('::set-output name=diff::' + diff_table)
|
||||||
|
|
||||||
|
|
||||||
def get_host_python(name):
|
|
||||||
"""Get the Python to use for a given requirement name.
|
|
||||||
|
|
||||||
pylint installs typed_ast on < 3.8 only
|
|
||||||
"""
|
|
||||||
if name == 'pylint':
|
|
||||||
return 'python3.7'
|
|
||||||
else:
|
|
||||||
return sys.executable
|
|
||||||
|
|
||||||
|
|
||||||
def get_venv_python(venv_dir):
|
def get_venv_python(venv_dir):
|
||||||
"""Get the path to Python inside a virtualenv."""
|
"""Get the path to Python inside a virtualenv."""
|
||||||
subdir = 'Scripts' if os.name == 'nt' else 'bin'
|
subdir = 'Scripts' if os.name == 'nt' else 'bin'
|
||||||
|
|
@ -375,14 +364,12 @@ def build_requirements(name):
|
||||||
"""Build a requirements file."""
|
"""Build a requirements file."""
|
||||||
utils.print_subtitle("Building")
|
utils.print_subtitle("Building")
|
||||||
filename = os.path.join(REQ_DIR, 'requirements-{}.txt-raw'.format(name))
|
filename = os.path.join(REQ_DIR, 'requirements-{}.txt-raw'.format(name))
|
||||||
host_python = get_host_python(name)
|
|
||||||
|
|
||||||
with open(filename, 'r', encoding='utf-8') as f:
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
comments = read_comments(f)
|
comments = read_comments(f)
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
init_venv(host_python=host_python,
|
init_venv(venv_dir=tmpdir,
|
||||||
venv_dir=tmpdir,
|
|
||||||
requirements=filename,
|
requirements=filename,
|
||||||
pre=comments['pre'],
|
pre=comments['pre'],
|
||||||
pip_args=comments['pip_args'])
|
pip_args=comments['pip_args'])
|
||||||
|
|
@ -411,14 +398,13 @@ def build_requirements(name):
|
||||||
|
|
||||||
def test_tox():
|
def test_tox():
|
||||||
"""Test requirements via tox."""
|
"""Test requirements via tox."""
|
||||||
host_python = get_host_python('tox')
|
|
||||||
req_path = os.path.join(REQ_DIR, 'requirements-tox.txt')
|
req_path = os.path.join(REQ_DIR, 'requirements-tox.txt')
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
venv_dir = os.path.join(tmpdir, 'venv')
|
venv_dir = os.path.join(tmpdir, 'venv')
|
||||||
tox_workdir = os.path.join(tmpdir, 'tox-workdir')
|
tox_workdir = os.path.join(tmpdir, 'tox-workdir')
|
||||||
venv_python = get_venv_python(venv_dir)
|
venv_python = get_venv_python(venv_dir)
|
||||||
init_venv(host_python, venv_dir, req_path)
|
init_venv(venv_dir, req_path)
|
||||||
list_proc = subprocess.run([venv_python, '-m', 'tox', '--listenvs'],
|
list_proc = subprocess.run([venv_python, '-m', 'tox', '--listenvs'],
|
||||||
check=True,
|
check=True,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
|
@ -448,9 +434,8 @@ def test_requirements(name, outfile, *, force=False):
|
||||||
with open(in_file, 'r', encoding='utf-8') as f:
|
with open(in_file, 'r', encoding='utf-8') as f:
|
||||||
comments = read_comments(f)
|
comments = read_comments(f)
|
||||||
|
|
||||||
host_python = get_host_python(name)
|
|
||||||
with tempfile.TemporaryDirectory() as tmpdir:
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
init_venv(host_python, tmpdir, outfile, pip_args=comments['pip_args'])
|
init_venv(tmpdir, outfile, pip_args=comments['pip_args'])
|
||||||
|
|
||||||
|
|
||||||
def cleanup_pylint_build():
|
def cleanup_pylint_build():
|
||||||
|
|
|
||||||
5
setup.py
5
setup.py
|
|
@ -73,7 +73,7 @@ try:
|
||||||
zip_safe=True,
|
zip_safe=True,
|
||||||
install_requires=['jinja2', 'PyYAML',
|
install_requires=['jinja2', 'PyYAML',
|
||||||
'importlib_resources>=1.1.0; python_version < "3.9"'],
|
'importlib_resources>=1.1.0; python_version < "3.9"'],
|
||||||
python_requires='>=3.7',
|
python_requires='>=3.8',
|
||||||
name='qutebrowser',
|
name='qutebrowser',
|
||||||
version=_get_constant('version'),
|
version=_get_constant('version'),
|
||||||
description=_get_constant('description'),
|
description=_get_constant('description'),
|
||||||
|
|
@ -95,9 +95,10 @@ try:
|
||||||
'Operating System :: MacOS',
|
'Operating System :: MacOS',
|
||||||
'Operating System :: POSIX :: BSD',
|
'Operating System :: POSIX :: BSD',
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.7',
|
|
||||||
'Programming Language :: Python :: 3.8',
|
'Programming Language :: Python :: 3.8',
|
||||||
'Programming Language :: Python :: 3.9',
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
|
'Programming Language :: Python :: 3.11',
|
||||||
'Topic :: Internet',
|
'Topic :: Internet',
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Internet :: WWW/HTTP :: Browsers',
|
'Topic :: Internet :: WWW/HTTP :: Browsers',
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@ def test_command_on_start(request, quteproc_new):
|
||||||
quteproc_new.wait_for_quit()
|
quteproc_new.wait_for_quit()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('python', ['python2', 'python3.6'])
|
@pytest.mark.parametrize('python', ['python2', 'python3.6', 'python3.7'])
|
||||||
def test_launching_with_old_python(python):
|
def test_launching_with_old_python(python):
|
||||||
try:
|
try:
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
|
|
@ -346,7 +346,7 @@ def test_launching_with_old_python(python):
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pytest.skip(f"{python} not found")
|
pytest.skip(f"{python} not found")
|
||||||
assert proc.returncode == 1
|
assert proc.returncode == 1
|
||||||
error = "At least Python 3.7 is required to run qutebrowser"
|
error = "At least Python 3.8 is required to run qutebrowser"
|
||||||
assert proc.stderr.decode('ascii').startswith(error)
|
assert proc.stderr.decode('ascii').startswith(error)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import pytest
|
||||||
from qutebrowser.misc import checkpyver
|
from qutebrowser.misc import checkpyver
|
||||||
|
|
||||||
|
|
||||||
TEXT = (r"At least Python 3.7 is required to run qutebrowser, but it's "
|
TEXT = (r"At least Python 3.8 is required to run qutebrowser, but it's "
|
||||||
r"running with \d+\.\d+\.\d+.")
|
r"running with \d+\.\d+\.\d+.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import logging
|
||||||
import textwrap
|
import textwrap
|
||||||
import datetime
|
import datetime
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import importlib.metadata
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import hypothesis
|
import hypothesis
|
||||||
|
|
@ -1106,24 +1107,10 @@ class TestChromiumVersion:
|
||||||
"""Simulate parsing the version from ELF to fail."""
|
"""Simulate parsing the version from ELF to fail."""
|
||||||
monkeypatch.setattr(elf, 'parse_webenginecore', lambda: None)
|
monkeypatch.setattr(elf, 'parse_webenginecore', lambda: None)
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def patch_no_importlib(self, monkeypatch, stubs):
|
|
||||||
"""Simulate missing importlib modules."""
|
|
||||||
import_fake = stubs.ImportFake({
|
|
||||||
'importlib_metadata': False,
|
|
||||||
'importlib.metadata': False,
|
|
||||||
}, monkeypatch)
|
|
||||||
import_fake.patch()
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def importlib_patcher(self, monkeypatch):
|
def importlib_patcher(self, monkeypatch):
|
||||||
"""Patch the importlib module."""
|
"""Patch the importlib module."""
|
||||||
def _patch(*, qt, qt5, qt6):
|
def _patch(*, qt, qt5, qt6):
|
||||||
try:
|
|
||||||
import importlib.metadata as importlib_metadata
|
|
||||||
except ImportError:
|
|
||||||
importlib_metadata = pytest.importorskip("importlib_metadata")
|
|
||||||
|
|
||||||
def _fake_version(name):
|
def _fake_version(name):
|
||||||
if name == 'PyQtWebEngine-Qt':
|
if name == 'PyQtWebEngine-Qt':
|
||||||
outcome = qt
|
outcome = qt
|
||||||
|
|
@ -1135,10 +1122,10 @@ class TestChromiumVersion:
|
||||||
raise utils.Unreachable(name)
|
raise utils.Unreachable(name)
|
||||||
|
|
||||||
if outcome is None:
|
if outcome is None:
|
||||||
raise importlib_metadata.PackageNotFoundError(name)
|
raise importlib.metadata.PackageNotFoundError(name)
|
||||||
return outcome
|
return outcome
|
||||||
|
|
||||||
monkeypatch.setattr(importlib_metadata, 'version', _fake_version)
|
monkeypatch.setattr(importlib.metadata, 'version', _fake_version)
|
||||||
|
|
||||||
return _patch
|
return _patch
|
||||||
|
|
||||||
|
|
@ -1150,7 +1137,6 @@ class TestChromiumVersion:
|
||||||
@pytest.mark.parametrize('patches, sources', [
|
@pytest.mark.parametrize('patches, sources', [
|
||||||
(['no_api'], ['ELF', 'importlib', 'PyQt', 'Qt']),
|
(['no_api'], ['ELF', 'importlib', 'PyQt', 'Qt']),
|
||||||
(['no_api', 'elf_fail'], ['importlib', 'PyQt', 'Qt']),
|
(['no_api', 'elf_fail'], ['importlib', 'PyQt', 'Qt']),
|
||||||
(['no_api', 'elf_fail', 'no_importlib'], ['PyQt', 'Qt']),
|
|
||||||
(['no_api', 'elf_fail', 'importlib_no_package'], ['PyQt', 'Qt']),
|
(['no_api', 'elf_fail', 'importlib_no_package'], ['PyQt', 'Qt']),
|
||||||
], ids=','.join)
|
], ids=','.join)
|
||||||
def test_simulated(self, request, patches, sources):
|
def test_simulated(self, request, patches, sources):
|
||||||
|
|
|
||||||
1
tox.ini
1
tox.ini
|
|
@ -35,7 +35,6 @@ passenv =
|
||||||
basepython =
|
basepython =
|
||||||
py: {env:PYTHON:python3}
|
py: {env:PYTHON:python3}
|
||||||
py3: {env:PYTHON:python3}
|
py3: {env:PYTHON:python3}
|
||||||
py37: {env:PYTHON:python3.7}
|
|
||||||
py38: {env:PYTHON:python3.8}
|
py38: {env:PYTHON:python3.8}
|
||||||
py39: {env:PYTHON:python3.9}
|
py39: {env:PYTHON:python3.9}
|
||||||
py310: {env:PYTHON:python3.10}
|
py310: {env:PYTHON:python3.10}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue