Commit Graph

2033 Commits

Author SHA1 Message Date
toofar 161ce7bfce Allow setuptools and pip in compiled requirements files
This aligns with the direction of pip-compile and uv, and removes some
code from this script. See:

    https://github.com/astral-sh/uv/issues/1353
    https://github.com/jazzband/pip-tools/issues/989#issuecomment-1134985118

The code being removed worked fine. So if it turns out that installing a
newer setuptools or pip in virtualenvs break stuff, it's fine to add
back.
2025-04-25 18:38:01 +12:00
toofar ea9619bfb3 Remove pip freeze based requirements compilation method 2025-04-25 18:38:01 +12:00
toofar a753d671a1 join strings safely 2025-04-25 18:38:00 +12:00
toofar 8575b9856d Specify tox requirement file name in full
Substring matches when you are actually only trying to match one
specific item is a smell, its unclear what's intended and causes the
reader to have to stop and think.
2025-04-25 18:38:00 +12:00
toofar f254a2ae94 Simplify empty lint check in recompile requirements
This is for parsing diffs like:

        # via importlib-metadata
    +
    + # The following packages were excluded from the output:
    + # setuptools

Otherwise further parsing breaks because it is looking for a package
name on the line.
2025-04-25 18:38:00 +12:00
toofar 5d8779a61e undo adaptations for setuptools vendored packages
see 433074c681, adf39e9f72, db83a82fe1 & 78a74a2e2a

Now that we are using pip-compile to build requirements lock files,
instead of pip-freeze, these things shouldn't be showing up in the
results.

Looks like `typeguard` was dropped in a192a3d9c7d0e87 "initial compile based bump"
I guess that was being pulled in by pip freeze too.
2025-04-25 18:38:00 +12:00
toofar a16ea8f710 Enable delightful pip compile lineage annotations
I find these comments useful to show why packages are included in the
final compiled requirements files.

Required a small change to `recompile_requirements` to ignore these new
comment line (it was saying there was a new requirement with an empty
name that needed a changelog entry).

The addition of the `os.path.realpath()` is to clean up the paths of the
requirements files in the annotations, eg:

     check-manifest==0.49
    -    # via -r scripts/dev/../../misc/requirements/requirements-check-manifest.txt-raw
    +    # via -r misc/requirements/requirements-check-manifest.txt-raw
2025-04-25 18:38:00 +12:00
toofar 48c15d3e1c Add pip and setuptools back to tox requirement file
For the pip freeze backend pip is being passed `--all` when the tox
requirements file is being processed so that pip and setuptools are
included in the requirements file. This was added in 922dca039b
for reasons I haven't fully grokked.

This commit adds similar behaviour for the pip compile backend via:
1. don't add the --no-emit-package args for the tox requirements file
2. add pip and setuptools to the tox requirements file

It seems that pip and setuptools aren't even requirements of tox, but
they are being included in the compiled requirements file anyway. Why
aren't the included in the raw requirements file? I don't know, but from
what I can figure it's not going to harm anything to have them in there.
2025-04-25 18:38:00 +12:00
toofar 2ee9f561af Exclude setuptools from pip-compile output
This is to match the `pip freeze` requirements compilation method. It's
not clear to me if we actually want this behaviour or not.

If seems `pip freeze` will exclude dependencies of itself: https://pip.pypa.io/en/stable/cli/pip_freeze/#cmdoption-all
Even if there are other packages installed that depend on those
dependencies.

`uv pip compile`, and now the original `pip-compile` both have decided
to include setuptools in generated requirements files:

    https://github.com/astral-sh/uv/issues/1353
    https://github.com/jazzband/pip-tools/issues/989#issuecomment-1134985118

So I'm not sure if we have a reason for going against this here or if
they were just being excluded because that's what pip freeze does.

Hopefully we can drop this commit and use the default behaviour in the
future. For now when I'm trying to provide the new backend it's here to
make the diff of generated files more precise.

This message prefix to identify a pip compile comment was taken from
these examples:

    # The following packages were excluded from the output:
    # setuptool

    # The following packages are considered to be unsafe in a requirements file:
    # setuptools==41.4.0        # via protobuf
2025-04-25 18:38:00 +12:00
toofar ae884a6da4 normalize package names pip freeze output too
This lets us more easily compare the output of runs of the different
requirements compiling methods.
2025-04-25 18:38:00 +12:00
toofar c0d1ae7661 Add tests for comments supported by recompile_requirements
Since I was looking at how hard it would be to support using pip-compile
to recompute requirements, I was worried that I would break the markers
we support in the raw requirements files.

This adds two tests:
* disabled_test_markers_real_pip_and_venv
  A test that sets up a local python index and runs the real pip/uv
  binaries. It works (and it was fun to setup a package index factory)
  but has a couple of downsides:
  1. it hits the real pypi index, which is not great in a test. This can
     be prevented by removing the EXTRA bit from the INDEX_URL env vars
     and pre-downloading pip, wheel, setuptools and uv to the test repo
     (and adding index.htmls for them). But because of the next item I'm
     not sure it's worth the effort of keeping this test around
  2. it's slow because of having to download packages from the internet
     (even if we pre-cached them it would still have to download them, I
     guess we could include a zip of fixed/vendored versions, but that
     will probably require maintenance over time) and because it cals
     venv to make new virtual environments, which isn't the quickest
     operation (maybe uv venv is quicker?)
* test_markers_in_comments
  Tests just the comment reading and line manipulation logic. Could be
  made a bit more pure by just calling read_comments() and
  convert_line(), but that wouldn't test that "add" marker.
2025-04-25 18:36:45 +12:00
toofar 8251b0f134 Combine the two "build_requirements" methods
There was a fair bit of duplicate code, so I've pulled out the "take a
list of requirements, give me a new one" out to separate methods. The
stuff around parsing the output can stay common thankfully!

Even if we drop one of the methods this level of abstraction is probably
fine to keep.
2025-04-25 18:36:45 +12:00
toofar be12df63cb Normalize module level CHANGELOG_URLS for misc check
The CHANGELOG_URLS variable is imported by the
`./scripts/dev/misc_checks.py changelog-urls` check. Since there is a
bit of churn in package name case in this change (and a while back when
a bunch of packages switched between underscores and hyphens), update
this variable at import time so that that checker will be looking at
normalized names too.
2025-04-25 18:36:45 +12:00
toofar b4c8f06a97 Use pip compile to find new deps instead of install and freeze
In #8269 we saw some packages leaking into the pip freeze output that we
don't want in the requirements files (if setuptools isn't supposed to be
in there, why should its dependencies).
I've also greatly missed the comments that pip-compile puts in
requirements.txt files explaining where indirect dependencies come from.
So I took the opportunity to switch our tooling for updating and parsing
new dependencies and their versions to use pip-compile instead of `pip -U
install && pip freeze`.

It turned out to not be a big change because the pip freeze output is
largely compatible with requirements files (we are writing directly to
one after all). So we just need to switch what commands we are running
and triage any compatibility issues.

I chose `uv pip compile` instead of `pip-compile` because I like what uv
is doing (fast, aiming for compatibility, consolidating a confusing
ecosystem into a single tool). But pip-compile/tools should do the same
job if we want to go that route.

The biggest differences are:
* outputs normalized names: this generally results in a larger diff than
  otherwise (I propose we go through an regenerate all the requirements
  files in one go, and maybe add that commit to a blame ignore file) and
  requires our comparison logic to deal with normalized package names
  everywhere
* setuptools and pip not included in tox requirement file - not sure
  what to do about that yet, should they be in the .text-raw file?

TODO:
* remove support for pip_args?
* change markers in raw files to lower case? Ideally don't require, if a human
  can write them in any case and a robot can normalize we should do that. If
  if there are patterns with `._` in them as part of names, how do we handle
  that?
* pull out similar bits of `build_requirements*` methods
  * maybe make it so you can pass `requirements=None` to `init_venv` to
    make it not install stuff, install uv, do the uv invocation, gate
    all that behind a `--method="freeze|compile"` arg?
* add pip and setuptools to tox requirements file?
* basename requirements file names so they don't have
* `script_path/../../` in them in the annotated version
* add tests for the markers (with inputs of differing cases) to make
  sure they all still work
* update changelog check used in CI to normalize names too
2025-04-25 18:36:45 +12:00
toofar e67aea60e8 Update changelog link for mypy extensions 2025-04-25 16:50:07 +12:00
Florian Bruhin ef397e9417 Update changelog URLs 2025-03-31 08:40:01 +02:00
Florian Bruhin 2f20e3b60b Update iniconfig changelog url 2025-03-24 11:29:35 +01:00
Florian Bruhin 237e90985d docker: Downgrade libxslt
ImportError: /usr/lib/libxslt.so.1: undefined symbol: xmlCtxtParseDocument
2025-03-15 12:25:43 +01:00
toofar 4f985feede update changelog URL 2025-03-10 23:05:00 +13:00
toofar 42c9973c01 update isort changelog link 2025-03-03 19:45:58 +13:00
Florian Bruhin eb2e39de1e scripts: Add new bump-my-version deps 2025-02-17 10:55:22 +01:00
Florian Bruhin 60f526d81f Add new changelog URLs from bump-my-version 2025-02-03 18:40:35 +01:00
Jun Chen 6b25fdf648 chore: replace bump2version with bump-my-version 2025-01-30 19:14:38 -07:00
Florian Bruhin 322977dc0d Update changelog URLs for twine upgrade 2025-01-27 16:15:28 +01:00
Florian Bruhin b3090870d3 scripts: Rename test_requirements function
Falsely flagged by https://github.com/m-burst/flake8-pytest-style/blob/master/docs/rules/PT028.md
2025-01-19 11:56:42 +01:00
Florian Bruhin 7eb9bc45de Adjust Pillow changelog URL 2025-01-06 15:05:02 +01:00
Florian Bruhin 9e70ffeaad Switch to legacy PDF.js build
The normal PDF.js build only officially supports the latest Chromium, so things
might break every once in a while with QtWebEngine (e.g. #8199, #7335).

Let's instead bundle and recommend the legacy build.

Closes #8332
Closes #7721 (reworded)
Also see #7135
2024-12-10 11:47:39 +01:00
Florian Bruhin e7b346ecf2 scripts: Try harder to 'hdiutil create' the .dmg
See https://github.com/actions/runner-images/issues/7522#issuecomment-2527820259
2024-12-10 10:31:47 +01:00
Florian Bruhin 8f274c4e18 mkvenv: Add arm64 to supported platforms 2024-12-10 00:47:04 +01:00
Florian Bruhin c501ae375e scripts: Close sqlite connections properly in importer
Found thanks to runnning Python 3.13 tests on CI.

See #8205
2024-12-09 16:51:55 +01:00
Florian Bruhin 4d5ed99ff5 link_pyqt: Try QtCore before sip
Makes for nicer error messages if there's no PyQt at all.
2024-12-09 13:59:33 +01:00
Florian Bruhin 557cd19a1d ci: Try harder to detach dmg image
See https://github.com/actions/runner-images/issues/7522
2024-12-06 21:45:27 +01:00
Ruben Gonzalez 3a3c03a4df In POSIX sh, echo flags are undefined 2024-12-06 19:40:28 +00:00
Florian Bruhin 5cb14d4d4b Run shellcheck over all scripts/*.sh files
See #8409
2024-12-06 20:39:34 +01:00
Florian Bruhin aed06c5f48 Add gherkin-official changelog URL 2024-12-05 19:26:58 +01:00
Florian Bruhin ffe7d00a62 Merge branch 'drop-py38' 2024-10-15 11:58:54 +02:00
toofar cc3c1e2050 Enable pylint Too many positional arguments warning
This re-enables the pylint too-many-positional-arguments for the main
application code. It's still disabled for tests because that's how you pull in
pytlint fixtures, and I don't think we want to push people into being creative
with fixtures just to get around that.

When functions are called with many positional arguments the reader has to do
a bit of heavy lifting to figure out in what position a value is being passed,
and it's easier to make mistakes. So I would like to encourage using keyword
arguments for long argument lists.

I've set the `max-positional-arguments` to a completely arbitrary 7, from a
completely arbitrary 5, because there were many more violations under 7. If
like 99% of our functions fit under 7 it's probably fine.

Regarding the exceptions:
* objreg.register: I grepped it and it looks like everything is only passing
  the first two args as positional already, lucky!
*  `_get_color_percentage`: only one usage of it, but I was in "add directive
  comment" mode
* update_3rdparty.py: only one usage, already using kwargs
* pyqtProperty: idk
* commands.py: "its complicated". Many methods in this file map to commands
  used in qutebrowser's command mode. In that case it's usual for them to be
  called as flags, rather than positional. But it could be complicated to wade
  into that, and having one file excluded isn't so bad.
2024-10-15 11:55:04 +02:00
Florian Bruhin 2ab963cef8 Remove pytz changelog URL 2024-10-15 11:55:04 +02:00
Florian Bruhin 0fd6fc19f2 recompile_requirements: Fix with diff.mnemonicPrefix set 2024-10-15 11:55:04 +02:00
Florian Bruhin 97104b2000 Use builtin list/dict/set/... types for annotations
See https://peps.python.org/pep-0585/
and https://docs.python.org/3/whatsnew/3.9.html#type-hinting-generics-in-standard-collections

Done via:

    ruff check --select 'UP006' --fix --config 'target-version = "py39"' --unsafe-fixes

followed by removing unused imports:

    ruff check --select 'F401' --fix --config 'target-version = "py39"'

and a semi-manual review to find imports that are still needed (but ruff doesn't know about yet):

    git diff | grep '^-' | grep import | grep -v "from typing"

Also see #7098.
2024-10-15 11:54:49 +02:00
Florian Bruhin c32b8090ca Import typing classes from collections.abc
See https://peps.python.org/pep-0585/
and https://docs.python.org/3/whatsnew/3.9.html#type-hinting-generics-in-standard-collections

Not changing List/Dict/Set/etc. in this commit, as that's a way bigger change.

Done via:

    ruff check --select 'UP035' --fix --config 'target-version = "py39"'

Also see #7098.
2024-10-15 11:54:35 +02:00
Florian Bruhin c598cbbc71 Revert "ci: Avoid Archlinux' pyqt6 6.1.7-3 which lacks QSignalSpy"
This reverts commit 27e446d26d.
Archlinux now uses a PyQt 6.8 development snapshot.
2024-10-15 00:47:31 +02:00
Florian Bruhin b976a31ffa
Merge pull request #8321 from qutebrowser/feat/8260_drop_qt5_builds
Remove support for making Qt5 builds
2024-10-13 21:45:05 +02:00
Florian Bruhin 27e446d26d ci: Avoid Archlinux' pyqt6 6.1.7-3 which lacks QSignalSpy
See https://github.com/qutebrowser/qutebrowser/issues/8242#issuecomment-2409077518
2024-10-13 20:28:43 +02:00
Florian Bruhin 4d069b8fc3 Use str.removeprefix() and str.removesuffix()
https://docs.python.org/3/whatsnew/3.9.html#new-string-methods-to-remove-prefixes-and-suffixes
2024-10-13 18:24:44 +02:00
toofar d24a4c5ab0 Remove Qt5 switches from release building scripts etc
I just searched for qt5 and deleted stuff. EZ.
Will leave on a branch for a bit and see if I feel like testing this at
all, otherwise maybe leave this stuff in here and make it not called.

Not 100% sure that we need to remove all this stuff when we just want
the CI to go green. But tbh if we don't need to make Qt5 releases then
we don't need it. Better to be bold and pull it out than have to work
around it in the future. And we can always revert the commit.
2024-10-05 13:55:15 +13:00
toofar 3bc30e748d Merge pull request #8243 from feat/e2e_screenshots 2024-10-05 11:30:57 +13:00
toofar a409f9acf7 add changelog for jaraco.collections 2024-09-18 11:35:30 +12:00
toofar d49dd3d48f fix changelog urls 2024-09-06 17:43:12 +12:00
toofar a3238eb494 upload e2e failure screenshots as artifacts
This commit takes a screenshot of the active browser window when an
end2end test fails. When running on CI a zip file of screenshots will be
attached to the run summary as an artifact. When run locally screenshots
will be left in /$TMPDIR/pytest-screenshots/.

The screenshot is of the Xvfb screen that the tests are running under.
If there are multiple windows open it will likely only show the active
window because a) we aren't running with a window manager b) the Xvfb
display is, by default, the same size as the browser window.

I'm not sure if xvfb is used on the Window runs in CI. We could fall
back to trying to take screenshots if not running under xvfb but I'm a
bit wary of an automatic feature that takes screenshots of people's
desktops when running locally. Even if they just to to /tmp/ it might be
surprising. We can change it later if it turns out we need to try to
take screenshots in more cases.

I'm using pillow ImageGrab, the same as pyvirtualdisplay.smartdisplay. I'm
getting the display number from the pytest-xvfb plugin and formatting it
appropriately (pyvirtualdisplay has an already formatted one which is used by
the smartdisplay, but that's not accessible).

Pillow is now a requirement for running the tests. I thought about making
it gracefully not required but I'm not sure how to inform the user with
a warning from pytest, or if they would even want one. Maybe we could
add a config thing to allow not taking screenshots?

I had to bump the colordepth config for pytest-xvfb otherwise pillow
complained that the default 16bit color depth wasn't supported as it
only supports 24bit, see https://github.com/python-pillow/Pillow/blob/1138ea5370cbda5eb328ec949
8c314d376c81265/src/display.c#L898

I'm saving screenshots to a temp dir because I don't want to put them in
my workdir when running locally. I want to clear the directory for each
run so that you don't get confused by looking at old images. I'm not
100% sure about the lifecycle of the process classes though. Eg if we
have two processes they might both try to create the output directory.
I'm using pytest.session.stash to save the directory so perhaps the
lifecycle of the stash will handle that? Not sure.

Ideally the images would be uploaded somewhere where we could click
through and open them in the browser without having to download a zip
file, but I'm not sure how to achieve that.

It would be nice to print in the test logs that a screenshot was saved
and where to. Just so you could copy paste the filename instead of
having to match the sanitized filename against failing test names. But I
don't know how to log stuff from this stage in the pytest lifecycle.

TODO:
* I'm not sure that the screenshot captures the whole browser window?
  Maybe the browser windows is bigger than the X11 display?

Closes: #7625
2024-08-18 12:42:29 +12:00