diff --git a/.circleci/config.yml b/.circleci/config.yml index af715bdab0..519f7caf58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -154,9 +154,11 @@ jobs: name: Download st2-packages repository command: | set -x + PIP_VERSION=$(grep ^PIP_VERSION Makefile) git clone ${ST2_PACKAGES_REPO} ~/st2-packages cd ~/st2-packages git checkout ${CIRCLE_BRANCH} || true + sed -i -e "s/^PIP_VERSION .*$/${PIP_VERSION}/" packages/st2/debian/rules - run: name: Initialize packages Build Environment command: | diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 13c500d354..ebc37c8179 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -258,34 +258,29 @@ jobs: include: - name: 'Unit Tests (chunk 1)' task: 'ci-unit' - nosetests_node_total: 2 - nosetests_node_index: 0 + shard: {k: 0, n: 2} python-version-short: '3.8' python-version: '3.8.10' - name: 'Unit Tests (chunk 2)' task: 'ci-unit' - nosetests_node_total: 2 - nosetests_node_index: 1 + shard: {k: 1, n: 2} python-version-short: '3.8' python-version: '3.8.10' - name: 'Unit Tests (chunk 1)' task: 'ci-unit' - nosetests_node_total: 2 - nosetests_node_index: 0 + shard: {k: 0, n: 2} python-version-short: '3.9' python-version: '3.9.14' - name: 'Unit Tests (chunk 2)' task: 'ci-unit' - nosetests_node_total: 2 - nosetests_node_index: 1 + shard: {k: 1, n: 2} python-version-short: '3.9' python-version: '3.9.14' # This job is slow so we only run in on a daily basis # - name: 'Micro Benchmarks' # task: 'micro-benchmarks' # python-version: '3.6.13' - # nosetests_node_total: 1 - # nosetests_node_ index: 0 + # shard: {k: 0, n: 1} services: mongo: image: mongo:7.0 @@ -317,8 +312,8 @@ jobs: env: TASK: '${{ matrix.task }}' PYTHON_VERSION_SHORT: '${{ matrix.python-version-short }}' - NODE_TOTAL: '${{ matrix.nosetests_node_total }}' - NODE_INDEX: '${{ matrix.nosetests_node_index }}' + NODE_TOTAL: '${{ matrix.shard.n }}' + NODE_INDEX: '${{ matrix.shard.k }}' # We need to explicitly specify terminal width otherwise some CLI tests fail on container # environments where small terminal size is used. @@ -417,38 +412,32 @@ jobs: # up (aka stanley user being present, etc.) - name: 'Pack Tests' task: 'ci-packs-tests' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.8' python-version: '3.8.10' - name: 'Integration Tests (chunk 1)' task: 'ci-integration' - nosetests_node_total: 2 - nosetests_node_index: 0 + shard: {k: 0, n: 2} python-version-short: '3.8' python-version: '3.8.10' - name: 'Integration Tests (chunk 2)' task: 'ci-integration' - nosetests_node_total: 2 - nosetests_node_index: 1 + shard: {k: 1, n: 2} python-version-short: '3.8' python-version: '3.8.10' - name: 'Pack Tests' task: 'ci-packs-tests' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.9' python-version: '3.9.14' - name: 'Integration Tests (chunk 1)' task: 'ci-integration' - nosetests_node_total: 2 - nosetests_node_index: 0 + shard: {k: 0, n: 2} python-version-short: '3.9' python-version: '3.9.14' - name: 'Integration Tests (chunk 2)' task: 'ci-integration' - nosetests_node_total: 2 - nosetests_node_index: 1 + shard: {k: 1, n: 2} python-version-short: '3.9' python-version: '3.9.14' services: @@ -504,8 +493,8 @@ jobs: env: TASK: '${{ matrix.task }}' PYTHON_VERSION_SHORT: '${{ matrix.python-version-short }}' - NODE_TOTAL: '${{ matrix.nosetests_node_total }}' - NODE_INDEX: '${{ matrix.nosetests_node_index }}' + NODE_TOTAL: '${{ matrix.shard.n }}' + NODE_INDEX: '${{ matrix.shard.k }}' # We need to explicitly specify terminal width otherwise some CLI tests fail on container # environments where small terminal size is used. @@ -591,7 +580,7 @@ jobs: if: ${{ failure() && env.TASK == 'ci-integration' }} uses: actions/upload-artifact@v4 with: - name: logs-py${{ matrix.python-version }}-nose-${{ matrix.nosetests_node_index }} + name: logs-py${{ matrix.python-version }}-pytest-${{ matrix.shard.k }} path: logs.tar.gz retention-days: 7 diff --git a/.github/workflows/microbenchmarks.yaml b/.github/workflows/microbenchmarks.yaml index 2c05fadb74..c333ca56ef 100644 --- a/.github/workflows/microbenchmarks.yaml +++ b/.github/workflows/microbenchmarks.yaml @@ -36,14 +36,12 @@ jobs: include: - name: 'Microbenchmarks' task: 'micro-benchmarks' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.8' python-version: '3.8.10' - name: 'Microbenchmarks' task: 'micro-benchmarks' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.9' python-version: '3.9.14' services: @@ -64,8 +62,8 @@ jobs: env: TASK: '${{ matrix.task }}' - NODE_TOTAL: '${{ matrix.nosetests_node_total }}' - NODE_INDEX: '${{ matrix.nosetests_node_index }}' + NODE_TOTAL: '${{ matrix.shard.n }}' + NODE_INDEX: '${{ matrix.shard.k }}' COLUMNS: '120' ST2_CI: 'true' diff --git a/.github/workflows/orquesta-integration-tests.yaml b/.github/workflows/orquesta-integration-tests.yaml index 9bde1b2488..7ef654b157 100644 --- a/.github/workflows/orquesta-integration-tests.yaml +++ b/.github/workflows/orquesta-integration-tests.yaml @@ -57,14 +57,12 @@ jobs: include: - name: 'Integration Tests (Orquesta)' task: 'ci-orquesta' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.8' python-version: '3.8.10' - name: 'Integration Tests (Orquesta)' task: 'ci-orquesta' - nosetests_node_total: 1 - nosetests_node_index: 0 + shard: {k: 0, n: 1} python-version-short: '3.9' python-version: '3.9.14' services: @@ -97,8 +95,8 @@ jobs: env: TASK: '${{ matrix.task }}' - NODE_TOTAL: '${{ matrix.nosetests_node_total }}' - NODE_INDEX: '${{ matrix.nosetests_node_index }}' + NODE_TOTAL: '${{ matrix.shard.n }}' + NODE_INDEX: '${{ matrix.shard.k }}' # We need to explicitly specify terminal width otherwise some CLI tests fail on container # environments where small terminal size is used. diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4cc1791006..5e4bbab7a0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -63,6 +63,10 @@ Changed * Relaxed `dnspython` pinning for compatibility with python 3.10 and greater. #6265 Contributed by @nzlosh +* Switched tests from `nosetest` to `pytest`. `st2-run-pack-tests` also uses pytest. + So, all pack tests must be runnable by `pytest`, which may require migration. #6291 + Contributed by @nzlosh, @FileMagic, @guzzijones, and @cognifloyd. + Added ~~~~~ * Continue introducing `pants `_ to improve DX (Developer Experience) diff --git a/Makefile b/Makefile index 57c5e524c4..b988f1b3d2 100644 --- a/Makefile +++ b/Makefile @@ -59,8 +59,8 @@ ST2TESTS_REDIS_PORT := 6379 # Pin common pip version here across all the targets # Note! Periodic maintenance pip upgrades are required to be up-to-date with the latest pip security fixes and updates -PIP_VERSION ?= 24.2 -SETUPTOOLS_VERSION ?= 75.2.0 +PIP_VERSION ?= 24.3.1 +SETUPTOOLS_VERSION ?= 75.3.0 PIP_OPTIONS := $(ST2_PIP_OPTIONS) ifndef PYLINT_CONCURRENCY @@ -71,21 +71,21 @@ ifndef XARGS_CONCURRENCY XARGS_CONCURRENCY := 8 endif +ifndef NODE_INDEX + NODE_INDEX := 0 +endif +ifndef NODE_TOTAL + NODE_TOTAL := 1 +endif + # NOTE: We exclude resourceregistrar DEBUG level log messages since those are very noisy (we # loaded resources for every tests) which makes tests hard to troubleshoot on failure due to # pages and pages and pages of noise. # The minus in front of st2.st2common.bootstrap filters out logging statements from that module. -# See https://nose.readthedocs.io/en/latest/usage.html#cmdoption-logging-filter -NOSE_OPTS := --rednose --immediate --with-parallel --parallel-strategy=FILE --nocapture --logging-filter=-st2.st2common.bootstrap - -ifndef NOSE_TIME - NOSE_TIME := yes -endif - -ifeq ($(NOSE_TIME),yes) - NOSE_OPTS := --rednose --immediate --with-parallel --parallel-strategy=FILE --with-timer --nocapture --logging-filter=-st2.st2common.bootstrap - NOSE_WITH_TIMER := 1 -endif +# https://github.com/pytest-dev/pytest-xdist/issues/71 +#PYTEST_OPTS := -n auto --tx 2*popen//execmodel=eventlet +# --suppress-no-test-exit-code is part of the pytest-custom_exit_code plugin +PYTEST_OPTS := --test-group=$(NODE_INDEX) --test-group-count=$(NODE_TOTAL) -s --log-level=error --suppress-no-test-exit-code ifndef PIP_OPTIONS PIP_OPTIONS := @@ -94,8 +94,8 @@ endif # NOTE: We only run coverage on master and version branches and not on pull requests since # it has a big performance overhead and is very slow. ifeq ($(ENABLE_COVERAGE),yes) - NOSE_COVERAGE_FLAGS := --with-coverage --cover-branches --cover-erase - NOSE_COVERAGE_PACKAGES := --cover-package=$(COMPONENTS_TEST_COMMA) + PYTEST_COVERAGE_FLAGS := --with-coverage --cover-branches --cover-erase + PYTEST_COVERAGE_PACKAGES := --cover-package=$(COMPONENTS_TEST_COMMA) else INCLUDE_TESTS_IN_COVERAGE := endif @@ -103,8 +103,8 @@ endif # If we aren't running test coverage, don't try to include tests in coverage # results ifdef INCLUDE_TESTS_IN_COVERAGE - NOSE_COVERAGE_FLAGS += --cover-tests - NOSE_COVERAGE_PACKAGES := $(NOSE_COVERAGE_PACKAGES),$(COMPONENTS_TEST_MODULES_COMMA) + PYTEST_COVERAGE_FLAGS += --cover-tests + PYTEST_COVERAGE_PACKAGES := $(PYTEST_COVERAGE_PACKAGES),$(COMPONENTS_TEST_MODULES_COMMA) endif .PHONY: all @@ -149,20 +149,17 @@ play: @echo @echo GITHUB_EVENT_NAME=$(GITHUB_EVENT_NAME) @echo - @echo NOSE_OPTS=$(NOSE_OPTS) + @echo PYTEST_OPTS=$(PYTEST_OPTS) @echo @echo ENABLE_COVERAGE=$(ENABLE_COVERAGE) @echo - @echo NOSE_COVERAGE_FLAGS=$(NOSE_COVERAGE_FLAGS) + @echo PYTEST_COVERAGE_FLAGS=$(PYTEST_COVERAGE_FLAGS) @echo - @echo NOSE_COVERAGE_PACKAGES=$(NOSE_COVERAGE_PACKAGES) + @echo PYTEST_COVERAGE_PACKAGES=$(PYTEST_COVERAGE_PACKAGES) @echo @echo INCLUDE_TESTS_IN_COVERAGE=$(INCLUDE_TESTS_IN_COVERAGE) @echo - @echo NODE_TOTAL=$(NODE_TOTAL) - @echo - @echo - @echo NODE_INDEX=$(NODE_INDEX) + @echo shard: NODE_INDEX/NODE_TOTAL=$(NODE_INDEX)/$(NODE_TOTAL) @echo .PHONY: check @@ -490,7 +487,7 @@ flake8: requirements .flake8 . $(VIRTUALENV_DIR)/bin/activate; flake8 --config ./lint-configs/python/.flake8 pylint_plugins/ # Make task which verifies st2client README will parse pypi checks -. PHONY: .st2client-pypi-check +.PHONY: .st2client-pypi-check .st2client-pypi-check: @echo @echo "==================== st2client pypi check ====================" @@ -830,17 +827,18 @@ unit-tests: requirements .unit-tests . $(VIRTUALENV_DIR)/bin/activate; \ ST2TESTS_REDIS_HOST=$(ST2TESTS_REDIS_HOST) \ ST2TESTS_REDIS_PORT=$(ST2TESTS_REDIS_PORT) \ - nosetests $(NOSE_OPTS) -s -v \ + pytest -rx --verbose \ $$component/tests/unit || ((failed+=1)); \ echo "-----------------------------------------------------------"; \ echo "Done running tests in" $$component; \ echo "==========================================================="; \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi .PHONY: .run-unit-tests-coverage ifdef INCLUDE_TESTS_IN_COVERAGE -.run-unit-tests-coverage: NOSE_COVERAGE_PACKAGES := $(NOSE_COVERAGE_PACKAGES),tests.unit +.run-unit-tests-coverage: PYTEST_COVERAGE_PACKAGES := $(PYTEST_COVERAGE_PACKAGES),tests.unit endif .run-unit-tests-coverage: @echo @@ -857,18 +855,18 @@ endif ST2TESTS_REDIS_HOST=$(ST2TESTS_REDIS_HOST) \ ST2TESTS_REDIS_PORT=$(ST2TESTS_REDIS_PORT) \ COVERAGE_FILE=.coverage.unit.$$(echo $$component | tr '/' '.') \ - nosetests $(NOSE_OPTS) -s -v $(NOSE_COVERAGE_FLAGS) \ - $(NOSE_COVERAGE_PACKAGES) \ + pytest --verbose $(PYTEST_OPTS) --cov=$$component --cov-branch \ $$component/tests/unit || ((failed+=1)); \ echo "-----------------------------------------------------------"; \ echo "Done running tests in" $$component; \ echo "==========================================================="; \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi .PHONY: .combine-unit-tests-coverage .combine-unit-tests-coverage: .run-unit-tests-coverage - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.unit \ coverage combine .coverage.unit.*; \ fi @@ -887,14 +885,14 @@ endif .PHONY: .report-unit-tests-coverage .report-unit-tests-coverage: .coverage.unit - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.unit \ coverage report; \ fi .PHONY: .unit-tests-coverage-html .unit-tests-coverage-html: .coverage.unit - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.unit \ coverage html; \ fi @@ -915,17 +913,18 @@ itests: requirements .itests echo "Running integration tests in" $$component; \ echo "-----------------------------------------------------------"; \ . $(VIRTUALENV_DIR)/bin/activate; \ - nosetests $(NOSE_OPTS) -s -v \ + pytest --capture=no --verbose $(PYTEST_OPTS) \ $$component/tests/integration || ((failed+=1)); \ echo "-----------------------------------------------------------"; \ echo "Done running integration tests in" $$component; \ echo "==========================================================="; \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi .PHONY: .run-integration-tests-coverage ifdef INCLUDE_TESTS_IN_COVERAGE -.run-integration-tests-coverage: NOSE_COVERAGE_PACKAGES := $(NOSE_COVERAGE_PACKAGES),tests.integration +.run-integration-tests-coverage: PYTEST_COVERAGE_PACKAGES := $(PYTEST_COVERAGE_PACKAGES),tests.integration endif .run-integration-tests-coverage: @echo @@ -940,13 +939,13 @@ endif echo "-----------------------------------------------------------"; \ . $(VIRTUALENV_DIR)/bin/activate; \ COVERAGE_FILE=.coverage.integration.$$(echo $$component | tr '/' '.') \ - nosetests $(NOSE_OPTS) -s -v $(NOSE_COVERAGE_FLAGS) \ - $(NOSE_COVERAGE_PACKAGES) \ + pytest --capture=no --verbose $(PYTEST_OPTS) --cov=$$component --cov-branch \ $$component/tests/integration || ((failed+=1)); \ echo "-----------------------------------------------------------"; \ echo "Done integration running tests in" $$component; \ echo "==========================================================="; \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi # NOTE: If you also want to run orquesta tests which seem to have a bunch of race conditions, use # ci-integration-full target @@ -956,12 +955,12 @@ endif # @echo # . $(VIRTUALENV_DIR)/bin/activate; \ @# COVERAGE_FILE=.coverage.integration.orquesta \ -@# nosetests $(NOSE_OPTS) -s -v \ -@# $(NOSE_COVERAGE_FLAGS) $(NOSE_COVERAGE_PACKAGES) st2tests/integration/orquesta || exit 1; \ +@# pytest --capture=no --verbose $(PYTEST_OPTS) \ +@# $(PYTEST_COVERAGE_FLAGS) $(PYTEST_COVERAGE_PACKAGES) st2tests/integration/orquesta || exit 1; \ .PHONY: .combine-integration-tests-coverage .combine-integration-tests-coverage: .run-integration-tests-coverage - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.integration \ coverage combine .coverage.integration.*; \ fi @@ -980,14 +979,14 @@ endif .PHONY: .report-integration-tests-coverage .report-integration-tests-coverage: .coverage.integration - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.integration \ coverage report; \ fi .PHONY: .integration-tests-coverage-html .integration-tests-coverage-html: .coverage.integration - @if [ -n "$(NOSE_COVERAGE_FLAGS)" ]; then \ + @if [ -n "$(PYTEST_COVERAGE_FLAGS)" ]; then \ . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.integration \ coverage html; \ fi @@ -1040,7 +1039,7 @@ orquesta-itests: requirements .orquesta-itests @echo "==================== Orquesta integration tests ====================" @echo "The tests assume st2 is running on 127.0.0.1." @echo - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v st2tests/integration/orquesta || exit 1; + . $(VIRTUALENV_DIR)/bin/activate; pytest --capture=no --verbose $(PYTEST_OPTS) st2tests/integration/orquesta || exit 1; .PHONY: .orquesta-itests-coverage-html .orquesta-itests-coverage-html: @@ -1048,8 +1047,7 @@ orquesta-itests: requirements .orquesta-itests @echo "==================== Orquesta integration tests with coverage (HTML reports) ====================" @echo "The tests assume st2 is running on 127.0.0.1." @echo - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v --with-coverage \ - --cover-inclusive --cover-html st2tests/integration/orquesta || exit 1; + . $(VIRTUALENV_DIR)/bin/activate; pytest --capture=no --verbose $(PYTEST_OPTS) --cov=orquesta --cov-branch st2tests/integration/orquesta || exit 1; .PHONY: packs-tests packs-tests: requirements .packs-tests @@ -1079,7 +1077,7 @@ runners-tests: requirements .runners-tests echo "==========================================================="; \ echo "Running tests in" $$component; \ echo "==========================================================="; \ - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v $$component/tests/unit || ((failed+=1)); \ + . $(VIRTUALENV_DIR)/bin/activate; pytest --capture=no --verbose $(PYTEST_OPTS) $$component/tests/unit || ((failed+=1)); \ done; \ if [ $$failed -gt 0 ]; then exit 1; fi @@ -1097,8 +1095,9 @@ runners-itests: requirements .runners-itests echo "==========================================================="; \ echo "Running integration tests in" $$component; \ echo "==========================================================="; \ - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v $$component/tests/integration || ((failed+=1)); \ + . $(VIRTUALENV_DIR)/bin/activate; pytest --capture=no --verbose $(PYTEST_OPTS) $$component/tests/integration || ((failed+=1)); \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi .PHONY: .runners-itests-coverage-html @@ -1112,9 +1111,10 @@ runners-itests: requirements .runners-itests echo "==========================================================="; \ echo "Running integration tests in" $$component; \ echo "==========================================================="; \ - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v --with-coverage \ - --cover-inclusive --cover-html $$component/tests/integration || ((failed+=1)); \ + . $(VIRTUALENV_DIR)/bin/activate; pytest --capture=no --verbose $(PYTEST_OPTS) \ + --cov=$$component --cov-report=html $$component/tests/integration || ((failed+=1)); \ done; \ + echo pytest runs failed=$$failed; \ if [ $$failed -gt 0 ]; then exit 1; fi .PHONY: cli diff --git a/conftest.py b/conftest.py index 7ca82b787d..8bfc45b048 100644 --- a/conftest.py +++ b/conftest.py @@ -11,6 +11,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import hashlib +from typing import Iterable, List, Sequence + +from _pytest import nodes +from _pytest.config import create_terminal_writer def pytest_configure(config): @@ -23,3 +28,63 @@ def pytest_unconfigure(config): import sys del sys._called_from_test + + +# TODO: Remove everything below here when we get rid of the Makefile +# everything below this is based on (MIT licensed) by mark-adams: +# https://github.com/mark-adams/pytest-test-groups/blob/5eca437ef95d23e8674b9e8765ce16005159d334/pytest_test_groups/__init__.py +# with some inspiration from (MIT licensed) by Adam Gleave: +# https://github.com/AdamGleave/pytest-shard/blob/64610a08dac6b0511b6d51cf895d0e1040d162ad/pytest_shard/pytest_shard.py + + +def get_group( + items: Iterable[nodes.Node], group_count: int, group_id: int +) -> Sequence[nodes.Node]: + """Get the items from the passed in group based on group count.""" + if not (0 <= group_id < group_count): + raise ValueError("Invalid test-group argument") + + def get_group_id(node: nodes.Node) -> int: + # use the file path instead of node id, so all tests in a file run together. + path_bytes = str(node.path).encode() + digest_bytes = hashlib.sha256(path_bytes).digest() + digest = int.from_bytes(digest_bytes, "little") + return digest % group_count + + return [item for item in items if get_group_id(item) == group_id] + + +def pytest_addoption(parser): + group = parser.getgroup("split your tests into evenly sized groups and run them") + group.addoption( + "--test-group-count", + dest="test-group-count", + type=int, + default=-1, + help="The number of groups to split the tests into", + ) + group.addoption( + "--test-group", + dest="test-group", + type=int, + default=-1, + help="The group of tests that should be executed", + ) + + +def pytest_collection_modifyitems(session, config, items: List[nodes.Node]): + group_count = config.getoption("test-group-count") + group_id = config.getoption("test-group") + + if group_count < 1 or group_id < 0: + return + + items[:] = get_group(items, group_count, group_id) + + terminal_reporter = config.pluginmanager.get_plugin("terminalreporter") + terminal_writer = create_terminal_writer(config) + message = terminal_writer.markup( + "Running test group #{0} ({1} tests)\n".format(group_id, len(items)), + yellow=True, + ) + terminal_reporter.write(message) diff --git a/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py b/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py index c1aa148433..7c2baa700a 100644 --- a/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py +++ b/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py @@ -37,6 +37,7 @@ import json import unittest +import pytest from shutil import which as shutil_which from st2common.util.shell import run_command @@ -65,7 +66,7 @@ TIME_BINARY_AVAILABLE = TIME_BINARY_PATH is not None -@unittest.skipIf(not TIME_BINARY_PATH, "time binary not available") +@pytest.mark.skipif(not TIME_BINARY_PATH, reason="time binary not available") class PythonRunnerActionWrapperProcessTestCase(unittest.TestCase): def test_process_wrapper_exits_in_reasonable_timeframe(self): # 1. Verify wrapper script path is correct and file exists diff --git a/fixed-requirements.txt b/fixed-requirements.txt index 97a1688bbb..f9ed0cf177 100644 --- a/fixed-requirements.txt +++ b/fixed-requirements.txt @@ -6,12 +6,12 @@ # - https://github.com/StackStorm/st2-rbac-backend # ---------------------------------------------------------------------- # Note: amqp is used by kombu -amqp==5.2.0 -apscheduler==3.10.4 +amqp==5.3.1 +apscheduler==3.11.0 chardet==5.2.0 cffi==1.17.1 cryptography==43.0.3 -eventlet==0.37.0 +eventlet==0.38.2 flex==6.14.1 # Note: installs gitpython==3.1.37 (security fixed) under py3.8 and gitpython==3.1.18 (latest available, vulnerable) under py3.6 # TODO: Pin to 3.1.37 or higher after dropping python3.6 support @@ -51,14 +51,14 @@ python-keyczar==0.716 pytz==2024.2 pywinrm==0.5.0 pyyaml==6.0.2 -redis==5.2.0 +redis==5.2.1 requests==2.32.3 retrying==1.3.4 routes==2.5.1 semver==3.0.2 -six==1.16.0 +six==1.17.0 argparse==1.4.0 -argcomplete==3.4.0 +argcomplete==3.5.2 prettytable==3.10.2 importlib-metadata==7.1.0 typing-extensions==4.12.2 @@ -68,20 +68,19 @@ stevedore==5.3.0 tenacity==9.0.0 tooz==6.3.0 # Note: virtualenv embeds wheels for pip, wheel, and setuptools. So pinning virtualenv pins those as well. -# virtualenv==20.26.5 (<21) has pip==24.2 wheel==0.44.0 setuptools==75.2.0 -# lockfiles/st2.lock has pip==24.2 wheel==0.44.0 setuptools==75.2.0 -virtualenv==20.27.0 +# virtualenv==20.27.2 (<21) has pip==24.3.1 wheel==0.45.1 setuptools==75.3.0 +# lockfiles/st2.lock has pip==24.3.1 wheel==0.45.1 setuptools==75.3.0 +virtualenv==20.28.0 webob==1.8.9 webtest==3.0.1 zake==0.2.2 # test requirements below -bcrypt==4.2.0 +bcrypt==4.2.1 jinja2==3.1.4 mock==5.1.0 -nose-timer==1.0.1 -nose-parallel==0.4.0 +pytest==7.0.1 psutil==6.1.0 python-dateutil==2.9.0.post0 python-statsd==2.1.0 -orjson==3.10.10 +orjson==3.10.12 zipp==3.20.2 diff --git a/lockfiles/st2.lock b/lockfiles/st2.lock index ba96a5f8c9..28c03b2114 100644 --- a/lockfiles/st2.lock +++ b/lockfiles/st2.lock @@ -36,9 +36,6 @@ // "mock", // "mongoengine<0.30.0,>=0.24.0", // "networkx", -// "nose", -// "nose-parallel", -// "nose-timer", // "orjson", // "orquesta@ git+https://github.com/StackStorm/orquesta.git@5ba1467614b2ef8b4709b2ca89e68baa671e8975", // "oslo.config", @@ -65,7 +62,6 @@ // "pytz", // "pywinrm", // "redis", -// "rednose", // "requests", // "retrying", // "routes", @@ -114,13 +110,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637", - "url": "https://files.pythonhosted.org/packages/b3/f0/8e5be5d5e0653d9e1d02b1144efa33ff7d2963dfad07049e02c0fa9b2e8d/amqp-5.2.0-py3-none-any.whl" + "hash": "43b3319e1b4e7d1251833a93d672b4af1e40f3d632d479b98661a95f117880a2", + "url": "https://files.pythonhosted.org/packages/26/99/fc813cd978842c26c82534010ea849eee9ab3a13ea2b74e95cb9c99e747b/amqp-5.3.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd", - "url": "https://files.pythonhosted.org/packages/32/2c/6eb09fbdeb3c060b37bd33f8873832897a83e7a428afe01aad333fc405ec/amqp-5.2.0.tar.gz" + "hash": "cddc00c725449522023bad949f70fff7b48f0b1ade74d170a6f10ab044739432", + "url": "https://files.pythonhosted.org/packages/79/fc/ec94a357dfc6683d8c86f8b4cfa5416a4c36b28052ec8260c77aca96a443/amqp-5.3.1.tar.gz" } ], "project_name": "amqp", @@ -128,56 +124,60 @@ "vine<6.0.0,>=5.0.0" ], "requires_python": ">=3.6", - "version": "5.2.0" + "version": "5.3.1" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "fb91e8a768632a4756a585f79ec834e0e27aad5860bac7eaa523d9ccefd87661", - "url": "https://files.pythonhosted.org/packages/13/b5/7af0cb920a476dccd612fbc9a21a3745fb29b1fcd74636078db8f7ba294c/APScheduler-3.10.4-py3-none-any.whl" + "hash": "fc134ca32e50f5eadcc4938e3a4545ab19131435e851abb40b34d63d5141c6da", + "url": "https://files.pythonhosted.org/packages/d0/ae/9a053dd9229c0fde6b1f1f33f609ccff1ee79ddda364c756a924c6d8563b/APScheduler-3.11.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "e6df071b27d9be898e486bc7940a7be50b4af2e9da7c08f0744a96d4bd4cef4a", - "url": "https://files.pythonhosted.org/packages/5e/34/5dcb368cf89f93132d9a31bd3747962a9dc874480e54333b0c09fa7d56ac/APScheduler-3.10.4.tar.gz" + "hash": "4c622d250b0955a65d5d0eb91c33e6d43fd879834bf541e0a18661ae60460133", + "url": "https://files.pythonhosted.org/packages/4e/00/6d6814ddc19be2df62c8c898c4df6b5b1914f3bd024b780028caa392d186/apscheduler-3.11.0.tar.gz" } ], "project_name": "apscheduler", "requires_dists": [ + "APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]; extra == \"test\"", + "PySide6; (platform_python_implementation == \"CPython\" and python_version < \"3.14\") and extra == \"test\"", + "anyio>=4.5.2; extra == \"test\"", + "backports.zoneinfo; python_version < \"3.9\"", + "etcd3; extra == \"etcd\"", "gevent; extra == \"gevent\"", - "importlib-metadata>=3.6.0; python_version < \"3.8\"", + "gevent; python_version < \"3.14\" and extra == \"test\"", "kazoo; extra == \"zookeeper\"", + "packaging; extra == \"doc\"", + "protobuf<=3.21.0; extra == \"etcd\"", "pymongo>=3.0; extra == \"mongodb\"", - "pytest-asyncio; extra == \"testing\"", - "pytest-cov; extra == \"testing\"", - "pytest-tornado5; extra == \"testing\"", - "pytest; extra == \"testing\"", - "pytz", + "pytest; extra == \"test\"", + "pytz; extra == \"test\"", "redis>=3.0; extra == \"redis\"", "rethinkdb>=2.4.0; extra == \"rethinkdb\"", - "six>=1.4.0", - "sphinx-rtd-theme; extra == \"doc\"", + "sphinx-rtd-theme>=1.3.0; extra == \"doc\"", "sphinx; extra == \"doc\"", "sqlalchemy>=1.4; extra == \"sqlalchemy\"", "tornado>=4.3; extra == \"tornado\"", "twisted; extra == \"twisted\"", - "tzlocal!=3.*,>=2.0" + "twisted; python_version < \"3.14\" and extra == \"test\"", + "tzlocal>=3.0" ], - "requires_python": ">=3.6", - "version": "3.10.4" + "requires_python": ">=3.8", + "version": "3.11.0" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "1a1d148bdaa3e3b93454900163403df41448a248af01b6e849edc5ac08e6c363", - "url": "https://files.pythonhosted.org/packages/f7/be/a606a6701d491cfae75583c80a6583f8abe9c36c0b9666e867e7cdd62fe8/argcomplete-3.5.1-py3-none-any.whl" + "hash": "036d020d79048a5d525bc63880d7a4b8d1668566b8a76daf1144c0bbe0f63472", + "url": "https://files.pythonhosted.org/packages/a9/37/3fa718aaadd36e073891138dc3ebd919a71bafd4881c97d8a133265af191/argcomplete-3.5.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "eb1ee355aa2557bd3d0145de7b06b2a45b0ce461e1e7813f5d066039ab4177b4", - "url": "https://files.pythonhosted.org/packages/5f/39/27605e133e7f4bb0c8e48c9a6b87101515e3446003e0442761f6a02ac35e/argcomplete-3.5.1.tar.gz" + "hash": "23146ed7ac4403b70bd6026402468942ceba34a6732255b9edf5b7354f68a6bb", + "url": "https://files.pythonhosted.org/packages/7f/03/581b1c29d88fffaa08abbced2e628c34dd92d32f1adaed7e42fc416938b0/argcomplete-3.5.2.tar.gz" } ], "project_name": "argcomplete", @@ -189,7 +189,7 @@ "wheel; extra == \"test\"" ], "requires_python": ">=3.8", - "version": "3.5.1" + "version": "3.5.2" }, { "artifacts": [ @@ -213,33 +213,31 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", - "url": "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl" + "hash": "39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", + "url": "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", - "url": "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz" + "hash": "d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", + "url": "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz" } ], "project_name": "async-timeout", - "requires_dists": [ - "typing-extensions>=3.6.5; python_version < \"3.8\"" - ], - "requires_python": ">=3.7", - "version": "4.0.3" + "requires_dists": [], + "requires_python": ">=3.8", + "version": "5.0.1" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", - "url": "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl" + "hash": "ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", + "url": "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", - "url": "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz" + "hash": "8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", + "url": "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz" } ], "project_name": "attrs", @@ -255,24 +253,23 @@ "hypothesis; extra == \"cov\"", "hypothesis; extra == \"dev\"", "hypothesis; extra == \"tests\"", - "importlib-metadata; python_version < \"3.8\"", - "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"benchmark\"", - "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"cov\"", - "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"dev\"", - "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"tests\"", - "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\") and extra == \"tests-mypy\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"benchmark\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"cov\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"dev\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"tests\"", + "mypy>=1.11.1; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"tests-mypy\"", "myst-parser; extra == \"docs\"", - "pre-commit; extra == \"dev\"", + "pre-commit-uv; extra == \"dev\"", "pympler; extra == \"benchmark\"", "pympler; extra == \"cov\"", "pympler; extra == \"dev\"", "pympler; extra == \"tests\"", "pytest-codspeed; extra == \"benchmark\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"benchmark\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"cov\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"dev\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"tests\"", - "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.9\" and python_version < \"3.13\") and extra == \"tests-mypy\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"benchmark\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"cov\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"dev\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"tests\"", + "pytest-mypy-plugins; (platform_python_implementation == \"CPython\" and python_version >= \"3.10\") and extra == \"tests-mypy\"", "pytest-xdist[psutil]; extra == \"benchmark\"", "pytest-xdist[psutil]; extra == \"cov\"", "pytest-xdist[psutil]; extra == \"dev\"", @@ -286,8 +283,8 @@ "sphinxcontrib-towncrier; extra == \"docs\"", "towncrier<24.7; extra == \"docs\"" ], - "requires_python": ">=3.7", - "version": "24.2.0" + "requires_python": ">=3.8", + "version": "24.3.0" }, { "artifacts": [ @@ -324,108 +321,98 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "373db9abe198e8e2c70d12b479464e0d5092cc122b20ec504097b5f2297ed184", - "url": "https://files.pythonhosted.org/packages/8b/79/76a139d1b9f11aa4afcb7ceb882d2e81003667681711f2fe8a302c4c10ca/bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl" + "hash": "807261df60a8b1ccd13e6599c779014a362ae4e795f5c59747f60208daddd96d", + "url": "https://files.pythonhosted.org/packages/5d/ab/a6c0da5c2cf86600f74402a72b06dfe365e1a1d30783b1bbeec460fd57d1/bcrypt-4.2.1-cp39-abi3-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "3698393a1b1f1fd5714524193849d0c6d524d33523acca37cd28f02899285060", - "url": "https://files.pythonhosted.org/packages/00/03/2af7c45034aba6002d4f2b728c1a385676b4eab7d764410e34fd768009f2/bcrypt-4.2.0-cp37-abi3-musllinux_1_2_aarch64.whl" + "hash": "8ad2f4528cbf0febe80e5a3a57d7a74e6635e41af1ea5675282a33d769fba413", + "url": "https://files.pythonhosted.org/packages/4a/57/23b46933206daf5384b5397d9878746d2249fe9d45efaa8e1467c87d3048/bcrypt-4.2.1-cp39-abi3-macosx_10_12_universal2.whl" }, { "algorithm": "sha256", - "hash": "c02d944ca89d9b1922ceb8a46460dd17df1ba37ab66feac4870f6862a1533c00", - "url": "https://files.pythonhosted.org/packages/05/d2/1be1e16aedec04bcf8d0156e01b987d16a2063d38e64c3f28030a3427d61/bcrypt-4.2.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "b7703ede632dc945ed1172d6f24e9f30f27b1b1a067f32f68bf169c5f08d0425", + "url": "https://files.pythonhosted.org/packages/4e/ef/f2cb7a0f7e1ed800a604f8ab256fb0afcf03c1540ad94ff771ce31e794aa/bcrypt-4.2.1-cp37-abi3-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "cb2a8ec2bc07d3553ccebf0746bbf3d19426d1c6d1adbd4fa48925f66af7b9e8", - "url": "https://files.pythonhosted.org/packages/1a/d4/586b9c18a327561ea4cd336ff4586cca1a7aa0f5ee04e23a8a8bb9ca64f1/bcrypt-4.2.0-cp39-abi3-musllinux_1_2_x86_64.whl" + "hash": "533e7f3bcf2f07caee7ad98124fab7499cb3333ba2274f7a36cf1daee7409d99", + "url": "https://files.pythonhosted.org/packages/50/68/f2e3959014b4d8874c747e6e171d46d3e63a3a39aaca8417a8d837eda0a8/bcrypt-4.2.1-cp39-abi3-manylinux_2_28_aarch64.whl" }, { "algorithm": "sha256", - "hash": "3d3a6d28cb2305b43feac298774b997e372e56c7c7afd90a12b3dc49b189151c", - "url": "https://files.pythonhosted.org/packages/3e/d0/31938bb697600a04864246acde4918c4190a938f891fd11883eaaf41327a/bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl" + "hash": "6765386e3ab87f569b276988742039baab087b2cdb01e809d74e74503c2faafe", + "url": "https://files.pythonhosted.org/packages/56/8c/dd696962612e4cd83c40a9e6b3db77bfe65a830f4b9af44098708584686c/bcrypt-4.2.1.tar.gz" }, { "algorithm": "sha256", - "hash": "1bb429fedbe0249465cdd85a58e8376f31bb315e484f16e68ca4c786dcc04291", - "url": "https://files.pythonhosted.org/packages/46/54/dc7b58abeb4a3d95bab653405935e27ba32f21b812d8ff38f271fb6f7f55/bcrypt-4.2.0-cp37-abi3-manylinux_2_28_aarch64.whl" + "hash": "f85b1ffa09240c89aa2e1ae9f3b1c687104f7b2b9d2098da4e923f1b7082d331", + "url": "https://files.pythonhosted.org/packages/5c/72/916e14fa12d2b1d1fc6c26ea195337419da6dd23d0bf53ac61ef3739e5c5/bcrypt-4.2.1-cp39-abi3-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "3413bd60460f76097ee2e0a493ccebe4a7601918219c02f503984f0a7ee0aebe", - "url": "https://files.pythonhosted.org/packages/4b/3b/ad784eac415937c53da48983756105d267b91e56aa53ba8a1b2014b8d930/bcrypt-4.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "b1ee315739bc8387aa36ff127afc99120ee452924e0df517a8f3e4c0187a0f5f", + "url": "https://files.pythonhosted.org/packages/6a/be/e7c6e0fd6087ee8fc6d77d8d9e817e9339d879737509019b9a9012a1d96f/bcrypt-4.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "27fe0f57bb5573104b5a6de5e4153c60814c711b29364c10a75a54bb6d7ff48d", - "url": "https://files.pythonhosted.org/packages/5d/2c/019bc2c63c6125ddf0483ee7d914a405860327767d437913942b476e9c9b/bcrypt-4.2.0-cp39-abi3-musllinux_1_1_x86_64.whl" + "hash": "041fa0155c9004eb98a232d54da05c0b41d4b8e66b6fc3cb71b4b3f6144ba837", + "url": "https://files.pythonhosted.org/packages/6e/5a/ee107961e84c41af2ac201d0460f962b6622ff391255ffd46429e9e09dc1/bcrypt-4.2.1-cp39-abi3-musllinux_1_1_aarch64.whl" }, { "algorithm": "sha256", - "hash": "1ff39b78a52cf03fdf902635e4c81e544714861ba3f0efc56558979dd4f09170", - "url": "https://files.pythonhosted.org/packages/73/5a/811c3c7af3be99888f39ee8845ddf849d2a03a83049d63ece5dfb4612f4d/bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl" + "hash": "cde78d385d5e93ece5479a0a87f73cd6fa26b171c786a884f955e165032b262c", + "url": "https://files.pythonhosted.org/packages/77/7f/b43622999f5d4de06237a195ac5501ac83516adf571b907228cd14bac8fe/bcrypt-4.2.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "8ac68872c82f1add6a20bd489870c71b00ebacd2e9134a8aa3f98a0052ab4b0e", - "url": "https://files.pythonhosted.org/packages/75/fe/9e137727f122bbe29771d56afbf4e0dbc85968caa8957806f86404a5bfe1/bcrypt-4.2.0-cp39-abi3-musllinux_1_2_aarch64.whl" + "hash": "aaa2e285be097050dba798d537b6efd9b698aa88eef52ec98d23dcd6d7cf6fea", + "url": "https://files.pythonhosted.org/packages/8e/ab/b8710a3d6231c587e575ead0b1c45bb99f5454f9f579c9d7312c17b069cc/bcrypt-4.2.1-cp37-abi3-manylinux_2_28_aarch64.whl" }, { "algorithm": "sha256", - "hash": "0da52759f7f30e83f1e30a888d9163a81353ef224d82dc58eb5bb52efcabc399", - "url": "https://files.pythonhosted.org/packages/7b/76/2aa660679abbdc7f8ee961552e4bb6415a81b303e55e9374533f22770203/bcrypt-4.2.0-cp37-abi3-musllinux_1_1_x86_64.whl" + "hash": "c6f5fa3775966cca251848d4d5393ab016b3afed251163c1436fefdec3b02c84", + "url": "https://files.pythonhosted.org/packages/97/92/3dc76d8bfa23300591eec248e950f85bd78eb608c96bd4747ce4cc06acdb/bcrypt-4.2.1-cp39-abi3-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "c52aac18ea1f4a4f65963ea4f9530c306b56ccd0c6f8c8da0c06976e34a6e841", - "url": "https://files.pythonhosted.org/packages/96/86/8c6a84daed4dd878fbab094400c9174c43d9b838ace077a2f8ee8bc3ae12/bcrypt-4.2.0-cp39-abi3-macosx_10_12_universal2.whl" + "hash": "04e56e3fe8308a88b77e0afd20bec516f74aecf391cdd6e374f15cbed32783d6", + "url": "https://files.pythonhosted.org/packages/98/bc/9d501ee9d754f63d4b1086b64756c284facc3696de9b556c146279a124a5/bcrypt-4.2.1-cp37-abi3-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "096a15d26ed6ce37a14c1ac1e48119660f21b24cba457f160a4b830f3fe6b5cb", - "url": "https://files.pythonhosted.org/packages/a9/81/4e8f5bc0cd947e91fb720e1737371922854da47a94bc9630454e7b2845f8/bcrypt-4.2.0-cp37-abi3-macosx_10_12_universal2.whl" + "hash": "76d3e352b32f4eeb34703370e370997065d28a561e4a18afe4fef07249cb4396", + "url": "https://files.pythonhosted.org/packages/9d/e5/2fd1ea6395358ffdfd4afe370d5b52f71408f618f781772a48971ef3b92b/bcrypt-4.2.1-cp37-abi3-manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "655ea221910bcac76ea08aaa76df427ef8625f92e55a8ee44fbf7753dbabb328", - "url": "https://files.pythonhosted.org/packages/ac/be/da233c5f11fce3f8adec05e8e532b299b64833cc962f49331cdd0e614fa9/bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl" + "hash": "cfdf3d7530c790432046c40cda41dfee8c83e29482e6a604f8930b9930e94139", + "url": "https://files.pythonhosted.org/packages/a1/25/2ec4ce5740abc43182bfc064b9acbbf5a493991246985e8b2bfe231ead64/bcrypt-4.2.1-cp37-abi3-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "1ee38e858bf5d0287c39b7a1fc59eec64bbf880c7d504d3a06a96c16e14058e7", - "url": "https://files.pythonhosted.org/packages/b0/b8/8b4add88d55a263cf1c6b8cf66c735280954a04223fcd2880120cc767ac3/bcrypt-4.2.0-cp37-abi3-musllinux_1_1_aarch64.whl" + "hash": "1340411a0894b7d3ef562fb233e4b6ed58add185228650942bdc885362f32c17", + "url": "https://files.pythonhosted.org/packages/bc/ca/e17b08c523adb93d5f07a226b2bd45a7c6e96b359e31c1e99f9db58cb8c3/bcrypt-4.2.1-cp37-abi3-macosx_10_12_universal2.whl" }, { "algorithm": "sha256", - "hash": "8d7bb9c42801035e61c109c345a28ed7e84426ae4865511eb82e913df18f58c2", - "url": "https://files.pythonhosted.org/packages/cc/14/b9ff8e0218bee95e517b70e91130effb4511e8827ac1ab00b4e30943a3f6/bcrypt-4.2.0-cp39-abi3-manylinux_2_28_aarch64.whl" + "hash": "8dbd0747208912b1e4ce730c6725cb56c07ac734b3629b60d4398f082ea718ad", + "url": "https://files.pythonhosted.org/packages/d6/53/ac084b7d985aee1a5f2b086d501f550862596dbf73220663b8c17427e7f2/bcrypt-4.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "762a2c5fb35f89606a9fde5e51392dad0cd1ab7ae64149a8b935fe8d79dd5ed7", - "url": "https://files.pythonhosted.org/packages/dc/5d/6843443ce4ab3af40bddb6c7c085ed4a8418b3396f7a17e60e6d9888416c/bcrypt-4.2.0-cp37-abi3-musllinux_1_2_x86_64.whl" + "hash": "687cf30e6681eeda39548a93ce9bfbb300e48b4d445a43db4298d2474d2a1e54", + "url": "https://files.pythonhosted.org/packages/d6/c3/4b4bad4da852924427c651589d464ad1aa624f94dd904ddda8493b0a35e5/bcrypt-4.2.1-cp39-abi3-manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "1d84cf6d877918620b687b8fd1bf7781d11e8a0998f576c7aa939776b512b98d", - "url": "https://files.pythonhosted.org/packages/e3/96/7a654027638ad9b7589effb6db77eb63eba64319dfeaf9c0f4ca953e5f76/bcrypt-4.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "89df2aea2c43be1e1fa066df5f86c8ce822ab70a30e4c210968669565c0f4685", + "url": "https://files.pythonhosted.org/packages/de/cb/578b0023c6a5ca16a177b9044ba6bd6032277bd3ef020fb863eccd22e49b/bcrypt-4.2.1-cp37-abi3-musllinux_1_1_x86_64.whl" }, { "algorithm": "sha256", - "hash": "cf69eaf5185fd58f268f805b505ce31f9b9fc2d64b376642164e9244540c1221", - "url": "https://files.pythonhosted.org/packages/e4/7e/d95e7d96d4828e965891af92e43b52a4cd3395dc1c1ef4ee62748d0471d0/bcrypt-4.2.0.tar.gz" - }, - { - "algorithm": "sha256", - "hash": "9c1c4ad86351339c5f320ca372dfba6cb6beb25e8efc659bedd918d921956bae", - "url": "https://files.pythonhosted.org/packages/e7/c3/dae866739989e3f04ae304e1201932571708cb292a28b2f1b93283e2dcd8/bcrypt-4.2.0-cp39-abi3-musllinux_1_1_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "3bbbfb2734f0e4f37c5136130405332640a1e46e6b23e000eeff2ba8d005da68", - "url": "https://files.pythonhosted.org/packages/f6/05/e394515f4e23c17662e5aeb4d1859b11dc651be01a3bd03c2e919a155901/bcrypt-4.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "909faa1027900f2252a9ca5dfebd25fc0ef1417943824783d1c8418dd7d6df4a", + "url": "https://files.pythonhosted.org/packages/fd/28/3ea8a39ddd4938b6c6b6136816d72ba5e659e2d82b53d843c8c53455ac4d/bcrypt-4.2.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" } ], "project_name": "bcrypt", @@ -434,7 +421,7 @@ "pytest!=3.3.0,>=3.2.1; extra == \"tests\"" ], "requires_python": ">=3.7", - "version": "4.2.0" + "version": "4.2.1" }, { "artifacts": [ @@ -501,19 +488,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", - "url": "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl" + "hash": "1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", + "url": "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", - "url": "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz" + "hash": "b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", + "url": "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz" } ], "project_name": "certifi", "requires_dists": [], "requires_python": ">=3.6", - "version": "2024.8.30" + "version": "2024.12.14" }, { "artifacts": [ @@ -780,84 +767,104 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "4ac00d293cdb3d1a5c78e09b3d75c7b0292ab45d5b26853b436ff5087eba2165", - "url": "https://files.pythonhosted.org/packages/58/18/2c40c4ee244506568398505558171c9243a7d0d46338fc5b87c3142573ed/ciso8601-2.3.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "7eb6c8756806f4b8320fe57e3b048dafc54e99af7586160ff9318f35fc521268", + "url": "https://files.pythonhosted.org/packages/ac/f5/2e9fdb94d2c7efe6389b454f99136ccf358755d4290c1f4411f464f0a770/ciso8601-2.3.2-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "566b4a8b2f9717e54ffcdd732a7c8051a91da30a60a4f1dafb62e303a1dbac69", - "url": "https://files.pythonhosted.org/packages/02/c1/64433e0e6c615d8c9e5949c4082d364890f2632064b187d4b33b1463e789/ciso8601-2.3.1-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "af399c2671dfe8fead4f34908a6e6ef3689db9606f2028269b578afd2326b96e", + "url": "https://files.pythonhosted.org/packages/04/46/fcab76d2ecc5f6474ed3987303492f32c6ebc049b40b9992db6544776a42/ciso8601-2.3.2-cp38-cp38-macosx_11_0_x86_64.whl" }, { "algorithm": "sha256", - "hash": "e4ac59453664781dfddebee51f9a36e41819993823fdb09ddc0ce0e4bd3ff0c3", - "url": "https://files.pythonhosted.org/packages/06/7b/674cbdc6fba47e2bb56d3ad5307d8fa5202ab853c8f5c69c42effa0e4436/ciso8601-2.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "ec1616969aa46c51310b196022e5d3926f8d3fa52b80ec17f6b4133623bd5434", + "url": "https://files.pythonhosted.org/packages/09/e9/d83711081c997540aee59ad2f49d81f01d33e8551d766b0ebde346f605af/ciso8601-2.3.2.tar.gz" }, { "algorithm": "sha256", - "hash": "2a64ff58904d4418d60fa9619014ae820ae21f7aef58da46df78a4c647f951ec", - "url": "https://files.pythonhosted.org/packages/07/12/975e4b102a95aa7a940793cd87439a19b3b4cf4c8b73cda1145bd72ec78e/ciso8601-2.3.1-cp38-cp38-macosx_10_9_x86_64.whl" + "hash": "69136ef63e7d5178727f358a9cfe4dfda52f132eafcddfa7e6d5933ee1d73b7a", + "url": "https://files.pythonhosted.org/packages/17/7a/f7a21101028204158a3ed4e9af477b3941cb4d39cf4c5f13f063295f9d54/ciso8601-2.3.2-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "d1f85c0b7fa742bbfd18177137ccbaa3f867dd06157f91595075bb959a733048", - "url": "https://files.pythonhosted.org/packages/09/bd/0cc7e7dbe08ad9c4913ece2abd975078fd6e91f2b78225d9dc02f1fb7793/ciso8601-2.3.1-cp38-cp38-macosx_11_0_arm64.whl" + "hash": "a323aa0143ad8e99d7a0b0ac3005419c505e073e6f850f0443b5994b31a52d14", + "url": "https://files.pythonhosted.org/packages/1a/78/078b57970e82b2dc80ce89249beb4c0d464bffb9e84d479dcd8179c36d0f/ciso8601-2.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "58a749d63f28c2eda71416c9d6014113b0748abf5fd14c502b01bd515502fedf", - "url": "https://files.pythonhosted.org/packages/12/b1/ddc338b59f1658d04fc8e61c91562d05b7003c05b1e300506745e9604fed/ciso8601-2.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "ff397592a0eadd5e0aec395a285751707c655439abb874ad93e34d04d925ec8d", + "url": "https://files.pythonhosted.org/packages/1f/c4/49c6e651cd8310580dc930d1f430ef35d7827e0335f2ff2c2c4f5da308b1/ciso8601-2.3.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "02828107880848ff497971ebc98e6dc851ad7af8ec14a58089e0e11f3111cad6", - "url": "https://files.pythonhosted.org/packages/15/ac/8dfe940808219f8ec3dcfa286cdcbcb704e7ccd9b02f64bc0a31ea4b8c8a/ciso8601-2.3.1-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "fc2a6bb31030b875c7706554b99e1d724250e0fc8160aa2f3ae32520b8dccbc5", + "url": "https://files.pythonhosted.org/packages/20/30/d4303931e31fe2df4b2c886cbac261b9e69515cade3d1de639793fba5092/ciso8601-2.3.2-cp39-cp39-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "eaecca7e0c3ef9e8f5e963e212b083684e849f9a9bb25834d3042363223a73cd", - "url": "https://files.pythonhosted.org/packages/4b/37/bdf84104ff6810116e9802be07212edfaa877a197433f1caec200b7aaa93/ciso8601-2.3.1-cp38-cp38-musllinux_1_1_i686.whl" + "hash": "361a49da3e53811ddc371ff2183d32ee673321899e4653c4d55ed06d0a81ef3d", + "url": "https://files.pythonhosted.org/packages/22/32/d2cd32d62fa7ddf23a9375990ab1db27064722f9c9de652b8fde9c0a8d62/ciso8601-2.3.2-cp38-cp38-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "025859ec286a994aa3f2120c0f27d053b719cabc975398338374f2cc1f961125", - "url": "https://files.pythonhosted.org/packages/64/18/3544594777a553d5e2b69739d215ccc12620973ff54ba67e4cb1ab60f6a5/ciso8601-2.3.1-cp38-cp38-macosx_10_9_universal2.whl" + "hash": "91dab638ffaff1da12e0a6de4cfca520430426a1c0eaba5841b1311f45516d49", + "url": "https://files.pythonhosted.org/packages/26/d8/039d89c7ae2994a5155f4366088ad6f86ee658e440d874dafdebebb2c586/ciso8601-2.3.2-cp38-cp38-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "3212c7ffe5d8080270548b5f2692ffd2039683b6628a8d2ad456122cc5793c4c", - "url": "https://files.pythonhosted.org/packages/ac/bc/cf42c1b0042f91c90a6b00244f63b6fb137af15e43e29f07bb72cf955be8/ciso8601-2.3.1.tar.gz" + "hash": "af26301e0e0cfc6cda225fd2a8b1888bf3828a7d24756774325bda7d29ab2468", + "url": "https://files.pythonhosted.org/packages/35/c5/c7b9b33afbdf1dd291d65d6a4556cec19d22d6b66909804834d3b1fef520/ciso8601-2.3.2-cp38-cp38-macosx_11_0_universal2.whl" }, { "algorithm": "sha256", - "hash": "070f568de3bc269268296cb9265704dc5fcb9d4c12b1f1c67536624174df5d09", - "url": "https://files.pythonhosted.org/packages/c1/32/389fb540c94b32b4938ba78329d8fcbc86d257cec65f83564dfd9c20752d/ciso8601-2.3.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "dac06a1bd3c12ab699c29024c5f052e7016cb904e085a5e2b26e6b92fd2dd1dc", + "url": "https://files.pythonhosted.org/packages/53/6b/6d3f90c4018eec00aa560356cf41fd1315d084863305c077f6af484ce673/ciso8601-2.3.2-cp39-cp39-macosx_11_0_x86_64.whl" }, { "algorithm": "sha256", - "hash": "695583810836a42945084b33621b22b0309701c6916689f6a3588fa44c5bc413", - "url": "https://files.pythonhosted.org/packages/ca/b7/b24f11ee31697a251ef2d1fcd249e6ce3b23e7bac272f9a2b98872d76c49/ciso8601-2.3.1-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "fbbe0af7ef440d679ce546f926fc441e31025c6a96c1bb54087df0e5e6c8e021", + "url": "https://files.pythonhosted.org/packages/62/ee/7383005feb6d089e6536639a74161a1e04d2ebd0bf427d706ed2c7203866/ciso8601-2.3.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "cb135de0e3b8feb7e74a4f7a234e8c8545957fe8d26316a1a549553f425c629d", - "url": "https://files.pythonhosted.org/packages/eb/3f/69e3ef7fe521edcdc5d5fd796c7425c607db86b060968127c3ce522cb094/ciso8601-2.3.1-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "5e9290e7e1b1c3a6df3967e3f1b22c334c980e841f5a1967ab6ef92b30a540d8", + "url": "https://files.pythonhosted.org/packages/78/b9/0fc865c2fd9870b6d220f2f9f47fd2ab51af29ebd8ceae56e7059bc43841/ciso8601-2.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "7eb7b5ef8714d3d1fe9f3256b7a679ad783da899a0b7503a5ace78186735f840", - "url": "https://files.pythonhosted.org/packages/ef/54/863616c6f435dee386d8533d85ac59efa301324d7745bbcdd891512a67c7/ciso8601-2.3.1-cp39-cp39-macosx_10_9_universal2.whl" + "hash": "69e137cf862c724a9477b62d89fb8190f141ed6d036f6c4cf824be6d9a7b819e", + "url": "https://files.pythonhosted.org/packages/99/28/5a2d1e7df04a37ad5e19c149ba74eb1f1fdbcef48ad13acd9d71d1ec9454/ciso8601-2.3.2-cp39-cp39-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "ad8f417c45eea973a694599b96f40d841215bfee352cb9963383e8d66b309981", - "url": "https://files.pythonhosted.org/packages/fc/41/c5689bb0b1824f180f80cba5a4bd793d3d0e17b7802f7576fa1b7fd3efe9/ciso8601-2.3.1-cp38-cp38-musllinux_1_1_x86_64.whl" + "hash": "0fbbe659093d4aef1e66de0ee9a10487439527be4b2f6a6710960f98a41e2cc5", + "url": "https://files.pythonhosted.org/packages/a3/bb/ba7bb497fa6093e478e54d870c8ffbfcd44c6b6400a3a0c8f485b229595b/ciso8601-2.3.2-cp39-cp39-macosx_11_0_arm64.whl" + }, + { + "algorithm": "sha256", + "hash": "8ccb16db7ca83cc39df3c73285e9ab4920a90f0dbef566f60f0c6cca44becaba", + "url": "https://files.pythonhosted.org/packages/af/8a/f08d6c7bd5f53f2896e91ffdb849e1197fb543a011ee2f7c3200ffe1c1e8/ciso8601-2.3.2-cp39-cp39-macosx_11_0_universal2.whl" + }, + { + "algorithm": "sha256", + "hash": "d7860ad2b52007becfd604cfe596f0b7ffa8ffe4f7336b58ef1a2234dc53fa10", + "url": "https://files.pythonhosted.org/packages/ba/08/ea4418f87674849a915ae34c7c7cfa0a57b12f203db0fdc2e49eec7590ec/ciso8601-2.3.2-cp38-cp38-musllinux_1_2_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "fa8978a69a6061380b352442160d468915d102c18b0b805a950311e6e0f3b821", + "url": "https://files.pythonhosted.org/packages/c5/8e/ac8adb80856d8b557ea14482ed3af36de0703c0b93517d8419cca68f4bd4/ciso8601-2.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + }, + { + "algorithm": "sha256", + "hash": "347db58040ad1cb3d2175f5699f0fb1abcb9e894ad744e3460b01bd101bb78a1", + "url": "https://files.pythonhosted.org/packages/d6/06/44d89362e5c804429e9eabe0c7b236a1df5e3262545d5507e0e1d86a76f1/ciso8601-2.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" } ], "project_name": "ciso8601", "requires_dists": [], "requires_python": null, - "version": "2.3.1" + "version": "2.3.2" }, { "artifacts": [ @@ -880,24 +887,6 @@ "requires_python": ">=3.7", "version": "8.1.7" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", - "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "url": "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz" - } - ], - "project_name": "colorama", - "requires_dists": [], - "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7", - "version": "0.4.6" - }, { "artifacts": [ { @@ -1236,13 +1225,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "801ac231401e41f33a799457c78fdbfabc1c2f28bf9346d4ec4188e9aebc2067", - "url": "https://files.pythonhosted.org/packages/bf/1e/6590b481bd698ad281f1ee601283421ff167274c15ba73ae80385617ddec/eventlet-0.37.0-py3-none-any.whl" + "hash": "4a2e3cbc53917c8f39074ccf689501168563d3a4df59e9cddd5e9d3b7f85c599", + "url": "https://files.pythonhosted.org/packages/aa/07/00feb2c708d71796e190a3051a0d530a4922bfb6b346aa8302725840698c/eventlet-0.38.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "fa49bf5a549cdbaa06919679979ea022ac8f8f3cf0499f26849a1cd8e64c30b1", - "url": "https://files.pythonhosted.org/packages/54/8c/d68a786f212bdf362ac91ab248ae94aaf413aeecfd652a08ced9a3d63427/eventlet-0.37.0.tar.gz" + "hash": "6a46823af1dca7d29cf04c0d680365805435473c3acbffc176765c7f8787edac", + "url": "https://files.pythonhosted.org/packages/a6/4e/f974cc85b8d19b31176e0cca90e1650156f385c9c294a96fc42846ca75e9/eventlet-0.38.2.tar.gz" } ], "project_name": "eventlet", @@ -1259,7 +1248,7 @@ "twine; extra == \"dev\"" ], "requires_python": ">=3.7", - "version": "0.37.0" + "version": "0.38.2" }, { "artifacts": [ @@ -2355,145 +2344,124 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", - "url": "https://files.pythonhosted.org/packages/15/d8/dd071918c040f50fa1cf80da16423af51ff8ce4a0f2399b7bf8de45ac3d9/nose-1.3.7-py3-none-any.whl" + "hash": "ff31d22ecc5fb85ef62c7d4afe8301d10c558d00dd24274d4bbe464380d3cd69", + "url": "https://files.pythonhosted.org/packages/81/d9/0216c950e295b1c493510ef546b80328dc06e2ae4a82bc693386e4cdebeb/orjson-3.10.12-cp39-cp39-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98", - "url": "https://files.pythonhosted.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz" - } - ], - "project_name": "nose", - "requires_dists": [], - "requires_python": null, - "version": "1.3.7" - }, - { - "artifacts": [ + "hash": "f29de3ef71a42a5822765def1febfb36e0859d33abf5c2ad240acad5c6a1b78d", + "url": "https://files.pythonhosted.org/packages/01/50/5a52cfe65fc70e7b843cbe143b850313095d4e45f99aeb278b4b3691f3cf/orjson-3.10.12-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" + }, { "algorithm": "sha256", - "hash": "3f7c48d7aa5030fe872211cbffc6852e64e4e356ddbac5958a35796bf15dc225", - "url": "https://files.pythonhosted.org/packages/64/08/9968ef72b3ee8f3243e1f300219afdfb753a3432b203afe9bef56e34ce95/nose_parallel-0.4.0-py2.py3-none-any.whl" + "hash": "0b32652eaa4a7539f6f04abc6243619c56f8530c53bf9b023e1269df5f7816dd", + "url": "https://files.pythonhosted.org/packages/15/04/e9a378cb24a2ea24a0ff84bcc27924c45b470c846cac2b26be2f8aad8f2a/orjson-3.10.12-cp38-cp38-musllinux_1_2_armv7l.whl" }, { "algorithm": "sha256", - "hash": "e4e6d6891a4bb417f09abf1f400554f557f0a9df3fdaed6517d4236e87ed0f51", - "url": "https://files.pythonhosted.org/packages/70/60/039898d68516d2086db9b8ec8e318f84f44a15a8584b2abdfc2d97980a68/nose-parallel-0.4.0.tar.gz" - } - ], - "project_name": "nose-parallel", - "requires_dists": [], - "requires_python": null, - "version": "0.4.0" - }, - { - "artifacts": [ + "hash": "897830244e2320f6184699f598df7fb9db9f5087d6f3f03666ae89d607e4f8ed", + "url": "https://files.pythonhosted.org/packages/27/55/29689b87b076156f8018e1ee6de12065f924fe2f05e64202e299b6b926e9/orjson-3.10.12-cp38-cp38-musllinux_1_2_aarch64.whl" + }, { "algorithm": "sha256", - "hash": "8f70d103b7ffd9122a589de0df9d037a7d967519bf6de122621d2186609b9e3a", - "url": "https://files.pythonhosted.org/packages/ee/fc/ad961aa29606e20b3c85f739ab7d2e5abe0c285310c468a5850dcaf9c720/nose-timer-1.0.1.tar.gz" - } - ], - "project_name": "nose-timer", - "requires_dists": [ - "nose" - ], - "requires_python": null, - "version": "1.0.1" - }, - { - "artifacts": [ + "hash": "7319cda750fca96ae5973efb31b17d97a5c5225ae0bc79bf5bf84df9e1ec2ab6", + "url": "https://files.pythonhosted.org/packages/53/70/956ca7999fe43b5e2ca51248f732850acaaf00f8fa5b8f7924bc504157bb/orjson-3.10.12-cp39-cp39-musllinux_1_2_armv7l.whl" + }, + { + "algorithm": "sha256", + "hash": "c47ce6b8d90fe9646a25b6fb52284a14ff215c9595914af63a5933a49972ce36", + "url": "https://files.pythonhosted.org/packages/54/80/f40805bb094d3470bcfca8d30ae9f4606bb90c809190fee18c17a4653956/orjson-3.10.12-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + }, { "algorithm": "sha256", - "hash": "1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a", - "url": "https://files.pythonhosted.org/packages/5e/5a/8c4b509288240f72f8a4a28bf0cc3f9df780c749a4ec57a588769bd0e8b9/orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl" + "hash": "7d69af5b54617a5fac5c8e5ed0859eb798e2ce8913262eb522590239db6c6763", + "url": "https://files.pythonhosted.org/packages/5c/28/552a97ba66b9b8ceedd854ae922f3ba76b872f4d3d3935033ce9bd85df81/orjson-3.10.12-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" }, { "algorithm": "sha256", - "hash": "e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785", - "url": "https://files.pythonhosted.org/packages/12/e4/fa329b75b182cea5601a8b1a4ba086ce64ae4ce1b8bb27a56e38810de8d7/orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "7ed119ea7d2953365724a7059231a44830eb6bbb0cfead33fcbc562f5fd8f935", + "url": "https://files.pythonhosted.org/packages/60/00/3bd7fea130dcd91630ae838f1d9165daec5fa9b611cd54fbadb31e53a5d3/orjson-3.10.12-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019", - "url": "https://files.pythonhosted.org/packages/54/d0/ff81ce26587459368a58ed772ce131938458c421b77fd0e74b1b11988f1e/orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl" + "hash": "9c5fc1238ef197e7cad5c91415f524aaa51e004be5a9b35a1b8a84ade196f73f", + "url": "https://files.pythonhosted.org/packages/61/fb/505f0e61086caf5253c7dbc35418f8a2a51e4e1eb3692b5be79255d4d169/orjson-3.10.12-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" }, { "algorithm": "sha256", - "hash": "7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8", - "url": "https://files.pythonhosted.org/packages/70/e1/47fa8d4745eb6d641b143c915ec1da9ea161c41783e00429f3d8bd41448c/orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl" + "hash": "9a904f9572092bb6742ab7c16c623f0cdccbad9eeb2d14d4aa06284867bddd31", + "url": "https://files.pythonhosted.org/packages/64/a0/76277224a3c22d158ecd434750ec350ee8ba6e443bd7bb7dd36ca840e153/orjson-3.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8", - "url": "https://files.pythonhosted.org/packages/7b/3c/04294098b67d1cd93d56e23cee874fac4a8379943c5e556b7a922775e672/orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" + "hash": "f72e27a62041cfb37a3de512247ece9f240a561e6c8662276beaf4d53d406db4", + "url": "https://files.pythonhosted.org/packages/68/82/a0c85a84e0ae455d91a892bb189fd3afce12ed2f58b6de39a3a884edcb7d/orjson-3.10.12-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b", - "url": "https://files.pythonhosted.org/packages/80/44/d36e86b33fc84f224b5f2cdf525adf3b8f9f475753e721c402b1ddef731e/orjson-3.10.10.tar.gz" + "hash": "35d3081bbe8b86587eb5c98a73b97f13d8f9fea685cf91a579beddacc0d10566", + "url": "https://files.pythonhosted.org/packages/6f/1f/c8fc64b25e2e4a5fa0fb514a0325719e99461c088a3b659954a57b8c1f3c/orjson-3.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4", - "url": "https://files.pythonhosted.org/packages/89/2f/5ddd09e893b07a82aa4b9be810332c3f5efaafa0e4ad5648f730e3e87c71/orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + "hash": "5472be7dc3269b4b52acba1433dac239215366f89dc1d8d0e64029abac4e714e", + "url": "https://files.pythonhosted.org/packages/85/03/87091a1c831076e8d6ed0be19d30bd837d3c27e29f43b6b2dc23efee3d29/orjson-3.10.12-cp39-cp39-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a", - "url": "https://files.pythonhosted.org/packages/90/c6/52ce917ea468ef564ec100e3f2164e548e61b4c71140c3e058a913bfea9b/orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "855c0833999ed5dc62f64552db26f9be767434917d8348d77bacaab84f787d7b", + "url": "https://files.pythonhosted.org/packages/a2/ec/b8bd31eeee6fc9cb56385b6710f8c4a06c82b6ecb7e8f6b6352eb4109b0b/orjson-3.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl" }, { "algorithm": "sha256", - "hash": "829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568", - "url": "https://files.pythonhosted.org/packages/93/7d/3ef9524d57343f0642be8f101296a4bccdf836bd0730654e066ecf88b2bc/orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" + "hash": "de365a42acc65d74953f05e4772c974dad6c51cfc13c3240899f534d611be967", + "url": "https://files.pythonhosted.org/packages/af/42/adb00fc60890e57ee6022257d70d9a20dfd28bfd955401e2d02a60192226/orjson-3.10.12-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25", - "url": "https://files.pythonhosted.org/packages/95/52/d4fc57145446c7d0cbf5cfdaceb0ea4d5f0636e7398de02e3abc3bf91341/orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + "hash": "73c23a6e90383884068bc2dba83d5222c9fcc3b99a0ed2411d38150734236755", + "url": "https://files.pythonhosted.org/packages/b3/f7/f5dba457bbc6aaf8ebd0131a17eb672835d2ea31f763d1462c191902bc10/orjson-3.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl" }, { "algorithm": "sha256", - "hash": "848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa", - "url": "https://files.pythonhosted.org/packages/cc/98/780c29851b4a1e7942087cc3b7beb0d40a985f96cffae03889c75307300b/orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "0eee4c2c5bfb5c1b47a5db80d2ac7aaa7e938956ae88089f098aff2c0f35d5d8", + "url": "https://files.pythonhosted.org/packages/b4/0a/c91265a075af28fcb118a9a690dccc0f31c52dd7f486f5cc73aa6f9a69b4/orjson-3.10.12-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff", - "url": "https://files.pythonhosted.org/packages/cd/2c/6bb8878e31ffe1ea6ff60e0250ccd326b5cf0d13ffe237f1cdfc525b95f2/orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + "hash": "5535163054d6cbf2796f93e4f0dbc800f61914c0e3c4ed8499cf6ece22b4a3da", + "url": "https://files.pythonhosted.org/packages/c4/12/fb6f27b3fc6daa2287a35ffd7243ead6068e2f14e6cbc90e5c20f8b73848/orjson-3.10.12-cp38-cp38-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa", - "url": "https://files.pythonhosted.org/packages/cf/75/9b081915f083a10832f276d24babee910029ea42368486db9a81741b8dba/orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + "hash": "74d5ca5a255bf20b8def6a2b96b1e18ad37b4a122d59b154c458ee9494377f80", + "url": "https://files.pythonhosted.org/packages/ca/7f/4f49c1a9da03e383198c0fa418cc4262d01d70931742dfc504c2a495ed7b/orjson-3.10.12-cp39-cp39-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6", - "url": "https://files.pythonhosted.org/packages/da/91/f021aa2eed9919f89ae2e4507e851fbbc8c5faef3fa79984549f415c7fa9/orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "36b4aa31e0f6a1aeeb6f8377769ca5d125db000f05c20e54163aef1d3fe8e833", + "url": "https://files.pythonhosted.org/packages/da/21/69f98fef458947f41600a862d94fbdc02cdc4ac7c2b61899a5295b64eb84/orjson-3.10.12-cp38-cp38-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7", - "url": "https://files.pythonhosted.org/packages/dc/40/139fc90e69a8200e8d971c4dd0495ed2c7de6d8d9f70254d3324cb9be026/orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff", + "url": "https://files.pythonhosted.org/packages/e0/04/bb9f72987e7f62fb591d6c880c0caaa16238e4e530cbc3bdc84a7372d75f/orjson-3.10.12.tar.gz" }, { "algorithm": "sha256", - "hash": "e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3", - "url": "https://files.pythonhosted.org/packages/f5/68/710fa568a27213968824d7673d2164b180700e7b05883970d0da6881a2ce/orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl" + "hash": "43509843990439b05f848539d6f6198d4ac86ff01dd024b2f9a795c0daeeab60", + "url": "https://files.pythonhosted.org/packages/f3/9c/ec5a9be77718f92a9971d38c255fd635ab24d501fc5bc7dcb9d6f3c454e0/orjson-3.10.12-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949", - "url": "https://files.pythonhosted.org/packages/f5/79/242ecc469ccb2db9c8bec583c4c5d169c32a4da3713a5cf9d927c3d50df5/orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "91a5a0158648a67ff0004cb0df5df7dcc55bfc9ca154d9c01597a23ad54c8d0c", + "url": "https://files.pythonhosted.org/packages/f5/f6/5ef130a2e28a0c633c82da67224212fa84b17f93d9d768c255f389d66641/orjson-3.10.12-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" } ], "project_name": "orjson", "requires_dists": [], "requires_python": ">=3.8", - "version": "3.10.10" + "version": "3.10.12" }, { "artifacts": [ @@ -2637,19 +2605,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", - "url": "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl" + "hash": "09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", + "url": "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", - "url": "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz" + "hash": "c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", + "url": "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz" } ], "project_name": "packaging", "requires_dists": [], "requires_python": ">=3.8", - "version": "24.1" + "version": "24.2" }, { "artifacts": [ @@ -2750,19 +2718,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2", - "url": "https://files.pythonhosted.org/packages/d4/55/90db48d85f7689ec6f81c0db0622d704306c5284850383c090e6c7195a5c/pip-24.2-py3-none-any.whl" + "hash": "3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", + "url": "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "5b5e490b5e9cb275c879595064adce9ebd31b854e3e803740b72f9ccf34a45b8", - "url": "https://files.pythonhosted.org/packages/4d/87/fb90046e096a03aeab235e139436b3fe804cdd447ed2093b0d70eba3f7f8/pip-24.2.tar.gz" + "hash": "ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", + "url": "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz" } ], "project_name": "pip", "requires_dists": [], "requires_python": ">=3.8", - "version": "24.2" + "version": "24.3.1" }, { "artifacts": [ @@ -3517,13 +3485,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "129a4294f2c4d681d5875240ef87accc6f1d921e8983737fb0b59642b397951e", - "url": "https://files.pythonhosted.org/packages/43/c3/4dc3d1d029e14bf065f1df9e98e3e503e622de34706a06ab6c3731377e85/pyspnego-0.11.1-py3-none-any.whl" + "hash": "74abc1fb51e59360eb5c5c9086e5962174f1072c7a50cf6da0bda9a4bcfdfbd4", + "url": "https://files.pythonhosted.org/packages/57/ea/b3c1438839d8724beff7b31ec42b9d041265dc9ca27ccb54477d442bfbcf/pyspnego-0.11.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "e92ed8b0a62765b9d6abbb86a48cf871228ddb97678598dc01c9c39a626823f6", - "url": "https://files.pythonhosted.org/packages/46/f5/1f938a781742d18475ac43a101ec8a9499e1655da0984e08b59e20012c04/pyspnego-0.11.1.tar.gz" + "hash": "994388d308fb06e4498365ce78d222bf4f3570b6df4ec95738431f61510c971b", + "url": "https://files.pythonhosted.org/packages/6b/f8/53f1fc851dab776a183ffc9f29ebde244fbb467f5237f3ea809519fc4b2e/pyspnego-0.11.2.tar.gz" } ], "project_name": "pyspnego", @@ -3535,7 +3503,7 @@ "sspilib>=0.1.0; sys_platform == \"win32\"" ], "requires_python": ">=3.8", - "version": "0.11.1" + "version": "0.11.2" }, { "artifacts": [ @@ -3718,19 +3686,41 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd", - "url": "https://files.pythonhosted.org/packages/35/a6/145655273568ee78a581e734cf35beb9e33a370b29c5d3c8fee3744de29f/python_json_logger-2.0.7-py3-none-any.whl" + "hash": "cdc17047eb5374bd311e748b42f99d71223f3b0e186f4206cc5d52aefe85b090", + "url": "https://files.pythonhosted.org/packages/4b/72/2f30cf26664fcfa0bd8ec5ee62ec90c03bd485e4a294d92aabc76c5203a5/python_json_logger-3.2.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c", - "url": "https://files.pythonhosted.org/packages/4f/da/95963cebfc578dabd323d7263958dfb68898617912bb09327dd30e9c8d13/python-json-logger-2.0.7.tar.gz" + "hash": "8eb0554ea17cb75b05d2848bc14fb02fbdbd9d6972120781b974380bfa162008", + "url": "https://files.pythonhosted.org/packages/e3/c4/358cd13daa1d912ef795010897a483ab2f0b41c9ea1b35235a8b2f7d15a7/python_json_logger-3.2.1.tar.gz" } ], "project_name": "python-json-logger", - "requires_dists": [], - "requires_python": ">=3.6", - "version": "2.0.7" + "requires_dists": [ + "backports.zoneinfo; python_version < \"3.9\" and extra == \"dev\"", + "black; extra == \"dev\"", + "build; extra == \"dev\"", + "freezegun; extra == \"dev\"", + "mdx_truly_sane_lists; extra == \"dev\"", + "mike; extra == \"dev\"", + "mkdocs-awesome-pages-plugin; extra == \"dev\"", + "mkdocs-gen-files; extra == \"dev\"", + "mkdocs-literate-nav; extra == \"dev\"", + "mkdocs-material>=8.5; extra == \"dev\"", + "mkdocs; extra == \"dev\"", + "mkdocstrings[python]; extra == \"dev\"", + "msgspec-python313-pre; (implementation_name != \"pypy\" and python_version == \"3.13\") and extra == \"dev\"", + "msgspec; (implementation_name != \"pypy\" and python_version < \"3.13\") and extra == \"dev\"", + "mypy; extra == \"dev\"", + "orjson; implementation_name != \"pypy\" and extra == \"dev\"", + "pylint; extra == \"dev\"", + "pytest; extra == \"dev\"", + "typing_extensions; python_version < \"3.10\"", + "tzdata; extra == \"dev\"", + "validate-pyproject[all]; extra == \"dev\"" + ], + "requires_python": ">=3.8", + "version": "3.2.1" }, { "artifacts": [ @@ -3907,13 +3897,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897", - "url": "https://files.pythonhosted.org/packages/12/f5/ffa560ecc4bafbf25f7961c3d6f50d627a90186352e27e7d0ba5b1f6d87d/redis-5.2.0-py3-none-any.whl" + "hash": "ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4", + "url": "https://files.pythonhosted.org/packages/3c/5f/fa26b9b2672cbe30e07d9a5bdf39cf16e3b80b42916757c5f92bca88e4ba/redis-5.2.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0", - "url": "https://files.pythonhosted.org/packages/53/17/2f4a87ffa4cd93714cf52edfa3ea94589e9de65f71e9f99cbcfa84347a53/redis-5.2.0.tar.gz" + "hash": "16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f", + "url": "https://files.pythonhosted.org/packages/47/da/d283a37303a995cd36f8b92db85135153dc4f7a8e4441aa827721b442cfb/redis-5.2.1.tar.gz" } ], "project_name": "redis", @@ -3925,24 +3915,7 @@ "requests>=2.31.0; extra == \"ocsp\"" ], "requires_python": ">=3.8", - "version": "5.2.0" - }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "6da77917788be277b70259edc0bb92fc6f28fe268b765b4ea88206cc3543a3e1", - "url": "https://files.pythonhosted.org/packages/3a/a8/4b73ae7466c2e9b63b3c4d66040d1c0eda1f764812353753702546d8c87f/rednose-1.3.0.tar.gz" - } - ], - "project_name": "rednose", - "requires_dists": [ - "colorama", - "setuptools", - "termstyle>=0.1.7" - ], - "requires_python": null, - "version": "1.3.0" + "version": "5.2.1" }, { "artifacts": [ @@ -4233,13 +4206,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8", - "url": "https://files.pythonhosted.org/packages/31/2d/90165d51ecd38f9a02c6832198c13a4e48652485e2ccf863ebb942c531b6/setuptools-75.2.0-py3-none-any.whl" + "hash": "f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", + "url": "https://files.pythonhosted.org/packages/90/12/282ee9bce8b58130cb762fbc9beabd531549952cac11fc56add11dcb7ea0/setuptools-75.3.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec", - "url": "https://files.pythonhosted.org/packages/07/37/b31be7e4b9f13b59cde9dcaeff112d401d49e0dc5b37ed4a9fc8fb12f409/setuptools-75.2.0.tar.gz" + "hash": "fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686", + "url": "https://files.pythonhosted.org/packages/ed/22/a438e0caa4576f8c383fa4d35f1cc01655a46c75be358960d815bfbb12bd/setuptools-75.3.0.tar.gz" } ], "project_name": "setuptools", @@ -4258,17 +4231,17 @@ "jaraco.functools; extra == \"core\"", "jaraco.packaging>=9.3; extra == \"doc\"", "jaraco.path>=3.2.0; extra == \"test\"", - "jaraco.test; extra == \"test\"", + "jaraco.test>=5.5; extra == \"test\"", "jaraco.text>=3.7; extra == \"core\"", "jaraco.tidelift>=1.4; extra == \"doc\"", "more-itertools; extra == \"core\"", "more-itertools>=8.8; extra == \"core\"", - "mypy==1.11.*; extra == \"type\"", + "mypy==1.12.*; extra == \"type\"", "packaging; extra == \"core\"", "packaging>=23.2; extra == \"test\"", "packaging>=24; extra == \"core\"", "pip>=19.1; extra == \"test\"", - "platformdirs>=2.6.2; extra == \"core\"", + "platformdirs>=4.2.2; extra == \"core\"", "pygments-github-lexers==0.0.5; extra == \"doc\"", "pyproject-hooks!=1.1; extra == \"doc\"", "pyproject-hooks!=1.1; extra == \"test\"", @@ -4300,7 +4273,7 @@ "wheel>=0.44.0; extra == \"test\"" ], "requires_python": ">=3.8", - "version": "75.2.0" + "version": "75.3.0" }, { "artifacts": [ @@ -4434,19 +4407,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", - "url": "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl" + "hash": "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", + "url": "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "url": "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz" + "hash": "ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", + "url": "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz" } ], "project_name": "six", "requires_dists": [], "requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7", - "version": "1.16.0" + "version": "1.17.0" }, { "artifacts": [ @@ -4632,34 +4605,19 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "ef74b83698ea014112040cf32b1a093c1ab3d91c4dd18ecc03ec178fd99c9f9f", - "url": "https://files.pythonhosted.org/packages/65/53/4dfdfe12b499f375cc78caca9cf146c01e752bab7713de4510d35e3da306/termstyle-0.1.11.tar.gz" - } - ], - "project_name": "termstyle", - "requires_dists": [ - "setuptools" - ], - "requires_python": null, - "version": "0.1.11" - }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", - "url": "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl" + "hash": "cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "url": "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", - "url": "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz" + "hash": "cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "url": "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz" } ], "project_name": "tomli", "requires_dists": [], "requires_python": ">=3.8", - "version": "2.0.2" + "version": "2.2.1" }, { "artifacts": [ @@ -4977,13 +4935,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655", - "url": "https://files.pythonhosted.org/packages/c8/15/828ec11907aee2349a9342fa71fba4ba7f3af938162a382dd7da339dea16/virtualenv-20.27.0-py3-none-any.whl" + "hash": "23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0", + "url": "https://files.pythonhosted.org/packages/10/f9/0919cf6f1432a8c4baa62511f8f8da8225432d22e83e3476f5be1a1edc6e/virtualenv-20.28.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2", - "url": "https://files.pythonhosted.org/packages/10/7f/192dd6ab6d91ebea7adf6c030eaf549b1ec0badda9f67a77b633602f66ac/virtualenv-20.27.0.tar.gz" + "hash": "2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa", + "url": "https://files.pythonhosted.org/packages/bf/75/53316a5a8050069228a2f6d11f32046cfa94fbb6cc3f08703f59b873de2e/virtualenv-20.28.0.tar.gz" } ], "project_name": "virtualenv", @@ -5013,7 +4971,7 @@ "towncrier>=23.6; extra == \"docs\"" ], "requires_python": ">=3.8", - "version": "20.27.0" + "version": "20.28.0" }, { "artifacts": [ @@ -5139,13 +5097,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c", - "url": "https://files.pythonhosted.org/packages/4b/84/997bbf7c2bf2dc3f09565c6d0b4959fefe5355c18c4096cfd26d83e0785b/werkzeug-3.0.4-py3-none-any.whl" + "hash": "1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17", + "url": "https://files.pythonhosted.org/packages/6c/69/05837f91dfe42109203ffa3e488214ff86a6d68b2ed6c167da6cdc42349b/werkzeug-3.0.6-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306", - "url": "https://files.pythonhosted.org/packages/0f/e2/6dbcaab07560909ff8f654d3a2e5a60552d937c909455211b1b36d7101dc/werkzeug-3.0.4.tar.gz" + "hash": "a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d", + "url": "https://files.pythonhosted.org/packages/d4/f9/0ba83eaa0df9b9e9d1efeb2ea351d0677c37d41ee5d0f91e98423c7281c9/werkzeug-3.0.6.tar.gz" } ], "project_name": "werkzeug", @@ -5154,19 +5112,19 @@ "watchdog>=2.3; extra == \"watchdog\"" ], "requires_python": ">=3.8", - "version": "3.0.4" + "version": "3.0.6" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f", - "url": "https://files.pythonhosted.org/packages/1b/d1/9babe2ccaecff775992753d8686970b1e2755d21c8a63be73aba7a4e7d77/wheel-0.44.0-py3-none-any.whl" + "hash": "708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", + "url": "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "a29c3f2817e95ab89aa4660681ad547c0e9547f20e75b0562fe7723c9a2a9d49", - "url": "https://files.pythonhosted.org/packages/b7/a0/95e9e962c5fd9da11c1e28aa4c0d8210ab277b1ada951d2aee336b505813/wheel-0.44.0.tar.gz" + "hash": "661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729", + "url": "https://files.pythonhosted.org/packages/8a/98/2d9906746cdc6a6ef809ae6338005b3f21bb568bea3165cfc6a243fdc25c/wheel-0.45.1.tar.gz" } ], "project_name": "wheel", @@ -5175,105 +5133,95 @@ "setuptools>=65; extra == \"test\"" ], "requires_python": ">=3.8", - "version": "0.44.0" + "version": "0.45.1" }, { "artifacts": [ { "algorithm": "sha256", - "hash": "6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1", - "url": "https://files.pythonhosted.org/packages/ff/21/abdedb4cdf6ff41ebf01a74087740a709e2edb146490e4d9beea054b0b7a/wrapt-1.16.0-py3-none-any.whl" + "hash": "d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371", + "url": "https://files.pythonhosted.org/packages/4b/d9/a8ba5e9507a9af1917285d118388c5eb7a81834873f45df213a6fe923774/wrapt-1.17.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6", - "url": "https://files.pythonhosted.org/packages/15/4e/081f59237b620a124b035f1229f55db40841a9339fdb8ef60b4decc44df9/wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl" + "hash": "baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c", + "url": "https://files.pythonhosted.org/packages/08/4e/313f99f271557cc85b6ba086fb9a0d785d0373f237f30d0b4a4d14c7daed/wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8", - "url": "https://files.pythonhosted.org/packages/28/d3/4f079f649c515727c127c987b2ec2e0816b80d95784f2d28d1a57d2a1029/wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801", + "url": "https://files.pythonhosted.org/packages/24/a1/fc03dca9b0432725c2e8cdbf91a349d2194cf03d8523c124faebe581de09/wrapt-1.17.0.tar.gz" }, { "algorithm": "sha256", - "hash": "6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267", - "url": "https://files.pythonhosted.org/packages/34/49/589db6fa2d5d428b71716815bca8b39196fdaeea7c247a719ed2f93b0ab4/wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl" + "hash": "bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad", + "url": "https://files.pythonhosted.org/packages/52/e0/ef637448514295a6b3a01cf1dff417e081e7b8cf1eb712839962459af1f6/wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb", - "url": "https://files.pythonhosted.org/packages/4a/cc/3402bcc897978be00fef608cd9e3e39ec8869c973feeb5e1e277670e5ad2/wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl" + "hash": "7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c", + "url": "https://files.pythonhosted.org/packages/60/01/12dd81522f8c1c953e98e2cbf356ff44fbb06ef0f7523cd622ac06ad7f03/wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e", - "url": "https://files.pythonhosted.org/packages/58/43/d72e625edb5926483c9868214d25b5e7d5858ace6a80c9dfddfbadf4d8f9/wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13", + "url": "https://files.pythonhosted.org/packages/71/da/1c12502da116b379e511c39d95cdc8f886ace2f3478217cde9494d38ca58/wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0", - "url": "https://files.pythonhosted.org/packages/69/21/b2ba809bafc9b6265e359f9c259c6d9a52a16cf6be20c72d95e76da609dd/wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9", + "url": "https://files.pythonhosted.org/packages/7f/44/8b7d417c3aae3a35ccfe361375ee3e452901c91062e5462e1aeef98255e8/wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2", - "url": "https://files.pythonhosted.org/packages/70/cc/b92e1da2cad6a9f8ee481000ece07a35e3b24e041e60ff8b850c079f0ebf/wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl" + "hash": "d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1", + "url": "https://files.pythonhosted.org/packages/89/03/518069f0708573c02cbba3a3e452be3642dc7d984d0a03a47e0850e2fb05/wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202", - "url": "https://files.pythonhosted.org/packages/72/b5/0c9be75f826c8e8d583a4ab312552d63d9f7c0768710146a22ac59bda4a9/wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl" + "hash": "2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f", + "url": "https://files.pythonhosted.org/packages/8a/b0/66f3e53c77257a505aaf7ef6d1b75ff7c8bb6a9da3d96f6aaa5810cd2f33/wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d", - "url": "https://files.pythonhosted.org/packages/95/4c/063a912e20bcef7124e0df97282a8af3ff3e4b603ce84c481d6d7346be0a/wrapt-1.16.0.tar.gz" + "hash": "c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33", + "url": "https://files.pythonhosted.org/packages/94/5c/03c911442b01b50e364572581430e12f82c3f5ea74d302907c1449d7ba36/wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f", - "url": "https://files.pythonhosted.org/packages/96/e8/27ef35cf61e5147c1c3abcb89cfbb8d691b2bb8364803fcc950140bc14d8/wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl" + "hash": "948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f", + "url": "https://files.pythonhosted.org/packages/aa/37/0fbed8e67bd10b6f8835047abb6f42b8870689af45d7ae581946f1685468/wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c", - "url": "https://files.pythonhosted.org/packages/a3/1c/226c2a4932e578a2241dcb383f425995f80224b446f439c2e112eb51c3a6/wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0", + "url": "https://files.pythonhosted.org/packages/af/a9/e65406a9c3a99162055efcb6bf5e0261924381228c0a7608066805da03df/wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a", - "url": "https://files.pythonhosted.org/packages/b1/e7/459a8a4f40f2fa65eb73cb3f339e6d152957932516d18d0e996c7ae2d7ae/wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578", + "url": "https://files.pythonhosted.org/packages/c4/2d/9853fe0009271b2841f839eb0e707c6b4307d169375f26c58812ecf4fd71/wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl" }, { "algorithm": "sha256", - "hash": "edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537", - "url": "https://files.pythonhosted.org/packages/b6/ad/7a0766341081bfd9f18a7049e4d6d45586ae5c5bb0a640f05e2f558e849c/wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl" + "hash": "a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d", + "url": "https://files.pythonhosted.org/packages/e1/62/5b50c324082081337c2b38daf4bae1de66e87eb126c754b0fa153b3525af/wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca", - "url": "https://files.pythonhosted.org/packages/c5/40/3eabe06c8dc54fada7364f34e8caa562efe3bf3f769bf3258de9c785a27f/wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl" + "hash": "ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627", + "url": "https://files.pythonhosted.org/packages/eb/54/f43889a2c787f2b8ac989461c0d2011f0ff69811ebf9b84796cc671aed63/wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664", - "url": "https://files.pythonhosted.org/packages/da/6f/6d0b3c4983f1fc764a422989dabc268ee87d937763246cd48aa92f1eed1e/wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f", - "url": "https://files.pythonhosted.org/packages/ef/c6/56e718e2c58a4078518c14d97e531ef1e9e8a5c1ddafdc0d264a92be1a1a/wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0", - "url": "https://files.pythonhosted.org/packages/fe/9e/d3bc95e75670ba15c5b25ecf07fc49941843e2678d777ca59339348d1c96/wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl" + "hash": "8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce", + "url": "https://files.pythonhosted.org/packages/eb/d2/31bb2c9362d84153d7597a471b22250783bf86be1a01c1acaba3bf7a0e01/wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl" } ], "project_name": "wrapt", "requires_dists": [], - "requires_python": ">=3.6", - "version": "1.16.0" + "requires_python": ">=3.8", + "version": "1.17.0" }, { "artifacts": [ @@ -5587,9 +5535,6 @@ "mock", "mongoengine<0.30.0,>=0.24.0", "networkx", - "nose", - "nose-parallel", - "nose-timer", "orjson", "orquesta", "oslo.config", @@ -5616,7 +5561,6 @@ "pytz", "pywinrm", "redis", - "rednose", "requests", "retrying", "routes", diff --git a/requirements-pants.txt b/requirements-pants.txt index 21e3e48c02..f0f269d6d5 100644 --- a/requirements-pants.txt +++ b/requirements-pants.txt @@ -99,11 +99,3 @@ zake # was in fixed-requirements.txt, but not in requirements-pants.txt # keyczar is used by a python2-only test. #python-keyczar - -########### - -# remove once we switch to pytest -nose -nose-timer -nose-parallel -rednose diff --git a/requirements.txt b/requirements.txt index 4ab082c4bf..01b11746ee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,10 +6,11 @@ # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt RandomWords -amqp==5.2.0 -apscheduler==3.10.4 -argcomplete==3.4.0 -bcrypt==4.2.0 +amqp==5.3.1 +apscheduler==3.11.0 +argcomplete==3.5.2 +backports.zoneinfo[tzdata]; python_version<"3.9" +bcrypt==4.2.1 cffi==1.17.1 chardet==5.2.0 ciso8601 @@ -17,7 +18,7 @@ cryptography==43.0.3 decorator==5.1.1 dnspython editor==1.6.6 -eventlet==0.37.0 +eventlet==0.38.2 flex==6.14.1 gitdb==4.0.11 gitpython==3.1.43 @@ -33,10 +34,7 @@ logshipper@ git+https://github.com/StackStorm/logshipper.git@stackstorm_patched mock==5.1.0 mongoengine==0.29.1 networkx==3.1 -nose -nose-parallel==0.4.0 -nose-timer==1.0.1 -orjson==3.10.10 +orjson==3.10.12 orquesta@ git+https://github.com/StackStorm/orquesta.git@5ba1467614b2ef8b4709b2ca89e68baa671e8975 oslo.config==9.6.0 oslo.utils==7.3.0 @@ -52,20 +50,20 @@ pymongo==4.6.3 pyparsing==3.1.4 pyrabbit pysocks +pytest==7.0.1 python-dateutil==2.9.0.post0 python-json-logger python-statsd==2.1.0 pytz==2024.2 pywinrm==0.5.0 pyyaml==6.0.2 -redis==5.2.0 -rednose +redis==5.2.1 requests==2.32.3 retrying==1.3.4 routes==2.5.1 semver==3.0.2 simplejson -six==1.16.0 +six==1.17.0 sseclient-py==1.8.0 st2-auth-backend-flat-file st2-auth-ldap@ git+https://github.com/StackStorm/st2-auth-ldap.git@master @@ -74,7 +72,6 @@ stevedore==5.3.0 tenacity==9.0.0 tooz==6.3.0 typing-extensions==4.12.2 -unittest2 webob==1.8.9 webtest==3.0.1 zake==0.2.2 diff --git a/scripts/github/setup-environment.sh b/scripts/github/setup-environment.sh index f999771681..c22f3f2e80 100755 --- a/scripts/github/setup-environment.sh +++ b/scripts/github/setup-environment.sh @@ -16,12 +16,6 @@ ENABLE_COVERAGE=$([ "${GITHUB_EVENT_NAME}" != "pull_request" ] && [ "${IS_NIGHTL # shellcheck disable=SC2086 echo "ENABLE_COVERAGE=${ENABLE_COVERAGE}" >> ${GITHUB_ENV} -# We only run tests with "--with-timer" flag on master and not for PRs since it adds 1-2 -# minutes of overhead to each build. -NOSE_TIME=$([ "${GITHUB_EVENT_NAME}" != "pull_request" ] && [ "${IS_NIGHTLY_BUILD}" = "no" ] && echo "yes" || echo "no") -# shellcheck disable=SC2086 -echo "NOSE_TIME=${NOSE_TIME}" >> $GITHUB_ENV - # Setup the path to the st2 repo in the CI build system # shellcheck disable=SC2086 echo "ST2_CI_REPO_PATH=${GITHUB_WORKSPACE}" >> ${GITHUB_ENV} diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index c585334f84..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[nosetests] -logging-level=INFO diff --git a/st2actions/in-requirements.txt b/st2actions/in-requirements.txt index 59ae7de83d..6e9aa3445a 100644 --- a/st2actions/in-requirements.txt +++ b/st2actions/in-requirements.txt @@ -21,3 +21,5 @@ logshipper@ git+https://github.com/StackStorm/logshipper.git@stackstorm_patched virtualenv # needed by requests chardet +# needed by kombu (dh_virtualenv on ubuntu focal is failing to put tzdata in the wheelhouse) +backports.zoneinfo[tzdata]; python_version<"3.9" diff --git a/st2actions/requirements.txt b/st2actions/requirements.txt index 71c1001f97..3a908fa6a8 100644 --- a/st2actions/requirements.txt +++ b/st2actions/requirements.txt @@ -5,9 +5,10 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -apscheduler==3.10.4 +apscheduler==3.11.0 +backports.zoneinfo[tzdata]; python_version<"3.9" chardet==5.2.0 -eventlet==0.37.0 +eventlet==0.38.2 gitpython==3.1.43 jinja2==3.1.4 kombu==5.4.2 @@ -21,4 +22,4 @@ python-dateutil==2.9.0.post0 python-json-logger pyyaml==6.0.2 requests==2.32.3 -six==1.16.0 +six==1.17.0 diff --git a/st2actions/setup.cfg b/st2actions/setup.cfg deleted file mode 100644 index 8503f775ba..0000000000 --- a/st2actions/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match=^st2actions -where=test -nocapture=1 -cover-package=st2actions -cover-erase=1 diff --git a/st2api/in-requirements.txt b/st2api/in-requirements.txt index d3506c27f1..25c9369f60 100644 --- a/st2api/in-requirements.txt +++ b/st2api/in-requirements.txt @@ -11,3 +11,5 @@ pymongo six gunicorn simplejson +# needed by kombu (dh_virtualenv on ubuntu focal is failing to put tzdata in the wheelhouse) +backports.zoneinfo[tzdata]; python_version<"3.9" diff --git a/st2api/requirements.txt b/st2api/requirements.txt index 1d3b21fe6f..034b180756 100644 --- a/st2api/requirements.txt +++ b/st2api/requirements.txt @@ -5,7 +5,8 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -eventlet==0.37.0 +backports.zoneinfo[tzdata]; python_version<"3.9" +eventlet==0.38.2 gunicorn==23.0.0 jsonschema==3.2.0 kombu==5.4.2 @@ -15,4 +16,4 @@ oslo.utils==7.3.0 pymongo==4.6.3 pyparsing==3.1.4 simplejson -six==1.16.0 +six==1.17.0 diff --git a/st2api/tests/integration/test_gunicorn_configs.py b/st2api/tests/integration/test_gunicorn_configs.py index 8362a0e7f9..c7df6d3978 100644 --- a/st2api/tests/integration/test_gunicorn_configs.py +++ b/st2api/tests/integration/test_gunicorn_configs.py @@ -17,10 +17,10 @@ import random from six.moves import http_client -import unittest import requests import eventlet from eventlet.green import subprocess +import pytest import st2tests.config from st2common.models.utils import profiling @@ -33,7 +33,7 @@ class GunicornWSGIEntryPointTestCase(IntegrationTestCase): - @unittest.skipIf(profiling.is_enabled(), "Profiling is enabled") + @pytest.mark.skipif(profiling.is_enabled(), reason="Profiling is enabled") def test_st2api_wsgi_entry_point(self): port = random.randint(10000, 30000) cmd = ( @@ -55,7 +55,7 @@ def test_st2api_wsgi_entry_point(self): finally: kill_process(process) - @unittest.skipIf(profiling.is_enabled(), "Profiling is enabled") + @pytest.mark.skipif(profiling.is_enabled(), reason="Profiling is enabled") def test_st2auth(self): port = random.randint(10000, 30000) cmd = ( diff --git a/st2api/tests/unit/test_validation_utils.py b/st2api/tests/unit/test_validation_utils.py index 579069f4de..e518a45e77 100644 --- a/st2api/tests/unit/test_validation_utils.py +++ b/st2api/tests/unit/test_validation_utils.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest import unittest from oslo_config import cfg @@ -48,8 +49,9 @@ def test_validate_auth_cookie_is_correctly_configured_error(self): invalid_values = ["strictx", "laxx", "nonex", "invalid"] for value in invalid_values: - with self.assertRaisesRegex( - ValueError, r"Valid values are \[strict, lax, none, unset\], but found" + with pytest.raises( + ValueError, + match=r"Valid values are \[strict, lax, none, unset\], but found", ): cfg.CONF.set_override( group="api", name="auth_cookie_same_site", override=value diff --git a/st2auth/requirements.txt b/st2auth/requirements.txt index 18b5601ce3..ab32a14743 100644 --- a/st2auth/requirements.txt +++ b/st2auth/requirements.txt @@ -5,13 +5,13 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -bcrypt==4.2.0 -eventlet==0.37.0 +bcrypt==4.2.1 +eventlet==0.38.2 gunicorn==23.0.0 oslo.config==9.6.0 passlib==1.7.4 pymongo==4.6.3 -six==1.16.0 +six==1.17.0 st2-auth-backend-flat-file st2-auth-ldap@ git+https://github.com/StackStorm/st2-auth-ldap.git@master stevedore==5.3.0 diff --git a/st2auth/setup.cfg b/st2auth/setup.cfg deleted file mode 100644 index 4c3f2f2bb2..0000000000 --- a/st2auth/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match=^st2auth -where=test -nocapture=1 -cover-package=st2auth -cover-erase=1 diff --git a/st2client/requirements.txt b/st2client/requirements.txt index bd7c6950fb..e44d1e93a2 100644 --- a/st2client/requirements.txt +++ b/st2client/requirements.txt @@ -5,7 +5,7 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -argcomplete==3.4.0 +argcomplete==3.5.2 cffi==1.17.1 chardet==5.2.0 cryptography==43.0.3 @@ -13,7 +13,7 @@ editor==1.6.6 importlib-metadata==7.1.0 jsonpath-rw==1.4.0 jsonschema==3.2.0 -orjson==3.10.10 +orjson==3.10.12 prettytable==3.10.2 prompt-toolkit==3.0.48 pyOpenSSL @@ -23,7 +23,7 @@ python-dateutil==2.9.0.post0 pytz==2024.2 pyyaml==6.0.2 requests==2.32.3 -six==1.16.0 +six==1.17.0 sseclient-py==1.8.0 typing-extensions==4.12.2 zipp==3.20.2 diff --git a/st2client/tests/unit/test_config_parser.py b/st2client/tests/unit/test_config_parser.py index 5bdd40a773..e06f2f4b45 100644 --- a/st2client/tests/unit/test_config_parser.py +++ b/st2client/tests/unit/test_config_parser.py @@ -19,6 +19,7 @@ import shutil import mock +import pytest import six import unittest @@ -200,7 +201,7 @@ def test_weird_but_correct_permissions_emit_no_warnings(self): self.assertTrue(os.path.exists(self.TEMP_CONFIG_DIR)) self.assertEqual(os.stat(self.TEMP_CONFIG_DIR).st_mode & 0o7777, 0o2770) - @unittest.skipIf(os.getuid() == 0, reason="Test must be run as non-root user.") + @pytest.mark.skipif(os.getuid() == 0, reason="Test must be run as non-root user.") def test_warn_on_bad_config_permissions(self): # Setup the config directory os.chmod(self.TEMP_CONFIG_DIR, 0o0755) diff --git a/st2client/tests/unit/test_shell.py b/st2client/tests/unit/test_shell.py index 64582fd1cc..f6cd048e0d 100644 --- a/st2client/tests/unit/test_shell.py +++ b/st2client/tests/unit/test_shell.py @@ -27,6 +27,7 @@ import requests import six import mock +import pytest import unittest import st2client @@ -516,7 +517,7 @@ def _write_mock_package_metadata_file(self): return package_metadata_path - @unittest.skipIf(True, "skipping until checks are re-enabled") + @pytest.mark.skipif(True, reason="skipping until checks are re-enabled") @mock.patch.object( requests, "get", mock.MagicMock(return_value=base.FakeResponse("{}", 200, "OK")) ) @@ -617,7 +618,7 @@ def _write_mock_config(self): with open(self._mock_config_path, "w") as fp: fp.write(MOCK_CONFIG) - @unittest.skipIf(os.getuid() == 0, reason="Test must be run as non-root user.") + @pytest.mark.skipif(os.getuid() == 0, reason="Test must be run as non-root user.") def test_get_cached_auth_token_invalid_permissions(self): shell = Shell() client = Client() @@ -681,7 +682,7 @@ def test_get_cached_auth_token_invalid_permissions(self): expected_msg = "Permissions .*? for cached token file .*? are too permissive.*" self.assertRegex(log_message, expected_msg) - @unittest.skipIf(os.getuid() == 0, reason="Test must be run as non-root user.") + @pytest.mark.skipif(os.getuid() == 0, reason="Test must be run as non-root user.") def test_cache_auth_token_invalid_permissions(self): shell = Shell() username = "testu" diff --git a/st2common/bin/st2-run-pack-tests b/st2common/bin/st2-run-pack-tests index e358aa1e63..37658ca629 100755 --- a/st2common/bin/st2-run-pack-tests +++ b/st2common/bin/st2-run-pack-tests @@ -34,17 +34,13 @@ function join { local IFS="$1"; shift; echo "$*"; } # package installation. When using StackStorm package installation, those dependencies are already # available (they are installed by st2tests package). PACK_TEST_PYTHON_DEPENDENCIES_NAMES=( + 'pytest' 'mock' - 'unittest2' - 'nose' - 'nose-timer' 'coverage' ) PACK_TEST_PYTHON_DEPENDENCIES_VERSIONS=( + '>7' '>=4.0.3' - '>=1.1.0,<2.0' - '>=1.3.7' - '>=0.7.0' '>=4.4.1' ) @@ -159,6 +155,7 @@ PACK_TESTS_PATH="${PACK_PATH}/tests/" SENSORS_PATH="${PACK_PATH}/sensors/" ACTIONS_PATH="${PACK_PATH}/actions/" ACTIONS_LIB_PATH="${PACK_PATH}/actions/lib/" +PACK_SHARED_LIB_PATH="${PACK_PATH}/lib/" ETC_PATH="${PACK_PATH}/etc/" # Bail early if no tests are found, this way we don't need to wait for @@ -226,12 +223,12 @@ if [ -n "${ST2_REPO_PATH}" ]; then ST2_REPO_PATH=${ST2_REPO_PATH:-/tmp/st2} ST2_COMPONENTS=$(find ${ST2_REPO_PATH}/* -maxdepth 0 -name "st2*" -type d) ST2_RUNNERS=$(find ${ST2_REPO_PATH}/contrib/runners/* -maxdepth 0 -type d 2> /dev/null) - PACK_PYTHONPATH="$(join ":" ${ST2_COMPONENTS}):$(join ":" ${ST2_RUNNERS}):${SENSORS_PATH}:${ACTIONS_PATH}:${ACTIONS_LIB_PATH}:${ETC_PATH}" + PACK_PYTHONPATH="${PACK_SHARED_LIB_PATH}:$(join ":" ${ST2_COMPONENTS}):$(join ":" ${ST2_RUNNERS}):${SENSORS_PATH}:${ACTIONS_PATH}:${ACTIONS_LIB_PATH}:${ETC_PATH}" else # ST2_REPO_PATH not provided, assume all the st2 component packages are # already in PYTHONPATH ST2_RUNNERS=$(find /opt/stackstorm/runners/* -maxdepth 0 -type d 2> /dev/null) - PACK_PYTHONPATH="$(join ":" ${ST2_COMPONENTS}):$(join ":" ${ST2_RUNNERS}):${SENSORS_PATH}:${ACTIONS_PATH}:${ACTIONS_LIB_PATH}:${ETC_PATH}" + PACK_PYTHONPATH="${PACK_SHARED_LIB_PATH}:$(join ":" ${ST2_COMPONENTS}):$(join ":" ${ST2_RUNNERS}):${SENSORS_PATH}:${ACTIONS_PATH}:${ACTIONS_LIB_PATH}:${ETC_PATH}" fi if [ "${JUST_TESTS}" = false ]; then @@ -306,7 +303,7 @@ if [ -n "${TEST_LOCATION}" ]; then TESTS_PYTHON_PATH+=("${PACK_TESTS_PATH}") fi -TESTS_PYTHON_PATH="$(join ":" ${TESTS_PYTHON_PATH[@]})" +TESTS_PYTHON_PATH="$(join ":" ${TESTS_PYTHON_PATH[@]} | sed -e 's/:+/:/')" export PYTHONPATH="${TESTS_PYTHON_PATH}" @@ -320,47 +317,29 @@ if [ "${VERBOSE}" = true ]; then fi echo "Running tests..." -# Note: We run nosetests with "--exe" option so it also runs test files which are executable +# Note: We run pytest with "--exe" option so it also runs test files which are executable # (pack install command automatically makes all the files, including test files executable) -NOSE_OPTS=(-s -v --exe --rednose --immediate) +PYTEST_OPTS=(-s -v ) # Is test coverage reporting enabled? if [ "${ENABLE_COVERAGE}" = true ]; then - verbose_log "Enabling nosetests coverage" - - # Base options to enable test coverage reporting - # --with-coverage : enables coverage reporting - # --cover-erase : removes old coverage reports before starting - NOSE_OPTS+=(--with-coverage --cover-erase) - - # Now, by default nosetests reports test coverage for every module found - # in the $PYTHONPATH... as you can imagine this is not ideal and may contain - # a LOT of files. - # We can restrict nosetest to only report on python files from certain - # directories by specifying those directories (absolute or relative) using - # the options: --cover-package=/absolte/path OR --cover-package=./relative/path + verbose_log "Enabling pytest coverage" # For each of the sub-directory in the pack, excluding the "tests" directory PACK_SUB_DIRS=$(find $PACK_PATH -mindepth 1 -maxdepth 1 -type d -and -not -name "tests") for pack_sub_dir in $PACK_SUB_DIRS; do - verbose_log "Enabling nosetests coverage for directory: $pack_sub_dir" - NOSE_OPTS+=(--cover-package=$pack_sub_dir) + verbose_log "Enabling pytest coverage for directory: $pack_sub_dir" + PYTEST_OPTS+=(--cov=$pack_sub_dir) done # end for each $PACK_PYTHON_DIR fi # end enable test coverage -# Should we pass in arguments to enable test timing -if [ "${ENABLE_TIMING}" = true ]; then - verbose_log "Enabling nosetests timings" - NOSE_OPTS+=(--with-timer) -fi - -NOSE=(nosetests) -if head -n 1 $(command -v nosetests) | grep -q ' -sE$'; then - # workaround pants+pex default of hermetic scripts so we can run nosetests with PYTHONPATH +PYTEST=(pytest) +if head -n 1 $(command -v pytest) | grep -q ' -sE$'; then + # workaround pants+pex default of hermetic scripts so we can run pytest with PYTHONPATH if [ -f "${STACKSTORM_VIRTUALENV_PYTHON_BINARY}" ]; then - NOSE=(${STACKSTORM_VIRTUALENV_PYTHON_BINARY} -m "nose") + PYTEST=(${STACKSTORM_VIRTUALENV_PYTHON_BINARY} -m "pytest") else - NOSE=(python3 -m "nose") + PYTEST=(python3 -m "pytest") fi fi @@ -370,10 +349,10 @@ pushd ${PACK_PATH} > /dev/null # Execute the tests if [ "${TEST_LOCATION}" ]; then # Run a specific test file, class or method - ${NOSE[@]} ${NOSE_OPTS[@]} ${TEST_LOCATION} + ${PYTEST[@]} ${PYTEST_OPTS[@]} ${TEST_LOCATION} else # Run all tests inside the pack - ${NOSE[@]} ${NOSE_OPTS[@]} ${PACK_TESTS_PATH} + ${PYTEST[@]} ${PYTEST_OPTS[@]} ${PACK_TESTS_PATH} fi TESTS_EXIT_CODE=$? diff --git a/st2common/in-requirements.txt b/st2common/in-requirements.txt index ab5340124c..260ac322d6 100644 --- a/st2common/in-requirements.txt +++ b/st2common/in-requirements.txt @@ -51,3 +51,5 @@ gitdb lockfile # needed by requests chardet +# needed by kombu (dh_virtualenv on ubuntu focal is failing to put tzdata in the wheelhouse) +backports.zoneinfo[tzdata]; python_version<"3.9" diff --git a/st2common/requirements.txt b/st2common/requirements.txt index a4547ffe7a..578bc80f0a 100644 --- a/st2common/requirements.txt +++ b/st2common/requirements.txt @@ -5,15 +5,16 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -amqp==5.2.0 -apscheduler==3.10.4 +amqp==5.3.1 +apscheduler==3.11.0 +backports.zoneinfo[tzdata]; python_version<"3.9" cffi==1.17.1 chardet==5.2.0 ciso8601 cryptography==43.0.3 decorator==5.1.1 dnspython -eventlet==0.37.0 +eventlet==0.38.2 flex==6.14.1 gitdb==4.0.11 gitpython==3.1.43 @@ -25,7 +26,7 @@ kombu==5.4.2 lockfile==0.12.2 mongoengine==0.29.1 networkx==3.1 -orjson==3.10.10 +orjson==3.10.12 orquesta@ git+https://github.com/StackStorm/orquesta.git@5ba1467614b2ef8b4709b2ca89e68baa671e8975 oslo.config==9.6.0 paramiko==3.5.0 @@ -34,12 +35,12 @@ pymongo==4.6.3 python-dateutil==2.9.0.post0 python-statsd==2.1.0 pyyaml==6.0.2 -redis==5.2.0 +redis==5.2.1 requests==2.32.3 retrying==1.3.4 routes==2.5.1 semver==3.0.2 -six==1.16.0 +six==1.17.0 st2-rbac-backend@ git+https://github.com/StackStorm/st2-rbac-backend.git@master tenacity==9.0.0 tooz==6.3.0 diff --git a/st2common/tests/integration/test_logging.py b/st2common/tests/integration/test_logging.py index 0f7cc77228..92069db2da 100644 --- a/st2common/tests/integration/test_logging.py +++ b/st2common/tests/integration/test_logging.py @@ -24,7 +24,7 @@ import os import sys import signal -import unittest +import pytest import eventlet from eventlet.green import subprocess @@ -75,7 +75,9 @@ def test_formatting_with_unicode_data_works_no_stdout_patching_valid_utf8_encodi "DEBUG [-] Test debug message with unicode 1 - \u597d\u597d\u597d", stdout ) - @unittest.skipIf(sys.version_info >= (3, 8, 0), "Skipping test under Python >= 3.8") + @pytest.mark.skipif( + sys.version_info >= (3, 8, 0), reason="Skipping test under Python >= 3.8" + ) def test_formatting_with_unicode_data_works_no_stdout_patching_non_valid_utf8_encoding( self, ): diff --git a/st2common/tests/integration/test_rabbitmq_ssl_listener.py b/st2common/tests/integration/test_rabbitmq_ssl_listener.py index e56bfa65d9..d45b72ee18 100644 --- a/st2common/tests/integration/test_rabbitmq_ssl_listener.py +++ b/st2common/tests/integration/test_rabbitmq_ssl_listener.py @@ -22,6 +22,7 @@ import six import unittest from oslo_config import cfg +import pytest from st2common.transport import utils as transport_utils @@ -37,9 +38,9 @@ # NOTE: We only run those tests on the CI provider because at the moment, local # vagrant dev VM doesn't expose RabbitMQ SSL listener by default -@unittest.skipIf( +@pytest.mark.skipif( not ST2_CI, - 'Skipping tests because ST2_CI environment variable is not set to "true"', + reason='Skipping tests because ST2_CI environment variable is not set to "true"', ) class RabbitMQTLSListenerTestCase(unittest.TestCase): def setUp(self): diff --git a/st2common/tests/unit/test_crypto_utils.py b/st2common/tests/unit/test_crypto_utils.py index 2717b605ec..5d261de63e 100644 --- a/st2common/tests/unit/test_crypto_utils.py +++ b/st2common/tests/unit/test_crypto_utils.py @@ -23,7 +23,7 @@ import json import binascii -import unittest +import pytest from unittest import TestCase from six.moves import range from cryptography.exceptions import InvalidSignature @@ -255,7 +255,7 @@ def test_symmetric_encrypt_decrypt_cryptography(self): self.assertEqual(decrypted, plaintext) - @unittest.skipIf(six.PY3, "keyczar doesn't work under Python 3") + @pytest.mark.skipif(six.PY3, reason="keyczar doesn't work under Python 3") def test_symmetric_encrypt_decrypt_roundtrips_1(self): encrypt_keys = [ AESKey.generate(), diff --git a/st2reactor/in-requirements.txt b/st2reactor/in-requirements.txt index a6624b07e3..e1bccfac12 100644 --- a/st2reactor/in-requirements.txt +++ b/st2reactor/in-requirements.txt @@ -7,3 +7,5 @@ jsonschema kombu oslo.config six +# needed by kombu (dh_virtualenv on ubuntu focal is failing to put tzdata in the wheelhouse) +backports.zoneinfo[tzdata]; python_version<"3.9" diff --git a/st2reactor/requirements.txt b/st2reactor/requirements.txt index 26b94bb5f6..00fa9a14ad 100644 --- a/st2reactor/requirements.txt +++ b/st2reactor/requirements.txt @@ -5,11 +5,12 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -apscheduler==3.10.4 -eventlet==0.37.0 +apscheduler==3.11.0 +backports.zoneinfo[tzdata]; python_version<"3.9" +eventlet==0.38.2 jsonpath-rw==1.4.0 jsonschema==3.2.0 kombu==5.4.2 oslo.config==9.6.0 python-dateutil==2.9.0.post0 -six==1.16.0 +six==1.17.0 diff --git a/st2reactor/setup.cfg b/st2reactor/setup.cfg deleted file mode 100644 index b2177f2ecb..0000000000 --- a/st2reactor/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match=^st2reactor -where=test -nocapture=1 -cover-package=st2reactor -cover-erase=1 diff --git a/st2stream/in-requirements.txt b/st2stream/in-requirements.txt index b6024af935..273a2b1b2f 100644 --- a/st2stream/in-requirements.txt +++ b/st2stream/in-requirements.txt @@ -10,3 +10,5 @@ pyparsing pymongo six gunicorn +# needed by kombu (dh_virtualenv on ubuntu focal is failing to put tzdata in the wheelhouse) +backports.zoneinfo[tzdata]; python_version<"3.9" diff --git a/st2stream/requirements.txt b/st2stream/requirements.txt index b382a77ee3..98baaf705d 100644 --- a/st2stream/requirements.txt +++ b/st2stream/requirements.txt @@ -5,7 +5,8 @@ # If you want to update depdencies for a single component, modify the # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt -eventlet==0.37.0 +backports.zoneinfo[tzdata]; python_version<"3.9" +eventlet==0.38.2 gunicorn==23.0.0 jsonschema==3.2.0 kombu==5.4.2 @@ -14,4 +15,4 @@ oslo.config==9.6.0 oslo.utils==7.3.0 pymongo==4.6.3 pyparsing==3.1.4 -six==1.16.0 +six==1.17.0 diff --git a/st2tests/in-requirements.txt b/st2tests/in-requirements.txt index 71af9feb58..0d723dace1 100644 --- a/st2tests/in-requirements.txt +++ b/st2tests/in-requirements.txt @@ -1,11 +1,7 @@ # Remember to list implicit packages here, otherwise version won't be fixated! mock -unittest2 -nose +pytest psutil webtest -nose-timer -nose-parallel -rednose RandomWords pyrabbit diff --git a/st2tests/integration/orquesta/test_wiring_pause_and_resume.py b/st2tests/integration/orquesta/test_wiring_pause_and_resume.py index b6588088ee..f5353720cd 100644 --- a/st2tests/integration/orquesta/test_wiring_pause_and_resume.py +++ b/st2tests/integration/orquesta/test_wiring_pause_and_resume.py @@ -16,7 +16,7 @@ from __future__ import absolute_import import os -import unittest +import pytest from integration.orquesta import base @@ -25,10 +25,10 @@ # Those tests hang and time out very often so they are disabled for the timing being until we find # the root cause for the race or run that test separately in isolation in retry loop -@unittest.skipIf( +@pytest.mark.skipif( os.environ.get("ST2_CI_RUN_ORQUESTA_PAUSE_RESUME_TESTS", "false").lower() not in ["1", "true"], - "Skipping race prone tests", + reason="Skipping race prone tests", ) class PauseResumeWiringTest( base.TestWorkflowExecution, base.WorkflowControlTestCaseMixin diff --git a/st2tests/requirements.txt b/st2tests/requirements.txt index 1fd708e95d..916188d0c2 100644 --- a/st2tests/requirements.txt +++ b/st2tests/requirements.txt @@ -7,11 +7,7 @@ # update the component requirements.txt RandomWords mock==5.1.0 -nose -nose-parallel==0.4.0 -nose-timer==1.0.1 psutil==6.1.0 pyrabbit -rednose -unittest2 +pytest==7.0.1 webtest==3.0.1 diff --git a/st2tests/setup.cfg b/st2tests/setup.cfg deleted file mode 100644 index 9ebd27b30b..0000000000 --- a/st2tests/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match=^st2tests -where=test -nocapture=1 -cover-package=st2tests -cover-erase=1 diff --git a/test-requirements.txt b/test-requirements.txt index 4392ed49b3..6c785583d6 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -16,18 +16,12 @@ pre-commit==2.1.0 bandit==1.7.10 isort>=4.2.5 mock==5.1.0 -nose>=1.3.7 tabulate # 4.5.0 required for Jinja-3.1.3 support but >5.0 required by rstcheck and lower than 7.2 which drops py3.8 support sphinx>=5.0.0,<7.2.0 sphinx-autobuild # pin alabaster (sphinx dependency) or pip installs one that is not compatible alabaster<0.7.14 -# nosetests enhancements -rednose -nose-timer==1.0.1 -# splitting tests run on a separate CI machines -nose-parallel==0.4.0 # Required by st2client tests pyyaml==6.0.2 # Constrain pygments required by editor to align with st2 core version @@ -48,6 +42,8 @@ pytest-benchmark[histogram]==3.4.1 pytest-icdiff==0.9 pytest-cov==3.0.0 pytest-xdist==2.5.0 +# for Makefile-based pytest runs +pytest-custom_exit_code # zstandard is used for micro benchmarks zstandard==0.23.0 # ujson is used for micro benchmarks