From e940761cf4f0d2505ce95f92ce12fb568d2de67a Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Sat, 26 Sep 2026 08:17:42 +0000 Subject: [PATCH 01/25] Updated from generate-constraints Pin versions for packages that are not ready for updating: - pyroute2: Nova/os-vif issues - sqlalchemy: broken compatibility with sqlalchemy-utils - pyparsing: due to regression in 3.3.3[1] [1] https://github.com/pyparsing/pyparsing/issues/672 Co-Authored-by: Dr. Jens Harbott Co-Authored-by: Takashi Kajinami Change-Id: I98b8c4c0c778dcd2cb20f2e830fb80d99351a228 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:playbooks/proposal/propose_update.sh --- upper-constraints.txt | 238 +++++++++++++++++++++++------------------- 1 file changed, 131 insertions(+), 107 deletions(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 757449101..b44ddc0be 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -8,15 +8,15 @@ voluptuous===0.16.0 chardet===6.0.0.post1 enum-compat===0.0.3 -netmiko===4.7.0 +netmiko===4.8.0 sshtunnel===0.4.0 PasteDeploy===3.1.0 Routes===2.5.1 rtslib-fb===2.2.4 oslo.limit===2.12.0 restructuredtext_lint===2.0.2 -yarl===1.24.5 -tzdata===2026.3 +yarl===1.25.1 +tzdata===2026.4 smmap===5.0.3 confget===5.1.2 XStatic-Angular-Bootstrap===2.5.0.1 @@ -24,34 +24,34 @@ WebOb===1.8.11 sphinxcontrib-actdiag===3.0.0 pecan===1.8.0 os-api-ref===3.2.0 -python-ldap===3.4.7 +python-ldap===3.4.8 oslo.concurrency===7.6.1 -websocket-client===1.9.0 +websocket-client===1.9.2 osprofiler===4.4.0 os-resource-classes===1.1.0 mypy_extensions===1.1.0 tabulate===0.10.0 python-ironic-inspector-client===5.4.0 -lxml===6.1.1 +lxml===6.1.3 vintage===0.4.1 rst2txt===1.1.0 setproctitle===1.3.7 pytest===9.1.1 a2wsgi===1.10.10 -python-slugify===8.0.4 +python-slugify===9.1.1 cursive===0.3.1 oslo.service===4.8.0 django-appconf===1.2.0 -ntc_templates===9.2.0 +ntc_templates===9.3.0 sphinxcontrib-nwdiag===2.0.0 rbd-iscsi-client===0.1.8 alabaster===1.0.0 -multidict===6.7.1 +multidict===6.9.1 pbr===7.0.3 munch===4.0.0 waiting===1.5.0 attrs===26.1.0 -jwcrypto===1.5.8 +jwcrypto===1.6.1 Pint===0.25.3 oslo.i18n===6.9.0 jsonpath-rw-ext===1.2.2 @@ -59,82 +59,90 @@ python-mistralclient===6.3.0 oslo.context===6.5.0 rcssmin===1.2.2 pycadf===4.1.0 -grpcio===1.83.0 +grpcio===1.84.0 sniffio===1.3.1 fixtures===4.3.2 neutron-lib===5.0.1 XStatic-FileSaver===1.3.2.1 jaraco.functools===4.6.0 +annotated-doc===0.0.5 +jaraco.text===4.3.0 oslo.metrics===0.17.0 storage-interfaces===1.0.5 -pydantic===2.13.4 +pydantic===2.13.5 pystache===0.6.8 XStatic-Font-Awesome===6.2.1.2 aiohttp===3.14.3 waitress===3.0.2 os-refresh-config===14.0.1 -pysnmp===7.1.28 -Mako===1.4.1 +pysnmp===7.1.29 +Mako===1.4.3 +vultr===1.0.1 sphinxcontrib-htmlhelp===2.1.0 XStatic-jQuery===3.7.1.1 sphinx-copybutton===0.5.2 beartype===0.22.9 +jaraco.collections===5.2.1 ddt===1.7.2 pyserial===3.5 -moto===5.2.2 +moto===5.2.3 infi.dtypes.wwn===0.2.0 -awscrt===0.36.2 +awscrt===0.37.0 pcre2===0.7.1 python-freezerclient===6.5.0 -py-pure-client===1.93.0 +py-pure-client===1.94.2 krest===1.3.8 -psycopg2===2.9.12 +psycopg2===2.9.13 networkx===3.6.1 cheroot===11.1.2 XStatic-Angular===1.8.2.3 zuul-sphinx===0.8.1 ply===3.11 -google-api-core===2.34.0 +google-api-core===2.39.0 requests-toolbelt===1.0.0 -simplejson===4.1.1 +simplejson===4.1.2 python-swiftclient===4.11.0 -pyOpenSSL===24.2.1 +shellingham===1.5.4 +pyOpenSSL===26.4.0 typing-inspection===0.4.4 monasca-common===3.8.0 hyperframe===6.1.0 -zeroconf===0.150.0 +zeroconf===0.151.3 scipy===1.17.1 -opentelemetry-exporter-otlp===1.44.0 +opentelemetry-exporter-otlp===1.45.0 +python-gnupg===0.5.6 rsd-lib===1.2.0 XStatic-Jasmine===2.4.1.3 -googleapis-common-protos===1.75.1 +googleapis-common-protos===1.75.4 python-glanceclient===4.13.0 prometheus_client===0.26.0 jaraco.classes===3.4.0 +typer-slim===0.24.0 debtcollector===3.1.0 -responses===0.26.2 +responses===0.26.3 prompt_toolkit===3.0.53 croniter===6.2.4 horizon===27.0.0 octavia-lib===3.12.0 python-watcherclient===4.11.0 MarkupSafe===3.0.3 +cloudpickle===3.1.2 doc8===2.0.0 -pymongo===4.17.0 +pymongo===4.18.2 python-cloudkittyclient===6.2.0 -soupsieve===2.9.2 +soupsieve===2.10 sqlparse===0.6.0 oslotest===6.1.1 jsonpointer===3.1.1 defusedxml===0.7.1 -opentelemetry-sdk===1.44.0 +opentelemetry-sdk===1.45.0 netaddr===1.3.0 pyghmi===1.6.19 sphinxcontrib-blockdiag===3.0.0 aiosqlite===0.22.1 priority===2.0.0 gnocchiclient===7.2.0 -wcwidth===0.8.2 +wcwidth===0.9.1 sphinxcontrib.datatemplates===0.11.0 jsonpath-rw===1.4.0 prettytable===3.18.0 @@ -143,14 +151,14 @@ pathspec===1.1.1 taskflow===6.4.0 arrow===1.4.0 semantic-version===2.10.0 -ConfigArgParse===1.7.5 +ConfigArgParse===1.7.7 async-timeout===5.0.1 virtualbmc===3.3.0 -SQLAlchemy===2.0.52 +SQLAlchemy===2.0.54 pyroute2===0.8.1 -google-auth===2.56.3 +google-auth===2.58.1 kazoo===2.11.0 -pyspnego===0.12.1 +pyspnego===0.12.2 trio-websocket===0.12.2 XStatic-roboto-fontface===0.8.0.1 pyudev===0.24.4 @@ -158,41 +166,45 @@ eventlet===0.41.2 openstack-doc-tools===4.0.3 oslo.messaging===18.3.0 jira===3.10.5 -PyJWT===2.13.0 +PyJWT===2.15.0 typing_extensions===4.16.0 zVMCloudConnector===1.6.3 -paramiko===4.0.0 +paramiko===5.0.0 ifaddr===0.2.0 reno===4.1.0 ncclient===0.7.1 -imagesize===2.0.0 +imagesize===2.0.1 pydot===4.0.1 -urllib3===2.7.0 +urllib3===2.8.0 graphviz===0.21 -PyKMIP===0.10.0 +portend===3.2.1 +PyKMIP===0.11.0 python-observabilityclient===1.4.0 whereto===0.6.0 networking-generic-switch===10.1.0 -pywbem===1.9.0 +pywbem===1.9.1 python-subunit===1.4.6 +tornado===6.5.10 pycparser===3.0 mock===5.2.0 PyYAML===6.0.3 beautifulsoup4===4.15.0 -ovs===3.7.1 -cryptography===43.0.3 +ovs===4.0.0 +cryptography===50.0.1 httpcore===1.0.9 URLObject===3.0.0 -psycopg2-binary===2.9.12 +psycopg2-binary===2.9.13 glance_store===5.7.0 openstack-release-test===8.5.0 +pycryptodomex===3.23.0 requests-mock===1.12.1 os-apply-config===14.0.1 -gunicorn===26.0.0 +xxhash===4.0.1 +gunicorn===26.2.0 storpool===7.3.0 textfsm===2.1.0 python-3parclient===4.4 -libvirt-python===12.6.0 +libvirt-python===12.7.0 python-zunclient===5.5.0 tzlocal===5.4.4 sysv_ipc===1.2.0 @@ -207,7 +219,7 @@ os-client-config===2.3.0 XStatic-Angular-Gettext===2.4.1.1 Deprecated===1.3.1 h11===0.16.0 -Pygments===2.20.0 +Pygments===2.21.0 XStatic-Hogan===2.0.0.5 api_object_schema===2.0.0 XStatic-objectpath===1.2.1.1 @@ -219,10 +231,11 @@ Jinja2===3.1.6 XStatic-Bootstrap-SCSS===3.4.1.1 pyzabbix===1.3.1 ptyprocess===0.7.0 -amqp===5.3.1 +amqp===5.4.0 ruamel.yaml===0.19.1 websockify===0.13.0 -gssapi===1.11.1 +CherryPy===18.10.0 +gssapi===1.12.0 XStatic-JQuery.quicksearch===2.0.3.3 pyasn1_modules===0.4.2 mpmath===1.3.0 @@ -233,8 +246,9 @@ sphinx-feature-classification===2.1.0 XStatic-JQuery-Migrate===3.3.2.2 pytest-html===4.2.0 appdirs===1.4.4 -google-auth-httplib2===0.4.1 +google-auth-httplib2===0.4.2 daiquiri===3.4.0 +apache-libcloud===3.9.1 influxdb===5.3.2 funcparserlib===2.0.0a0 passlib===1.7.4 @@ -243,39 +257,42 @@ os-brick===7.1.1 valkey===6.1.1 scp===0.16.1 lark===1.3.1 +opentelemetry-exporter-prometheus===0.66b0 python-zaqarclient===4.7.0 ldappool===3.0.0 hpack===4.2.0 -joblib===1.5.3 +joblib===1.6.0 roman-numerals===4.1.0 -google-api-python-client===2.198.0 +google-api-python-client===2.200.0 castellan===5.8.0 oslo.versionedobjects===3.12.0 enmerkar===0.7.1 +typer===0.27.2 webcolors===25.10.0 aodhclient===3.12.0 autobahn===26.7.1 +truststore===0.10.4 SQLAlchemy-Utils===0.42.1 retryz===0.1.9 pluggy===1.6.0 -coverage===7.15.4 +coverage===7.16.1 pyee===13.0.1 freezegun===1.5.5 mdurl===0.1.2 toml===0.10.2 -pycdlib===1.20.0 +pycdlib===1.21.0 pyperclip===1.11.0 cassandra-driver===3.30.1 XStatic-Angular-Schema-Form===0.8.13.1 -opentelemetry-exporter-otlp-proto-http===1.44.0 -gabbi===4.2.0 +opentelemetry-exporter-otlp-proto-http===1.45.0 +gabbi===4.2.3 nwdiag===3.0.0 XStatic-bootswatch===3.3.7.1 annotated-types===0.8.0 pytest-xdist===3.8.0 XStatic-JS-Yaml===3.13.1.2 XStatic-term.js===0.0.7.1 -oslo.log===8.3.1 +oslo.log===8.3.2 nodeenv===1.10.0 gossip===2.5.0 suds-community===1.2.0 @@ -283,13 +300,13 @@ os_vif===5.2.1 qrcode===8.2 oslo.middleware===8.2.0 XStatic-mdi===1.6.50.3 -pydantic_core===2.46.4 +pydantic_core===2.46.5 uritemplate===4.2.0 docutils===0.21.2 -threadpoolctl===3.6.0 +threadpoolctl===3.7.0 os-ken===4.2.2 -ujson===5.13.0 -selenium===4.47.0 +ujson===6.0.0 +selenium===4.49.0 pytest-subtests===0.15.0 mistral-lib===3.6.0 dogtag-pki===11.2.1 @@ -298,11 +315,11 @@ dfs_sdk===1.2.27 sphinxcontrib-seqdiag===3.0.0 os-win===5.9.0 capacity===1.3.14 -playwright===1.62.0 +playwright===1.63.0 markdown-it-py===4.2.0 retrying===1.4.2 -python-discovery===1.5.2 -platformdirs===4.11.3 +python-discovery===1.6.1 +platformdirs===4.11.15 pydotplus===2.0.2 boto3===1.35.99 jeepney===0.9.0 @@ -311,7 +328,7 @@ pillow===12.3.0 infoblox-client===0.6.2 oslo.serialization===5.11.0 warlock===2.1.0 -exabgp===5.0.10 +exabgp===5.0.13 aiomysql===0.3.2 sphinxcontrib-httpdomain===2.0.0 metalsmith===2.5.0 @@ -322,7 +339,7 @@ oslo.vmware===4.10.1 autopage===0.6.0 gitdb===4.0.12 python-monascaclient===2.8.0 -opentelemetry-api===1.44.0 +opentelemetry-api===1.45.0 frozenlist===1.8.0 automaton===3.5.0 os-service-types===1.9.0 @@ -330,17 +347,17 @@ keyring===25.7.0 elementpath===4.8.0 wsgi_intercept===1.13.1 jsonschema-specifications===2025.9.1 -testscenarios===0.6.2 +testscenarios===0.7.0 sphinxcontrib-pecanwsme===0.11.0 sadisplay===0.4.9 enum34===1.1.10 infinisdk===289.1.4 rich-argparse===1.8.0 -packaging===26.3 -opentelemetry-exporter-otlp-proto-grpc===1.44.0 +packaging===24.0 +opentelemetry-exporter-otlp-proto-grpc===1.45.0 psutil===7.2.2 txaio===26.6.1 -elasticsearch===9.5.0 +elasticsearch===9.5.1 asgiref===3.12.1 XStatic-JQuery.TableSorter===2.14.5.3 pifpaf===3.4.0 @@ -361,19 +378,19 @@ SecretStorage===3.5.0 XStatic-Rickshaw===1.5.1.3 iso8601===2.1.0 tooz===9.1.0 -idna===3.18 +idna===3.20 Hypercorn===0.18.0 yamlloader===1.6.0 -protobuf===7.35.1 +protobuf===7.36.2 sushy===5.13.0 python-neutronclient===14.0.0 pika===1.4.4 oslo.cache===4.3.0 WebTest===3.0.7 os-collect-config===14.0.1 -edgegrid-python===2.0.7 +edgegrid-python===2.0.8 python-octaviaclient===3.15.0 -pysaml2===7.5.4 +pysaml2===7.5.5 requests-oauthlib===2.0.0 oslo.reports===3.9.0 bitmath===2.1.1 @@ -385,8 +402,9 @@ PyNaCl===1.6.2 osc-lib===4.7.0 more-itertools===11.1.0 seqdiag===3.0.0 +zc.lockfile===4.0 numpy===2.4.6 -msgpack===1.2.1 +msgpack===1.2.2 Sphinx===9.0.4 oslo.config===10.7.0 openstackdocstheme===3.6.0 @@ -395,27 +413,29 @@ rpds-py===2026.6.3 zake===0.2.2 flux===1.4.0 flexparser===0.4 -krb5===0.9.0 -PyMySQL===1.2.0 +krb5===0.10.0 +PyMySQL===1.2.3 uhashring===2.5 kubernetes===36.0.3 httplib2===0.32.0 +opentelemetry-exporter-otlp-common===0.66b0 betamax===0.9.0 construct===2.10.70 pytest-metadata===3.1.1 pyparsing===3.3.2 geomet===1.1.0 -opentelemetry-exporter-otlp-proto-common===1.44.0 +opentelemetry-exporter-otlp-proto-common===1.45.0 distlib===0.4.3 -ast_serialize===0.8.0 +ast_serialize===0.11.2 dogpile.cache===1.5.0 python-barbicanclient===7.6.0 -salt===3008.0 -opentelemetry-semantic-conventions===0.65b0 +salt===3008.2 +opentelemetry-semantic-conventions===0.66b0 blinker===1.9.0 WSME===0.13.0 oslo.upgradecheck===2.8.0 sherlock===0.4.1 +tempora===5.12.0 stevedore===5.9.1 botocore===1.35.99 xmltodict===1.0.4 @@ -424,12 +444,12 @@ oslo.rootwrap===7.10.0 Django===5.2.17 pexpect===4.9.0 elastic-transport===9.4.2 -cmd2===4.2.0 -python-json-logger===4.1.0 +cmd2===4.2.4 +python-json-logger===4.2.0 redis===8.1.0 jmespath===1.1.0 cbor2===6.1.4 -click===8.4.2 +click===8.5.0 XStatic-smart-table===1.4.13.3 kuryr-lib===3.5.0 jsonpatch===1.33 @@ -442,35 +462,39 @@ systemd-python===235 python-memcached===1.62 openstacksdk===4.20.0 infi.dtypes.nqn===0.1.0 +looseversion===1.3.0 six===1.17.0 h2===4.4.1 -dulwich===1.2.12 +dulwich===1.2.15 sentinels===1.1.1 kombu===5.6.2 distro===1.9.0 zstd===1.5.7.2 yaql===3.2.0 -durationpy===0.10 +durationpy===0.11 requestsexceptions===1.4.0 testresources===2.1.2 falcon===4.3.1 tomlkit===0.15.1 +opentelemetry-exporter-http-transport===0.66b0 etcd3gw===2.7.0 +timelib===0.3.0 +rpm_vercmp===0.1.2 Flask-RESTful===0.3.10 -GitPython===3.1.59 +GitPython===3.1.62 python-ironicclient===6.3.0 babel===2.18.0 XStatic===1.0.3 XStatic-Angular-FileUpload===12.2.13.2 python-openstackclient===10.3.0 -pyzmq===27.1.0 +pyzmq===27.2.0 oslo.db===18.1.1 simplegeneric===0.8.1 yappi===1.7.6 mbstrdecoder===1.1.5 wsproto===1.3.2 pymemcache===4.0.0 -wrapt===2.3.0 +wrapt===2.4.1 PySocks===1.7.1 oslo.privsep===3.12.0 sphinxcontrib-apidoc===0.6.0 @@ -499,28 +523,28 @@ hpe-storage-flowkit-py===0.9.5 cachez===0.1.2 XStatic-Bootstrap-Datepicker===1.4.0.1 netifaces===0.11.0 -propcache===0.5.2 -cachetools===7.1.7 +propcache===0.5.4 +cachetools===7.2.0 flexcache===0.3 sphinxcontrib-qthelp===2.0.0 keystoneauth1===5.17.0 statsd===4.0.1 -proto-plus===1.28.3 +proto-plus===1.28.4 python-keystoneclient===6.0.0 -diskimage-builder===3.42.0 +diskimage-builder===3.43.0 py-consul===1.7.1 heat-translator===3.5.0 python-magnumclient===5.0.0 docker===7.2.0 repoze-lru===0.8 storops===1.2.12 -anyio===4.14.2 +anyio===4.15.1 aiosignal===1.4.0 XStatic-Angular-lrdragndrop===1.0.2.7 ovsdbapp===2.19.0 aniso8601===10.0.1 rjsmin===1.2.5 -icalendar===7.2.2 +icalendar===7.3.0 configparser===7.2.0 decorator===5.3.1 DateTimeRange===2.3.2 @@ -530,36 +554,36 @@ futurist===3.5.0 jsonschema===4.26.0 sphinxcontrib-devhelp===2.0.0 python-blazarclient===4.6.0 -alembic===1.19.1 +alembic===1.20.0 execnet===2.1.2 sphinxcontrib-programoutput===0.20 storpool.spopenstack===3.2.0 dnspython===2.8.0 oauthlib===3.3.1 zipp===4.1.0 -greenlet===3.5.5 +greenlet===3.5.6 XStatic-Angular-Vis===4.16.0.1 iniconfig===2.3.0 referencing===0.37.0 -confluent-kafka===2.15.0 +confluent-kafka===2.15.1 backports.tarfile===1.2.0 -narwhals===2.24.0 -xvfbwrapper===0.2.29 +narwhals===2.26.0 +xvfbwrapper===0.2.34 influxdb-client===1.50.0 -tosca-parser===2.14.0 +tosca-parser===2.15.0 python-consul2===0.1.5 -charset-normalizer===3.5.0 +charset-normalizer===3.5.1 Flask===3.1.3 httpx===0.28.1 sqlalchemy-filters===0.13.0 sphinxcontrib-runcmd===0.2.0 confspirator===0.3.0 fasteners===0.20 -importlib_metadata===9.0.0 +importlib_metadata===9.0.1 sortedcontainers===2.4.0 microversion_parse===2.1.0 -python-linstor===1.29.0 -filelock===3.32.3 +python-linstor===1.29.1 +filelock===4.0.3 python-tackerclient===2.6.0 python-heatclient===5.3.0 oslo.utils===10.2.0 @@ -568,14 +592,14 @@ itsdangerous===2.2.0 XStatic-jquery-ui===1.13.0.2 monasca-statsd===2.7.0 python-dateutil===2.9.0.post0 -virtualenv===21.7.4 +virtualenv===21.12.1 colorama===0.4.6 confetti===2.5.3 ironic-lib===7.0.0 aiohappyeyeballs===2.7.1 -pytz===2026.3.post1 -opentelemetry-proto===1.44.0 +pytz===2026.4 +opentelemetry-proto===1.45.0 XStatic-D3===3.5.17.1 actdiag===3.0.0 sphinxcontrib-applehelp===2.0.0 -scikit-learn===1.9.0 +scikit-learn===1.9.1 From 3d18c773440f6e000a33d6de67f05f95fe8e95e5 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Mon, 28 Sep 2026 23:45:42 +0900 Subject: [PATCH 02/25] Downgrade salt salt 3008.2 pins the packaging library to 24.0, which is not compatible with the latest tox. The latest tox requires the packaging.pylock module which was added in packaging 26.0. [1] e940761cf4f0d2505ce95f92ce12fb568d2de67a Change-Id: Ib1eae8b3e3752bba4bc6e75ecb9c6c25b38be58b Signed-off-by: Takashi Kajinami --- upper-constraints.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index b44ddc0be..24ba51218 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -353,7 +353,7 @@ sadisplay===0.4.9 enum34===1.1.10 infinisdk===289.1.4 rich-argparse===1.8.0 -packaging===24.0 +packaging===26.3 opentelemetry-exporter-otlp-proto-grpc===1.45.0 psutil===7.2.2 txaio===26.6.1 @@ -429,7 +429,7 @@ distlib===0.4.3 ast_serialize===0.11.2 dogpile.cache===1.5.0 python-barbicanclient===7.6.0 -salt===3008.2 +salt===3008.0 opentelemetry-semantic-conventions===0.66b0 blinker===1.9.0 WSME===0.13.0 From 994cd799ab2ae9040f96f6d702a229a7ff66cda7 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Thu, 1 Oct 2026 11:30:37 +0000 Subject: [PATCH 03/25] update constraint for os-refresh-config to new release 14.1.0 meta: version: 14.1.0 meta: team: heat meta: diff-start: - meta: series: independent meta: branch: master meta: release-type: release meta: pypi: no meta: first: no meta: release:Author: Takashi Kajinami meta: release:Commit: Takashi Kajinami meta: release:Change-Id: I4c795bf48b6558aa8923a88a45c71292927cc203 meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: I9971d3a58676513d171c3d588426598cd2f91ad9 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 24ba51218..6bb98780c 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -74,7 +74,7 @@ pystache===0.6.8 XStatic-Font-Awesome===6.2.1.2 aiohttp===3.14.3 waitress===3.0.2 -os-refresh-config===14.0.1 +os-refresh-config===14.1.0 pysnmp===7.1.29 Mako===1.4.3 vultr===1.0.1 From bac8d9b2f12815875ce070608e8ebd2d5b128ae0 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Thu, 1 Oct 2026 11:34:37 +0000 Subject: [PATCH 04/25] update constraint for os-apply-config to new release 14.1.0 meta: version: 14.1.0 meta: team: heat meta: diff-start: - meta: series: independent meta: branch: master meta: release-type: release meta: pypi: no meta: first: no meta: release:Author: Takashi Kajinami meta: release:Commit: Takashi Kajinami meta: release:Change-Id: I4c795bf48b6558aa8923a88a45c71292927cc203 meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: I5d4d5089c160564274c00b8987815d61820646b8 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 24ba51218..7fa7c5ad9 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -198,7 +198,7 @@ glance_store===5.7.0 openstack-release-test===8.5.0 pycryptodomex===3.23.0 requests-mock===1.12.1 -os-apply-config===14.0.1 +os-apply-config===14.1.0 xxhash===4.0.1 gunicorn===26.2.0 storpool===7.3.0 From fb491acb493b99e8a5c99fe98014b2f9d5fc4b19 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Thu, 1 Oct 2026 11:35:56 +0000 Subject: [PATCH 05/25] update constraint for os-collect-config to new release 14.1.0 meta: version: 14.1.0 meta: team: heat meta: diff-start: - meta: series: independent meta: branch: master meta: release-type: release meta: pypi: no meta: first: no meta: release:Author: Takashi Kajinami meta: release:Commit: Takashi Kajinami meta: release:Change-Id: I4c795bf48b6558aa8923a88a45c71292927cc203 meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: I0028e5bd22e060e70a229e792e290d0029524a49 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 24ba51218..39711d11e 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -387,7 +387,7 @@ python-neutronclient===14.0.0 pika===1.4.4 oslo.cache===4.3.0 WebTest===3.0.7 -os-collect-config===14.0.1 +os-collect-config===14.1.0 edgegrid-python===2.0.8 python-octaviaclient===3.15.0 pysaml2===7.5.5 From b3ccdfb30f19877d17ab000d2778fddb7470cb7b Mon Sep 17 00:00:00 2001 From: Michal Nasiadka Date: Wed, 8 Jul 2026 12:57:59 +0200 Subject: [PATCH 06/25] Do not fail on optional dependencies Some of the optional dependencies are quite specific to projects and we may not want to maintain these fully in global requirements. Change-Id: I27af77991b850249d9fef3aa60c3645b83ad6cc4 Signed-off-by: Michal Nasiadka --- openstack_requirements/check.py | 46 ++++++--- openstack_requirements/project.py | 8 +- openstack_requirements/tests/test_check.py | 108 ++++++++++++++++++--- 3 files changed, 132 insertions(+), 30 deletions(-) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index c6a5d6637..502ff3fb9 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -36,6 +36,7 @@ class RequirementsList: def __init__(self, name: str, project: Project) -> None: self.name = name self.reqs_by_file: dict[str, dict[str, set[str]]] = {} + self.optional_reqs_by_file: dict[str, dict[str, set[str]]] = {} self.project = project self.failed = False @@ -112,7 +113,7 @@ def process(self, strict: bool = True) -> None: print(f"Processing {fname} (extras)") for name, content in extras.items(): print(f" Processing {name!r} extra") - self.reqs_by_file[f'{fname} ({name!r} extra)'] = ( + self.optional_reqs_by_file[f'{fname} ({name!r} extra)'] = ( self.extract_reqs(content, strict) ) @@ -120,9 +121,9 @@ def process(self, strict: bool = True) -> None: print(f"Processing {fname} (dependency-groups)") for name, content in groups.items(): print(f" Processing {name!r} dependency group") - self.reqs_by_file[f'{fname} ({name!r} dependency group)'] = ( - self.extract_reqs(content, strict) - ) + self.optional_reqs_by_file[ + f'{fname} ({name!r} dependency group)' + ] = self.extract_reqs(content, strict) def _get_exclusions(req): @@ -257,6 +258,8 @@ def _validate_one( denylist, global_reqs, backports, + *, + is_optional, ): """Returns True if there is a failure.""" @@ -267,6 +270,9 @@ def _validate_one( return False if name not in global_reqs: + if is_optional: + return False + print(f"ERROR: Requirement '{reqs}' not in openstack/requirements") return True @@ -319,18 +325,26 @@ def validate( failed = False # iterate through the changing entries and see if they match the global # equivalents we want enforced - for fname, freqs in head_reqs.reqs_by_file.items(): - print(f"Validating {fname}") - for name, reqs in freqs.items(): - failed = ( - _validate_one( - name, - reqs, - denylist, - global_reqs, - backports, + # note that extras and dependency groups are project-specific and may not + # be present in global-requirements, so we only note their absence rather + # than failing if so + for reqs_by_file, is_optional in ( + (head_reqs.reqs_by_file, False), + (head_reqs.optional_reqs_by_file, True), + ): + for fname, freqs in reqs_by_file.items(): + print(f"Validating {fname}") + for name, reqs in freqs.items(): + failed = ( + _validate_one( + name, + reqs, + denylist, + global_reqs, + backports, + is_optional=is_optional, + ) + or failed ) - or failed - ) return failed diff --git a/openstack_requirements/project.py b/openstack_requirements/project.py index 6924a9c08..3676c9e0d 100644 --- a/openstack_requirements/project.py +++ b/openstack_requirements/project.py @@ -164,10 +164,14 @@ def verify_pyproject_toml(root: str) -> bool: return False if 'build-system' not in data: - print("pyproject.toml is missing 'build-system' table", file=sys.stderr) + print( + "pyproject.toml is missing 'build-system' table", file=sys.stderr + ) return False - if (build_backend := data['build-system'].get('build-backend')) != 'pbr.build': + if ( + build_backend := data['build-system'].get('build-backend') + ) != 'pbr.build': print( f"pyproject.toml has invalid 'build-system.build-backend'. " f"Expected 'pbr.build'; got {build_backend!r}", diff --git a/openstack_requirements/tests/test_check.py b/openstack_requirements/tests/test_check.py index 09b28a581..881228323 100644 --- a/openstack_requirements/tests/test_check.py +++ b/openstack_requirements/tests/test_check.py @@ -44,11 +44,15 @@ def test_extras__setup_cfg(self): req_list = check.RequirementsList('test-project', project_data) req_list.process(strict=False) - self.assertIn("setup.cfg ('test' extra)", req_list.reqs_by_file) - self.assertIn("setup.cfg ('dev' extra)", req_list.reqs_by_file) + self.assertIn( + "setup.cfg ('test' extra)", req_list.optional_reqs_by_file + ) + self.assertIn( + "setup.cfg ('dev' extra)", req_list.optional_reqs_by_file + ) - test_reqs = req_list.reqs_by_file["setup.cfg ('test' extra)"] - dev_reqs = req_list.reqs_by_file["setup.cfg ('dev' extra)"] + test_reqs = req_list.optional_reqs_by_file["setup.cfg ('test' extra)"] + dev_reqs = req_list.optional_reqs_by_file["setup.cfg ('dev' extra)"] self.assertEqual(2, len(test_reqs)) self.assertIn('pytest', test_reqs) @@ -88,30 +92,33 @@ def test_extras__pyproject_toml(self): self.assertIn('pyproject.toml (dependencies)', req_list.reqs_by_file) self.assertIn( - "pyproject.toml ('security' extra)", req_list.reqs_by_file + "pyproject.toml ('security' extra)", + req_list.optional_reqs_by_file, ) self.assertIn( - "pyproject.toml ('test' dependency group)", req_list.reqs_by_file + "pyproject.toml ('test' dependency group)", + req_list.optional_reqs_by_file, ) self.assertIn( - "pyproject.toml ('typing' dependency group)", req_list.reqs_by_file + "pyproject.toml ('typing' dependency group)", + req_list.optional_reqs_by_file, ) self.assertIn( "pyproject.toml ('typing-test' dependency group)", - req_list.reqs_by_file, + req_list.optional_reqs_by_file, ) main_reqs = req_list.reqs_by_file['pyproject.toml (dependencies)'] - security_reqs = req_list.reqs_by_file[ + security_reqs = req_list.optional_reqs_by_file[ "pyproject.toml ('security' extra)" ] - test_reqs = req_list.reqs_by_file[ + test_reqs = req_list.optional_reqs_by_file[ "pyproject.toml ('test' dependency group)" ] - typing_reqs = req_list.reqs_by_file[ + typing_reqs = req_list.optional_reqs_by_file[ "pyproject.toml ('typing' dependency group)" ] - typing_test_reqs = req_list.reqs_by_file[ + typing_test_reqs = req_list.optional_reqs_by_file[ "pyproject.toml ('typing-test' dependency group)" ] @@ -347,6 +354,7 @@ def test_unchanged(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -361,6 +369,7 @@ def test_denylisted(self): denylist=requirement.parse('name'), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -376,6 +385,7 @@ def test_denylisted_mismatch(self): denylist=requirement.parse('name'), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -390,6 +400,7 @@ def test_not_in_global_list(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -404,6 +415,7 @@ def test_new_item_matches_global_list(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -419,6 +431,7 @@ def test_new_item_lower_min(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -436,6 +449,7 @@ def test_new_item_extra_exclusion(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -451,6 +465,7 @@ def test_new_item_missing_exclusion(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -476,6 +491,7 @@ def test_new_item_matches_global_list_with_extra(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -500,6 +516,7 @@ def test_new_item_missing_extra_line(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, ) ) @@ -525,6 +542,73 @@ def test_new_item_mismatches_global_list_with_extra(self): denylist=requirement.parse(''), backports=self.backports, global_reqs=global_reqs, + is_optional=False, + ) + ) + + def test_optional_not_in_global_list(self): + # If an optional package is not in the global list, that is not an + # error. + reqs = [r for r, line in requirement.parse('name>=1.2,!=1.4')['name']] + global_reqs = check.get_global_reqs('') + self.assertFalse( + check._validate_one( + 'name', + reqs=reqs, + denylist=requirement.parse(''), + backports=self.backports, + global_reqs=global_reqs, + is_optional=True, + ) + ) + + def test_optional_matches_global_list(self): + # If an optional package is in the global list and matches, + # everything is OK. + reqs = [r for r, line in requirement.parse('name>=1.2,!=1.4')['name']] + global_reqs = check.get_global_reqs('name>=1.2,!=1.4') + self.assertFalse( + check._validate_one( + 'name', + reqs=reqs, + denylist=requirement.parse(''), + backports=self.backports, + global_reqs=global_reqs, + is_optional=True, + ) + ) + + def test_optional_mismatches_global_list(self): + # If an optional package is in the global list and does not match, + # that is an error. + reqs = [ + r for r, line in requirement.parse('name>=1.2,!=1.4,!=1.5')['name'] + ] + global_reqs = check.get_global_reqs('name>=1.2,!=1.4') + self.assertTrue( + check._validate_one( + 'name', + reqs=reqs, + denylist=requirement.parse(''), + backports=self.backports, + global_reqs=global_reqs, + is_optional=True, + ) + ) + + def test_optional_denylisted(self): + # If the optional package is denylisted, everything is OK even if absent + # from global-requirements. + reqs = [r for r, line in requirement.parse('name>=1.2,!=1.4')['name']] + global_reqs = check.get_global_reqs('') + self.assertFalse( + check._validate_one( + 'name', + reqs=reqs, + denylist=requirement.parse('name'), + backports=self.backports, + global_reqs=global_reqs, + is_optional=True, ) ) From 2e5d2be48264f0a27a059eaab06b0b04e6181afc Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 1 Oct 2026 15:09:24 +0100 Subject: [PATCH 07/25] Remove dead code These are unused since I65fd1ae3a4c00a4fd6186f4cd915ae4095c2916f. Change-Id: Ied6621a2e7c1702aa7f0061a6de925359735bfcf Signed-off-by: Stephen Finucane --- openstack_requirements/check.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index c6a5d6637..65ff17508 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -18,12 +18,9 @@ import re import sys -from packaging import markers - from openstack_requirements.project import Project from openstack_requirements import requirement -MIN_PY_VERSION = '3.5' PY3_GLOBAL_SPECIFIER_RE = re.compile( r'python_version(==|>=|>)[\'"]3\.\d+[\'"]' ) @@ -234,23 +231,6 @@ def get_global_reqs(content): return global_reqs -def _get_python3_reqs(reqs): - """Filters out the reqs that are less than our minimum version.""" - results = [] - for req in reqs: - if not req.markers: - results.append(req) - else: - req_markers = markers.Marker(req.markers) - if req_markers.evaluate( - { - 'python_version': MIN_PY_VERSION, - } - ): - results.append(req) - return results - - def _validate_one( name, reqs, From b233f03163602d4ca4623597ff3993ac7c7387c2 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 1 Oct 2026 15:11:52 +0100 Subject: [PATCH 08/25] Remove unused property Nothing is using this in- or out-of-tree. Change-Id: I49ab4d38f3357e4af6bcfaa272f89fb6f4219df4 Signed-off-by: Stephen Finucane --- openstack_requirements/check.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index 65ff17508..d9a262753 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -36,11 +36,6 @@ def __init__(self, name: str, project: Project) -> None: self.project = project self.failed = False - @property - def reqs(self) -> dict[str, set[str]]: - """Flattens the list of per-file reqs.""" - return {k: v for d in self.reqs_by_file.values() for k, v in d.items()} - def extract_reqs( self, content: list[str], strict: bool ) -> dict[str, set[str]]: From abe5957924a34676b3f0a2b791084852cbee5b38 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 2 Oct 2026 11:22:06 +0100 Subject: [PATCH 09/25] Remove backports.txt file, backport handling Commit a968919e (July 2022) and its follow-up commits 5d31764c (July 2022) and 84129943 (October 2022) allowed "backport" packages to have arbitrary python_version markers. The idea was that projects would be able to specify a different python_version marker for backport packages depending on which equivalent Python stdlib version they wanted compatibility with. Commit 28af2ea1 (November 2023) later added the ability to allow *any* package to specify a local python_version marker when said marker did not exist in global-requirements.txt. This was specifically called out for packages like pytz and tzdata, which are not backports but are simply no longer necessary on recent Python versions. This complemented an existing check which allowed the inverse, where global-requirements.txt specified a python_version marker but one was not specified locally. There is a lot of overlap between these checks. The backport check happens after the other two checks, which means the only case where this will trigger is if both global and local requirements specify a python_version marker *and* there is a mismatch *and* the package is in the list of backports. However, our backports.txt file still only contains a single entry - importlib-metadata - and there is no marker specified for this in global-requirements.txt. As a result, the best course of action here is to drop the file and supporting logic entirely. The local-only marker logic added in 28af2ea1 is sufficient for our use case. Change-Id: I5e9fba2320975053b46524876ec13c0a43121177 Signed-off-by: Stephen Finucane --- backports.txt | 1 - openstack_requirements/check.py | 44 +++------- openstack_requirements/tests/test_check.py | 83 ------------------- .../files/project-requirements-change.py | 8 -- 4 files changed, 11 insertions(+), 125 deletions(-) delete mode 100644 backports.txt diff --git a/backports.txt b/backports.txt deleted file mode 100644 index d0437a41d..000000000 --- a/backports.txt +++ /dev/null @@ -1 +0,0 @@ -importlib-metadata diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index e3d877272..cca3a3293 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -129,7 +129,6 @@ def _get_exclusions(req): def _is_requirement_in_global_reqs( local_req, global_reqs, - backports, ): req_exclusions = _get_exclusions(local_req) for global_req in global_reqs: @@ -138,14 +137,19 @@ def _is_requirement_in_global_reqs( local_req_val = getattr(local_req, aname) global_req_val = getattr(global_req, aname) if local_req_val != global_req_val: - # if a python 3 version is not specified in only one of - # global requirements or local requirements, allow it since - # python 3-only is okay if matching and aname == 'markers': - if not local_req_val and PY3_GLOBAL_SPECIFIER_RE.match( - global_req_val + # if a Python version marker is specified globally but not + # locally, allow it since this is unnecessary boilerplate + # for projects to carry + if ( + not local_req_val + and PY3_GLOBAL_SPECIFIER_RE.match(global_req_val) ): continue + + # if a Python version marker is specified locally but not + # globally, allow it since projects might only need the + # package on specific Python versions if ( not global_req_val and local_req_val @@ -153,25 +157,6 @@ def _is_requirement_in_global_reqs( ): continue - # likewise, if a package is one of the backport packages then - # we're okay with a potential marker (e.g. if a package - # requires a feature that is only available in a newer Python - # library, while other packages are happy without this feature - if ( - matching - and aname == 'markers' - and local_req.package in backports - ): - if re.match( - r'python_version(==|<=|<)[\'"]3\.\d+[\'"]', - local_req_val, - ): - print( - 'Ignoring backport package with python_version ' - 'marker' - ) - continue - print( f'WARNING: possible mismatch found for package "{local_req.package}"' ) # noqa: E501 @@ -232,7 +217,6 @@ def _validate_one( reqs, denylist, global_reqs, - backports, *, is_optional, ): @@ -259,11 +243,7 @@ def _validate_one( else: counts[''] = counts.get('', 0) + 1 - if not _is_requirement_in_global_reqs( - req, - global_reqs[name], - backports, - ): + if not _is_requirement_in_global_reqs(req, global_reqs[name]): return True # check for minimum being defined @@ -295,7 +275,6 @@ def validate( head_reqs, denylist, global_reqs, - backports, ): failed = False # iterate through the changing entries and see if they match the global @@ -316,7 +295,6 @@ def validate( reqs, denylist, global_reqs, - backports, is_optional=is_optional, ) or failed diff --git a/openstack_requirements/tests/test_check.py b/openstack_requirements/tests/test_check.py index 881228323..18c6e02ef 100644 --- a/openstack_requirements/tests/test_check.py +++ b/openstack_requirements/tests/test_check.py @@ -150,7 +150,6 @@ def setUp(self): self._stdout_fixture = fixtures.StringStream('stdout') self.stdout = self.useFixture(self._stdout_fixture).stream - self.backports = list() self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) self.global_reqs = check.get_global_reqs( @@ -168,7 +167,6 @@ def test_match(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -183,7 +181,6 @@ def test_match_with_markers(self): check._is_requirement_in_global_reqs( req, self.global_reqs['withmarker'], - self.backports, ) ) @@ -198,7 +195,6 @@ def test_match_with_local_markers(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -217,22 +213,6 @@ def test_match_without_python3_markers(self): check._is_requirement_in_global_reqs( req, self.global_reqs['withmarker'], - self.backports, - ) - ) - - def test_backport(self): - """Test a stdlib backport pacakge. - - The python_version marker should be ignored for stdlib backport-type - packages. - """ - req = requirement.parse("name;python_version<'3.9'")['name'][0][0] - self.assertTrue( - check._is_requirement_in_global_reqs( - req, - self.global_reqs['name'], - ['name'], ) ) @@ -246,7 +226,6 @@ def test_name_mismatch(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -261,7 +240,6 @@ def test_marker_mismatch(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -277,7 +255,6 @@ def test_min_mismatch(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -292,7 +269,6 @@ def test_extra_exclusion(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -306,7 +282,6 @@ def test_missing_exclusion(self): check._is_requirement_in_global_reqs( req, self.global_reqs['name'], - self.backports, ) ) @@ -340,7 +315,6 @@ def setUp(self): self._stdout_fixture = fixtures.StringStream('stdout') self.stdout = self.useFixture(self._stdout_fixture).stream self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) - self.backports = dict() def test_unchanged(self): # If the line matches the value in the branch list everything @@ -352,7 +326,6 @@ def test_unchanged(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -367,7 +340,6 @@ def test_denylisted(self): 'name', reqs=reqs, denylist=requirement.parse('name'), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -383,7 +355,6 @@ def test_denylisted_mismatch(self): 'name', reqs=reqs, denylist=requirement.parse('name'), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -398,7 +369,6 @@ def test_not_in_global_list(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -413,7 +383,6 @@ def test_new_item_matches_global_list(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -429,7 +398,6 @@ def test_new_item_lower_min(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -447,7 +415,6 @@ def test_new_item_extra_exclusion(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -463,7 +430,6 @@ def test_new_item_missing_exclusion(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -489,7 +455,6 @@ def test_new_item_matches_global_list_with_extra(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -514,7 +479,6 @@ def test_new_item_missing_extra_line(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -540,7 +504,6 @@ def test_new_item_mismatches_global_list_with_extra(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=False, ) @@ -556,7 +519,6 @@ def test_optional_not_in_global_list(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=True, ) @@ -572,7 +534,6 @@ def test_optional_matches_global_list(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=True, ) @@ -590,7 +551,6 @@ def test_optional_mismatches_global_list(self): 'name', reqs=reqs, denylist=requirement.parse(''), - backports=self.backports, global_reqs=global_reqs, is_optional=True, ) @@ -606,50 +566,7 @@ def test_optional_denylisted(self): 'name', reqs=reqs, denylist=requirement.parse('name'), - backports=self.backports, global_reqs=global_reqs, is_optional=True, ) ) - - -class TestBackportPythonMarkers(testtools.TestCase): - def setUp(self): - super().setUp() - self._stdout_fixture = fixtures.StringStream('stdout') - self.stdout = self.useFixture(self._stdout_fixture).stream - self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout)) - - self.req = requirement.parse( - textwrap.dedent(""" - name>=1.5;python_version=='3.11' - """) - )['name'][0][0] - self.global_reqs = check.get_global_reqs( - textwrap.dedent(""" - name>=1.5;python_version=='3.10' - """) - ) - - def test_notmatching_no_backport(self): - backports = requirement.parse("") - self.assertFalse( - check._is_requirement_in_global_reqs( - self.req, - self.global_reqs["name"], - list(backports.keys()), - ) - ) - - def test_notmatching_with_backport(self): - b_content = textwrap.dedent(""" - name - """) - backports = requirement.parse(b_content) - self.assertTrue( - check._is_requirement_in_global_reqs( - self.req, - self.global_reqs["name"], - list(backports.keys()), - ) - ) diff --git a/playbooks/files/project-requirements-change.py b/playbooks/files/project-requirements-change.py index 1baf73733..f063515d5 100755 --- a/playbooks/files/project-requirements-change.py +++ b/playbooks/files/project-requirements-change.py @@ -118,13 +118,6 @@ def main(): with open(os.path.join(reqdir, 'denylist.txt')) as fh: denylist = requirement.parse(fh.read()) - backports_file = os.path.join(reqdir, 'backports.txt') - if os.path.exists(backports_file): - with open(backports_file) as fh: - backports = requirement.parse(fh.read()) - else: - backports = {} - cwd = os.getcwd() # Verify that pyproject.toml is present and contains the required @@ -153,7 +146,6 @@ def main(): head_reqs, denylist, global_reqs, - list(backports.keys()), ) # report the results From 7d877fc93c4c674e061c2f44d32bea4d2ac762b6 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 2 Oct 2026 11:45:30 +0100 Subject: [PATCH 10/25] Allow projects to drop their Windows specifiers OpenStack no longer supports Windows. Additionally, pbr has a bug with setuptools >= 83.0.0 where it silently drops dependencies that carry PEP 508 environment markers like sys_platform!='win32' [1]. Ultimately the fix here exists in pbr, but there's no reason we shouldn't let projects drop these specifiers anyway, given we no longer care about Windows. [1] https://bugs.launchpad.net/pbr/+bug/2162730 Change-Id: Id6ddc9d85a27f3bc40b4a680b020a61c29aeb15e Signed-off-by: Stephen Finucane --- openstack_requirements/check.py | 9 ++++ openstack_requirements/tests/test_check.py | 61 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index cca3a3293..67826fd64 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -27,6 +27,7 @@ PY3_LOCAL_SPECIFIER_RE = re.compile( r'python_version(==|>=|>|<=|<)[\'"]3\.\d+[\'"]' ) +WINDOWS_SPECIFIER_RE = re.compile(r'sys_platform!=[\'"]win32[\'"]') class RequirementsList: @@ -157,6 +158,14 @@ def _is_requirement_in_global_reqs( ): continue + # OpenStack no longer supports Windows. If a package wants + # to drop their sys_platform marker, let them. + if ( + not local_req_val + and WINDOWS_SPECIFIER_RE.match(global_req_val) + ): + continue + print( f'WARNING: possible mismatch found for package "{local_req.package}"' ) # noqa: E501 diff --git a/openstack_requirements/tests/test_check.py b/openstack_requirements/tests/test_check.py index 18c6e02ef..4dbcf487b 100644 --- a/openstack_requirements/tests/test_check.py +++ b/openstack_requirements/tests/test_check.py @@ -157,6 +157,7 @@ def setUp(self): name>=1.2,!=1.4 withmarker>=1.5;python_version=='3.5' withmarker>=1.2,!=1.4;python_version=='2.7' + withwinmarker>=1.0;sys_platform!='win32' """) ) @@ -216,6 +217,49 @@ def test_match_without_python3_markers(self): ) ) + def test_match_with_windows_markers(self): + """Test a package specified with Windows markers.""" + req = requirement.parse( + textwrap.dedent(""" + withwinmarker>=1.0;sys_platform!='win32' + """) + )['withwinmarker'][0][0] + self.assertTrue( + check._is_requirement_in_global_reqs( + req, + self.global_reqs['withwinmarker'], + ) + ) + + def test_match_without_windows_markers(self): + """Test a package specified without Windows markers. + + OpenStack no longer supports Windows, so packages can drop Windows + markers even if they are present in global requirements. + """ + req = requirement.parse( + textwrap.dedent(""" + withwinmarker>=1.0 + """) + )['withwinmarker'][0][0] + self.assertTrue( + check._is_requirement_in_global_reqs( + req, + self.global_reqs['withwinmarker'], + ) + ) + + # Also test with double quotes + global_reqs = check.get_global_reqs( + 'withwinmarker>=1.0;sys_platform!="win32"' + ) + self.assertTrue( + check._is_requirement_in_global_reqs( + req, + global_reqs['withwinmarker'], + ) + ) + def test_name_mismatch(self): """Test a mismatch in package names. @@ -388,6 +432,23 @@ def test_new_item_matches_global_list(self): ) ) + def test_new_item_matches_global_list_without_windows_marker(self): + # A project can omit the Windows marker even if it's present in the + # global list. + reqs = [r for r, line in requirement.parse('name>=1.2,!=1.4')['name']] + global_reqs = check.get_global_reqs( + "name>=1.2,!=1.4;sys_platform!='win32'" + ) + self.assertFalse( + check._validate_one( + 'name', + reqs=reqs, + denylist=requirement.parse(''), + global_reqs=global_reqs, + is_optional=False, + ) + ) + def test_new_item_lower_min(self): # If the new item has a lower minimum value than the global # list, that is OK. From 0cf20d3be791501704bc5f853d8d7e418d5d4e6c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 2 Oct 2026 12:13:58 +0100 Subject: [PATCH 11/25] test: Remove use of testscenarios This is not required since the addition of TestCase.subTest in Python 3.4 [1]. [1] https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests Change-Id: Ia81ebd808b135300b3a37f22e21aafddc90b9228 Signed-off-by: Stephen Finucane --- .../tests/test_check_constraints.py | 3 - .../tests/test_edit_constraint.py | 4 - openstack_requirements/tests/test_project.py | 4 - .../tests/test_requirement.py | 181 ++++++++---------- test-requirements.txt | 1 - 5 files changed, 77 insertions(+), 116 deletions(-) diff --git a/openstack_requirements/tests/test_check_constraints.py b/openstack_requirements/tests/test_check_constraints.py index 311944a56..3592c1dd8 100644 --- a/openstack_requirements/tests/test_check_constraints.py +++ b/openstack_requirements/tests/test_check_constraints.py @@ -14,15 +14,12 @@ import os from unittest import mock -import testscenarios import testtools from openstack_requirements.cmds import check_exists from openstack_requirements import project from openstack_requirements.tests import common -load_tests = testscenarios.load_tests_apply_scenarios - def mock_read_requirements_file(filename): if os.path.basename(filename) == 'upper-constraints.txt': diff --git a/openstack_requirements/tests/test_edit_constraint.py b/openstack_requirements/tests/test_edit_constraint.py index b65acd22a..eeb80d0d2 100644 --- a/openstack_requirements/tests/test_edit_constraint.py +++ b/openstack_requirements/tests/test_edit_constraint.py @@ -15,16 +15,12 @@ import textwrap import fixtures -import testscenarios import testtools from openstack_requirements.cmds import edit_constraint as edit from openstack_requirements import requirement -load_tests = testscenarios.load_tests_apply_scenarios - - class SmokeTest(testtools.TestCase): def test_make_url(self): stdout = io.StringIO() diff --git a/openstack_requirements/tests/test_project.py b/openstack_requirements/tests/test_project.py index 99f3dd8b5..336829fec 100644 --- a/openstack_requirements/tests/test_project.py +++ b/openstack_requirements/tests/test_project.py @@ -15,16 +15,12 @@ import textwrap import fixtures -import testscenarios import testtools from openstack_requirements import project from openstack_requirements.tests import common -load_tests = testscenarios.load_tests_apply_scenarios - - class TestReadProject(testtools.TestCase): def test_pyproject_toml(self): root = self.useFixture(common.pep_518_fixture).root diff --git a/openstack_requirements/tests/test_requirement.py b/openstack_requirements/tests/test_requirement.py index 1de817623..be896cda4 100644 --- a/openstack_requirements/tests/test_requirement.py +++ b/openstack_requirements/tests/test_requirement.py @@ -12,187 +12,160 @@ import textwrap -import testscenarios import testtools from openstack_requirements import requirement -load_tests = testscenarios.load_tests_apply_scenarios - - class TestParseRequirement(testtools.TestCase): dist_scenarios = [ ( 'package', - dict( - line='swift', - req=requirement.Requirement('swift', '', '', '', ''), - ), + 'swift', + requirement.Requirement('swift', '', '', '', ''), + False, ), ( 'specifier', - dict( - line='alembic>=0.4.1', - req=requirement.Requirement('alembic', '', '>=0.4.1', '', ''), - ), + 'alembic>=0.4.1', + requirement.Requirement('alembic', '', '>=0.4.1', '', ''), + False, ), ( 'specifiers', - dict( - line='alembic>=0.4.1,!=1.1.8', - req=requirement.Requirement( - 'alembic', '', '!=1.1.8,>=0.4.1', '', '' - ), + 'alembic>=0.4.1,!=1.1.8', + requirement.Requirement( + 'alembic', '', '!=1.1.8,>=0.4.1', '', '' ), + False, ), ( 'comment-only', - dict( - line='# foo', - req=requirement.Requirement('', '', '', '', '# foo'), - ), + '# foo', + requirement.Requirement('', '', '', '', '# foo'), + False, ), ( 'comment', - dict( - line='Pint>=0.5 # BSD', - req=requirement.Requirement('Pint', '', '>=0.5', '', '# BSD'), - ), + 'Pint>=0.5 # BSD', + requirement.Requirement('Pint', '', '>=0.5', '', '# BSD'), + False, ), ( 'comment-with-semicolon', - dict( - line='Pint>=0.5 # BSD;fred', - req=requirement.Requirement( - 'Pint', '', '>=0.5', '', '# BSD;fred' - ), - ), + 'Pint>=0.5 # BSD;fred', + requirement.Requirement('Pint', '', '>=0.5', '', '# BSD;fred'), + False, ), ( 'case', - dict( - line='Babel>=1.3', - req=requirement.Requirement('Babel', '', '>=1.3', '', ''), - ), + 'Babel>=1.3', + requirement.Requirement('Babel', '', '>=1.3', '', ''), + False, ), ( 'markers', - dict( - line="pywin32;sys_platform=='win32'", - req=requirement.Requirement( - 'pywin32', '', '', "sys_platform=='win32'", '' - ), + "pywin32;sys_platform=='win32'", + requirement.Requirement( + 'pywin32', '', '', "sys_platform=='win32'", '' ), + False, ), ( 'markers-with-comment', - dict( - line="Sphinx<=1.2; python_version=='2.7'# Sadface", - req=requirement.Requirement( - 'Sphinx', '', '<=1.2', "python_version=='2.7'", '# Sadface' - ), + "Sphinx<=1.2; python_version=='2.7'# Sadface", + requirement.Requirement( + 'Sphinx', '', '<=1.2', "python_version=='2.7'", '# Sadface' ), + False, ), ] url_scenarios = [ ( 'url', - dict( - line='file:///path/to/thing#egg=thing', - req=requirement.Requirement( - 'thing', 'file:///path/to/thing', '', '', '' - ), - permit_urls=True, + 'file:///path/to/thing#egg=thing', + requirement.Requirement( + 'thing', 'file:///path/to/thing', '', '', '' ), + True, ), ( 'oslo-url', - dict( - line='file:///path/to/oslo.thing#egg=oslo.thing', - req=requirement.Requirement( - 'oslo.thing', 'file:///path/to/oslo.thing', '', '', '' - ), - permit_urls=True, + 'file:///path/to/oslo.thing#egg=oslo.thing', + requirement.Requirement( + 'oslo.thing', 'file:///path/to/oslo.thing', '', '', '' ), + True, ), ( 'url-comment', - dict( - line='file:///path/to/thing#egg=thing # http://altpath#egg=boo', - req=requirement.Requirement( - 'thing', - 'file:///path/to/thing', - '', - '', - '# http://altpath#egg=boo', - ), - permit_urls=True, + 'file:///path/to/thing#egg=thing # http://altpath#egg=boo', + requirement.Requirement( + 'thing', + 'file:///path/to/thing', + '', + '', + '# http://altpath#egg=boo', ), + True, ), ( 'editable', - dict( - line='-e file:///path/to/bar#egg=bar', - req=requirement.Requirement( - 'bar', '-e file:///path/to/bar', '', '', '' - ), - permit_urls=True, + '-e file:///path/to/bar#egg=bar', + requirement.Requirement( + 'bar', '-e file:///path/to/bar', '', '', '' ), + True, ), ( 'editable_vcs_git', - dict( - line='-e git+http://github.com/path/to/oslo.bar#egg=oslo.bar', - req=requirement.Requirement( - 'oslo.bar', - '-e git+http://github.com/path/to/oslo.bar', - '', - '', - '', - ), - permit_urls=True, + '-e git+http://github.com/path/to/oslo.bar#egg=oslo.bar', + requirement.Requirement( + 'oslo.bar', + '-e git+http://github.com/path/to/oslo.bar', + '', + '', + '', ), + True, ), ( 'editable_vcs_git_ssh', - dict( - line='-e git+ssh://github.com/path/to/oslo.bar#egg=oslo.bar', - req=requirement.Requirement( - 'oslo.bar', - '-e git+ssh://github.com/path/to/oslo.bar', - '', - '', - '', - ), - permit_urls=True, + '-e git+ssh://github.com/path/to/oslo.bar#egg=oslo.bar', + requirement.Requirement( + 'oslo.bar', + '-e git+ssh://github.com/path/to/oslo.bar', + '', + '', + '', ), + True, ), ] scenarios = dist_scenarios + url_scenarios def test_parse(self): - parsed = requirement.parse_line( - self.line, permit_urls=getattr(self, 'permit_urls', False) - ) - self.assertEqual(self.req, parsed) + for name, line, req, permit_urls in self.scenarios: + with self.subTest(name): + parsed = requirement.parse_line(line, permit_urls=permit_urls) + self.assertEqual(req, parsed) class TestParseRequirementFailures(testtools.TestCase): scenarios = [ ( 'url', - dict( - line='http://tarballs.openstack.org/oslo.config/' - 'oslo.config-1.2.0a3.tar.gz#egg=oslo.config' - ), + 'http://tarballs.openstack.org/oslo.config/oslo.config-1.2.0a3.tar.gz#egg=oslo.config', ), - ('-e', dict(line='-e git+https://foo.com#egg=foo')), - ('-f', dict(line='-f http://tarballs.openstack.org/')), + ('-e', '-e git+https://foo.com#egg=foo'), + ('-f', '-f http://tarballs.openstack.org/'), ] def test_does_not_parse(self): - self.assertRaises(ValueError, requirement.parse_line, self.line) + for name, line in self.scenarios: + with self.subTest(name): + with self.assertRaises(ValueError): + requirement.parse_line(line) class TestToContent(testtools.TestCase): diff --git a/test-requirements.txt b/test-requirements.txt index 69ff89422..c710fc3e1 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,5 @@ # NOTE: These are requirements for testing the requirements project only # See global-requirements for the actual requirements list stestr>=1.0.0 # Apache-2.0 -testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT virtualenv>=14.0.6 # MIT From ac8d1dd2c1183f2b75a040bab0688ff226d7b4c4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 2 Oct 2026 12:43:37 +0100 Subject: [PATCH 12/25] Remove tomli dependency We only support Python 3.11+ now so we can depend on the stdlib tomllib. Change-Id: Iec4bd48cb007521055178657daaa68c042a129fb Signed-off-by: Stephen Finucane --- openstack_requirements/project.py | 8 +------- requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/openstack_requirements/project.py b/openstack_requirements/project.py index 3676c9e0d..f0bad78b1 100644 --- a/openstack_requirements/project.py +++ b/openstack_requirements/project.py @@ -20,16 +20,10 @@ import io import os import sys +import tomllib from typing import Any from typing import TypedDict -try: - # Python 3.11+ - import tomllib -except ImportError: - # Python 3.10 and lower - import tomli as tomllib # type: ignore - def _read_raw(root: str, filename: str) -> str | None: try: diff --git a/requirements.txt b/requirements.txt index 1ed6c384f..dd27509d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ +# NOTE: These are requirements for the requirements project only +# See global-requirements for the actual requirements list fixtures>=3.0.0 # Apache-2.0/BSD packaging!=20.5,!=20.6,!=20.7,>=16.5 # Apache-2.0 requests>=2.14.2 # Apache-2.0 PyYAML>=3.12 # MIT beagle>=0.2.1 # Apache-2.0 setuptools!=24.0.0,!=34.0.0,!=34.0.1,!=34.0.2,!=34.0.3,!=34.1.0,!=34.1.1,!=34.2.0,!=34.3.0,!=34.3.1,!=34.3.2,!=36.2.0,>=21.0.0 # PSF/ZPL -tomli;python_version<'3.11' # MIT From 5c724ec0b755ad197211d81ad1639283fa91fe1a Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Mon, 5 Oct 2026 15:56:19 +0000 Subject: [PATCH 13/25] update constraint for openstack-release-test to new release 8.6.0 meta: version: 8.6.0 meta: team: Release Management meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: no meta: first: yes meta: release:Author: Elod Illes meta: release:Commit: Elod Illes meta: release:Change-Id: I5fc84f01b9d9ceedb87169b9aa0ae4e2b3734074 meta: release:Code-Review+2: Jeremy Stanley meta: release:Workflow+1: Jeremy Stanley Change-Id: I9f087b780279ad1be4119b8376556d82e6c12cc2 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..fbe5de1dc 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -195,7 +195,7 @@ httpcore===1.0.9 URLObject===3.0.0 psycopg2-binary===2.9.13 glance_store===5.7.0 -openstack-release-test===8.5.0 +openstack-release-test===8.6.0 pycryptodomex===3.23.0 requests-mock===1.12.1 os-apply-config===14.1.0 From c9301f6565425a49763441655cf568d4b83f6a38 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 28 Sep 2026 16:00:58 +0100 Subject: [PATCH 14/25] tox: Fail if ruff format makes changes We were not checking the result of the ruff commands, which meant it could make changes but we wouldn't see failures in CI. Fix this by adding the missing arguments to ensure this happens and address issues that have crept in in the interim. Change-Id: Ide5b9a452255a9f36ccb7057be833901271e89fe Signed-off-by: Stephen Finucane --- openstack_requirements/check.py | 10 ++++------ openstack_requirements/tests/test_requirement.py | 4 +--- tox.ini | 8 ++++---- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index 67826fd64..c7794aef5 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -142,9 +142,8 @@ def _is_requirement_in_global_reqs( # if a Python version marker is specified globally but not # locally, allow it since this is unnecessary boilerplate # for projects to carry - if ( - not local_req_val - and PY3_GLOBAL_SPECIFIER_RE.match(global_req_val) + if not local_req_val and PY3_GLOBAL_SPECIFIER_RE.match( + global_req_val ): continue @@ -160,9 +159,8 @@ def _is_requirement_in_global_reqs( # OpenStack no longer supports Windows. If a package wants # to drop their sys_platform marker, let them. - if ( - not local_req_val - and WINDOWS_SPECIFIER_RE.match(global_req_val) + if not local_req_val and WINDOWS_SPECIFIER_RE.match( + global_req_val ): continue diff --git a/openstack_requirements/tests/test_requirement.py b/openstack_requirements/tests/test_requirement.py index be896cda4..14132356c 100644 --- a/openstack_requirements/tests/test_requirement.py +++ b/openstack_requirements/tests/test_requirement.py @@ -34,9 +34,7 @@ class TestParseRequirement(testtools.TestCase): ( 'specifiers', 'alembic>=0.4.1,!=1.1.8', - requirement.Requirement( - 'alembic', '', '!=1.1.8,>=0.4.1', '', '' - ), + requirement.Requirement('alembic', '', '!=1.1.8,>=0.4.1', '', ''), False, ), ( diff --git a/tox.ini b/tox.ini index e335a8c07..827bfe34a 100644 --- a/tox.ini +++ b/tox.ini @@ -62,14 +62,14 @@ commands = validate-projects {toxinidir}/projects.txt description = Perform linting skip_install = true deps = - ruff~=0.13.0 # MIT - hacking~=7.0 # Apache-2.0 + ruff~=0.16.0 # MIT + hacking~=8.0 # Apache-2.0 bashate~=2.1 # Apache-2.0 allowlist_externals = bash commands = - ruff check --fix --unsafe-fixes - ruff format + ruff check --fix --unsafe-fixes --exit-non-zero-on-fix + ruff format --exit-non-zero-on-format flake8 bash -c "find {toxinidir}/tools \ -type f \ From 4068debe3d1c94a44391c1e83ae96c3f2a5392ef Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 28 Sep 2026 16:10:32 +0100 Subject: [PATCH 15/25] ruff: Enable E5 rules The E5 rules included E501 (line too long) and E502 (backslash is redundant between brackets) rules. The former is important since it catches cases of too long strings, which ruff won't automatically rewrap for us (doing so would be an AST change). This contrasts with function calls, which ruff has handled all along (due to tool.ruff.line-length being set in pyproject.toml). Enable these rules and manually fix the issues that they highlight. In most cases this just means splitting string across lines, but we also tweak how some print statements are handled. Change-Id: I7574f7f8f13412f6d819e6f719d0d199c8449c2d Signed-off-by: Stephen Finucane --- doc/source/conf.py | 14 +++++++------- openstack_requirements/check.py | 18 ++++++++---------- openstack_requirements/cmds/check_exists.py | 19 ++++++++++++------- openstack_requirements/constraints.py | 6 ++++-- openstack_requirements/project_config.py | 3 ++- openstack_requirements/requirement.py | 3 ++- openstack_requirements/tests/test_check.py | 4 ++-- openstack_requirements/tests/test_generate.py | 2 +- pyproject.toml | 2 +- 9 files changed, 39 insertions(+), 32 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index ee761f553..0891c2fb7 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,7 +1,7 @@ -# -- General configuration ----------------------------------------------------- +# -- General configuration ---------------------------------------------------- -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['openstackdocstheme'] todo_include_todos = True @@ -30,7 +30,7 @@ # A list of ignored prefixes for module index sorting. modindex_common_prefix = ['requirements-doc.'] -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. @@ -42,10 +42,10 @@ # If false, no index is generated. html_use_index = False -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output ------------------------------------------------- # Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). +# (index file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ( 'index', @@ -56,7 +56,7 @@ ), ] -# -- Options for openstackdocstheme extension ---------------------------------- +# -- Options for openstackdocstheme extension --------------------------------- openstackdocs_repo_name = 'openstack/requirements' openstackdocs_auto_name = False diff --git a/openstack_requirements/check.py b/openstack_requirements/check.py index c7794aef5..ed1444ea3 100644 --- a/openstack_requirements/check.py +++ b/openstack_requirements/check.py @@ -165,14 +165,13 @@ def _is_requirement_in_global_reqs( continue print( - f'WARNING: possible mismatch found for package "{local_req.package}"' - ) # noqa: E501 - print(f' Attribute "{aname}" does not match') - print( - f' "{local_req_val}" does not match "{global_req_val}"' - ) # noqa: E501 - print(f' {local_req}') - print(f' {global_req}') + f'WARNING: possible mismatch found for package ' + f'{local_req.package!r}\n' + f' Attribute "{aname}" does not match\n' + f' "{local_req_val}" does not match "{global_req_val}"\n' + f' {local_req}\n' + f' {global_req}' + ) matching = False if not matching: continue @@ -187,8 +186,7 @@ def _is_requirement_in_global_reqs( difference = req_exclusions - global_exclusions print( f"ERROR: Requirement for package {local_req.package} " - f"excludes a version not excluded in the " - f"global list.\n" + f"excludes a version not excluded in the global list.\n" f" Local settings : {list(req_exclusions)}\n" f" Global settings: {list(global_exclusions)}\n" f" Unexpected : {list(difference)}" diff --git a/openstack_requirements/cmds/check_exists.py b/openstack_requirements/cmds/check_exists.py index dd2d5c680..95a989cbc 100644 --- a/openstack_requirements/cmds/check_exists.py +++ b/openstack_requirements/cmds/check_exists.py @@ -65,7 +65,8 @@ def main(args=None): for require_file, data in project_data.get('requirements', {}).items(): print( - f'\nComparing {require_file} with global-requirements and upper-constraints' + f'\nComparing {require_file} with global-requirements and ' + f'upper-constraints' ) requirements = requirement.parse_lines(data) for name, spec_list in requirements.items(): @@ -73,13 +74,15 @@ def main(args=None): continue if name not in global_requirements: print( - f'{name} from {require_file} not found in global-requirements' + f'{name} from {require_file} not found in ' + f'global-requirements' ) error_count += 1 continue if name not in upper_constraints: print( - f'{name} from {require_file} not found in upper-constraints' + f'{name} from {require_file} not found in ' + f'upper-constraints' ) error_count += 1 continue @@ -95,8 +98,9 @@ def main(args=None): # then something is wrong. if Version(uc_spec.version) not in specs: print( - f'{name} must be <= {uc_spec.version} from upper-constraints and ' - 'include the upper-constraints version' + f'{name} must be <= {uc_spec.version} from ' + f'upper-constraints and include the ' + f'upper-constraints version' ) error_count += 1 continue @@ -109,8 +113,9 @@ def main(args=None): continue if spec.version not in spec_gr: print( - f'Specifier {spec.version} from {name} is failing check ' - f'from global-requirements specifiers {str(spec_gr)}' + f'Specifier {spec.version} from {name} is ' + f'failing check from global-requirements ' + f'specifiers {str(spec_gr)}' ) error_count += 1 continue diff --git a/openstack_requirements/constraints.py b/openstack_requirements/constraints.py index f06d0e0fe..3adce31dc 100644 --- a/openstack_requirements/constraints.py +++ b/openstack_requirements/constraints.py @@ -67,7 +67,8 @@ def check_format(parsed_constraints): for req, original_line in spec_list: if not req.specifiers.startswith('==='): yield ( - f'Invalid constraint for {name} does not have 3 "=": {original_line}' + f'Invalid constraint for {name} does not have 3 "=": ' + f'{original_line}' ) @@ -106,7 +107,8 @@ def satisfied(reqs, name, version, failures): return True tested.append(constraint.specifiers) failures.append( - f'Constraint {version} for {name} does not match requirement {tested}' + f'Constraint {version} for {name} does not match requirement ' + f'{tested}' ) return False diff --git a/openstack_requirements/project_config.py b/openstack_requirements/project_config.py index 23c91704d..71831df0d 100644 --- a/openstack_requirements/project_config.py +++ b/openstack_requirements/project_config.py @@ -54,6 +54,7 @@ def require_check_requirements_for_repo(zuul_projects, repo): # jobs, because we want projects to use the templates. if 'check-requirements' not in templates: errors.append( - f'{ZUUL_PROJECTS_FILENAME} no check-requirements job specified for {repo}' + f'{ZUUL_PROJECTS_FILENAME} no check-requirements job ' + f'specified for {repo}' ) return errors diff --git a/openstack_requirements/requirement.py b/openstack_requirements/requirement.py index 40e4ea325..020d4048a 100644 --- a/openstack_requirements/requirement.py +++ b/openstack_requirements/requirement.py @@ -242,5 +242,6 @@ def check_reqs_bounds_policy(global_reqs): lower_bound.add(spec) if len(lower_bound): yield ( - f'Requirement {req.package} should not include a >= specifier' + f'Requirement {req.package} should not include a >= ' + f'specifier' ) diff --git a/openstack_requirements/tests/test_check.py b/openstack_requirements/tests/test_check.py index 4dbcf487b..51b02f640 100644 --- a/openstack_requirements/tests/test_check.py +++ b/openstack_requirements/tests/test_check.py @@ -618,8 +618,8 @@ def test_optional_mismatches_global_list(self): ) def test_optional_denylisted(self): - # If the optional package is denylisted, everything is OK even if absent - # from global-requirements. + # If the optional package is denylisted, everything is OK even if + # absent from global-requirements. reqs = [r for r, line in requirement.parse('name>=1.2,!=1.4')['name']] global_reqs = check.get_global_reqs('') self.assertFalse( diff --git a/openstack_requirements/tests/test_generate.py b/openstack_requirements/tests/test_generate.py index b8568e993..515c3d98b 100644 --- a/openstack_requirements/tests/test_generate.py +++ b/openstack_requirements/tests/test_generate.py @@ -34,7 +34,7 @@ def test_freeze_smoke(self): [ py, '-c', - 'import pkgutil; [print(x) for x in pkgutil.iter_modules()]', + 'import pkgutil; [print(x) for x in pkgutil.iter_modules()]', # noqa: E501 ] ) ) diff --git a/pyproject.toml b/pyproject.toml index 44691de36..5df4dd082 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ quote-style = "preserve" docstring-code-format = true [tool.ruff.lint] -select = ["E4", "E7", "E9", "F", "UP"] +select = ["E", "F", "UP"] # [tool.ruff.lint.per-file-ignores] # "openstack/tests/*" = ["S"] From 37970a5892f4142833be589e55d22f752dd321f0 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 6 Oct 2026 14:35:29 +0100 Subject: [PATCH 16/25] Remove sqlalchemy-filters The only reference to this dependency that we can find is in Tacker, where there is a release note from July 2021 indicating that it is no longer used [1]. The library itself has not seen a release since April 2023 [2]. [1] https://opendev.org/openstack/tacker/src/branch/master/releasenotes/notes/drop-sqlalchemy-filters-7ba7a03a309654bc.yaml [2] https://pypi.org/project/sqlalchemy-filters/ Change-Id: I3ff9dee88314118e6bdb45d479ea6a7825585e98 Signed-off-by: Stephen Finucane --- global-requirements.txt | 1 - upper-constraints.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/global-requirements.txt b/global-requirements.txt index 663c31a4a..5455bccac 100644 --- a/global-requirements.txt +++ b/global-requirements.txt @@ -165,7 +165,6 @@ scipy # BSD semantic-version # BSD setproctitle # BSD SQLAlchemy # MIT -sqlalchemy-filters # Apache-2.0 SQLAlchemy-Utils # BSD License sshtunnel # MIT statsd # MIT diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..a647ffea6 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -575,7 +575,6 @@ python-consul2===0.1.5 charset-normalizer===3.5.1 Flask===3.1.3 httpx===0.28.1 -sqlalchemy-filters===0.13.0 sphinxcontrib-runcmd===0.2.0 confspirator===0.3.0 fasteners===0.20 From 80ab707121b114f906c9f0c0b59dbf4e537ecbb1 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Tue, 6 Oct 2026 15:03:57 +0000 Subject: [PATCH 17/25] update constraint for sushy to new release 5.14.0 meta: version: 5.14.0 meta: team: ironic meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: no meta: first: yes meta: release:Author: Riccardo Pittau meta: release:Commit: Riccardo Pittau meta: release:Change-Id: I26472a549c8f0b97e63071009b30877c62b07af9 meta: release:Workflow+1: Elod Illes meta: release:Code-Review+2: Elod Illes meta: release:Code-Review+1: Iury Gregory Melo Ferreira Change-Id: Ib2c1fde7021b3fd733f5d557ff7e4e1baa179603 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..5f87436b5 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -382,7 +382,7 @@ idna===3.20 Hypercorn===0.18.0 yamlloader===1.6.0 protobuf===7.36.2 -sushy===5.13.0 +sushy===5.14.0 python-neutronclient===14.0.0 pika===1.4.4 oslo.cache===4.3.0 From aaa0cbc59e0a55fdb9f0628fd7b5b879f2100cfb Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Wed, 7 Oct 2026 11:04:11 +0000 Subject: [PATCH 18/25] update constraint for pbr to new release 7.1.3 meta: version: 7.1.3 meta: team: oslo meta: diff-start: - meta: series: independent meta: branch: master meta: release-type: release meta: pypi: yes meta: first: no meta: release:Author: Stephen Finucane meta: release:Commit: Stephen Finucane meta: release:Change-Id: I5709bbf28ef444087eb260c08a453f4b1ccefb61 meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes meta: release:Code-Review+2: Jeremy Stanley meta: release:Code-Review+1: Rodolfo Alonso Change-Id: I70970b945294b6b5eaa554daef5bc901806ead56 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..8518ef555 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -47,7 +47,7 @@ sphinxcontrib-nwdiag===2.0.0 rbd-iscsi-client===0.1.8 alabaster===1.0.0 multidict===6.9.1 -pbr===7.0.3 +pbr===7.1.3 munch===4.0.0 waiting===1.5.0 attrs===26.1.0 From 393515313ea5d6eddf87c8e63bacf5a10cc7a5d6 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Wed, 7 Oct 2026 11:07:41 +0000 Subject: [PATCH 19/25] update constraint for networking-generic-switch to new release 10.2.0 meta: version: 10.2.0 meta: team: ironic meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Riccardo Pittau meta: release:Commit: Riccardo Pittau meta: release:Change-Id: I8111610d1dc4477414a1491f239546870b97f9b0 meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: I890fef1e0246b21d4c808a5976d0b00a0b232aa0 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..9d4964bd0 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -181,7 +181,7 @@ portend===3.2.1 PyKMIP===0.11.0 python-observabilityclient===1.4.0 whereto===0.6.0 -networking-generic-switch===10.1.0 +networking-generic-switch===10.2.0 pywbem===1.9.1 python-subunit===1.4.6 tornado===6.5.10 From ea52bf6cffb0c79ba67e19df044b999436fdf0bf Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Wed, 7 Oct 2026 12:55:51 +0000 Subject: [PATCH 20/25] update constraint for openstacksdk to new release 4.21.0 meta: version: 4.21.0 meta: team: OpenStackSDK meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Stephen Finucane meta: release:Commit: Stephen Finucane meta: release:Change-Id: I0c3294c67f8a13c61bd018365ea1ae7c89e8056b meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: I5803e1efcd0396cda690879696ba64f9de090f99 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 13f24bab6..48363a198 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -460,7 +460,7 @@ cotyledon===2.2.0 xattr===1.3.0 systemd-python===235 python-memcached===1.62 -openstacksdk===4.20.0 +openstacksdk===4.21.0 infi.dtypes.nqn===0.1.0 looseversion===1.3.0 six===1.17.0 From 482080bf80d8092a5b3798e730e2c1a39c0bb9df Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Wed, 7 Oct 2026 14:20:04 +0000 Subject: [PATCH 21/25] update constraint for keystoneauth1 to new release 5.18.0 meta: version: 5.18.0 meta: team: OpenStackSDK meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Stephen Finucane meta: release:Commit: Stephen Finucane meta: release:d9510af pre-commit: Add codespell meta: release:5d398c4 Default OIDC device authorization polling interval to 5s meta: release:Change-Id: I18297e7d48c0eed059e034f6f4a94a74d933dcbd meta: release:Workflow+1: Elod Illes meta: release:Code-Review+2: Elod Illes Change-Id: I5bd5110c7932440122521b286975170fa49df68c Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 6714d366a..550301c9e 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -527,7 +527,7 @@ propcache===0.5.4 cachetools===7.2.0 flexcache===0.3 sphinxcontrib-qthelp===2.0.0 -keystoneauth1===5.17.0 +keystoneauth1===5.18.0 statsd===4.0.1 proto-plus===1.28.4 python-keystoneclient===6.0.0 From f1080af1b9f89d1d7449aa9c8d04cd724143b415 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Wed, 7 Oct 2026 15:04:17 +0000 Subject: [PATCH 22/25] update constraint for taskflow to new release 6.5.0 meta: version: 6.5.0 meta: team: oslo meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Stephen Finucane meta: release:Commit: Stephen Finucane meta: release:as noted in that commit: meta: release:f0d789a1 pre-commit: Bump versions meta: release:Change-Id: I7fa725280b4bb236ecda6919caf46b4c9761d84b meta: release:Code-Review+2: Elod Illes meta: release:Workflow+1: Elod Illes Change-Id: Ifa824aeddbe22c12e227cd9e14812eddb9baf0eb Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 3275a07c4..7d911a3f6 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -148,7 +148,7 @@ jsonpath-rw===1.4.0 prettytable===3.18.0 vine===5.1.0 pathspec===1.1.1 -taskflow===6.4.0 +taskflow===6.5.0 arrow===1.4.0 semantic-version===2.10.0 ConfigArgParse===1.7.7 From 7c9b41a04f9ec00b982e7dba92c6eb5053b69ec9 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Fri, 9 Oct 2026 07:13:36 +0000 Subject: [PATCH 23/25] update constraint for os_vif to new release 5.3.0 meta: version: 5.3.0 meta: team: nova meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Rodolfo Alonso Hernandez meta: release:Commit: Rodolfo Alonso Hernandez meta: release:Change-Id: I7e7d215fba5ea179bdf9e240cbeaa7b0132f266e meta: release:Workflow+1: Elod Illes meta: release:Code-Review+2: Elod Illes meta: release:Code-Review+1: yatin meta: release:Code-Review+1: ribaudr Change-Id: I72e890bf3dd206866b13c47725e8579a721c3288 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 7cffed51b..e5a27e508 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -296,7 +296,7 @@ oslo.log===8.3.2 nodeenv===1.10.0 gossip===2.5.0 suds-community===1.2.0 -os_vif===5.2.1 +os_vif===5.3.0 qrcode===8.2 oslo.middleware===8.2.0 XStatic-mdi===1.6.50.3 From e62231a804cd41fe053b73ca4fee6d3361cd1ac6 Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Fri, 9 Oct 2026 07:43:36 +0000 Subject: [PATCH 24/25] update constraint for python-openstackclient to new release 10.4.0 meta: version: 10.4.0 meta: team: OpenStackSDK meta: diff-start: - meta: series: indri meta: branch: master meta: release-type: release meta: pypi: yes meta: first: yes meta: release:Author: Stephen Finucane meta: release:Commit: Stephen Finucane meta: release:Change-Id: I280cbd599e0616e82af8d077fa23738889422432 meta: release:Workflow+1: Elod Illes meta: release:Code-Review+2: Elod Illes Change-Id: Id7263caa2e0c0cee5bdc2abf0f89c828e9cd2137 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/update_constraints.sh --- upper-constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 7cffed51b..57f629bf5 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -486,7 +486,7 @@ python-ironicclient===6.3.0 babel===2.18.0 XStatic===1.0.3 XStatic-Angular-FileUpload===12.2.13.2 -python-openstackclient===10.3.0 +python-openstackclient===10.4.0 pyzmq===27.2.0 oslo.db===18.1.1 simplegeneric===0.8.1 From dc2c70bf1e6ffc3688d08473c98fd756cf06a35d Mon Sep 17 00:00:00 2001 From: OpenStack Proposal Bot Date: Sat, 3 Oct 2026 08:07:51 +0000 Subject: [PATCH 25/25] Updated from generate-constraints Fixes applied to automated upper-constraints.txt update: Pin versions for packages that are not ready for updating: - pyroute2: Nova/os-vif issues - sqlalchemy: broken compatibility with sqlalchemy-utils - pyparsing: due to regression in 3.3.3[1] - Pin salt to 3008.0 to avoid the packaging pin [1] https://github.com/pyparsing/pyparsing/issues/672 Co-Authored-by: Dr. Jens Harbott Co-Authored-by: Takashi Kajinami Change-Id: I9512485505b705d7f5cc77f8be2a539476421b32 Signed-off-by: OpenStack Proposal Bot Generated-By: openstack/project-config:playbooks/proposal/propose_update.sh --- upper-constraints.txt | 76 +++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/upper-constraints.txt b/upper-constraints.txt index 7cffed51b..2cee6b90c 100644 --- a/upper-constraints.txt +++ b/upper-constraints.txt @@ -35,10 +35,10 @@ python-ironic-inspector-client===5.4.0 lxml===6.1.3 vintage===0.4.1 rst2txt===1.1.0 -setproctitle===1.3.7 +setproctitle===1.3.8 pytest===9.1.1 a2wsgi===1.10.10 -python-slugify===9.1.1 +python-slugify===9.1.2 cursive===0.3.1 oslo.service===4.8.0 django-appconf===1.2.0 @@ -75,9 +75,8 @@ XStatic-Font-Awesome===6.2.1.2 aiohttp===3.14.3 waitress===3.0.2 os-refresh-config===14.1.0 -pysnmp===7.1.29 +pysnmp===7.1.30 Mako===1.4.3 -vultr===1.0.1 sphinxcontrib-htmlhelp===2.1.0 XStatic-jQuery===3.7.1.1 sphinx-copybutton===0.5.2 @@ -90,7 +89,7 @@ infi.dtypes.wwn===0.2.0 awscrt===0.37.0 pcre2===0.7.1 python-freezerclient===6.5.0 -py-pure-client===1.94.2 +py-pure-client===1.95.0 krest===1.3.8 psycopg2===2.9.13 networkx===3.6.1 @@ -98,22 +97,22 @@ cheroot===11.1.2 XStatic-Angular===1.8.2.3 zuul-sphinx===0.8.1 ply===3.11 -google-api-core===2.39.0 +google-api-core===2.40.0 requests-toolbelt===1.0.0 -simplejson===4.1.2 +simplejson===4.2.0 python-swiftclient===4.11.0 shellingham===1.5.4 pyOpenSSL===26.4.0 typing-inspection===0.4.4 monasca-common===3.8.0 hyperframe===6.1.0 -zeroconf===0.151.3 +zeroconf===0.151.5 scipy===1.17.1 opentelemetry-exporter-otlp===1.45.0 -python-gnupg===0.5.6 +python-gnupg===0.5.7 rsd-lib===1.2.0 XStatic-Jasmine===2.4.1.3 -googleapis-common-protos===1.75.4 +googleapis-common-protos===1.75.5 python-glanceclient===4.13.0 prometheus_client===0.26.0 jaraco.classes===3.4.0 @@ -125,7 +124,7 @@ croniter===6.2.4 horizon===27.0.0 octavia-lib===3.12.0 python-watcherclient===4.11.0 -MarkupSafe===3.0.3 +MarkupSafe===3.0.4 cloudpickle===3.1.2 doc8===2.0.0 pymongo===4.18.2 @@ -151,22 +150,22 @@ pathspec===1.1.1 taskflow===6.5.0 arrow===1.4.0 semantic-version===2.10.0 -ConfigArgParse===1.7.7 +ConfigArgParse===1.8.0 async-timeout===5.0.1 virtualbmc===3.3.0 SQLAlchemy===2.0.54 pyroute2===0.8.1 -google-auth===2.58.1 +google-auth===2.59.1 kazoo===2.11.0 -pyspnego===0.12.2 +pyspnego===0.12.3 trio-websocket===0.12.2 XStatic-roboto-fontface===0.8.0.1 -pyudev===0.24.4 +pyudev===0.24.5 eventlet===0.41.2 openstack-doc-tools===4.0.3 oslo.messaging===18.3.0 jira===3.10.5 -PyJWT===2.15.0 +PyJWT===2.15.1 typing_extensions===4.16.0 zVMCloudConnector===1.6.3 paramiko===5.0.0 @@ -190,7 +189,7 @@ mock===5.2.0 PyYAML===6.0.3 beautifulsoup4===4.15.0 ovs===4.0.0 -cryptography===50.0.1 +cryptography===50.0.2 httpcore===1.0.9 URLObject===3.0.0 psycopg2-binary===2.9.13 @@ -204,7 +203,7 @@ gunicorn===26.2.0 storpool===7.3.0 textfsm===2.1.0 python-3parclient===4.4 -libvirt-python===12.7.0 +libvirt-python===12.8.0 python-zunclient===5.5.0 tzlocal===5.4.4 sysv_ipc===1.2.0 @@ -246,7 +245,7 @@ sphinx-feature-classification===2.1.0 XStatic-JQuery-Migrate===3.3.2.2 pytest-html===4.2.0 appdirs===1.4.4 -google-auth-httplib2===0.4.2 +google-auth-httplib2===0.4.4 daiquiri===3.4.0 apache-libcloud===3.9.1 influxdb===5.3.2 @@ -263,7 +262,7 @@ ldappool===3.0.0 hpack===4.2.0 joblib===1.6.0 roman-numerals===4.1.0 -google-api-python-client===2.200.0 +google-api-python-client===2.201.0 castellan===5.8.0 oslo.versionedobjects===3.12.0 enmerkar===0.7.1 @@ -275,7 +274,7 @@ truststore===0.10.4 SQLAlchemy-Utils===0.42.1 retryz===0.1.9 pluggy===1.6.0 -coverage===7.16.1 +coverage===7.16.2 pyee===13.0.1 freezegun===1.5.5 mdurl===0.1.2 @@ -293,7 +292,7 @@ pytest-xdist===3.8.0 XStatic-JS-Yaml===3.13.1.2 XStatic-term.js===0.0.7.1 oslo.log===8.3.2 -nodeenv===1.10.0 +nodeenv===1.11.0 gossip===2.5.0 suds-community===1.2.0 os_vif===5.2.1 @@ -306,7 +305,7 @@ docutils===0.21.2 threadpoolctl===3.7.0 os-ken===4.2.2 ujson===6.0.0 -selenium===4.49.0 +selenium===4.50.0 pytest-subtests===0.15.0 mistral-lib===3.6.0 dogtag-pki===11.2.1 @@ -319,7 +318,7 @@ playwright===1.63.0 markdown-it-py===4.2.0 retrying===1.4.2 python-discovery===1.6.1 -platformdirs===4.11.15 +platformdirs===4.12.2 pydotplus===2.0.2 boto3===1.35.99 jeepney===0.9.0 @@ -404,7 +403,7 @@ more-itertools===11.1.0 seqdiag===3.0.0 zc.lockfile===4.0 numpy===2.4.6 -msgpack===1.2.2 +msgpack===1.2.3 Sphinx===9.0.4 oslo.config===10.7.0 openstackdocstheme===3.6.0 @@ -426,7 +425,7 @@ pyparsing===3.3.2 geomet===1.1.0 opentelemetry-exporter-otlp-proto-common===1.45.0 distlib===0.4.3 -ast_serialize===0.11.2 +ast_serialize===0.12.0 dogpile.cache===1.5.0 python-barbicanclient===7.6.0 salt===3008.0 @@ -435,7 +434,7 @@ blinker===1.9.0 WSME===0.13.0 oslo.upgradecheck===2.8.0 sherlock===0.4.1 -tempora===5.12.0 +tempora===5.13.0 stevedore===5.9.1 botocore===1.35.99 xmltodict===1.0.4 @@ -448,7 +447,7 @@ cmd2===4.2.4 python-json-logger===4.2.0 redis===8.1.0 jmespath===1.1.0 -cbor2===6.1.4 +cbor2===6.1.5 click===8.5.0 XStatic-smart-table===1.4.13.3 kuryr-lib===3.5.0 @@ -474,14 +473,13 @@ yaql===3.2.0 durationpy===0.11 requestsexceptions===1.4.0 testresources===2.1.2 -falcon===4.3.1 +falcon===4.4.0 tomlkit===0.15.1 opentelemetry-exporter-http-transport===0.66b0 etcd3gw===2.7.0 timelib===0.3.0 -rpm_vercmp===0.1.2 Flask-RESTful===0.3.10 -GitPython===3.1.62 +GitPython===3.2.0 python-ironicclient===6.3.0 babel===2.18.0 XStatic===1.0.3 @@ -494,7 +492,7 @@ yappi===1.7.6 mbstrdecoder===1.1.5 wsproto===1.3.2 pymemcache===4.0.0 -wrapt===2.4.1 +wrapt===2.5.0 PySocks===1.7.1 oslo.privsep===3.12.0 sphinxcontrib-apidoc===0.6.0 @@ -514,12 +512,12 @@ boto===2.49.0 hyperlink===21.0.0 mitba===1.1.1 python-masakariclient===8.9.0 -Werkzeug===3.1.8 +Werkzeug===3.1.9 outcome===1.3.0.post0 APScheduler===3.11.3 xmlschema===2.5.1 python-troveclient===8.11.0 -hpe-storage-flowkit-py===0.9.5 +hpe-storage-flowkit-py===1.0.1 cachez===0.1.2 XStatic-Bootstrap-Datepicker===1.4.0.1 netifaces===0.11.0 @@ -529,7 +527,7 @@ flexcache===0.3 sphinxcontrib-qthelp===2.0.0 keystoneauth1===5.18.0 statsd===4.0.1 -proto-plus===1.28.4 +proto-plus===1.29.0 python-keystoneclient===6.0.0 diskimage-builder===3.43.0 py-consul===1.7.1 @@ -559,7 +557,7 @@ execnet===2.1.2 sphinxcontrib-programoutput===0.20 storpool.spopenstack===3.2.0 dnspython===2.8.0 -oauthlib===3.3.1 +oauthlib===4.0.0 zipp===4.1.0 greenlet===3.5.6 XStatic-Angular-Vis===4.16.0.1 @@ -572,7 +570,7 @@ xvfbwrapper===0.2.34 influxdb-client===1.50.0 tosca-parser===2.15.0 python-consul2===0.1.5 -charset-normalizer===3.5.1 +charset-normalizer===3.5.2 Flask===3.1.3 httpx===0.28.1 sphinxcontrib-runcmd===0.2.0 @@ -582,7 +580,7 @@ importlib_metadata===9.0.1 sortedcontainers===2.4.0 microversion_parse===2.1.0 python-linstor===1.29.1 -filelock===4.0.3 +filelock===4.0.9 python-tackerclient===2.6.0 python-heatclient===5.3.0 oslo.utils===10.2.0 @@ -591,7 +589,7 @@ itsdangerous===2.2.0 XStatic-jquery-ui===1.13.0.2 monasca-statsd===2.7.0 python-dateutil===2.9.0.post0 -virtualenv===21.12.1 +virtualenv===21.14.5 colorama===0.4.6 confetti===2.5.3 ironic-lib===7.0.0