Skip to content

chore: bump idna and pygments in uv.lock to clear Dependabot alerts#424

Merged
erichare merged 2 commits into
mainfrom
security/dependabot-bumps
Jun 19, 2026
Merged

chore: bump idna and pygments in uv.lock to clear Dependabot alerts#424
erichare merged 2 commits into
mainfrom
security/dependabot-bumps

Conversation

@erichare

Copy link
Copy Markdown
Collaborator

Summary

Resolves the Dependabot security alerts that can be cleared without dropping Python 3.9 support — a lock-file-only change (transitive dependencies, no pyproject.toml constraints touched):

Alert Package Bump Advisory Patched in py3.9?
#32 (medium) idna 3.10 → 3.18 idna.encode() can bypass the CVE-2024-3651 fix 3.15 ✅ requires >=3.8
#27 (low) pygments 2.19.2 → 2.20.0 ReDoS in GUID-matching regex 2.20.0 ✅ requires >=3.9

Both patched versions still support Python 3.9, so uv resolves each to a single (non-forked) version and the alerts clear.

Why the other 7 alerts are not included

The remaining open alerts — urllib3 (#30, #31), requests (#26), python-dotenv (#29), pytest (#28), filelock (#20, #23) — cannot be cleared while the project supports Python 3.9. Every one of their first-patched versions requires python >=3.10:

  • urllib3 2.7.0, requests 2.33.0, python-dotenv 1.2.2, pytest 9.0.3, filelock 3.20.3 → all requires-python >=3.10.

With requires-python = ">=3.9", uv forks the resolution: it installs the patched version for py3.10+ but keeps the vulnerable version pinned for the py3.9 branch of uv.lock. Dependabot scans the whole lock, so the alert stays open. (filelock already demonstrates this today — it's at the safe 3.24.3 for py3.10+ but stuck at 3.18.0 for py3.9.) These are the same exceptions documented in #398 ("address dependabot vulns except incompatible with supporting py 3.9").

Clearing those 7 requires a separate decision to drop Python 3.9 (already EOL as of Oct 2025), which is out of scope for a routine version-bump PR.

Test plan

  • ruff check astrapy tests — passes
  • ruff format --check astrapy tests — passes
  • mypy astrapy tests — passes (215 files, no issues)
  • pytest tests/base/unit — no new failures vs. baseline (idna/pygments are transitive deps unused at the astrapy layer)
  • CI green

Addresses the Dependabot security alerts that can be resolved while still
supporting Python 3.9:

- idna 3.10 -> 3.18  (GHSA: idna.encode() bypass, alert #32; first patched 3.15)
- pygments 2.19.2 -> 2.20.0  (ReDoS in GUID regex, alert #27; first patched 2.20.0)

Both patched versions still support Python 3.9 (idna requires >=3.8,
pygments requires >=3.9), so the lock resolves to a single, non-forked
version and the alerts clear.

The remaining open alerts (urllib3, requests, python-dotenv, pytest,
filelock) cannot be cleared without dropping Python 3.9: their first
patched versions all require Python >=3.10, so uv forks the resolution and
strands the vulnerable version on the py3.9 branch of the lock. These are
the same exceptions noted in #398.
@erichare erichare requested a review from sl-at-ibm June 17, 2026 17:19
@sl-at-ibm

Copy link
Copy Markdown
Collaborator

You know... I start to think nobody would get mad at astrapy for dropping a long-EOL'd version of Python. Let's get this one in, then we update min-python-required, so that the other CVEs can be addressed (filelock and the others).

  • This will mean a couple of adjustments here and there (there's a "min python version" somewhere in the ci/cd, plus pyproject, readme, etc).
  • But I was mistaken: the next language simplification comes when 3.10 will be dropped (it's the way Self is imported in context_managers.py)
  • On the other hand, 3.9+ would make it possible to restore using a modern testcontainers, which right now is partially replaced/subclasses/monkeypatched because ...um... (checks code) invoke docker compose rather than docker-compose (which would not run in the GH runners). <-- Definitely not urgent lol

@github-actions

Copy link
Copy Markdown

Coverage report

for commit: aabb01fa12cf58797733757d43e7705ebb210a20.
download detailed report here.

                                                File   Stmts   Miss      Cover     Delta
----------------------------------------------------------------------------------------
                                     astrapy/repl.py      77     77      0.00%     0.00%
                              astrapy/admin/admin.py     789    331     58.05%     0.00%
                                 astrapy/__init__.py      26     10     61.54%     0.00%
                               astrapy/utils/meta.py      42     15     64.29%     0.00%
                                  astrapy/results.py      50     16     68.00%     0.00%
              astrapy/exceptions/table_exceptions.py      27      8     70.37%     0.00%
         astrapy/exceptions/collection_exceptions.py      40     11     72.50%     0.00%
                  astrapy/data_types/data_api_set.py      90     23     74.44%     0.00%
                         astrapy/exceptions/utils.py      53     11     79.25%     0.00%
                  astrapy/data/cursors/pagination.py      21      4     80.95%     0.00%
                      astrapy/exceptions/__init__.py     108     19     82.41%     0.00%
                           astrapy/authentication.py     138     24     82.61%     0.00%
                  astrapy/data/info/database_info.py     135     23     82.96%     0.00%
                        astrapy/utils/user_agents.py      18      3     83.33%     0.00%
                                   astrapy/client.py      68     11     83.82%     0.00%
               astrapy/data_types/data_api_vector.py      44      7     84.09%     0.00%
          astrapy/data/info/collection_descriptor.py     222     33     85.14%     0.00%
                      astrapy/data/info/reranking.py     122     18     85.25%     0.00%
                            astrapy/utils/parsing.py       7      1     85.71%     0.00%
                  astrapy/data_types/data_api_map.py      59      8     86.44%     0.00%
 astrapy/data/info/table_descriptor/table_listing.py      49      6     87.76%     0.00%
                            astrapy/data/database.py     657     75     88.58%     0.00%
 astrapy/data/info/table_descriptor/table_indexes.py     230     26     88.70%     0.00%
            astrapy/data_types/data_api_timestamp.py      98     11     88.78%     0.00%
                      astrapy/data/info/vectorize.py     131     14     89.31%     0.00%
    astrapy/settings/definitions/definitions_data.py      38      4     89.47%     0.00%
  astrapy/data/info/table_descriptor/type_listing.py      39      4     89.74%     0.00%
             astrapy/data_types/data_api_dict_udt.py      10      1     90.00%     0.00%
                              astrapy/utils/unset.py      10      1     90.00%     0.00%
                        astrapy/utils/api_options.py     206     20     90.29%     0.00%
astrapy/data/info/table_descriptor/table_altering.py     114     11     90.35%     0.00%
             astrapy/data_types/data_api_duration.py      55      5     90.91%     0.00%
                               astrapy/data/table.py     738     65     91.19%     0.00%
                      astrapy/utils/api_commander.py     248     21     91.53%     0.00%
 astrapy/data/info/table_descriptor/table_columns.py     204     17     91.67%     0.00%
 astrapy/data/info/table_descriptor/type_altering.py      85      7     91.76%     0.00%
                 astrapy/utils/duration_std_utils.py      92      7     92.39%     0.00%
         astrapy/exceptions/devops_api_exceptions.py      79      6     92.41%     0.00%
                          astrapy/data/collection.py     752     57     92.42%     0.00%
                astrapy/data/cursors/query_engine.py     214     16     92.52%     0.00%
         astrapy/event_observers/context_managers.py      27      2     92.59%     0.00%
                 astrapy/data_types/data_api_time.py      98      7     92.86%     0.00%
                 astrapy/data_types/data_api_date.py      89      6     93.26%     0.00%
 astrapy/data/info/table_descriptor/type_creation.py      32      2     93.75%     0.00%
             astrapy/exceptions/error_descriptors.py      53      3     94.34%     0.00%
                          astrapy/admin/endpoints.py      36      2     94.44%     0.00%
   astrapy/settings/definitions/definitions_types.py      19      1     94.74%     0.00%
         astrapy/data/utils/collection_converters.py      80      4     95.00%     0.00%
              astrapy/data/utils/table_converters.py     411     20     95.13%     0.00%
                 astrapy/data/cursors/find_cursor.py     631     30     95.25%     0.00%
astrapy/data/info/table_descriptor/table_creation.py      49      2     95.92%     0.00%
                astrapy/event_observers/observers.py      30      1     96.67%     0.00%
                      astrapy/data/cursors/cursor.py      92      3     96.74%     0.00%
                 astrapy/data/cursors/farr_cursor.py     350     11     96.86%     0.00%
                           astrapy/utils/str_enum.py      32      1     96.88%     0.00%
                   astrapy/utils/duration_c_utils.py      66      2     96.97%     0.00%
                         astrapy/utils/date_utils.py      80      2     97.50%     0.00%
   astrapy/settings/definitions/definitions_admin.py      41      1     97.56%     0.00%
           astrapy/exceptions/data_api_exceptions.py      84      1     98.81%     0.00%
           astrapy/data/utils/distinct_extractors.py     104      1     99.04%     0.00%
                           astrapy/admin/__init__.py       3      0    100.00%     0.00%
                              astrapy/api_options.py       3      0    100.00%     0.00%
                               astrapy/collection.py       2      0    100.00%     0.00%
                                astrapy/constants.py       5      0    100.00%     0.00%
                                  astrapy/cursors.py       7      0    100.00%     0.00%
                            astrapy/data/__init__.py       0      0    100.00%     0.00%
                    astrapy/data/cursors/__init__.py       1      0    100.00%     0.00%
             astrapy/data/cursors/reranked_result.py       8      0    100.00%     0.00%
                      astrapy/data/utils/__init__.py       0      0    100.00%     0.00%
      astrapy/data/utils/extended_json_converters.py      28      0    100.00%     0.00%
                   astrapy/data/utils/table_types.py      36      0    100.00%     0.00%
               astrapy/data/utils/vector_coercion.py      13      0    100.00%     0.00%
                      astrapy/data_types/__init__.py      10      0    100.00%     0.00%
                                 astrapy/database.py       2      0    100.00%     0.00%
                 astrapy/event_observers/__init__.py       5      0    100.00%     0.00%
                   astrapy/event_observers/events.py      50      0    100.00%     0.00%
                                      astrapy/ids.py       5      0    100.00%     0.00%
                                     astrapy/info.py      15      0    100.00%     0.00%
                        astrapy/settings/__init__.py       0      0    100.00%     0.00%
                        astrapy/settings/defaults.py      47      0    100.00%     0.00%
            astrapy/settings/definitions/__init__.py       0      0    100.00%     0.00%
                  astrapy/settings/error_messages.py       2      0    100.00%     0.00%
                                    astrapy/table.py       2      0    100.00%     0.00%
                           astrapy/utils/__init__.py       0      0    100.00%     0.00%
                     astrapy/utils/document_paths.py      46      0    100.00%     0.00%
                     astrapy/utils/python_version.py       5      0    100.00%     0.00%
                      astrapy/utils/request_tools.py      32      0    100.00%     0.00%
----------------------------------------------------------------------------------------
                                              totals    8916   1129     87.34%     0.00%

@sl-at-ibm

Copy link
Copy Markdown
Collaborator

Generally all ok, but just a question for my own education: these are changes to the lockfile only (as opposed to pyproject explicit pinning).
What happens when I next run uv lock as part of some other work and then commit: wouldn't thes present changes be potentially lost/overwritten?

(I am interested in the answer because in the past I have addressed some earlier CVEs with pyproject-explicit pinning (of the >= kind of course) and would like to learn if that was too much/if it can be made less intrusive as a post-edit).

@erichare

erichare commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator Author

Generally all ok, but just a question for my own education: these are changes to the lockfile only (as opposed to pyproject explicit pinning). What happens when I next run uv lock as part of some other work and then commit: wouldn't thes present changes be potentially lost/overwritten?

(I am interested in the answer because in the past I have addressed some earlier CVEs with pyproject-explicit pinning (of the >= kind of course) and would like to learn if that was too much/if it can be made less intrusive as a post-edit).

@sl-at-ibm I recently had a task like this in Langflow and had the same question. My understanding is:

pyproject.toml is where we declare project-level constraints, so it makes sense to edit it for direct astrapy dependencies. But these two are transitive dependencies (i think idna from httpx and pygments from ipython), so adding them there would promote them into explicit project dependencies just to influence the resolver.

For uv.lock, plain uv lock uses the existing lockfile as preferences. So after this is merged, a future ordinary uv lock should preserve these resolved versions. They could still change if someone runs uv lock --upgrade / --upgrade-package, or if a future direct dependency change imposes different constraints.

If a future direct dependency actually forced an old vulnerable version, I think that would be a deeper dependency problem to address. Adding the transitive package directly to pyproject.toml probably would not solve that cleanly; it would more likely create a resolver conflict. hopefully that wouldn't happen haha

That was longer than i intended haha but i had to convince myself as well :) Does that make sense?

@sl-at-ibm sl-at-ibm left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the explanation! I think it makes sense, yes.
(A couple of times it has happened to me on some PRs that I found myself with a botched lockfile, so I deleted it and ran a fresh uv lock. This may potentially be trouble, I don't know -- perhaps the right thing in that case is to restore the lockfile from main and run "ordinary uv lock" as you mention.)

Anyway, there's no big risk in going forward like this PR does and keep an eye if some weird dynamics brings lower vulnerable versions around again (unlikely as it may be...)

So: LGTM!

@erichare erichare merged commit f1880b7 into main Jun 19, 2026
20 of 21 checks passed
@erichare erichare deleted the security/dependabot-bumps branch June 19, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants