From ff3a36363a7c8fa6735da1ede118edac6c07e088 Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 22 Oct 2026 15:11:34 -0600 Subject: [PATCH 1/5] Drop Python 3.10 support Python 3.10 is EOL. Raise requires-python, the ruff target and the ty python-version to 3.11, update the classifiers (add 3.15), docs and script headers, and re-lock to drop the 3.10-only dependency forks (tomli, exceptiongroup, older numpy). Remove the code that only existed for 3.10: the tomli fallback in the license audit and the sys.version_info TryStar guards in the script instrumentor. Apply the pyupgrade fixes the py311 target enables (timezone.utc -> UTC, asyncio.TimeoutError -> TimeoutError). protocol.py and test_time.py used timezone via `from openc3.api import *` rather than importing it, so they now import UTC explicitly; removing the unused timezone imports from the api modules would otherwise break them. Co-Authored-By: Claude Opus 5.5 --- .github/scripts/check_tool_versions.py | 2 +- CLAUDE.md | 6 +- docs.openc3.com/docs/guides/bridges.md | 2 +- examples/throughput_server/README.md | 61 ++-- .../scripts/run_script.py | 6 +- openc3.code-workspace | 2 + openc3/python/README-DEV.md | 14 +- openc3/python/openc3/api/calendar_api.py | 10 +- openc3/python/openc3/api/limits_api.py | 14 +- .../conversions/unix_time_conversion.py | 4 +- openc3/python/openc3/interfaces/interface.py | 6 +- .../interfaces/protocols/fixed_protocol.py | 4 +- .../protocols/preidentified_protocol.py | 6 +- .../openc3/interfaces/protocols/protocol.py | 10 +- .../interfaces/protocols/template_protocol.py | 6 +- .../interfaces/simulated_target_interface.py | 6 +- openc3/python/openc3/logs/log_writer.py | 14 +- .../python/openc3/logs/packet_log_reader.py | 4 +- .../python/openc3/logs/packet_log_writer.py | 4 +- openc3/python/openc3/logs/stream_log.py | 4 +- .../microservices/decom_microservice.py | 4 +- .../host_interface_microservice.py | 2 +- .../microservices/interface_decom_common.py | 6 +- .../microservices/interface_microservice.py | 8 +- openc3/python/openc3/models/activity_model.py | 12 +- .../python/openc3/models/db_sharded_model.py | 4 +- openc3/python/openc3/models/model.py | 4 +- .../openc3/models/script_status_model.py | 4 +- openc3/python/openc3/packets/commands.py | 4 +- openc3/python/openc3/packets/json_packet.py | 4 +- openc3/python/openc3/script/suite_results.py | 4 +- .../tools/cmd_tlm_server/interface_thread.py | 4 +- openc3/python/openc3/utilities/logger.py | 4 +- openc3/python/openc3/utilities/message_log.py | 4 +- .../python/openc3/utilities/questdb_client.py | 16 +- .../python/openc3/utilities/running_script.py | 20 +- .../openc3/utilities/script_instrumentor.py | 8 +- openc3/python/openc3/utilities/string.py | 4 +- openc3/python/openc3/utilities/time.py | 6 +- openc3/python/pyproject.toml | 12 +- openc3/python/test/api/test_calendar_api.py | 20 +- .../test/api/test_inject_tlm_received_time.py | 6 +- openc3/python/test/api/test_limits_api.py | 8 +- openc3/python/test/api/test_tlm_api.py | 24 +- .../test_packet_time_formatted_conversion.py | 4 +- .../test_packet_time_seconds_conversion.py | 4 +- ...test_received_time_formatted_conversion.py | 4 +- .../test_received_time_seconds_conversion.py | 4 +- .../test_unix_time_formatted_conversion.py | 8 +- .../test_unix_time_seconds_conversion.py | 8 +- .../protocols/test_fixed_protocol.py | 14 +- .../protocols/test_ignore_packet_protocol.py | 20 +- .../protocols/test_preidentified_protocol.py | 6 +- .../test/logs/test_packet_log_reader.py | 22 +- .../microservices/test_decom_microservice.py | 20 +- .../test_interface_microservice.py | 4 +- .../microservices/test_router_microservice.py | 6 +- .../microservices/test_tsdb_microservice.py | 4 +- .../test/models/test_script_status_model.py | 6 +- openc3/python/test/packets/test_packet.py | 14 +- .../test/script/test_messages_batch_size.py | 4 +- openc3/python/test/script/test_metadata.py | 8 +- .../python/test/script/test_suite_results.py | 4 +- .../python/test/script/test_web_socket_api.py | 22 +- .../test/topics/test_telemetry_topic.py | 4 +- openc3/python/test/utilities/test_string.py | 4 +- openc3/python/test/utilities/test_time.py | 10 +- .../python/tools/generate_singleton_stubs.py | 2 +- openc3/python/tools/ty_report.py | 2 +- openc3/python/uv.lock | 275 +----------------- scripts/license_audit/license_audit.py | 12 +- 71 files changed, 302 insertions(+), 570 deletions(-) diff --git a/.github/scripts/check_tool_versions.py b/.github/scripts/check_tool_versions.py index 9d0a8f4989..03a7510b62 100755 --- a/.github/scripts/check_tool_versions.py +++ b/.github/scripts/check_tool_versions.py @@ -1,6 +1,6 @@ #!/usr/bin/env -S uv run --script # /// script -# requires-python = ">=3.10" +# requires-python = ">=3.11" # dependencies = ["requests==2.34.2"] # /// diff --git a/CLAUDE.md b/CLAUDE.md index 45bc18bf8c..1eedb5d0a1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -202,7 +202,7 @@ PWDEBUG=1 pnpm test:parallel --headed # Debug mode - **Ruby 3.4** - Backend APIs and core library - **Rails 7.2** - REST APIs with AnyCable for WebSockets -- **Python 3.10-3.14** - Alternative scripting language +- **Python 3.11-3.15** - Alternative scripting language - **UV** - Python package manager (fast Rust-based replacement for pip/poetry) - **Ruff** - Python linter and formatter (fast Rust-based replacement for flake8/black) - **Vue.js 3 + Vuetify 3** - Frontend UI framework @@ -227,9 +227,9 @@ PWDEBUG=1 pnpm test:parallel --headed # Debug mode - **Linter & Formatter**: Ruff (replaces flake8, black, isort) - **Active Rules**: E, F, I, N, UP, B, W, C4, SIM (pycodestyle, Pyflakes, isort, naming, pyupgrade, bugbear, simplify) - **Line Length**: 120 -- **Target Python**: 3.10 (minimum ruff target for backwards compatibility) +- **Target Python**: 3.11 (minimum ruff target for backwards compatibility) - **Docker Python**: 3.12 (used in Alpine/UBI base images) -- **Supported Versions**: 3.11, 3.12, 3.13 (Docker version ±1) +- **Supported Versions**: 3.11, 3.12, 3.13, 3.14, 3.15 (Docker version ±1) - **Config**: `openc3/python/pyproject.toml` - **Lockfile**: `openc3/python/uv.lock` (replaces poetry.lock) - **Python Version**: `openc3/python/.python-version` (default: 3.12) diff --git a/docs.openc3.com/docs/guides/bridges.md b/docs.openc3.com/docs/guides/bridges.md index 00c2edbb5d..68486fed15 100644 --- a/docs.openc3.com/docs/guides/bridges.md +++ b/docs.openc3.com/docs/guides/bridges.md @@ -26,7 +26,7 @@ protocol like LENGTH. -- Requires a host Python 3.10+ installation +- Requires a host Python 3.11+ installation - Install the OpenC3 package (recommend using a venv) ```bash diff --git a/examples/throughput_server/README.md b/examples/throughput_server/README.md index 8dfeab275c..0ff111cfa3 100644 --- a/examples/throughput_server/README.md +++ b/examples/throughput_server/README.md @@ -30,7 +30,7 @@ COSMOS Container Throughput Server (Python) ## Requirements -- Python 3.10 or higher +- Python 3.11 or higher - No external dependencies (uses only standard library) ## Usage @@ -50,44 +50,44 @@ python throughput_server.py --debug ### Command Line Options -| Option | Default | Description | -|--------|---------|-------------| -| `--inst-port` | 7778 | Port for INST (Ruby) target | -| `--inst2-port` | 7780 | Port for INST2 (Python) target | -| `--debug` | False | Enable debug logging | +| Option | Default | Description | +| -------------- | ------- | ------------------------------ | +| `--inst-port` | 7778 | Port for INST (Ruby) target | +| `--inst2-port` | 7780 | Port for INST2 (Python) target | +| `--debug` | False | Enable debug logging | ## Supported Commands The server responds to the following CCSDS commands: -| Command | PKTID | Description | -|---------|-------|-------------| -| START_STREAM | 200 | Start telemetry streaming at specified rate | -| STOP_STREAM | 201 | Stop telemetry streaming | -| GET_STATS | 202 | Request THROUGHPUT_STATUS telemetry packet | -| RESET_STATS | 203 | Reset all throughput statistics | +| Command | PKTID | Description | +| ------------ | ----- | ------------------------------------------- | +| START_STREAM | 200 | Start telemetry streaming at specified rate | +| STOP_STREAM | 201 | Stop telemetry streaming | +| GET_STATS | 202 | Request THROUGHPUT_STATUS telemetry packet | +| RESET_STATS | 203 | Reset all throughput statistics | ### START_STREAM Payload -| Field | Type | Description | -|-------|------|-------------| -| RATE | 32-bit UINT | Packets per second (1-100000) | +| Field | Type | Description | +| ------------ | ----------- | --------------------------------------- | +| RATE | 32-bit UINT | Packets per second (1-100000) | | PACKET_TYPES | 32-bit UINT | Bitmask of packet types (default: 0x01) | ## Telemetry Packets ### THROUGHPUT_STATUS (APID 100) -| Field | Type | Description | -|-------|------|-------------| -| CMD_RECV_COUNT | 32-bit UINT | Total commands received | -| CMD_RECV_RATE | 32-bit FLOAT | Commands per second | -| TLM_SENT_COUNT | 32-bit UINT | Total telemetry packets sent | -| TLM_SENT_RATE | 32-bit FLOAT | Telemetry packets per second | -| TLM_TARGET_RATE | 32-bit UINT | Configured streaming rate | -| BYTES_RECV | 64-bit UINT | Total bytes received | -| BYTES_SENT | 64-bit UINT | Total bytes sent | -| UPTIME_SEC | 32-bit UINT | Server uptime in seconds | +| Field | Type | Description | +| --------------- | ------------ | ---------------------------- | +| CMD_RECV_COUNT | 32-bit UINT | Total commands received | +| CMD_RECV_RATE | 32-bit FLOAT | Commands per second | +| TLM_SENT_COUNT | 32-bit UINT | Total telemetry packets sent | +| TLM_SENT_RATE | 32-bit FLOAT | Telemetry packets per second | +| TLM_TARGET_RATE | 32-bit UINT | Configured streaming rate | +| BYTES_RECV | 64-bit UINT | Total bytes received | +| BYTES_SENT | 64-bit UINT | Total bytes sent | +| UPTIME_SEC | 32-bit UINT | Server uptime in seconds | ## CCSDS Packet Format @@ -133,16 +133,17 @@ To use the throughput server with COSMOS, install the modified DEMO plugin with ### Plugin Variables -| Variable | Default | Description | -|----------|---------|-------------| -| `use_throughput_server` | false | Enable throughput server mode | +| Variable | Default | Description | +| ------------------------ | -------------------- | ----------------------------- | +| `use_throughput_server` | false | Enable throughput server mode | | `throughput_server_host` | host.docker.internal | Hostname of throughput server | -| `inst_throughput_port` | 7778 | Port for INST connection | -| `inst2_throughput_port` | 7780 | Port for INST2 connection | +| `inst_throughput_port` | 7778 | Port for INST connection | +| `inst2_throughput_port` | 7780 | Port for INST2 connection | ### Running Throughput Tests 1. Start the throughput server: + ```bash python throughput_server.py ``` diff --git a/openc3-cosmos-script-runner-api/scripts/run_script.py b/openc3-cosmos-script-runner-api/scripts/run_script.py index edfd75161e..ae83d4cd4b 100644 --- a/openc3-cosmos-script-runner-api/scripts/run_script.py +++ b/openc3-cosmos-script-runner-api/scripts/run_script.py @@ -16,7 +16,7 @@ import sys import time import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime working_dir = os.getcwd() @@ -38,7 +38,7 @@ def run_script_log(script_id, message, color="BLACK", message_log=True): line_to_write = ( # Can't use isoformat because it appends "+00:00" instead of "Z" - datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%fZ") + " (SCRIPTRUNNER): " + message + datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S.%fZ") + " (SCRIPTRUNNER): " + message ) if message_log: RunningScript.message_log().write(line_to_write + "\n", True) @@ -263,7 +263,7 @@ def run_script_log(script_id, message, color="BLACK", message_log=True): # Ensure script is marked as complete with an end time if not script_status.is_complete(): script_status.state = "completed" - script_status.end_time = datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + script_status.end_time = datetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") script_status.update() running = ScriptStatusModel.all(scope=scope, type="running") diff --git a/openc3.code-workspace b/openc3.code-workspace index 6363e6b48d..a5e9a77013 100644 --- a/openc3.code-workspace +++ b/openc3.code-workspace @@ -80,6 +80,8 @@ "app-store/openc3-cosmos-clam/targets", "cosmos/plugins/openc3-cosmos-demo/openc3-cosmos-demo-5.21.0.pre.beta0.gem/targets", "cosmos-enterprise-plugins/openc3-cosmos-gems-interface-python/targets", + "cosmos-enterprise/openc3-enterprise-gem/spec/install/config/targets", + "cosmos/openc3/test/integration/cmd_tlm/generated/targets", ], }, } diff --git a/openc3/python/README-DEV.md b/openc3/python/README-DEV.md index 1df0216526..f6968b9eca 100644 --- a/openc3/python/README-DEV.md +++ b/openc3/python/README-DEV.md @@ -13,11 +13,13 @@ This project uses modern Python tooling: ### Installing Tools **macOS:** + ```bash brew install uv ruff just ``` **Linux/WSL:** + ```bash # Install UV curl -LsSf https://astral.sh/uv/install.sh | sh @@ -51,6 +53,7 @@ just verify ``` **Note:** UV will automatically: + - Install Python 3.12 (specified in `.python-version`) if not already installed - Create a `.venv` virtual environment if it doesn't exist - Install all project dependencies and the openc3 package @@ -76,6 +79,7 @@ just test ``` **What's different:** + - `poetry.lock` is replaced by `uv.lock` - `poetry install` → `uv sync` - `poetry add` → `just add` or `uv add` @@ -89,6 +93,7 @@ You can now uninstall Poetry if you no longer need it: `brew uninstall poetry` o Run `just` to see all available commands. Here are the most common: ### Code Quality + ```bash just format # Format all code with Ruff just format-changed # Format only changed files (fast!) @@ -100,6 +105,7 @@ just lint-stats # Show linting statistics ``` ### Testing + ```bash just test # Run all tests just test-cov # Run with coverage report @@ -109,6 +115,7 @@ just test-file FILE # Run specific test file ``` ### Pre-commit + ```bash just verify # Format, lint, and test everything just verify-changed # Format and lint only changed files (fast!) @@ -116,6 +123,7 @@ just check # CI-friendly check (no modifications) ``` ### Dependencies + ```bash just add PACKAGE # Add new dependency just add-dev PACKAGE # Add dev dependency @@ -124,6 +132,7 @@ just deps # Show dependency tree ``` ### Building + ```bash just build # Build wheel and source distribution just build-wheel # Build wheel only @@ -133,6 +142,7 @@ just install-editable # Install package in editable mode ``` ### Cleanup + ```bash just clean # Remove build artifacts ``` @@ -151,7 +161,7 @@ openc3/python/ ## Python Version Support -This library supports Python 3.10 through 3.14. The library uses environment markers to install version-specific dependencies (e.g., different numpy versions for different Python versions). +This library supports Python 3.11 through 3.15. The library uses environment markers to install version-specific dependencies (e.g., different numpy versions for different Python versions). ## Code Style @@ -191,6 +201,7 @@ just verify-changed ``` This will: + 1. Format only changed Python files 2. Auto-fix linting issues in changed files 3. Show any remaining issues @@ -204,6 +215,7 @@ just verify ``` This will: + 1. Format all code 2. Auto-fix all linting issues 3. Run all tests diff --git a/openc3/python/openc3/api/calendar_api.py b/openc3/python/openc3/api/calendar_api.py index 5c3648bfd4..fd89d91dae 100644 --- a/openc3/python/openc3/api/calendar_api.py +++ b/openc3/python/openc3/api/calendar_api.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import re -from datetime import date, datetime, timedelta, timezone +from datetime import UTC, date, datetime, timedelta from openc3.environment import OPENC3_SCOPE from openc3.models.activity_model import ActivityModel @@ -171,7 +171,7 @@ def get_timeline_activities(name, start=None, stop=None, limit=None, scope=OPENC When limit is None, defaults to one event per minute over the window. Returns a list of matching activities. """ - now = datetime.now(timezone.utc) + now = datetime.now(UTC) start_score = int((now - timedelta(days=7)).timestamp()) if start is None else _cal_to_epoch(start) stop_score = int((now + timedelta(days=7)).timestamp()) if stop is None else _cal_to_epoch(stop) if limit is None: @@ -222,15 +222,15 @@ def _cal_to_epoch(value): return int(value) if isinstance(value, datetime): if value.tzinfo is None: - value = value.replace(tzinfo=timezone.utc) + value = value.replace(tzinfo=UTC) return int(value.timestamp()) # datetime is a subclass of date, so check date last if isinstance(value, date): - return int(datetime(value.year, value.month, value.day, tzinfo=timezone.utc).timestamp()) + return int(datetime(value.year, value.month, value.day, tzinfo=UTC).timestamp()) s = str(value) if _EPOCH_INT_RE.match(s): return int(s) parsed = datetime.fromisoformat(s.replace("Z", "+00:00")) if parsed.tzinfo is None: - parsed = parsed.replace(tzinfo=timezone.utc) + parsed = parsed.replace(tzinfo=UTC) return int(parsed.timestamp()) diff --git a/openc3/python/openc3/api/limits_api.py b/openc3/python/openc3/api/limits_api.py index 47a56ed4f7..8261a1fe03 100644 --- a/openc3/python/openc3/api/limits_api.py +++ b/openc3/python/openc3/api/limits_api.py @@ -9,7 +9,7 @@ # This file may also be used under the terms of a commercial license # if purchased from OpenC3, Inc. -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.api import WHITELIST from openc3.api.tlm_api import _tlm_process_args @@ -158,7 +158,7 @@ def enable_limits(*args, scope=OPENC3_SCOPE): "packet_name": packet_name, "item_name": item_name, "enabled": True, - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, } LimitsEventTopic.write(event, scope=scope) @@ -202,7 +202,7 @@ def disable_limits(*args, scope=OPENC3_SCOPE): "packet_name": packet_name, "item_name": item_name, "enabled": False, - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, } LimitsEventTopic.write(event, scope=scope) @@ -316,7 +316,7 @@ def set_limits( "limits_set": limits_set, "persistence": persistence, "enabled": enabled, - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, } LimitsEventTopic.write(event, scope=scope) @@ -381,7 +381,7 @@ def set_state_color(target_name, packet_name, item_name, state_name, color, scop "item_name": item_name, "state_name": state_name, "color": color, - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, } LimitsEventTopic.write(event, scope=scope) @@ -430,7 +430,7 @@ def set_limits_set(limits_set, scope=OPENC3_SCOPE): { "type": "LIMITS_SET", "set": str(limits_set), - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, }, scope=scope, @@ -520,7 +520,7 @@ def _limits_group(group_name, action, scope): "packet_name": packet_name, "item_name": item_name, "enabled": enabled, - "time_nsec": to_nsec_from_epoch(datetime.now(timezone.utc)), + "time_nsec": to_nsec_from_epoch(datetime.now(UTC)), "message": message, } LimitsEventTopic.write(event, scope=scope) diff --git a/openc3/python/openc3/conversions/unix_time_conversion.py b/openc3/python/openc3/conversions/unix_time_conversion.py index 0d86467a9b..f2dde0c5a6 100644 --- a/openc3/python/openc3/conversions/unix_time_conversion.py +++ b/openc3/python/openc3/conversions/unix_time_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.conversions.conversion import Conversion @@ -45,7 +45,7 @@ def call(self, value, packet, buffer): time = packet.read(self.seconds_item_name, self.seconds_type, buffer) if self.microseconds_item_name: time += packet.read(self.microseconds_item_name, self.microseconds_type, buffer) / 1000000.0 - return datetime.fromtimestamp(time, tz=timezone.utc) + return datetime.fromtimestamp(time, tz=UTC) # @return [String] The name of the class followed by the time conversion def __str__(self): diff --git a/openc3/python/openc3/interfaces/interface.py b/openc3/python/openc3/interfaces/interface.py index d75e75d5b4..e6f4700536 100644 --- a/openc3/python/openc3/interfaces/interface.py +++ b/openc3/python/openc3/interfaces/interface.py @@ -14,7 +14,7 @@ import time import traceback from contextlib import contextmanager -from datetime import datetime, timezone +from datetime import UTC, datetime import schedule @@ -427,7 +427,7 @@ def convert_packet_to_data(self, packet): # self.return [String] Raw packet data def read_interface_base(self, data, extra=None): if self.save_raw_data: - self.read_raw_data_time = datetime.now(timezone.utc) + self.read_raw_data_time = datetime.now(UTC) self.read_raw_data = data self.bytes_read += len(data) if self.stream_log_pair: @@ -441,7 +441,7 @@ def read_interface_base(self, data, extra=None): # self.return [String] The exact data written def write_interface_base(self, data, extra=None): if self.save_raw_data: - self.written_raw_data_time = datetime.now(timezone.utc) + self.written_raw_data_time = datetime.now(UTC) self.written_raw_data = data self.bytes_written += len(data) if self.stream_log_pair: diff --git a/openc3/python/openc3/interfaces/protocols/fixed_protocol.py b/openc3/python/openc3/interfaces/protocols/fixed_protocol.py index b2cd2bf715..4441a333d2 100644 --- a/openc3/python/openc3/interfaces/protocols/fixed_protocol.py +++ b/openc3/python/openc3/interfaces/protocols/fixed_protocol.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.config.config_parser import ConfigParser from openc3.interfaces.protocols.burst_protocol import BurstProtocol @@ -125,7 +125,7 @@ def identify_and_finish_packet(self): # Set some variables so we can update the packet in # read_packet - self.received_time = datetime.now(timezone.utc) + self.received_time = datetime.now(UTC) self.target_name = identified_packet.target_name self.packet_name = identified_packet.packet_name diff --git a/openc3/python/openc3/interfaces/protocols/preidentified_protocol.py b/openc3/python/openc3/interfaces/protocols/preidentified_protocol.py index b8e89fc894..6267e438ed 100644 --- a/openc3/python/openc3/interfaces/protocols/preidentified_protocol.py +++ b/openc3/python/openc3/interfaces/protocols/preidentified_protocol.py @@ -12,7 +12,7 @@ import json import math import struct -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.config.config_parser import ConfigParser from openc3.interfaces.protocols.burst_protocol import BurstProtocol @@ -52,7 +52,7 @@ def read_packet(self, packet): def write_packet(self, packet): received_time = packet.received_time if not received_time: - received_time = datetime.now(timezone.utc) + received_time = datetime.now(UTC) tv_usec, tv_sec = math.modf(received_time.timestamp()) self.write_time_seconds = struct.pack(">I", int(tv_sec)) # UINT32 self.write_time_microseconds = struct.pack(">I", int(tv_usec * 1_000_000)) # UINT32 @@ -176,7 +176,7 @@ def reduce_to_single_packet(self): time_seconds = struct.unpack(">I", self.data[0:4])[0] # UINT32 time_microseconds = struct.unpack(">I", self.data[4:8])[0] # UINT32 - self.read_received_time = datetime.fromtimestamp(time_seconds + time_microseconds / 1_000_000, timezone.utc) + self.read_received_time = datetime.fromtimestamp(time_seconds + time_microseconds / 1_000_000, UTC) self.data = self.data[8:] self.reduction_state = "TIME_REMOVED" diff --git a/openc3/python/openc3/interfaces/protocols/protocol.py b/openc3/python/openc3/interfaces/protocols/protocol.py index 3dae4d04e3..81147da693 100644 --- a/openc3/python/openc3/interfaces/protocols/protocol.py +++ b/openc3/python/openc3/interfaces/protocols/protocol.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. -from datetime import datetime +from datetime import UTC, datetime from openc3.api import * from openc3.config.config_parser import ConfigParser @@ -50,7 +50,7 @@ def disconnect_reset(self): # Called to provide insight into the protocol read_data for the input data def read_protocol_input_base(self, data, _extra=None): if self.interface is not None and self.interface.save_raw_data: - self.read_data_input_time = datetime.now(timezone.utc) + self.read_data_input_time = datetime.now(UTC) self.read_data_input = data # Todo in future enhancement with packet logger # if self.interface.stream_log_pair is not None: @@ -59,7 +59,7 @@ def read_protocol_input_base(self, data, _extra=None): # Called to provide insight into the protocol read_data for the output data def read_protocol_output_base(self, data, _extra=None): if self.interface is not None and self.interface.save_raw_data: - self.read_data_output_time = datetime.now(timezone.utc) + self.read_data_output_time = datetime.now(UTC) self.read_data_output = data # Todo in future enhancement with packet logger # if self.interface.stream_log_pair is not None: @@ -68,7 +68,7 @@ def read_protocol_output_base(self, data, _extra=None): # Called to provide insight into the protocol write_data for the input data def write_protocol_input_base(self, data, _extra=None): if self.interface is not None and self.interface.save_raw_data: - self.write_data_input_time = datetime.now(timezone.utc) + self.write_data_input_time = datetime.now(UTC) self.write_data_input = data # Todo in future enhancement with packet logger # if self.interface.stream_log_pair is not None: @@ -77,7 +77,7 @@ def write_protocol_input_base(self, data, _extra=None): # Called to provide insight into the protocol write_data for the output data def write_protocol_output_base(self, data, _extra=None): if self.interface is not None and self.interface.save_raw_data: - self.write_data_output_time = datetime.now(timezone.utc) + self.write_data_output_time = datetime.now(UTC) self.write_data_output = data # Todo in future enhancement with packet logger # if self.interface.stream_log_pair is not None: diff --git a/openc3/python/openc3/interfaces/protocols/template_protocol.py b/openc3/python/openc3/interfaces/protocols/template_protocol.py index a164bfde0b..b74d5b8446 100644 --- a/openc3/python/openc3/interfaces/protocols/template_protocol.py +++ b/openc3/python/openc3/interfaces/protocols/template_protocol.py @@ -12,7 +12,7 @@ import re import time import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime from queue import Empty, SimpleQueue from openc3.config.config_parser import ConfigParser @@ -282,7 +282,7 @@ def write_details(self): result["response_timeout"] = self.response_timeout result["response_polling_period"] = self.response_polling_period if self.connect_complete_time: - result["connect_complete_time"] = datetime.fromtimestamp(self.connect_complete_time, timezone.utc).strftime( + result["connect_complete_time"] = datetime.fromtimestamp(self.connect_complete_time, UTC).strftime( self.DATETIME_FORMAT ) else: @@ -301,7 +301,7 @@ def read_details(self): result["response_timeout"] = self.response_timeout result["response_polling_period"] = self.response_polling_period if self.connect_complete_time: - result["connect_complete_time"] = datetime.fromtimestamp(self.connect_complete_time, timezone.utc).strftime( + result["connect_complete_time"] = datetime.fromtimestamp(self.connect_complete_time, UTC).strftime( self.DATETIME_FORMAT ) else: diff --git a/openc3/python/openc3/interfaces/simulated_target_interface.py b/openc3/python/openc3/interfaces/simulated_target_interface.py index f805da7616..80cee6c119 100644 --- a/openc3/python/openc3/interfaces/simulated_target_interface.py +++ b/openc3/python/openc3/interfaces/simulated_target_interface.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import time -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.interfaces.interface import Interface from openc3.top_level import get_class_from_module @@ -124,7 +124,7 @@ def write(self, packet): # Update count of commands sent through this interface self.write_count += 1 self.bytes_written += len(packet.buffer) - self.written_raw_data_time = datetime.now(timezone.utc) + self.written_raw_data_time = datetime.now(UTC) self.written_raw_data = packet.buffer # Have simulated target handle the packet @@ -147,6 +147,6 @@ def first_pending_packet(self): self.read_count += 1 packet = self.pending_packets.pop(0).clone() self.bytes_read += len(packet.buffer) - self.read_raw_data_time = datetime.now(timezone.utc) + self.read_raw_data_time = datetime.now(UTC) self.read_raw_data = packet.buffer return packet diff --git a/openc3/python/openc3/logs/log_writer.py b/openc3/python/openc3/logs/log_writer.py index 55385ffa88..b152cce866 100644 --- a/openc3/python/openc3/logs/log_writer.py +++ b/openc3/python/openc3/logs/log_writer.py @@ -13,7 +13,7 @@ import tempfile import threading import traceback -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from openc3.config.config_parser import ConfigParser from openc3.top_level import kill_thread @@ -90,7 +90,7 @@ def __init__( self.label = None self.file_size = 0 self.filename = None - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.first_time = None self.last_time = None self.cancel_threads = False @@ -172,13 +172,13 @@ def create_unique_filename(self, ext=".log"): def cycle_thread_body(self): LogWriter.cycle_sleeper = Sleeper() while True: - start_time = datetime.now(timezone.utc) + start_time = datetime.now(UTC) with LogWriter.mutex: for instance in LogWriter.instances: # The check against start_time needs to be mutex protected to prevent a packet coming in between the check # and closing the file with instance.mutex: - utc_now = datetime.now(timezone.utc) + utc_now = datetime.now(UTC) if instance.logging_enabled and instance.filename: # Logging and file opened # Cycle based on total time logging if ( @@ -227,7 +227,7 @@ def cycle_thread_body(self): instance.cleanup_times = [x for x in instance.cleanup_times if x is not None] # Only check whether to cycle at a set interval - run_time = (datetime.now(timezone.utc) - start_time).total_seconds() + run_time = (datetime.now(UTC) - start_time).total_seconds() sleep_time = LogWriter.CYCLE_TIME_INTERVAL - run_time if sleep_time < 0: sleep_time = 0 @@ -247,7 +247,7 @@ def start_new_file(self): self.file = open(self.filename, "bx") # noqa: SIM115 self.file_size = 0 - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.out_of_order = False self.first_time = None self.last_time = None @@ -315,7 +315,7 @@ def close_file(self, take_mutex=True): self.cleanup_offsets.append({}) for redis_topic, last_offset in self.last_offsets: self.cleanup_offsets[-1][redis_topic] = last_offset - self.cleanup_times.append(datetime.now(timezone.utc) + timedelta(seconds=LogWriter.CLEANUP_DELAY)) + self.cleanup_times.append(datetime.now(UTC) + timedelta(seconds=LogWriter.CLEANUP_DELAY)) self.last_offsets.clear() self.file = None self.file_size = 0 diff --git a/openc3/python/openc3/logs/packet_log_reader.py b/openc3/python/openc3/logs/packet_log_reader.py index a37a6935c7..df118f3926 100644 --- a/openc3/python/openc3/logs/packet_log_reader.py +++ b/openc3/python/openc3/logs/packet_log_reader.py @@ -19,7 +19,7 @@ import json import struct from collections.abc import Iterator -from datetime import datetime, timezone +from datetime import UTC, datetime import cbor2 @@ -519,4 +519,4 @@ def _identify_and_define_packet_data( def _nsec_to_datetime(nsec: int) -> datetime: """Convert nanoseconds since epoch to datetime.""" seconds = nsec / 1_000_000_000 - return datetime.fromtimestamp(seconds, tz=timezone.utc) + return datetime.fromtimestamp(seconds, tz=UTC) diff --git a/openc3/python/openc3/logs/packet_log_writer.py b/openc3/python/openc3/logs/packet_log_writer.py index 3d5b44e5fa..1b01e9992f 100644 --- a/openc3/python/openc3/logs/packet_log_writer.py +++ b/openc3/python/openc3/logs/packet_log_writer.py @@ -19,7 +19,7 @@ import json import os import struct -from datetime import datetime, timezone +from datetime import UTC, datetime import cbor2 @@ -118,7 +118,7 @@ def start_new_file(self): self.close_file() # Generate filename - timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S%f")[:20] + timestamp = datetime.now(UTC).strftime("%Y%m%d%H%M%S%f")[:20] self._filename = os.path.join(self.log_directory, f"{timestamp}__{self.label}.bin") self._file = open(self._filename, "wb") # noqa: SIM115 diff --git a/openc3/python/openc3/logs/stream_log.py b/openc3/python/openc3/logs/stream_log.py index a7a71a90ce..25a91f5857 100644 --- a/openc3/python/openc3/logs/stream_log.py +++ b/openc3/python/openc3/logs/stream_log.py @@ -11,7 +11,7 @@ import copy import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.environment import OPENC3_SCOPE from openc3.utilities.logger import Logger @@ -95,7 +95,7 @@ def write(self, data): try: with self.mutex: - time_nsec_since_epoch = to_nsec_from_epoch(datetime.now(timezone.utc)) + time_nsec_since_epoch = to_nsec_from_epoch(datetime.now(UTC)) self.prepare_write(time_nsec_since_epoch, len(data)) if self.file: self.write_entry(time_nsec_since_epoch, data) diff --git a/openc3/python/openc3/microservices/decom_microservice.py b/openc3/python/openc3/microservices/decom_microservice.py index 297854bec5..1a0a851592 100644 --- a/openc3/python/openc3/microservices/decom_microservice.py +++ b/openc3/python/openc3/microservices/decom_microservice.py @@ -16,7 +16,7 @@ import threading import time import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.config.config_parser import ConfigParser from openc3.microservices.interface_decom_common import ( @@ -313,7 +313,7 @@ def limits_change_callback(self, packet, item, old_limits_state, value, log_chan if packet.packet_time is not None: packet_time = packet.packet_time else: - packet_time = datetime.now(timezone.utc) + packet_time = datetime.now(UTC) if value is not None: message = f"{packet.target_name} {packet.packet_name} {item.name} = {value} is {item.limits.state}" if item.limits.values: diff --git a/openc3/python/openc3/microservices/host_interface_microservice.py b/openc3/python/openc3/microservices/host_interface_microservice.py index 2a7008d309..f2e975d093 100644 --- a/openc3/python/openc3/microservices/host_interface_microservice.py +++ b/openc3/python/openc3/microservices/host_interface_microservice.py @@ -528,7 +528,7 @@ async def _run_device_operation(self, operation, name): loop.run_in_executor(None, operation), timeout=DEVICE_OPERATION_TIMEOUT, ) - except asyncio.TimeoutError as error: + except TimeoutError as error: raise TimeoutError( f"{self.name}: device {name} timed out after {DEVICE_OPERATION_TIMEOUT:g} seconds" ) from error diff --git a/openc3/python/openc3/microservices/interface_decom_common.py b/openc3/python/openc3/microservices/interface_decom_common.py index a51451d559..99d9e59f1a 100644 --- a/openc3/python/openc3/microservices/interface_decom_common.py +++ b/openc3/python/openc3/microservices/interface_decom_common.py @@ -13,7 +13,7 @@ # See https://github.com/OpenC3/cosmos/pull/1963 import json -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.models.target_model import TargetModel from openc3.system.system import System @@ -37,9 +37,7 @@ def handle_inject_tlm(inject_tlm_json, scope): stored = inject_tlm_hash.get("stored", False) packet.stored = str(stored).lower() == "true" received_time = inject_tlm_hash.get("received_time") - packet.received_time = ( - from_nsec_from_epoch(received_time) if received_time is not None else datetime.now(timezone.utc) - ) + packet.received_time = from_nsec_from_epoch(received_time) if received_time is not None else datetime.now(UTC) packet.received_count = TargetModel.increment_telemetry_count( packet.target_name, packet.packet_name, 1, scope=scope ) diff --git a/openc3/python/openc3/microservices/interface_microservice.py b/openc3/python/openc3/microservices/interface_microservice.py index b0588e03f7..16a6ff81d8 100644 --- a/openc3/python/openc3/microservices/interface_microservice.py +++ b/openc3/python/openc3/microservices/interface_microservice.py @@ -21,7 +21,7 @@ import time import traceback import uuid -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.config.config_parser import ConfigParser from openc3.interfaces.interface import WriteRejectError @@ -171,7 +171,7 @@ def process_cmd(self, topic, msg_id, msg_hash, _redis): ) command = command.clone() command.buffer = msg_hash[b"raw"] - command.received_time = datetime.now(timezone.utc) + command.received_time = datetime.now(UTC) CommandTopic.write_packet(command, scope=self.scope) self.logger.info( f"write_raw sent {len(msg_hash[b'raw'])} bytes to {self.interface.name}", @@ -324,7 +324,7 @@ def process_cmd(self, topic, msg_id, msg_hash, _redis): command.target_name, command.packet_name, 1, scope=self.scope ) command.received_count = orig_command.received_count - command.received_time = datetime.now(timezone.utc) + command.received_time = datetime.now(UTC) except ValueError as e: # Command parameter out of range is a user error, not a bug, # so only log the message and not the full stack trace @@ -867,7 +867,7 @@ def handle_packet(self, packet): if not self.cancel_thread: InterfaceStatusModel.set(self.interface.as_json(), queued=True, scope=self.scope) if packet.received_time is None: - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) if packet.stored: # Stored telemetry does not update the current value table diff --git a/openc3/python/openc3/models/activity_model.py b/openc3/python/openc3/models/activity_model.py index 8c9457afce..06c7b4f784 100644 --- a/openc3/python/openc3/models/activity_model.py +++ b/openc3/python/openc3/models/activity_model.py @@ -14,7 +14,7 @@ import json import time import uuid as uuid_module -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.models.model import Model from openc3.topics.timeline_topic import TimelineTopic @@ -235,8 +235,8 @@ def validate_time(self, start, stop, ignore_score=None): # - A task MUST have a data object/dict. def validate_input(self, start, stop, kind, data): try: - datetime.fromtimestamp(int(start), tz=timezone.utc) - datetime.fromtimestamp(int(stop), tz=timezone.utc) + datetime.fromtimestamp(int(start), tz=UTC) + datetime.fromtimestamp(int(stop), tz=UTC) except (TypeError, ValueError, OverflowError, OSError) as e: raise ActivityInputError(f"start and stop must be seconds: {start}, {stop}") from e now_f = time.time() @@ -320,7 +320,7 @@ def create(self, update=False, force=False, queued=False, overlap=True, username last_stop = None # Update updated_at and add an event assuming it all completes ok - self.updated_at = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at = to_nsec_from_epoch(datetime.now(UTC)) self.add_event(status="created", username=username) start_time = self.start @@ -352,7 +352,7 @@ def create(self, update=False, force=False, queued=False, overlap=True, username collision = self.validate_time(self.start, self.stop) if collision is not None: raise ActivityOverlapError(f"activity overlaps existing at {collision}") - self.updated_at = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at = to_nsec_from_epoch(datetime.now(UTC)) self.add_event(status="created", username=username) Store.zadd(self._zset_key, {json.dumps(self.as_json()): self.start}) self.notify(kind="created") @@ -390,7 +390,7 @@ def update( self.diff_field(changes, f"data.{key}", old_data.get(key), new_data.get(key)) self.set_input(start=start, stop=stop, kind=kind, data=data, events=self.events) - self.updated_at = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at = to_nsec_from_epoch(datetime.now(UTC)) self.add_event(status="updated", username=username, changes=changes if changes else None) json_values = Store.zrangebyscore(self._zset_key, old_start, old_start) diff --git a/openc3/python/openc3/models/db_sharded_model.py b/openc3/python/openc3/models/db_sharded_model.py index 5ca970684c..17b9b4250f 100644 --- a/openc3/python/openc3/models/db_sharded_model.py +++ b/openc3/python/openc3/models/db_sharded_model.py @@ -15,7 +15,7 @@ # _collect_db_shards(scope) -> set[int] import json -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.utilities.time import to_nsec_from_epoch @@ -93,7 +93,7 @@ def _db_sharded_create(self, db_shard, update=False, force=False, queued=False, raise RuntimeError(f"{self.primary_key}:{self.name} already exists at create") if not existing and update: raise RuntimeError(f"{self.primary_key}:{self.name} doesn't exist at update") - self.updated_at: int = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at: int = to_nsec_from_epoch(datetime.now(UTC)) if queued: store = self.__class__.store_queued().instance(db_shard=db_shard) diff --git a/openc3/python/openc3/models/model.py b/openc3/python/openc3/models/model.py index d232fec02e..f34a2aebf4 100644 --- a/openc3/python/openc3/models/model.py +++ b/openc3/python/openc3/models/model.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import json -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.utilities.store import EphemeralStore, Store from openc3.utilities.store_queued import EphemeralStoreQueued, StoreQueued @@ -116,7 +116,7 @@ def create(self, update=False, force=False, queued=False): raise RuntimeError(f"{self.primary_key}:{self.name} already exists at create") if not existing and update: raise RuntimeError(f"{self.primary_key}:{self.name} doesn't exist at update") - self.updated_at = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at = to_nsec_from_epoch(datetime.now(UTC)) write_store = self.store_queued() if queued else self.store() write_store.hset(self.primary_key, self.name, json.dumps(self.as_json())) diff --git a/openc3/python/openc3/models/script_status_model.py b/openc3/python/openc3/models/script_status_model.py index ce25100357..a9331c9ef9 100644 --- a/openc3/python/openc3/models/script_status_model.py +++ b/openc3/python/openc3/models/script_status_model.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import json -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.models.model import Model from openc3.utilities.time import to_nsec_from_epoch @@ -176,7 +176,7 @@ def state(self, new_state): # Update the Redis hash at primary_key and set the field "name" # to the JSON generated via calling as_json def create(self, update=False, force=False, queued=False): - self.updated_at: int = to_nsec_from_epoch(datetime.now(timezone.utc)) + self.updated_at: int = to_nsec_from_epoch(datetime.now(UTC)) if queued: write_store = self.store_queued() diff --git a/openc3/python/openc3/packets/commands.py b/openc3/python/openc3/packets/commands.py index 01eb06d2b0..de98a57d75 100644 --- a/openc3/python/openc3/packets/commands.py +++ b/openc3/python/openc3/packets/commands.py @@ -12,7 +12,7 @@ # A portion of this file was funded by Blue Origin Enterprises, L.P. # See https://github.com/OpenC3/cosmos/pull/1953 and https://github.com/OpenC3/cosmos/pull/1963 -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.utilities.cmd_log import _build_cmd_output_string @@ -202,7 +202,7 @@ def build_cmd( command.buffer = bytearray(b"\x00" * command.defined_length) # Set time, parameters, and restore defaults - command.received_time = datetime.now(timezone.utc) + command.received_time = datetime.now(UTC) command.stored = False command.extra = None command.given_values = params diff --git a/openc3/python/openc3/packets/json_packet.py b/openc3/python/openc3/packets/json_packet.py index 2d5679a9de..a1e30c061c 100644 --- a/openc3/python/openc3/packets/json_packet.py +++ b/openc3/python/openc3/packets/json_packet.py @@ -18,7 +18,7 @@ """ import json -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import Any @@ -97,7 +97,7 @@ def __init__( def _nsec_to_datetime(nsec: int) -> datetime: """Convert nanoseconds since epoch to datetime.""" seconds = nsec / 1_000_000_000 - return datetime.fromtimestamp(seconds, tz=timezone.utc) + return datetime.fromtimestamp(seconds, tz=UTC) def read(self, name: str, value_type: str = "CONVERTED", reduced_type: str | None = None) -> Any: """ diff --git a/openc3/python/openc3/script/suite_results.py b/openc3/python/openc3/script/suite_results.py index ff750be770..c2b225654e 100644 --- a/openc3/python/openc3/script/suite_results.py +++ b/openc3/python/openc3/script/suite_results.py @@ -12,7 +12,7 @@ import re import time import traceback -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.utilities.extract import remove_quotes @@ -133,7 +133,7 @@ def footer(self): def write(self, string): # Can't use isoformat because it appends "+00:00" instead of "Z" - self._report.append(datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%fZ") + ": " + string) + self._report.append(datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S.%fZ") + ": " + string) # Define a few aliases puts = write diff --git a/openc3/python/openc3/tools/cmd_tlm_server/interface_thread.py b/openc3/python/openc3/tools/cmd_tlm_server/interface_thread.py index 003ab79eba..80634ff4ac 100644 --- a/openc3/python/openc3/tools/cmd_tlm_server/interface_thread.py +++ b/openc3/python/openc3/tools/cmd_tlm_server/interface_thread.py @@ -11,7 +11,7 @@ import socket import threading -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.system.system import System from openc3.top_level import kill_thread @@ -118,7 +118,7 @@ def _run(self): # Set received time if not already set if not packet.received_time: - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) except Exception as e: self._handle_connection_lost(e) diff --git a/openc3/python/openc3/utilities/logger.py b/openc3/python/openc3/utilities/logger.py index 549fae2486..1b9bd65d65 100644 --- a/openc3/python/openc3/utilities/logger.py +++ b/openc3/python/openc3/utilities/logger.py @@ -12,7 +12,7 @@ import json import socket import sys -from datetime import datetime, timezone +from datetime import UTC, datetime from enum import IntEnum from threading import Lock @@ -227,7 +227,7 @@ def build_log_data( url=None, other=None, ): - now_time = datetime.now(timezone.utc) + now_time = datetime.now(UTC) data = { "time": int(now_time.timestamp() * 1000000000), # Can't use isoformat because it appends "+00:00" instead of "Z" diff --git a/openc3/python/openc3/utilities/message_log.py b/openc3/python/openc3/utilities/message_log.py index 5682537ef8..ed8cb9c918 100644 --- a/openc3/python/openc3/utilities/message_log.py +++ b/openc3/python/openc3/utilities/message_log.py @@ -11,7 +11,7 @@ import os import time -from datetime import datetime, timezone +from datetime import UTC, datetime from threading import Lock from openc3.environment import OPENC3_SCOPE @@ -24,7 +24,7 @@ class MessageLog: @classmethod def build_timestamped_filename(cls, tags=None, extension=".txt", time=None): if time is None: - time = datetime.now(timezone.utc) + time = datetime.now(UTC) timestamp = time.strftime("%Y_%m_%d_%H_%M_%S") tags = tags or [] tags = [i for i in tags if i is not None] # Remove Nones diff --git a/openc3/python/openc3/utilities/questdb_client.py b/openc3/python/openc3/utilities/questdb_client.py index 768bb7e16e..e450934f98 100644 --- a/openc3/python/openc3/utilities/questdb_client.py +++ b/openc3/python/openc3/utilities/questdb_client.py @@ -22,7 +22,7 @@ import re import threading import time -from datetime import datetime, timezone +from datetime import UTC, datetime from decimal import Decimal from typing import NamedTuple @@ -603,7 +603,7 @@ def nsec_to_utc_time(nsec): seconds = nsec / 1_000_000_000 remainder_ns = nsec % 1_000_000_000 microseconds = remainder_ns / 1000 - return datetime.fromtimestamp(seconds, tz=timezone.utc).replace(microsecond=int(microseconds)) + return datetime.fromtimestamp(seconds, tz=UTC).replace(microsecond=int(microseconds)) @staticmethod def coerce_to_utc(value): @@ -621,17 +621,17 @@ def coerce_to_utc(value): return None if isinstance(value, datetime): if value.tzinfo is None: - return value.replace(tzinfo=timezone.utc) - return value.astimezone(timezone.utc) + return value.replace(tzinfo=UTC) + return value.astimezone(UTC) elif isinstance(value, float): - return datetime.fromtimestamp(value, tz=timezone.utc) + return datetime.fromtimestamp(value, tz=UTC) elif isinstance(value, int): return QuestDBClient.nsec_to_utc_time(value) elif isinstance(value, str): from datetime import datetime as dt parsed = dt.fromisoformat(value.replace("Z", "+00:00")) - return parsed.astimezone(timezone.utc) + return parsed.astimezone(UTC) else: # Assume PG timestamp-like object return QuestDBClient.pg_timestamp_to_utc(value) @@ -1053,7 +1053,7 @@ def pg_timestamp_to_utc(pg_time): if pg_time is None: return None # Replace timezone info with UTC (psycopg may return naive datetimes) - return pg_time.replace(tzinfo=timezone.utc) + return pg_time.replace(tzinfo=UTC) @staticmethod def format_timestamp(utc_time, format_type): @@ -1638,7 +1638,7 @@ def write_row(self, table_name, columns, timestamp_ns, rx_timestamp_ns=None): """ if rx_timestamp_ns is not None: # Convert nanoseconds to datetime for QuestDB timestamp column - columns["RECEIVED_TIMESECONDS"] = datetime.fromtimestamp(rx_timestamp_ns / 1_000_000_000, tz=timezone.utc) + columns["RECEIVED_TIMESECONDS"] = datetime.fromtimestamp(rx_timestamp_ns / 1_000_000_000, tz=UTC) self.pending_rows.append((table_name, columns.copy(), timestamp_ns)) self.ingest.row(table_name, columns=columns, at=TimestampNanos(timestamp_ns)) # Flush in batches to avoid overwhelming QuestDB's HTTP endpoint diff --git a/openc3/python/openc3/utilities/running_script.py b/openc3/python/openc3/utilities/running_script.py index e681102518..f8ffa6978e 100644 --- a/openc3/python/openc3/utilities/running_script.py +++ b/openc3/python/openc3/utilities/running_script.py @@ -131,8 +131,8 @@ def _openc3_script_sleep(sleep_time=None): import time import traceback import uuid +from datetime import UTC from datetime import datetime as cdatetime -from datetime import timezone from io import StringIO from threading import Lock @@ -341,7 +341,7 @@ def __init__(self, script_status): self.debug_history = [] self.debug_code_completion = None self.top_level_instrumented_cache = None - self.output_time = cdatetime.now(timezone.utc).strftime(RunningScript.STRFTIME_FORMAT) + self.output_time = cdatetime.now(UTC).strftime(RunningScript.STRFTIME_FORMAT) self.output_time_value = _time.time() self.script_globals = globals() self.suite_report = None @@ -479,9 +479,7 @@ def do_pause(self): def do_stop(self): if RunningScript.run_thread: self.stop = True - self.script_status.end_time = ( - cdatetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") - ) + self.script_status.end_time = cdatetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") self.update_running_script_store("stopped") kill_thread(self, RunningScript.run_thread) RunningScript.run_thread = None @@ -731,9 +729,7 @@ def execute_while_paused(self, filename, line_no=1, end_line_no=None, bind_varia ) def scriptrunner_puts(self, string, color="BLACK"): - line_to_write = ( - cdatetime.now(timezone.utc).strftime(RunningScript.STRFTIME_FORMAT) + " (SCRIPTRUNNER): " + string - ) + line_to_write = cdatetime.now(UTC).strftime(RunningScript.STRFTIME_FORMAT) + " (SCRIPTRUNNER): " + string print(line_to_write) running_script_anycable_publish( f"running-script-channel:{self.script_status.id}", @@ -754,7 +750,7 @@ def handle_output_io(self, filename=None, line_number=None): filename = self.script_status.current_filename if not line_number: line_number = self.script_status.line_no - self.output_time = cdatetime.now(timezone.utc).strftime(RunningScript.STRFTIME_FORMAT) + self.output_time = cdatetime.now(UTC).strftime(RunningScript.STRFTIME_FORMAT) self.output_time_value = _time.time() string = self.output_io.getvalue() self.output_io.truncate(0) @@ -965,7 +961,7 @@ def mark_error(self): ) def mark_crashed(self): - self.script_status.end_time = cdatetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + self.script_status.end_time = cdatetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") self.update_running_script_store("crashed") running_script_anycable_publish( f"running-script-channel:{self.script_status.id}", @@ -978,7 +974,7 @@ def mark_crashed(self): ) def mark_completed(self): - self.script_status.end_time = cdatetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + self.script_status.end_time = cdatetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") self.update_running_script_store("completed") running_script_anycable_publish( f"running-script-channel:{self.script_status.id}", @@ -1479,7 +1475,7 @@ def start(procedure_name, line_no=1, end_line_no=None, bind_variables=False, com if complete: RunningScript.instance.script_status.state = "completed" RunningScript.instance.script_status.end_time = ( - cdatetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + cdatetime.now(UTC).isoformat(timespec="seconds").replace("+00:00", "Z") ) RunningScript.instance.script_status.update(queued=True) raise StopScriptError diff --git a/openc3/python/openc3/utilities/script_instrumentor.py b/openc3/python/openc3/utilities/script_instrumentor.py index e99a1c19b8..76afb88316 100644 --- a/openc3/python/openc3/utilities/script_instrumentor.py +++ b/openc3/python/openc3/utilities/script_instrumentor.py @@ -10,7 +10,6 @@ # if purchased from OpenC3, Inc. import ast -import sys # For details on the AST, see https://docs.python.org/3/library/ast.html @@ -44,9 +43,7 @@ def __init__(self, filename, line_offset=0): self.filename = filename self.line_offset = line_offset self.try_count = 0 - self.try_nodes = [ast.Try] - if sys.version_info >= (3, 11): - self.try_nodes.append(ast.TryStar) + self.try_nodes = [ast.Try, ast.TryStar] # What we're trying to do is wrap executable statements in a while True try/except block # For example if the input code is "print('HI')", we want to transform it to: @@ -188,8 +185,7 @@ def track_import_from(self, node): visit_Raise = track_enter_leave visit_Try = track_reached - if sys.version_info >= (3, 11): - visit_TryStar = track_reached + visit_TryStar = track_reached visit_Assert = track_enter_leave visit_Import = track_enter_leave diff --git a/openc3/python/openc3/utilities/string.py b/openc3/python/openc3/utilities/string.py index 4dc5341a79..0cf54d215f 100644 --- a/openc3/python/openc3/utilities/string.py +++ b/openc3/python/openc3/utilities/string.py @@ -11,7 +11,7 @@ import os import sys -from datetime import datetime, timezone +from datetime import UTC, datetime def quote_if_necessary(string: str): @@ -113,7 +113,7 @@ def formatted( # extension def build_timestamped_filename(tags=None, extension=".txt", time=None): if time is None: - time = datetime.now(timezone.utc) + time = datetime.now(UTC) timestamp = time.strftime("%Y_%m_%d_%H_%M_%S") if not tags: tags = [] diff --git a/openc3/python/openc3/utilities/time.py b/openc3/python/openc3/utilities/time.py index 2134c12cca..0a8f9b57c5 100644 --- a/openc3/python/openc3/utilities/time.py +++ b/openc3/python/openc3/utilities/time.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. -from datetime import datetime, timezone +from datetime import UTC, datetime NSEC_PER_SECOND = 1_000_000_000 @@ -18,8 +18,8 @@ def from_nsec_from_epoch(nsec_from_epoch): if nsec_from_epoch is None: - nsec_from_epoch = datetime().now(timezone.utc) - return datetime.fromtimestamp(nsec_from_epoch / NSEC_PER_SECOND, timezone.utc) + nsec_from_epoch = datetime().now(UTC) + return datetime.fromtimestamp(nsec_from_epoch / NSEC_PER_SECOND, UTC) def to_nsec_from_epoch(time): diff --git a/openc3/python/pyproject.toml b/openc3/python/pyproject.toml index 65c21451be..fab8fb8e62 100644 --- a/openc3/python/pyproject.toml +++ b/openc3/python/pyproject.toml @@ -6,7 +6,7 @@ authors = [{ name = "Support", email = "support@openc3.com" }] maintainers = [{ name = "OpenC3 Support", email = "support@openc3.com" }] license = "LicenseRef-OpenC3-Builders-License" license-files = ["LICENSE.md"] -requires-python = ">=3.10,<4.0" +requires-python = ">=3.11,<4.0" readme = "README.md" keywords = [ "cosmos", @@ -21,11 +21,11 @@ classifiers = [ "Intended Audience :: Science/Research", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Embedded Systems", ] @@ -94,8 +94,8 @@ include = ["openc3*"] # Line length to match Black line-length = 120 -# Assume Python 3.10 (minimum supported version) -target-version = "py310" +# Assume Python 3.11 (minimum supported version) +target-version = "py311" # Exclude a variety of commonly ignored directories exclude = [ @@ -175,8 +175,8 @@ docstring-code-format = true [tool.ty.environment] # Match the minimum supported version so type errors that only appear on older -# Pythons are still caught (same rationale as ruff's target-version = py310) -python-version = "3.10" +# Pythons are still caught (same rationale as ruff's target-version = py311) +python-version = "3.11" [tool.ty.src] exclude = [".venv", "build", "dist", "node_modules"] diff --git a/openc3/python/test/api/test_calendar_api.py b/openc3/python/test/api/test_calendar_api.py index d2a05156a9..aac8124495 100644 --- a/openc3/python/test/api/test_calendar_api.py +++ b/openc3/python/test/api/test_calendar_api.py @@ -11,7 +11,7 @@ import time import unittest -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from unittest.mock import patch from openc3.api.calendar_api import ( @@ -53,7 +53,7 @@ def setUp(self): self.addCleanup(patcher.stop) def _future_window(self, offset_hours=1, duration_hours=1): - now = datetime.now(timezone.utc) + now = datetime.now(UTC) start = now + timedelta(hours=offset_hours) stop = now + timedelta(hours=offset_hours + duration_hours) return start, stop @@ -228,7 +228,7 @@ def test_create_activity_recurring(self): def test_create_activity_rejects_past_start(self): self._make_timeline() - now = datetime.now(timezone.utc) + now = datetime.now(UTC) with self.assertRaises(ActivityInputError): create_timeline_activity( TIMELINE, @@ -240,7 +240,7 @@ def test_create_activity_rejects_past_start(self): def test_create_activity_rejects_too_long(self): self._make_timeline() - now = datetime.now(timezone.utc) + now = datetime.now(UTC) with self.assertRaises(ActivityInputError): create_timeline_activity( TIMELINE, @@ -325,8 +325,8 @@ def test_get_activities_excludes_outside_window(self): self._make_timeline() start, stop = self._future_window() create_timeline_activity(TIMELINE, kind="COMMAND", start=start, stop=stop, scope=SCOPE) - far = (datetime.now(timezone.utc) + timedelta(days=30)).isoformat() - far_stop = (datetime.now(timezone.utc) + timedelta(days=31)).isoformat() + far = (datetime.now(UTC) + timedelta(days=30)).isoformat() + far_stop = (datetime.now(UTC) + timedelta(days=31)).isoformat() self.assertEqual(get_timeline_activities(TIMELINE, start=far, stop=far_stop, scope=SCOPE), []) # --- delete_timeline_activity ---------------------------------------- @@ -411,20 +411,20 @@ def test_cal_to_epoch_numeric_string(self): self.assertEqual(_cal_to_epoch("-7"), -7) def test_cal_to_epoch_iso_string(self): - dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=timezone.utc) + dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=UTC) self.assertEqual(_cal_to_epoch(dt.isoformat()), int(dt.timestamp())) def test_cal_to_epoch_iso_string_with_z(self): - dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=timezone.utc) + dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=UTC) self.assertEqual(_cal_to_epoch("2031-04-16T01:02:03Z"), int(dt.timestamp())) def test_cal_to_epoch_datetime_naive_treated_as_utc(self): dt = datetime(2031, 4, 16, 1, 2, 3) - expected = int(dt.replace(tzinfo=timezone.utc).timestamp()) + expected = int(dt.replace(tzinfo=UTC).timestamp()) self.assertEqual(_cal_to_epoch(dt), expected) def test_cal_to_epoch_datetime_with_tz(self): - dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=timezone.utc) + dt = datetime(2031, 4, 16, 1, 2, 3, tzinfo=UTC) self.assertEqual(_cal_to_epoch(dt), int(dt.timestamp())) def test_cal_to_epoch_invalid_string_raises(self): diff --git a/openc3/python/test/api/test_inject_tlm_received_time.py b/openc3/python/test/api/test_inject_tlm_received_time.py index 7c48c04f65..f77ce4e301 100644 --- a/openc3/python/test/api/test_inject_tlm_received_time.py +++ b/openc3/python/test/api/test_inject_tlm_received_time.py @@ -8,7 +8,7 @@ import json import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import Mock, patch from openc3.api.tlm_api import inject_tlm @@ -93,7 +93,7 @@ def test_handler_uses_historical_received_time(self, system, _increment, write_p self.assertEqual( packet.received_time, - datetime(2021, 1, 1, 0, 0, 0, 123456, tzinfo=timezone.utc), + datetime(2021, 1, 1, 0, 0, 0, 123456, tzinfo=UTC), ) write_packet.assert_called_once_with(packet, "DEFAULT") @@ -123,7 +123,7 @@ def test_handler_accepts_unix_epoch_zero(self, system, _increment, _write_packet "DEFAULT", ) - self.assertEqual(packet.received_time, datetime(1970, 1, 1, tzinfo=timezone.utc)) + self.assertEqual(packet.received_time, datetime(1970, 1, 1, tzinfo=UTC)) @patch("openc3.script.telemetry.openc3.script.API_SERVER") def test_script_wrapper_forwards_received_time(self, api_server): diff --git a/openc3/python/test/api/test_limits_api.py b/openc3/python/test/api/test_limits_api.py index 5a10d4860d..c110bce743 100644 --- a/openc3/python/test/api/test_limits_api.py +++ b/openc3/python/test/api/test_limits_api.py @@ -13,7 +13,7 @@ import threading import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.api.limits_api import * @@ -99,12 +99,12 @@ def test_gets_limits_for_an_item(self): def test_gets_limits_for_a_latest_item(self): packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") time.sleep(0.01) # Allow the write to happen - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") time.sleep(0.01) # Allow the write to happen @@ -393,7 +393,7 @@ def test_get_limits_events_returns_an_offset_and_limits_event_hash(self): "message": "nope", } LimitsEventTopic.write(event, scope="DEFAULT") - time = datetime.now(timezone.utc) + time = datetime.now(UTC) event = { "type": "LIMITS_CHANGE", "target_name": "TGT", diff --git a/openc3/python/test/api/test_tlm_api.py b/openc3/python/test/api/test_tlm_api.py index d349d6def1..7d656d7417 100644 --- a/openc3/python/test/api/test_tlm_api.py +++ b/openc3/python/test/api/test_tlm_api.py @@ -17,7 +17,7 @@ import threading import time import unittest -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from unittest.mock import * from openc3.api.tlm_api import * @@ -60,7 +60,7 @@ def xread_side_effect(*args, **kwargs): model.create() packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") @@ -103,7 +103,7 @@ def test_complains_if_too_many_parameters(self): tlm("INST", "HEALTH_STATUS", "TEMP1", "TEMP2") def test_returns_the_value_using_latest(self): - now = datetime.now(timezone.utc) + now = datetime.now(UTC) packet = System.telemetry.packet("INST", "IMAGE") packet.received_time = now packet.write("CCSDSVER", 1) @@ -681,7 +681,7 @@ def test_reads_all_telemetry_items_as_converted_with_their_limits_states(self): self.assertEqual(vals[28][0], "PACKET_TIMEFORMATTED") self.assertEqual( vals[28][1].split(" ")[0], - formatted(datetime.now(timezone.utc)).split(" ")[0], + formatted(datetime.now(UTC)).split(" ")[0], ) # Match the date self.assertIsNone(vals[28][2]) self.assertEqual(vals[29][0], "RECEIVED_TIMESECONDS") @@ -690,7 +690,7 @@ def test_reads_all_telemetry_items_as_converted_with_their_limits_states(self): self.assertEqual(vals[30][0], "RECEIVED_TIMEFORMATTED") self.assertEqual( vals[30][1].split(" ")[0], - formatted(datetime.now(timezone.utc)).split(" ")[0], + formatted(datetime.now(UTC)).split(" ")[0], ) # Match the date self.assertIsNone(vals[30][2]) self.assertEqual(vals[31][0], "RECEIVED_COUNT") @@ -744,7 +744,7 @@ def test_reads_all_telemetry_items_as_with_units(self): def test_marks_data_as_stale(self): packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) - timedelta(seconds=100) + packet.received_time = datetime.now(UTC) - timedelta(seconds=100) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") @@ -957,7 +957,7 @@ def test_get_tlm_values_handles_block_data_as_binary(self): def test_get_tlm_values_marks_data_as_stale(self): packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) - timedelta(seconds=100) + packet.received_time = datetime.now(UTC) - timedelta(seconds=100) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") @@ -1135,7 +1135,7 @@ def test_subscribe_packets_with_bad_input(self): def test_streams_packets_since_the_subscription_was_created(self): # Write an initial packet that should not be returned packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.write("DURATION", 1.0) TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") time.sleep(0.01) @@ -1144,17 +1144,17 @@ def test_streams_packets_since_the_subscription_was_created(self): time.sleep(0.01) # Write some packets that should be returned and one that will not - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.write("DURATION", 2.0) TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.write("DURATION", 3.0) TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") packet = System.telemetry.packet("INST", "ADCS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") packet = System.telemetry.packet("INST", "IMAGE") # Not subscribed - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") id, packets = get_packets(id) diff --git a/openc3/python/test/conversions/test_packet_time_formatted_conversion.py b/openc3/python/test/conversions/test_packet_time_formatted_conversion.py index 3c95e3c6ba..e50e3b5ce1 100644 --- a/openc3/python/test/conversions/test_packet_time_formatted_conversion.py +++ b/openc3/python/test/conversions/test_packet_time_formatted_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.packet_time_formatted_conversion import ( @@ -29,7 +29,7 @@ def test_initializes_converted_type_and_converted_bit_size(self): def test_returns_the_formatted_packet_time(self): gc = PacketTimeFormattedConversion() packet = Packet("TGT", "PKT") - packet.received_time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc) + packet.received_time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC) self.assertEqual(gc.call(None, packet, None), "2020/01/31 12:15:30.000") def test_returns_a_string_if_packet_time_isnt_set(self): diff --git a/openc3/python/test/conversions/test_packet_time_seconds_conversion.py b/openc3/python/test/conversions/test_packet_time_seconds_conversion.py index 2db30a762e..9deb1ac1cd 100644 --- a/openc3/python/test/conversions/test_packet_time_seconds_conversion.py +++ b/openc3/python/test/conversions/test_packet_time_seconds_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.packet_time_seconds_conversion import ( @@ -29,7 +29,7 @@ def test_initializes_converted_type_and_converted_bit_size(self): def test_returns_the_formatted_packet_time(self): gc = PacketTimeSecondsConversion() packet = Packet("TGT", "PKT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc) + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC) packet.received_time = time self.assertEqual(gc.call(None, packet, None), time.timestamp()) diff --git a/openc3/python/test/conversions/test_received_time_formatted_conversion.py b/openc3/python/test/conversions/test_received_time_formatted_conversion.py index dfb00ce3c4..6f623fbbc4 100644 --- a/openc3/python/test/conversions/test_received_time_formatted_conversion.py +++ b/openc3/python/test/conversions/test_received_time_formatted_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.received_time_formatted_conversion import ( @@ -29,7 +29,7 @@ def test_initializes_converted_type_and_converted_bit_size(self): def test_returns_the_formatted_packet_time(self): gc = ReceivedTimeFormattedConversion() packet = Packet("TGT", "PKT") - packet.received_time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc) + packet.received_time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC) self.assertEqual(gc.call(None, packet, None), "2020/01/31 12:15:30.000") def test_returns_a_string_if_packet_time_isnt_set(self): diff --git a/openc3/python/test/conversions/test_received_time_seconds_conversion.py b/openc3/python/test/conversions/test_received_time_seconds_conversion.py index edb2752873..d208647074 100644 --- a/openc3/python/test/conversions/test_received_time_seconds_conversion.py +++ b/openc3/python/test/conversions/test_received_time_seconds_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.received_time_seconds_conversion import ( @@ -29,7 +29,7 @@ def test_initializes_converted_type_and_converted_bit_size(self): def test_returns_the_formatted_packet_time(self): gc = ReceivedTimeSecondsConversion() packet = Packet("TGT", "PKT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc) + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC) packet.received_time = time self.assertEqual(gc.call(None, packet, None), time.timestamp()) diff --git a/openc3/python/test/conversions/test_unix_time_formatted_conversion.py b/openc3/python/test/conversions/test_unix_time_formatted_conversion.py index 66b8817faa..520ce2d9d7 100644 --- a/openc3/python/test/conversions/test_unix_time_formatted_conversion.py +++ b/openc3/python/test/conversions/test_unix_time_formatted_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.unix_time_formatted_conversion import ( @@ -30,7 +30,7 @@ def test_returns_the_formatted_packet_time_based_on_seconds(self): utfc = UnixTimeFormattedConversion("TIME") packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) self.assertEqual(utfc.call(None, packet, packet.buffer), "2020/01/31 12:15:30.000") @@ -38,7 +38,7 @@ def test_returns_the_formatted_packet_time_based_on_seconds_and_microseconds(sel utfc = UnixTimeFormattedConversion("TIME", "TIME_US") packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) packet.append_item("TIME_US", 32, "UINT") packet.write("TIME_US", 500000) @@ -75,7 +75,7 @@ def test_creates_a_reproducable_format(self): new_utfc = UnixTimeFormattedConversion(*json["params"]) packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) packet.append_item("TIME_US", 32, "UINT") packet.write("TIME_US", 500000) diff --git a/openc3/python/test/conversions/test_unix_time_seconds_conversion.py b/openc3/python/test/conversions/test_unix_time_seconds_conversion.py index 276e7db46c..61c7523f2b 100644 --- a/openc3/python/test/conversions/test_unix_time_seconds_conversion.py +++ b/openc3/python/test/conversions/test_unix_time_seconds_conversion.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.conversions.unix_time_seconds_conversion import UnixTimeSecondsConversion @@ -28,7 +28,7 @@ def test_returns_the_formatted_packet_time_based_on_seconds(self): utsc = UnixTimeSecondsConversion("TIME") packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) self.assertEqual(utsc.call(None, packet, packet.buffer), time) @@ -36,7 +36,7 @@ def test_returns_the_formatted_packet_time_based_on_seconds_and_microseconds(sel utsc = UnixTimeSecondsConversion("TIME", "TIME_US") packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) packet.append_item("TIME_US", 32, "UINT") packet.write("TIME_US", 500000) @@ -73,7 +73,7 @@ def test_creates_a_reproducable_format(self): new_utsc = UnixTimeSecondsConversion(*json.get("params")) packet = Packet("TGT", "PKT") packet.append_item("TIME", 32, "UINT") - time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=timezone.utc).timestamp() + time = datetime(2020, 1, 31, 12, 15, 30, tzinfo=UTC).timestamp() packet.write("TIME", time) packet.append_item("TIME_US", 32, "UINT") packet.write("TIME_US", 500000) diff --git a/openc3/python/test/interfaces/protocols/test_fixed_protocol.py b/openc3/python/test/interfaces/protocols/test_fixed_protocol.py index eadc0e7adb..cf8afe177d 100644 --- a/openc3/python/test/interfaces/protocols/test_fixed_protocol.py +++ b/openc3/python/test/interfaces/protocols/test_fixed_protocol.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.interfaces.protocols.fixed_protocol import FixedProtocol @@ -115,7 +115,7 @@ def test_reads_telemetry_data_from_the_stream(self): TestFixedProtocol.index = 1 packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") @@ -123,7 +123,7 @@ def test_reads_telemetry_data_from_the_stream(self): TestFixedProtocol.index = 2 packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") @@ -132,7 +132,7 @@ def test_reads_telemetry_data_from_the_stream(self): TestFixedProtocol.index = 1 packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") @@ -140,7 +140,7 @@ def test_reads_telemetry_data_from_the_stream(self): TestFixedProtocol.index = 2 packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") @@ -173,7 +173,7 @@ def read(self): target.cmd_unique_id_mode = False packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") @@ -182,7 +182,7 @@ def read(self): target.cmd_unique_id_mode = True packet = self.interface.read() self.assertLess( - datetime.now(timezone.utc).timestamp() - packet.received_time.timestamp(), + datetime.now(UTC).timestamp() - packet.received_time.timestamp(), 0.1, ) self.assertEqual(packet.target_name, "SYSTEM") diff --git a/openc3/python/test/interfaces/protocols/test_ignore_packet_protocol.py b/openc3/python/test/interfaces/protocols/test_ignore_packet_protocol.py index 2b86e12cf2..9970f63b06 100644 --- a/openc3/python/test/interfaces/protocols/test_ignore_packet_protocol.py +++ b/openc3/python/test/interfaces/protocols/test_ignore_packet_protocol.py @@ -13,7 +13,7 @@ import threading import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.interfaces.protocols.ignore_packet_protocol import IgnorePacketProtocol @@ -85,7 +85,7 @@ def test_read_ignores_the_packet_specified(self): # Ensure the ID items are set so this packet can be identified for item in pkt.id_items: pkt.write_item(item, item.id_value) - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write went out @@ -119,7 +119,7 @@ def test_read_can_be_added_multiple_times_to_ignore_different_packets(self): # Ensure the ID items are set so this packet can be identified for item in pkt.id_items: pkt.write_item(item, item.id_value) - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) self.assertEqual(TestIgnorePacketProtocol.buffer, pkt.buffer) @@ -157,7 +157,7 @@ def my_read(): # Ensure the ID items are set so this packet can be identified for item in pkt.id_items: pkt.write_item(item, item.id_value) - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) self.assertEqual(TestIgnorePacketProtocol.buffer, pkt.buffer) @@ -182,7 +182,7 @@ def my_read2(): # Ensure the ID items are set so this packet can be identified for item in pkt.id_items: pkt.write_item(item, item.id_value) - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write went out @@ -196,7 +196,7 @@ def test_write_ignores_the_packet_specified(self): self.interface.add_protocol(IgnorePacketProtocol, ["SYSTEM", "META"], "WRITE") pkt = System.telemetry.packet("SYSTEM", "META") pkt.write("OPENC3_VERSION", "TEST") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write was ignored @@ -213,21 +213,21 @@ def test_write_can_be_added_multiple_times_to_ignore_different_packets(self): self.interface.add_protocol(IgnorePacketProtocol, ["INST", "ADCS"], "WRITE") pkt = System.telemetry.packet("INST", "HEALTH_STATUS") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write was ignored self.assertIsNone(TestIgnorePacketProtocol.buffer) pkt = System.telemetry.packet("INST", "ADCS") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write was ignored self.assertIsNone(TestIgnorePacketProtocol.buffer) pkt = System.telemetry.packet("INST", "PARAMS") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write went out @@ -238,7 +238,7 @@ def test_read_write_ignores_the_packet_specified(self): self.interface.add_protocol(IgnorePacketProtocol, ["SYSTEM", "META"], "READ_WRITE") pkt = System.telemetry.packet("SYSTEM", "META") pkt.write("OPENC3_VERSION", "TEST") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) TestIgnorePacketProtocol.buffer = None self.interface.write(pkt) # Verify the write was ignored diff --git a/openc3/python/test/interfaces/protocols/test_preidentified_protocol.py b/openc3/python/test/interfaces/protocols/test_preidentified_protocol.py index 22134bc305..b5f9e156cc 100644 --- a/openc3/python/test/interfaces/protocols/test_preidentified_protocol.py +++ b/openc3/python/test/interfaces/protocols/test_preidentified_protocol.py @@ -13,7 +13,7 @@ import os import struct import unittest -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from unittest.mock import * from openc3.interfaces.protocols.preidentified_protocol import PreidentifiedProtocol @@ -98,7 +98,7 @@ def test_handles_receiving_a_bad_packet_length(self): self.interface.stream = TestPreidentifiedProtocol.PreStream() self.interface.add_protocol(PreidentifiedProtocol, [None, 5], "READ_WRITE") pkt = System.telemetry.packet("SYSTEM", "META") - pkt.received_time = datetime.now(timezone.utc) + pkt.received_time = datetime.now(UTC) self.interface.write(pkt) with self.assertRaises(RuntimeError): self.interface.read() @@ -237,7 +237,7 @@ def test_reads_a_cosmos_4_file(self): self.assertEqual(packet.target_name, "SYSTEM") self.assertEqual(packet.packet_name, "META") self.assertTrue(packet.identified()) - time = datetime(2025, 5, 1, 18, 0, 0, tzinfo=timezone.utc) + time = datetime(2025, 5, 1, 18, 0, 0, tzinfo=UTC) for i in range(0, 10): packet = self.interface.read() self.assertEqual(packet.target_name, "INST") diff --git a/openc3/python/test/logs/test_packet_log_reader.py b/openc3/python/test/logs/test_packet_log_reader.py index a6b160e9ec..152474ae1f 100644 --- a/openc3/python/test/logs/test_packet_log_reader.py +++ b/openc3/python/test/logs/test_packet_log_reader.py @@ -20,7 +20,7 @@ import tempfile import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.logs.packet_log_constants import ( COSMOS2_FILE_HEADER, @@ -96,7 +96,7 @@ class TestPacketLogReaderWithJsonTelemetry(unittest.TestCase): def setUp(self): self.plr = PacketLogReader() self.temp_dir = tempfile.mkdtemp() - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.start_nsec = int(self.start_time.timestamp() * 1_000_000_000) self.times = [ self.start_nsec, @@ -159,7 +159,7 @@ class TestPacketLogReaderWithJsonCommands(unittest.TestCase): def setUp(self): self.plr = PacketLogReader() self.temp_dir = tempfile.mkdtemp() - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.start_nsec = int(self.start_time.timestamp() * 1_000_000_000) self.times = [ self.start_nsec, @@ -218,7 +218,7 @@ class TestPacketLogReaderWithRawTelemetry(unittest.TestCase): def setUp(self): self.plr = PacketLogReader() self.temp_dir = tempfile.mkdtemp() - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.start_nsec = int(self.start_time.timestamp() * 1_000_000_000) self.times = [ self.start_nsec, @@ -275,7 +275,7 @@ class TestPacketLogReaderWithStartEndTimes(unittest.TestCase): def setUp(self): self.plr = PacketLogReader() self.temp_dir = tempfile.mkdtemp() - self.start_time = datetime.now(timezone.utc) + self.start_time = datetime.now(UTC) self.start_nsec = int(self.start_time.timestamp() * 1_000_000_000) self.times = [ self.start_nsec, @@ -316,7 +316,7 @@ def _setup_logfile(self): def test_returns_all_packets_if_start_time_before_all(self): """returns all packets if the start time is before all""" - start = datetime.fromtimestamp((self.start_nsec - NSEC_PER_SECOND) / 1e9, tz=timezone.utc) + start = datetime.fromtimestamp((self.start_nsec - NSEC_PER_SECOND) / 1e9, tz=UTC) index = 0 for packet in self.plr.each(self.logfile, start_time=start): self.assertEqual(packet.time_nsec, self.times[index]) @@ -325,7 +325,7 @@ def test_returns_all_packets_if_start_time_before_all(self): def test_returns_no_packets_if_start_time_after_all(self): """returns no packets if the start time is after all""" - start = datetime.fromtimestamp((self.start_nsec + 10 * NSEC_PER_SECOND) / 1e9, tz=timezone.utc) + start = datetime.fromtimestamp((self.start_nsec + 10 * NSEC_PER_SECOND) / 1e9, tz=UTC) index = 0 for _packet in self.plr.each(self.logfile, start_time=start): index += 1 @@ -334,7 +334,7 @@ def test_returns_no_packets_if_start_time_after_all(self): def test_returns_all_packets_after_start_time(self): """returns all packets after a start time""" # Start after first packet (use half second offset since datetime has only microsecond precision) - start = datetime.fromtimestamp((self.start_nsec + NSEC_PER_SECOND // 2) / 1e9, tz=timezone.utc) + start = datetime.fromtimestamp((self.start_nsec + NSEC_PER_SECOND // 2) / 1e9, tz=UTC) index = 1 # Start at index 1 for packet in self.plr.each(self.logfile, start_time=start): self.assertEqual(packet.time_nsec, self.times[index]) @@ -343,7 +343,7 @@ def test_returns_all_packets_after_start_time(self): def test_returns_no_packets_if_end_time_before_all(self): """returns no packets if the end time is before all""" - end = datetime.fromtimestamp((self.start_nsec - NSEC_PER_SECOND) / 1e9, tz=timezone.utc) + end = datetime.fromtimestamp((self.start_nsec - NSEC_PER_SECOND) / 1e9, tz=UTC) index = 0 for _packet in self.plr.each(self.logfile, end_time=end): index += 1 @@ -351,7 +351,7 @@ def test_returns_no_packets_if_end_time_before_all(self): def test_returns_all_packets_if_end_time_after_all(self): """returns all packets if the end time is after all""" - end = datetime.fromtimestamp((self.start_nsec + 4 * NSEC_PER_SECOND) / 1e9, tz=timezone.utc) + end = datetime.fromtimestamp((self.start_nsec + 4 * NSEC_PER_SECOND) / 1e9, tz=UTC) index = 0 for packet in self.plr.each(self.logfile, end_time=end): self.assertEqual(packet.time_nsec, self.times[index]) @@ -361,7 +361,7 @@ def test_returns_all_packets_if_end_time_after_all(self): def test_returns_all_packets_before_end_time(self): """returns all packets before an end time""" # End at second packet (exactly) - end = datetime.fromtimestamp((self.start_nsec + NSEC_PER_SECOND) / 1e9, tz=timezone.utc) + end = datetime.fromtimestamp((self.start_nsec + NSEC_PER_SECOND) / 1e9, tz=UTC) index = 0 for packet in self.plr.each(self.logfile, end_time=end): self.assertEqual(packet.time_nsec, self.times[index]) diff --git a/openc3/python/test/microservices/test_decom_microservice.py b/openc3/python/test/microservices/test_decom_microservice.py index ec91aa6aab..6b36c7cd92 100644 --- a/openc3/python/test/microservices/test_decom_microservice.py +++ b/openc3/python/test/microservices/test_decom_microservice.py @@ -15,7 +15,7 @@ import threading import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import Mock, patch from openc3.api.tlm_api import tlm @@ -85,7 +85,7 @@ def test_run_decommutates_a_packet_from_raw_to_engineering_values(self): packet = System.telemetry.packet("INST", "HEALTH_STATUS") packet.extra = {} packet.extra["STATUS"] = "OK" - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) for stdout in capture_io(): TelemetryTopic.write_packet(packet, scope="DEFAULT") # Wait for async processing to complete with retries for CI reliability @@ -198,7 +198,7 @@ def test_run_decommutates_a_packet_from_raw_to_engineering_values(self): def test_limits_change_with_zero_value_is_not_disabled(self): """A telemetry value of 0 must report a limits change, not 'is disabled'.""" packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) item = packet.get_item("TEMP1") item.limits.state = "BLUE" @@ -218,7 +218,7 @@ def test_falls_back_to_default_limits_set_when_selected_set_is_not_defined(self, mock_limits_set.return_value = "TVAC" packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) # TEMP4 only has DEFAULT limits (no TVAC), TEMP1 has both DEFAULT and TVAC temp4 = packet.get_item("TEMP4") @@ -250,7 +250,7 @@ def test_falls_back_to_default_limits_set_for_green_and_blue_states(self, mock_l mock_limits_set.return_value = "TVAC" packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) # TEMP4 only has DEFAULT limits: -80.0 -70.0 60.0 80.0 (no green/blue range) temp4 = packet.get_item("TEMP4") @@ -284,7 +284,7 @@ def test_handles_exceptions_in_user_processors(self): processor = Processor() processor.call = lambda packet, buffer: exec("raise RuntimeError('Bad processor')") packet.processors["TEMP1"] = processor - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) for stdout in capture_io(): TelemetryTopic.write_packet(packet, scope="DEFAULT") # Wait for async processing to complete with retries for CI reliability @@ -307,7 +307,7 @@ def call(self, packet, item, old_limits_state): packet = System.telemetry.packet("INST", "HEALTH_STATUS") temp1 = packet.get_item("TEMP1") temp1.limits.response = DelayedLimitsResponse() - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) TelemetryTopic.write_packet(packet, scope="DEFAULT") time.sleep(0.02) @@ -364,7 +364,7 @@ def call(self, packet, item, old_limits_state): packet = System.telemetry.packet("INST", "HEALTH_STATUS") temp1 = packet.get_item("TEMP1") temp1.limits.response = BadLimitsResponse() - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) for stdout in capture_io(): TelemetryTopic.write_packet(packet, scope="DEFAULT") # Wait for async processing to complete with retries for CI reliability @@ -455,7 +455,7 @@ def call(self, packet, item, old_limits_state): packet = System.telemetry.packet("INST", "HEALTH_STATUS") temp1 = packet.get_item("TEMP1") temp1.limits.response = TrackingLimitsResponse() - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = True for stdout in capture_io(): @@ -481,7 +481,7 @@ def test_disable_mode_skips_limits_for_stored_packets(self, limits_set): self._start_decom_with_mode("DISABLE") packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = True for stdout in capture_io(): diff --git a/openc3/python/test/microservices/test_interface_microservice.py b/openc3/python/test/microservices/test_interface_microservice.py index d5304ddfa4..c861bea74a 100644 --- a/openc3/python/test/microservices/test_interface_microservice.py +++ b/openc3/python/test/microservices/test_interface_microservice.py @@ -15,7 +15,7 @@ import threading import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.config.config_parser import ConfigParser @@ -105,7 +105,7 @@ def setUp(self): model.create() packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") diff --git a/openc3/python/test/microservices/test_router_microservice.py b/openc3/python/test/microservices/test_router_microservice.py index e8fad2fff1..1261960b70 100644 --- a/openc3/python/test/microservices/test_router_microservice.py +++ b/openc3/python/test/microservices/test_router_microservice.py @@ -12,7 +12,7 @@ import threading import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.interfaces.interface import Interface @@ -90,7 +90,7 @@ def setUp(self): model.create() packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = False packet.check_limits() TelemetryTopic.write_packet(packet, scope="DEFAULT") @@ -225,7 +225,7 @@ def test_forwards_telemetry_to_the_router(self): self.assertEqual(data["TEST_INT"]["state"], "CONNECTED") packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.received_count = 1 TelemetryTopic.write_packet(packet, scope="DEFAULT") time.sleep(0.2) diff --git a/openc3/python/test/microservices/test_tsdb_microservice.py b/openc3/python/test/microservices/test_tsdb_microservice.py index ecc2aedb14..b2e52fbe20 100644 --- a/openc3/python/test/microservices/test_tsdb_microservice.py +++ b/openc3/python/test/microservices/test_tsdb_microservice.py @@ -15,7 +15,7 @@ import re import time import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import Mock, patch from questdb.ingress import IngressError @@ -57,7 +57,7 @@ def setUp(self): model.create() packet = System.telemetry.packet("INST", "HEALTH_STATUS") - packet.received_time = datetime.now(timezone.utc) + packet.received_time = datetime.now(UTC) packet.stored = False packet.check_limits() TelemetryDecomTopic.write_packet(packet, scope="DEFAULT") diff --git a/openc3/python/test/models/test_script_status_model.py b/openc3/python/test/models/test_script_status_model.py index c263416c37..0fefa9af5b 100644 --- a/openc3/python/test/models/test_script_status_model.py +++ b/openc3/python/test/models/test_script_status_model.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from openc3.models.script_status_model import ScriptStatusModel from openc3.utilities.time import to_nsec_from_epoch @@ -22,10 +22,10 @@ def setUp(self): self.redis = mock_redis(self) def test_sets_updated_at_to_nsec_from_epoch_on_create(self): - before = to_nsec_from_epoch(datetime.now(timezone.utc)) + before = to_nsec_from_epoch(datetime.now(UTC)) model = ScriptStatusModel(name="1000", state="running", scope="DEFAULT") model.create() - after = to_nsec_from_epoch(datetime.now(timezone.utc)) + after = to_nsec_from_epoch(datetime.now(UTC)) # updated_at should be an integer number of nanoseconds since the epoch, # not the previous ISO 8601 string representation diff --git a/openc3/python/test/packets/test_packet.py b/openc3/python/test/packets/test_packet.py index 2b70cae579..d516b9d5d1 100644 --- a/openc3/python/test/packets/test_packet.py +++ b/openc3/python/test/packets/test_packet.py @@ -14,7 +14,7 @@ import math import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from cbor2 import dumps @@ -123,13 +123,13 @@ def test_complains_about_non_string_descriptions(self): def test_sets_the_received_time_fast_to_a_time(self): p = Packet("tgt", "pkt") - t = datetime.now(timezone.utc) + t = datetime.now(UTC) p.set_received_time_fast(t) self.assertEqual(p.received_time, t) def test_sets_the_received_time_to_a_time(self): p = Packet("tgt", "pkt") - t = datetime.now(timezone.utc) + t = datetime.now(UTC) p.received_time = t self.assertEqual(p.received_time, t) @@ -601,14 +601,14 @@ def test_reads_the_time(self): self.assertEqual(0, seconds) seconds = self.p.read("RECEIVED_TIMESECONDS") self.assertEqual(0, seconds) - time = datetime.now(timezone.utc) + time = datetime.now(UTC) self.p.received_time = time seconds = self.p.read("PACKET_TIMESECONDS") self.assertEqual(time.timestamp(), seconds) seconds = self.p.read("RECEIVED_TIMESECONDS") self.assertEqual(time.timestamp(), seconds) - time2 = datetime.now(timezone.utc) + time2 = datetime.now(UTC) self.p.packet_time = time2 seconds = self.p.read("PACKET_TIMESECONDS") self.assertAlmostEqual(time2.timestamp(), seconds, 3) @@ -1734,7 +1734,7 @@ def test_duplicates_the_packet(self): class Reset(unittest.TestCase): def test_does_nothing_to_the_system_meta_packet(self): p = Packet("SYSTEM", "META") - time = datetime.now(timezone.utc) + time = datetime.now(UTC) p.received_time = time p.received_count = 50 p.reset() @@ -1744,7 +1744,7 @@ def test_does_nothing_to_the_system_meta_packet(self): def test_resets_the_received_time_and_received_count(self): p = Packet("tgt", "pkt") # p.processors['processor'] = double("reset", :reset : True) - p.received_time = datetime.now(timezone.utc) + p.received_time = datetime.now(UTC) p.received_count = 50 p.reset() self.assertEqual(p.received_time, None) diff --git a/openc3/python/test/script/test_messages_batch_size.py b/openc3/python/test/script/test_messages_batch_size.py index 594431c965..55d9bef645 100644 --- a/openc3/python/test/script/test_messages_batch_size.py +++ b/openc3/python/test/script/test_messages_batch_size.py @@ -11,7 +11,7 @@ import json import unittest -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from unittest.mock import Mock, patch from openc3.script.web_socket_api import MessagesWebSocketApi @@ -295,7 +295,7 @@ def test_time_range_query_batch_sizes(self, mock_auth, mock_stream_class): responses.append(json.dumps({"message": []})) mock_stream_instance.read.side_effect = responses - now = datetime.now(timezone.utc) + now = datetime.now(UTC) with MessagesWebSocketApi( start_time=to_nsec_from_epoch(now - timedelta(hours=1)), end_time=to_nsec_from_epoch(now), diff --git a/openc3/python/test/script/test_metadata.py b/openc3/python/test/script/test_metadata.py index 384daacd84..2e63fe82dd 100644 --- a/openc3/python/test/script/test_metadata.py +++ b/openc3/python/test/script/test_metadata.py @@ -11,7 +11,7 @@ import json import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.script.metadata import * @@ -34,7 +34,7 @@ def request(*args, **kwargs): mock.text = json.dumps(kwargs["data"]["metadata"]) case "get": mock.status_code = 200 - gData["start"] = datetime.now(timezone.utc).timestamp() + gData["start"] = datetime.now(UTC).timestamp() mock.text = json.dumps(gData) case "put": mock.status_code = 200 @@ -77,7 +77,7 @@ def test_metadata_set(self): metadata_set(meta, color="#123456") self.assertEqual(gData["color"], "#123456") # Set explicit start time - start = datetime.now(timezone.utc) + start = datetime.now(UTC) metadata_set(meta, start=start.timestamp()) # It would be nice to simply do this: start.strftime("%a %b %-d %H:%M:%S %Y") # But according to https://docs.python.org/3/library/time.html#time.asctime: @@ -106,7 +106,7 @@ def test_metadata_update(self): self.assertEqual("#123456", json["color"]) # Set explicit start time - start = datetime.now(timezone.utc) + start = datetime.now(UTC) meta["key1"] = "value4" metadata_update(meta, start=start.timestamp()) formatted = f"{start:%a} {start:%b} {start.day:2d} {start:%H}:{start:%M}:{start:%S} {start:%Y}" diff --git a/openc3/python/test/script/test_suite_results.py b/openc3/python/test/script/test_suite_results.py index 065bcd4da6..575cb8a307 100644 --- a/openc3/python/test/script/test_suite_results.py +++ b/openc3/python/test/script/test_suite_results.py @@ -11,7 +11,7 @@ import re import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import patch from openc3.script.suite_results import SuiteResults @@ -21,7 +21,7 @@ class TestSuiteResults(unittest.TestCase): def setUp(self): self.suite_results = SuiteResults() # Freeze time for consistent testing - self.frozen_time_utc = datetime(2025, 11, 22, 15, 30, 45, 123456, tzinfo=timezone.utc) + self.frozen_time_utc = datetime(2025, 11, 22, 15, 30, 45, 123456, tzinfo=UTC) def test_format_timestamp_always_uses_utc(self): """Test that timestamp is always formatted as UTC with Z suffix""" diff --git a/openc3/python/test/script/test_web_socket_api.py b/openc3/python/test/script/test_web_socket_api.py index eee7b3d34d..74308b812c 100644 --- a/openc3/python/test/script/test_web_socket_api.py +++ b/openc3/python/test/script/test_web_socket_api.py @@ -14,7 +14,7 @@ import sys import time import unittest -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from unittest.mock import Mock, patch from websockets.exceptions import ConnectionClosedOK @@ -131,8 +131,8 @@ def test_connection_closed_ok_returns_none(self): mock_auth = Mock() mock_auth.token.return_value = "test-token" api = MessagesWebSocketApi( - start_time=to_nsec_from_epoch(datetime.now(timezone.utc) - timedelta(minutes=5)), - end_time=to_nsec_from_epoch(datetime.now(timezone.utc)), + start_time=to_nsec_from_epoch(datetime.now(UTC) - timedelta(minutes=5)), + end_time=to_nsec_from_epoch(datetime.now(UTC)), authentication=mock_auth, ) @@ -958,8 +958,8 @@ def test_add_omits_items_and_packets_when_neither_is_given(self): # The channel expects 64-bit nanoseconds from the epoch, not a datetime def test_add_converts_datetimes_to_nanoseconds(self): api = self._make_api() - start_time = datetime(2026, 1, 1, tzinfo=timezone.utc) - end_time = datetime(2026, 1, 2, tzinfo=timezone.utc) + start_time = datetime(2026, 1, 1, tzinfo=UTC) + end_time = datetime(2026, 1, 2, tzinfo=UTC) api.add(items=["ITEM"], start_time=start_time, end_time=end_time) data = self._action_data(api)[0] self.assertEqual(data["start_time"], to_nsec_from_epoch(start_time)) @@ -1010,12 +1010,12 @@ def test_concatenates_batches_until_an_empty_batch_ends_the_stream(self): '{"message":[]}', '{"message":[{"__time":4}]}', # must never be read ) - data = StreamingWebSocketApi.read_all(items=["ITEM"], end_time=datetime(2026, 1, 1, tzinfo=timezone.utc)) + data = StreamingWebSocketApi.read_all(items=["ITEM"], end_time=datetime(2026, 1, 1, tzinfo=UTC)) self.assertEqual(data, [{"__time": 1}, {"__time": 2}, {"__time": 3}]) def test_sends_the_add_action_for_the_requested_range(self): - start_time = datetime(2026, 1, 1, tzinfo=timezone.utc) - end_time = datetime(2026, 1, 2, tzinfo=timezone.utc) + start_time = datetime(2026, 1, 1, tzinfo=UTC) + end_time = datetime(2026, 1, 2, tzinfo=UTC) self.stream.queue_read('{"type":"confirm_subscription"}', '{"message":[]}') StreamingWebSocketApi.read_all(items=["ITEM"], start_time=start_time, end_time=end_time, scope="OTHER") self.assertEqual( @@ -1039,7 +1039,7 @@ def test_returns_the_data_collected_so_far_once_the_timeout_elapses(self): ) data = StreamingWebSocketApi.read_all( items=["ITEM"], - end_time=datetime(2026, 1, 1, tzinfo=timezone.utc), + end_time=datetime(2026, 1, 1, tzinfo=UTC), timeout=0.0, ) self.assertEqual(data, [{"__time": 1}]) @@ -1052,7 +1052,7 @@ def test_raises_when_a_bounded_querys_socket_closes_before_the_end_marker(self): '{"message":[{"__time":1}]}', # Socket closes without ever sending the empty-batch end marker ) - end = datetime(2026, 1, 1, tzinfo=timezone.utc) + end = datetime(2026, 1, 1, tzinfo=UTC) with self.assertRaisesRegex(RuntimeError, "WebSocket closed before end marker"): StreamingWebSocketApi.read_all(items=["ITEM"], end_time=end) @@ -1080,7 +1080,7 @@ def test_omits_end_time_when_none_is_given_and_stops_on_the_timeout(self): def test_disconnects_the_stream_when_done(self): self.stream.queue_read('{"type":"confirm_subscription"}', '{"message":[]}') - StreamingWebSocketApi.read_all(items=["ITEM"], end_time=datetime(2026, 1, 1, tzinfo=timezone.utc)) + StreamingWebSocketApi.read_all(items=["ITEM"], end_time=datetime(2026, 1, 1, tzinfo=UTC)) self.assertEqual(self.stream.disconnect_count, 1) diff --git a/openc3/python/test/topics/test_telemetry_topic.py b/openc3/python/test/topics/test_telemetry_topic.py index fd9a54f82b..9705a0abaa 100644 --- a/openc3/python/test/topics/test_telemetry_topic.py +++ b/openc3/python/test/topics/test_telemetry_topic.py @@ -26,8 +26,8 @@ def setUp(self): self.addCleanup(shard_patch.stop) self.packet = Packet("TARGET", "PACKET") - self.packet.received_time = datetime.datetime.now(datetime.timezone.utc) - self.packet.packet_time = datetime.datetime.now(datetime.timezone.utc) + self.packet.received_time = datetime.datetime.now(datetime.UTC) + self.packet.packet_time = datetime.datetime.now(datetime.UTC) self.packet.received_count = 1 @patch("openc3.topics.telemetry_topic.EphemeralStoreQueued.instance") diff --git a/openc3/python/test/utilities/test_string.py b/openc3/python/test/utilities/test_string.py index 497de7eaaf..a8a376294e 100644 --- a/openc3/python/test/utilities/test_string.py +++ b/openc3/python/test/utilities/test_string.py @@ -11,7 +11,7 @@ import importlib import unittest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import * from openc3.utilities.logger import Logger @@ -103,7 +103,7 @@ def test_changes_the_line_separator(self): class TestBuildTimestampedFilename(unittest.TestCase): def test_formats_the_time(self): - time = datetime.now(timezone.utc) + time = datetime.now(UTC) timestamp = time.strftime("%Y_%m_%d_%H_%M_%S") self.assertIn(timestamp, build_timestamped_filename(None, ".txt", time)) diff --git a/openc3/python/test/utilities/test_time.py b/openc3/python/test/utilities/test_time.py index 61e09f4caf..7a90cbcd89 100644 --- a/openc3/python/test/utilities/test_time.py +++ b/openc3/python/test/utilities/test_time.py @@ -10,7 +10,7 @@ # if purchased from OpenC3, Inc. import unittest -from datetime import datetime +from datetime import UTC, datetime from unittest.mock import * from openc3.utilities.time import * @@ -19,17 +19,17 @@ class TestTime(unittest.TestCase): def test_from_nsec_from_epoch(self): - date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=timezone.utc) + date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=UTC) self.assertEqual(from_nsec_from_epoch(1656718485123456000), date) def test_to_nsec_from_epoch(self): - date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=timezone.utc) + date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=UTC) self.assertEqual(to_nsec_from_epoch(date), 1656718485123456000) def test_to_timestamp(self): - date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=timezone.utc) + date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=UTC) self.assertEqual(to_timestamp(date), "20220701233445123456000") def test_formatted(self): - date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=timezone.utc) + date = datetime(2022, 7, 1, 23, 34, 45, 123456, tzinfo=UTC) self.assertEqual(formatted(date), "2022/07/01 23:34:45.123") diff --git a/openc3/python/tools/generate_singleton_stubs.py b/openc3/python/tools/generate_singleton_stubs.py index cdf231abd5..020ed669e6 100755 --- a/openc3/python/tools/generate_singleton_stubs.py +++ b/openc3/python/tools/generate_singleton_stubs.py @@ -1,6 +1,6 @@ #!/usr/bin/env -S uv run --script # /// script -# requires-python = ">=3.10" +# requires-python = ">=3.11" # dependencies = ["mypy==2.3.1", "ruff==0.16.8"] # /// diff --git a/openc3/python/tools/ty_report.py b/openc3/python/tools/ty_report.py index 29c8b7b283..7e35636a43 100755 --- a/openc3/python/tools/ty_report.py +++ b/openc3/python/tools/ty_report.py @@ -1,6 +1,6 @@ #!/usr/bin/env -S uv run --script # /// script -# requires-python = ">=3.10" +# requires-python = ">=3.11" # /// # Copyright 2026 OpenC3, Inc. diff --git a/openc3/python/uv.lock b/openc3/python/uv.lock index 550bf63548..e02022087a 100644 --- a/openc3/python/uv.lock +++ b/openc3/python/uv.lock @@ -1,10 +1,9 @@ version = 1 revision = 3 -requires-python = ">=3.10, <4.0" +requires-python = ">=3.11, <4.0" resolution-markers = [ "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version < '3.11'", + "python_full_version < '3.12'", ] [[package]] @@ -50,14 +49,6 @@ version = "6.1.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c6/14/b02446bacfe44351b1689c04937ade007588f44570431880a6937e525e6c/cbor2-6.1.4.tar.gz", hash = "sha256:01ecc79a28f33d17331943ce508fc1e21f4b06553c73f874f4c77120d72b2ef9", size = 90840, upload-time = "2026-08-01T20:41:39.797Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/7d/91e6b680e8ae313e53ae8da1d0b578c668d240c9f294be06d729fc014854/cbor2-6.1.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3cfb7eec57406b86aab47183f6dc90ece888e03721d37a4d33315e79e486898d", size = 415427, upload-time = "2026-08-01T20:40:24.371Z" }, - { url = "https://files.pythonhosted.org/packages/6b/43/3d8d53f22be9566cbb011bdaaf799a77f52e447b60a54efc9537f271f177/cbor2-6.1.4-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ae14eb3f2f251102d72625ab02a28c83a8d11adf3d0383bd6d7bd9d672e18119", size = 458280, upload-time = "2026-08-01T20:40:26.362Z" }, - { url = "https://files.pythonhosted.org/packages/0f/d8/0b2fb7e936b63395ab1acf91074dc0788c575a57e8d808d9e8489de631f4/cbor2-6.1.4-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7b697c2a18eab9a3326447fe0f1c927db065a096febc57f064f0f5ed67fe96fc", size = 464737, upload-time = "2026-08-01T20:40:27.897Z" }, - { url = "https://files.pythonhosted.org/packages/52/e1/f794155ec864c0e85a2df293adc589e7e45133ab15c0d21ac5ae3a51f804/cbor2-6.1.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:032ce71cbdc9267e9cec42132f6ac6c40f441ec27ebc87ca9dd209dcab6804ee", size = 524277, upload-time = "2026-08-01T20:40:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/7b/819912a5192ffdb0261b9c73e57b2ee77b4141132ffac77bf374c738e310/cbor2-6.1.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e8097e8259b78c8feb5dd5b833b23f83ed588e821ef44cf1455082cfc9434440", size = 533360, upload-time = "2026-08-01T20:40:30.922Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f4/73aaf73837bae5c47f01e1a602214a9b9ece6c0687b7b1d6e4ecafe55b74/cbor2-6.1.4-cp310-cp310-win32.whl", hash = "sha256:41aae72e8863ac0d50705ea8290b72c49db90a6d953110feaa91360ae526fa8d", size = 282266, upload-time = "2026-08-01T20:40:32.576Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a9/a1a88346b44a7fbcd4b4aa4f527fbc5f46649bf0706e994d8e59aada4641/cbor2-6.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:deff027a56e04caebfee649029bfd1836f4fb468d2cf66d2a396ae1018f655db", size = 303781, upload-time = "2026-08-01T20:40:34.198Z" }, - { url = "https://files.pythonhosted.org/packages/6b/fb/969a945d3f3c0bd619d73e7eb375ef1800af33451d7ece2d56d881ef1732/cbor2-6.1.4-cp310-cp310-win_arm64.whl", hash = "sha256:c435720a25c1de9b241df883b5890b35aff3bf64365efc8037d4d26df085724e", size = 296316, upload-time = "2026-08-01T20:40:35.885Z" }, { url = "https://files.pythonhosted.org/packages/a7/84/1e363301c06f509963d134f5479e82b3ade87fb1495ddacf9bf7ff24ac42/cbor2-6.1.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8156fdeb73c3ff6c8cf67ad414fb5c887cd708ff0af6d61f62629f41cb4c17b2", size = 414947, upload-time = "2026-08-01T20:40:37.405Z" }, { url = "https://files.pythonhosted.org/packages/8d/96/d8e1ed3e79ea20a3423a96b5c89ce794fa02cb428e4429e601f8ebcbac7c/cbor2-6.1.4-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e1fe2d62c50df290576280b18247ec63486f78be73e285bae269c2456c6ddff0", size = 457343, upload-time = "2026-08-01T20:40:38.868Z" }, { url = "https://files.pythonhosted.org/packages/d5/0c/5796c2ed2dcd0696fc4abedf0ea0dfd5361b3f022a311481f977fa51b2b8/cbor2-6.1.4-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c204a75f91f8cd9ed0881f6b88ec395c59aeac9fcf4d08155e7f899db2a1c46e", size = 464314, upload-time = "2026-08-01T20:40:40.63Z" }, @@ -115,22 +106,6 @@ version = "3.5.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e5/3f/143b048436775b0f76ac3eec145c019e8173ccc2885c8f20319b996d5e83/charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3", size = 171764, upload-time = "2026-08-15T08:20:44.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/aa/554e2614f38fc34c58ff1d0911ae8535ad2516440d5482d76fe59f1088b0/charset_normalizer-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa", size = 369072, upload-time = "2026-08-15T08:16:22.964Z" }, - { url = "https://files.pythonhosted.org/packages/03/6d/439231dfc3ccfa6f8c06477b7da2219cbd41a2de3d49084df8ec7b5100f2/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda", size = 251142, upload-time = "2026-08-15T08:16:24.81Z" }, - { url = "https://files.pythonhosted.org/packages/55/53/7d819bd23a00ef45039146fa2cce1daa2f0771e758c5653ee1f6edac91ed/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45", size = 240714, upload-time = "2026-08-15T08:16:26.392Z" }, - { url = "https://files.pythonhosted.org/packages/b2/2c/45847198c16f4b38090cc7423b2b6a9008e438704d8ab413211832498d31/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab", size = 279637, upload-time = "2026-08-15T08:16:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/69/2b/d8be3523ddf9f0b0f3e56d1359034aa10653a4d11564c697f802b4775766/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a", size = 276543, upload-time = "2026-08-15T08:16:29.399Z" }, - { url = "https://files.pythonhosted.org/packages/32/cd/4f564b8f132de25db594efc706897069f016790cea63a5669c9df2675f64/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3", size = 261644, upload-time = "2026-08-15T08:16:30.722Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e3/38b975422534a608f98c360e79c2f07c763d66dd4272300d45fb1fee54b0/charset_normalizer-3.5.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb", size = 259609, upload-time = "2026-08-15T08:16:32.248Z" }, - { url = "https://files.pythonhosted.org/packages/87/bd/fbc24d825c66f1c74f6ccdea3742c3d8354a4888e86d1315a197fee69061/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f", size = 252457, upload-time = "2026-08-15T08:16:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2d/918d0e98a0e679469ed05bb2d90c2088b4d315bb612969d8499f76fb5210/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea", size = 242240, upload-time = "2026-08-15T08:16:35.396Z" }, - { url = "https://files.pythonhosted.org/packages/20/c8/c36f6e0b2dfec351bd38cbc05362697e58bcd073d7dbd95154290c9714ce/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f", size = 280308, upload-time = "2026-08-15T08:16:36.825Z" }, - { url = "https://files.pythonhosted.org/packages/ca/7b/311b3e02e8c4092400c449c850a760d8c45d900983c83a70cc07208c551d/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182", size = 258679, upload-time = "2026-08-15T08:16:38.22Z" }, - { url = "https://files.pythonhosted.org/packages/b9/90/082cc45599c392f28c036a497f49e0634041a785fc3849c80ccf396d096f/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa", size = 277221, upload-time = "2026-08-15T08:16:39.62Z" }, - { url = "https://files.pythonhosted.org/packages/58/ad/b9aecf38d805cbcf84fa94f14c5d972a16561e20296a11dc799a5dcf3763/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818", size = 263799, upload-time = "2026-08-15T08:16:40.885Z" }, - { url = "https://files.pythonhosted.org/packages/b7/23/b38a20598d5a825f85d9d7636860e56ff0db1479f86497a6e485aa9326f7/charset_normalizer-3.5.1-cp310-cp310-win32.whl", hash = "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20", size = 182037, upload-time = "2026-08-15T08:16:42.198Z" }, - { url = "https://files.pythonhosted.org/packages/d2/21/83fffb77864408b8bf0fe1ca603926401d6f8775a8e150b39aacc9958f8a/charset_normalizer-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d", size = 206030, upload-time = "2026-08-15T08:16:43.787Z" }, - { url = "https://files.pythonhosted.org/packages/86/2e/b93135b5034b1157fb29554b0d06d4844ce62282f0e0a14036f93d7ee2e7/charset_normalizer-3.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5", size = 185092, upload-time = "2026-08-15T08:16:45.177Z" }, { url = "https://files.pythonhosted.org/packages/6a/b6/034f6802e9c3f6418966cfabb7db8c9252cc2429c5098f41cc43af804149/charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30", size = 363585, upload-time = "2026-08-15T08:16:46.646Z" }, { url = "https://files.pythonhosted.org/packages/d5/fa/6a7e2a7c4b5451912b8c417732df79574354443592a88d616de03da66ae5/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488", size = 251189, upload-time = "2026-08-15T08:16:48.287Z" }, { url = "https://files.pythonhosted.org/packages/a4/c8/ab42b07cfd82e919f427fcfaa7c41abae8242833ad1aad66d42bae40b669/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22", size = 239724, upload-time = "2026-08-15T08:16:49.67Z" }, @@ -287,20 +262,6 @@ version = "7.16.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/65/2d/c738872f477f5687152acae68635790387425d407ae37dd3d3a8a6692307/coverage-7.16.1.tar.gz", hash = "sha256:f83981779bcf9dfa06fa0a8d4cb43e0faec1706328ce07aa3e7b665b4ac0f210", size = 969651, upload-time = "2026-09-13T19:12:21.422Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/62/a8b4dd53308a4b1571e6bdd77ee562c9b1c1742db9886c0aef2f69463067/coverage-7.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4f12a9e27ca7b65e40a8475d27899b2d45064d9020e6a89148939e01987b5853", size = 223178, upload-time = "2026-09-13T19:08:21.805Z" }, - { url = "https://files.pythonhosted.org/packages/5e/7a/b9325b8d486a5c05fd4a9eb1cd9c9f697c361ddeda0e73567d5c2d8959f6/coverage-7.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f590d46c30d9e4c1fda3efefe5443f4c2f6a4192c5ca2ba403653e9ebadf097", size = 223701, upload-time = "2026-09-13T19:08:23.391Z" }, - { url = "https://files.pythonhosted.org/packages/ef/ee/3ab3ac6e9e7165a623695b73a83d1bfbdf5069681a68a012cb5abb096060/coverage-7.16.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3df82f0a3cef4e1bcfc799436056f0b978dda319d0bfd4460c6e479b2802d98a", size = 250434, upload-time = "2026-09-13T19:08:24.948Z" }, - { url = "https://files.pythonhosted.org/packages/b6/a9/31ffc231e9879876f611cf1ac7622cf092d76762c07ca64dce47b29a200b/coverage-7.16.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb462d59146656e278d1e8ed913ce374d0ba68a4e081acde1867f6d3377fc881", size = 252264, upload-time = "2026-09-13T19:08:26.734Z" }, - { url = "https://files.pythonhosted.org/packages/c9/f4/4fb4f6b16de07dbae3d3a111ae28d32ad657ce6ff4d364c49c10962daad5/coverage-7.16.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7db888dd0a1df1a653cae7f99d4047430d2187a3626eda51bc847b0fd6b9b43", size = 254127, upload-time = "2026-09-13T19:08:28.254Z" }, - { url = "https://files.pythonhosted.org/packages/9b/3d/048e88eb610f44b7542dac10fa45bb2ffad5fbfcdab0f03289a843da934b/coverage-7.16.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:38a7e16f061504ac2b45370bf5bf97e8250d8d3f25e37385bae884978166554b", size = 256043, upload-time = "2026-09-13T19:08:30.019Z" }, - { url = "https://files.pythonhosted.org/packages/97/59/d27b113c80b04c7fc64c69457132648e1d287b83a1de41189a504b50b52b/coverage-7.16.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2b26b55b18e1a53e1a159dd743728c4ddbbef28ba19000a91aaff5ce023197ec", size = 251092, upload-time = "2026-09-13T19:08:31.57Z" }, - { url = "https://files.pythonhosted.org/packages/45/42/b7eafaceff08dc1dcbfc924fa9233031fd00c8b8287cc4a1a0dcdedcb0f9/coverage-7.16.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fdb2f528b50953e29d22033b3256c396a700193c6e45b2490222ef9c333cbbf9", size = 252170, upload-time = "2026-09-13T19:08:33.191Z" }, - { url = "https://files.pythonhosted.org/packages/7c/8f/57dcc5360aa6d8d24370c12fe855f6ebf5fbf2718c154fb9fdec7161de07/coverage-7.16.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3284754371dc78592aa3ae4d661d30ee20e02b2b6b0de3590a181a936d0d3b38", size = 250173, upload-time = "2026-09-13T19:08:34.75Z" }, - { url = "https://files.pythonhosted.org/packages/10/bf/379a8c7ac0f3063769dc43fd2475e9fc9b2722cb88eabe71f4d862660c93/coverage-7.16.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:802d1246c540e07486d4ee1adfa19a797e4b33529ffc371dc140644e8f27da0a", size = 253986, upload-time = "2026-09-13T19:08:36.737Z" }, - { url = "https://files.pythonhosted.org/packages/45/25/70218d2a6077730843b75ee2525fa64a750283d71cc4c063dc0b75ba6979/coverage-7.16.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:6fc735d6fe6d57f803e7ba021be4dde48e43e6aff94e6954350555d5332b0594", size = 250444, upload-time = "2026-09-13T19:08:38.434Z" }, - { url = "https://files.pythonhosted.org/packages/58/ac/6c41c441baa6c8a1fed5615e4e1e7d0ca649b33b472ee28591a92d70a1ff/coverage-7.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ed5ade1bb18f62edace1bd198c66f9d4c75a8385d5fd24e87d917ea1a5958773", size = 251046, upload-time = "2026-09-13T19:08:40.133Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f9/01166d6f8aa42acd148b4c2c88173d60eefdd0270ea2bcbba79be35bc193/coverage-7.16.1-cp310-cp310-win32.whl", hash = "sha256:0c309096926b119543dc16438a11ef4c80783d2f4e59ff94f7f462651a944cdc", size = 225242, upload-time = "2026-09-13T19:08:41.672Z" }, - { url = "https://files.pythonhosted.org/packages/d2/28/a76060478919becf0fbea2df2053a6e1a7195f11edf8dfd51c58c1636b43/coverage-7.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:7562f8067ed9360e8b9739e5703403a7686dd1b36bf0f89fc538047c54cdea90", size = 225868, upload-time = "2026-09-13T19:08:43.22Z" }, { url = "https://files.pythonhosted.org/packages/af/3a/d09495dfd5191b5593852bbe2f037afae768157443378d066d9ecea69a49/coverage-7.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72e013665e25cf9d44779f01f340af26319756f9a76822b7c94ce6b1d93813da", size = 223307, upload-time = "2026-09-13T19:08:44.914Z" }, { url = "https://files.pythonhosted.org/packages/a3/34/310196a80258e28ebf6e5aa814a5a6ffbb18c03cf3c0c0c04191ed893e88/coverage-7.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb05c0ff98b56ba6969adf35556bc43bcb8d094df8bc9cb403acff53460c4e07", size = 223817, upload-time = "2026-09-13T19:08:46.738Z" }, { url = "https://files.pythonhosted.org/packages/73/29/ed0fda1fcd440cdfc07e72a07f3c9c3b43f65a6b3d53bff2cba9b9de50e8/coverage-7.16.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0d0ececb32090e3fbb03e0d352b973a0485879b4de6c58daf47227b9988b99e5", size = 254222, upload-time = "2026-09-13T19:08:48.358Z" }, @@ -421,18 +382,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f", size = 11298, upload-time = "2025-10-30T08:19:00.758Z" }, ] -[[package]] -name = "exceptiongroup" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, -] - [[package]] name = "fakeredis" version = "2.38.0" @@ -440,7 +389,6 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "redis" }, { name = "sortedcontainers" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/bf/6b/ad7db311fea3a62f7e359720cc8c064f06f8f0006e65272f50d3a23d37f6/fakeredis-2.38.0.tar.gz", hash = "sha256:d2abfd24652f86501044499bf08c9d639db050f695eefc06b8b8b6f0bb24dbd6", size = 271116, upload-time = "2026-09-08T21:15:04.806Z" } wheels = [ @@ -509,19 +457,6 @@ version = "4.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/59/d1/67b4c46b71039f4895fb757bcc257c301161782f353c0e3a901bec164ccf/libvalkey-4.1.0.tar.gz", hash = "sha256:b88231e09600909723cd07949982cc7758298027d86504d948a223075f0022f4", size = 118634, upload-time = "2026-07-18T18:44:07.266Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/64/34213df07741dc16e51ec413247831f3802b203d6d46fa4454c609360ccd/libvalkey-4.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:332a54420a9ca2f329a86aee8b5a2ade30db1b7201fbe8b4f9ea3c060470b1d3", size = 45111, upload-time = "2026-07-18T18:42:10.412Z" }, - { url = "https://files.pythonhosted.org/packages/02/3e/9b2fefe489f185b368e6250294df4913933cd55dbab9eab1665f2d246190/libvalkey-4.1.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:ebc80b361744800c241603c35b31f412f6c2e78ee9282bb5842b07d1e8aa794f", size = 86835, upload-time = "2026-07-18T18:42:11.721Z" }, - { url = "https://files.pythonhosted.org/packages/69/f5/c28c93930bb753f059863c54bed8f122f9ab202e35dcc6fbdeef18ff124b/libvalkey-4.1.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:55a41035de8b21c9f7b94d1bca09080213e9691eb55738baa722f96e66d932ef", size = 47876, upload-time = "2026-07-18T18:42:12.945Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2d/5aa4e52c5386e641e44eecbab7755de4209f22867cf3bc3a883e0c7f7901/libvalkey-4.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:84f0e28e3ad1469ac6619874d525bce4af5b8129190992fceee645071e4d6fd2", size = 177530, upload-time = "2026-07-18T18:42:14.086Z" }, - { url = "https://files.pythonhosted.org/packages/4f/5c/1f051efc74e4ccc220f6c9f174b8cdfcabd7875f64adda8593384fd635e5/libvalkey-4.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:976e99e7ce80907cc8bc95f59614f2c98dd4ac53cc7ba6edf585aee9c1f185cd", size = 188174, upload-time = "2026-07-18T18:42:15.601Z" }, - { url = "https://files.pythonhosted.org/packages/ab/78/1d06fc821279fbea8c1e70a912d7d9847af57033b0aa44f13223514b4a60/libvalkey-4.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1baa41721d05e436f35b3480666d4bf5b44e6e958748ffe966f7820c5ef5e51f", size = 187186, upload-time = "2026-07-18T18:42:16.948Z" }, - { url = "https://files.pythonhosted.org/packages/53/2f/395a0321b2e3ec99953c7358e9b33bfe2c4c203a76400e060293b534e250/libvalkey-4.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02aa894d27c93e121e15c0af77dfddadb578a4210d8dcaab3749e23a724bee7e", size = 179638, upload-time = "2026-07-18T18:42:18.199Z" }, - { url = "https://files.pythonhosted.org/packages/ac/c1/be3c2aa1d6edea6027eb6b31859c02e27d3d51d274a802cd01ec944347c2/libvalkey-4.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3c84396aa9c393ae90fa4beb148dac79ccb4ceca250c24faa468e130e8bbd3de", size = 172955, upload-time = "2026-07-18T18:42:19.531Z" }, - { url = "https://files.pythonhosted.org/packages/03/bb/d40faab193a8229536e5ed767b2b73238bee690519d20212a30444728c59/libvalkey-4.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3cee71a6069094e561c5583f9e6e104d8db590f70af3d22180eaa7faace64edb", size = 183372, upload-time = "2026-07-18T18:42:20.835Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d6/2724ed818a31889ce45b3af2b5cb15239d5e786f1871f994bc3905bd1b9e/libvalkey-4.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fd0f6176e30137c96fb2a5d2908577d56e855f869ac43446e52409f9d38a0943", size = 177450, upload-time = "2026-07-18T18:42:22.196Z" }, - { url = "https://files.pythonhosted.org/packages/e6/f4/6841b1f33b357a5909d82e3368c09b432b512f837334b2899a16401eed7e/libvalkey-4.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ef6f6c3edcd014b006cc6f15868adacc728291c12d38a09c8ec4fe1ac83f0e3a", size = 175397, upload-time = "2026-07-18T18:42:23.51Z" }, - { url = "https://files.pythonhosted.org/packages/25/e3/5986b81adb963fa24d8d9365f6b8502b9ceda3402a697888ef11950b2088/libvalkey-4.1.0-cp310-cp310-win32.whl", hash = "sha256:4b348a17cbd0200de6e99bfe8bc1b56d102c7c16c8486de3a559ddfc5faf8dac", size = 35415, upload-time = "2026-07-18T18:42:24.939Z" }, - { url = "https://files.pythonhosted.org/packages/d3/0c/2ae3ee1b7d6d2b70524eca5f3ca46a72b1378ee959312630dc2915420cf1/libvalkey-4.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c313516769c0f21ccd21e14afb4a44aa1b33bdfe6772d9c431bc4dfe3c6b7e5", size = 40403, upload-time = "2026-07-18T18:42:25.959Z" }, { url = "https://files.pythonhosted.org/packages/f7/53/093d5a868391558eeb57be6934e75e661d4c415855b952a279b632fa5932/libvalkey-4.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef2fd872635a0ee9442de51219dfe60578178101e6583d756c9043e5afb19422", size = 45106, upload-time = "2026-07-18T18:42:26.979Z" }, { url = "https://files.pythonhosted.org/packages/7f/17/348afee56fdbf8c065be076f40f4b4aef938f2e5b65e7cfc9759d2b76816/libvalkey-4.1.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:3af97968ce0020b45144f980d7ae17e913f5da6f59b6e08263521357481c006c", size = 86832, upload-time = "2026-07-18T18:42:28.352Z" }, { url = "https://files.pythonhosted.org/packages/10/11/dc8029b1c836767b1528ef751c7a4a0bf3cf39c9355fc7559ffdd89de3de/libvalkey-4.1.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:6169de7163705824874e7073cce81cd204b4230a8368ca78227db1653ae7f182", size = 47879, upload-time = "2026-07-18T18:42:29.443Z" }, @@ -595,22 +530,6 @@ version = "6.1.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/23/ad/28ecd7cb894d172f3c9c80a075eeeb2017ac62e3632cee05a5f9493547eb/lxml-6.1.3.tar.gz", hash = "sha256:45222d94ddd511536f3b2f7d9deae3b2339b4ce0f075f1ca25703b07cad9dd21", size = 4211198, upload-time = "2026-09-02T14:48:02.287Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/6b/a7d5c08e19a8e69887ed722fffaefdbaffc8959d5ef5c370a65e52c895ac/lxml-6.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:40bcbd9f94166ffe925811e730607385cec959f42fb1bb7dad83748680465221", size = 8575497, upload-time = "2026-09-02T14:46:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/96/dd/c25a32f9f6039a96cfd52296a4630075868aa16e71858b3076699a059201/lxml-6.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:05f5bce9af14fd1506997594bd81cee6d9c6b58ea80a39c058327aa6371ed9e9", size = 4619233, upload-time = "2026-09-02T14:46:08.898Z" }, - { url = "https://files.pythonhosted.org/packages/3e/f0/d49375a47644369d84f90a9fe4ff1924faad58d4f95563831eca84ca29ae/lxml-6.1.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff88a92cafde90888511242d1c54afcc1a8adbb6dc0a88fa7f87e29e92400d4a", size = 5015387, upload-time = "2026-09-02T14:46:10.797Z" }, - { url = "https://files.pythonhosted.org/packages/76/0f/d1b1f52925442f7b4b1abd81a41905987322f6df6a5dd42fab8579415828/lxml-6.1.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c00e26288784460885fe76e4d4b293573e0f791f52e6d60e27b42edf005922eb", size = 5168571, upload-time = "2026-09-02T14:46:12.989Z" }, - { url = "https://files.pythonhosted.org/packages/b2/13/e5d8291a68a27e564e4e1eefba08c3844c6800bcb43f3e72a32b20971132/lxml-6.1.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:773062aec2f2e56b2b22d37054123f0de8a22a4688a0c3376c3fe42685f975cf", size = 5068024, upload-time = "2026-09-02T14:46:15.325Z" }, - { url = "https://files.pythonhosted.org/packages/a1/ce/dbea34cd115ae9b8ef53816daa912563615adf4daed42531878a2fb29c77/lxml-6.1.3-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6449672f9c93316deb5e2839e18931f468670e44d5bd9b1301a5a9655d45c07", size = 5296830, upload-time = "2026-09-02T14:46:17.52Z" }, - { url = "https://files.pythonhosted.org/packages/20/f6/12a2ab6e8c8afecb82a3f0e9a518952b6a1cddf405ad8542883bd71e6096/lxml-6.1.3-cp310-cp310-manylinux_2_28_i686.whl", hash = "sha256:ec295280f4b37769256da025acf5890370355ac589c27e89caae0b5e9eedc702", size = 5424696, upload-time = "2026-09-02T14:46:19.706Z" }, - { url = "https://files.pythonhosted.org/packages/02/3f/5670e198266c764595687a234fdaed33837f487b95a596262b2548e48933/lxml-6.1.3-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:5929d9df5e7e3379183be0e21f7d559618a5b61cb63280df6164019242e337ed", size = 4783635, upload-time = "2026-09-02T14:46:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/70/24/007ce6b7bffb61a6ca88c3a8f21b26f3f0aa3b3f6bb648a56e328c994a14/lxml-6.1.3-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6e1eb8a4cbffd5553680ad96be6680e364710656eced73d1dc90ec489df599a3", size = 5373212, upload-time = "2026-09-02T14:46:23.572Z" }, - { url = "https://files.pythonhosted.org/packages/4e/00/cf09f38cf9005bd5cfa4fd452b03b290b1c48c403fe0319a8013f4b3cae0/lxml-6.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:16148acd77ed1d8836a56db883af2f5eed720f9723088110b16a0d08582130a6", size = 5116476, upload-time = "2026-09-02T14:46:26.262Z" }, - { url = "https://files.pythonhosted.org/packages/15/83/eb021e5db4336f0bb1438cba6f053ea135aa00b9f4ef0439473d6b986308/lxml-6.1.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:23c366231259cd75ad06495174701afb3fcb36a92917fa47de2d1f1bd9d95739", size = 4814172, upload-time = "2026-09-02T14:46:28.3Z" }, - { url = "https://files.pythonhosted.org/packages/c8/4e/147b6f9088cc191713249ac547b0af2fece489c8cdff1f2801ab47dda8a9/lxml-6.1.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:da85db328e507da922d586c3c7416ec360ec22e9cd9e0700691afacde0c81f53", size = 5361711, upload-time = "2026-09-02T14:46:31.035Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d9/8cfdac0d7d771e25af2c1f4bc874032f025a4b59e0b6917c3c7858070795/lxml-6.1.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0f17d83c48ee9dfd96abae3ac3e2108c76d2fc86ce96355e37b8da9f7f4ecc08", size = 5321598, upload-time = "2026-09-02T14:46:33.165Z" }, - { url = "https://files.pythonhosted.org/packages/f3/5b/d2413c71f312dccdd07ed985be356657fc624d822ba7e2c87e8722646156/lxml-6.1.3-cp310-cp310-win32.whl", hash = "sha256:7dd624c1eaa629ad44b59a1a0145fdf2d67895592dce94c9358b938b3d075e65", size = 3604471, upload-time = "2026-09-02T14:46:35.245Z" }, - { url = "https://files.pythonhosted.org/packages/7a/bf/74b6785beac6488fd395e78796339bc197fbad6fd6103b41b15a4009dc4b/lxml-6.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:18a4db52b5a7b53a3540b0b0f4123319334621ee8083d496de314d0bf06ff59a", size = 4029086, upload-time = "2026-09-02T14:46:37.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a5/ddf6e1744cd76fc9f0ce11cb16b117d6eaac46ebaeca01968e9014e8770c/lxml-6.1.3-cp310-cp310-win_arm64.whl", hash = "sha256:0feebef8d0521188d0157f758356072e840173aa61ca45b8b3f87959ac283dd5", size = 3674608, upload-time = "2026-09-02T14:46:39.802Z" }, { url = "https://files.pythonhosted.org/packages/96/f1/95133bde7af7afb1f5ba6090b674d826b7a518318bba54bbbb633b27865a/lxml-6.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c66f858b82497173f73366795fc6ee8171620e75a338506d6b2e7bc16f5fca11", size = 8563141, upload-time = "2026-09-02T14:46:42.334Z" }, { url = "https://files.pythonhosted.org/packages/80/54/5a79ee2181ac773ee13e48205411845feec69e1c3d097e985c1343171712/lxml-6.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:032a0a97eed428bd143c75a11118238546424ceb2fa311cca5f073aa44658dc4", size = 4613690, upload-time = "2026-09-02T14:46:45.253Z" }, { url = "https://files.pythonhosted.org/packages/ab/29/8c24672f56807f119312f073f24204368574bd16b384ede861b5104b3a2b/lxml-6.1.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4a579dfb9c835f8ab47f4b8ed33440cbc75b806b73297208e6ec2a33e903740b", size = 4935630, upload-time = "2026-09-02T14:46:48.071Z" }, @@ -729,12 +648,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b8/d7/ed6ee6186a89e69ca4ea9658b2a278f46a5efe8b5d4db56c7197f18653fe/lxml-6.1.3-cp315-cp315t-win32.whl", hash = "sha256:ace1d2c83b2bd24db5940600541140e87a325e119cb32d5fa9ad720d7e76648e", size = 3901093, upload-time = "2026-09-02T14:51:37.234Z" }, { url = "https://files.pythonhosted.org/packages/67/9d/11d10257a4a048d04195d638bb61f0246ce2448eb05f682bcbab25a257a8/lxml-6.1.3-cp315-cp315t-win_amd64.whl", hash = "sha256:b49638355ea3bebba70da783ccbc630fd72afa16bc46c54474bfa1f9a915bbc6", size = 4395446, upload-time = "2026-09-02T14:51:39.884Z" }, { url = "https://files.pythonhosted.org/packages/f8/b7/44edd7de434181c582892e68d1ffe6775ca403ce14aea07cb5a218a936cf/lxml-6.1.3-cp315-cp315t-win_arm64.whl", hash = "sha256:5a721a98c649855963811b59b55755b30566e7f7fc40bdc9803d66dee9f811cf", size = 3822836, upload-time = "2026-09-02T14:51:42.471Z" }, - { url = "https://files.pythonhosted.org/packages/ad/23/dc1fdf3a53f84ca88b6e942277ddb47954844a0ececea8cc5fa3c1324831/lxml-6.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4b061064b4a2fe8598a466d723d43dbcd5a610a5d5cfe02fb6226f5c17349f75", size = 3947704, upload-time = "2026-09-02T14:46:22.27Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ed/e36d547d6c958b5693b873504735cb4d0388d545945d66a7aed8983a720b/lxml-6.1.3-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8499d464de86fab0f102313cce32a9bed9ab1f06ec813cf025cb790964fbb765", size = 4220149, upload-time = "2026-09-02T14:46:24.907Z" }, - { url = "https://files.pythonhosted.org/packages/98/54/7f51e6b6cc0755f9b5fc6637748279e9f48289d917b3a47ac9fedf3318d3/lxml-6.1.3-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9e67324961ac9bbe616cce5100514d2e34d88665aeb07071e8b16eac55d06d94", size = 4329391, upload-time = "2026-09-02T14:46:27.111Z" }, - { url = "https://files.pythonhosted.org/packages/eb/9e/840b0d2e25c10c491b010d555b46e6e5264d3ad73a91557405fceb738c35/lxml-6.1.3-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d12669a2c419b0e8dc423d23dea24bb82f6f9cb829f32e04674b0ba40322a7c", size = 4262125, upload-time = "2026-09-02T14:46:29.199Z" }, - { url = "https://files.pythonhosted.org/packages/69/8f/42a41571dfc772c12628747f883d24c978053856825b99d7a187117b8079/lxml-6.1.3-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97acecb11cbc411473f15b8d780df06d7a9f3a2aad9aca78364f56640c8fb70e", size = 4410104, upload-time = "2026-09-02T14:46:32.102Z" }, - { url = "https://files.pythonhosted.org/packages/f3/aa/27d93812be916f1f674b2035edd86d41c77745ff2ad84f58c25a7445a397/lxml-6.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f8b9c8ceebae6387d0dc77f7f4dbbfbfc962dba2efbfe6877486075a480726b4", size = 3510724, upload-time = "2026-09-02T14:46:34.122Z" }, { url = "https://files.pythonhosted.org/packages/ec/c1/2433176de263cc3f51fd2c303f993d5bb7f1da3139a0f7d168116c0bfa7a/lxml-6.1.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d2765c18ce303149ee804b1f3dad11232726dd0a702d73a15cf19179ac8cc962", size = 3942969, upload-time = "2026-09-02T14:46:36.55Z" }, { url = "https://files.pythonhosted.org/packages/7c/71/de7759096f480180fd9e43ff7c017860e2d2a9a43741ab093cbdf1820f07/lxml-6.1.3-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d5a748d12dd9b535e0a130f60dae9ddf0adafbabe61e7864f55c7436c84547a", size = 4213008, upload-time = "2026-09-02T14:46:38.784Z" }, { url = "https://files.pythonhosted.org/packages/b8/9b/c2d09af47a34fa6c0c27473083812b449a411680bd04bbe609cde291ddc8/lxml-6.1.3-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:41096ec0740a58dad03d3ae0c7486d306d20becefb13ceb1649835ab3eb64167", size = 4322012, upload-time = "2026-09-02T14:46:41.031Z" }, @@ -743,77 +656,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/5c/91fe48856f9f8089be3096fa4dbe4b3fb5526f3bf3e852ea9497f399cb9f/lxml-6.1.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bc8dd3d9c93e70c3df974a201ac2958b6d77b465d813c51d1f15fa8e645763ae", size = 3511258, upload-time = "2026-09-02T14:46:49.046Z" }, ] -[[package]] -name = "numpy" -version = "2.2.6" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, - { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, - { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, - { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, - { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, - { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, - { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, - { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, - { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, -] - [[package]] name = "numpy" version = "2.4.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*'", + "python_full_version < '3.12'", ] sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } wheels = [ @@ -977,8 +825,7 @@ dependencies = [ { name = "iroh" }, { name = "jsonpath-ng" }, { name = "lxml" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "orjson" }, { name = "paho-mqtt" }, @@ -1039,15 +886,6 @@ version = "3.12.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0f/f3/742fb1f62b825f2c010697eaf4e828004bc2a81e7e806666989c132c7c42/orjson-3.12.0.tar.gz", hash = "sha256:d14203fb1aae2ad9b3d52f8a0e82aeb10197ef1c9bc61da7f358bd70b00123d5", size = 4142915, upload-time = "2026-08-14T16:13:30.607Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/35/819eeb4fa8ee676d38fdbb8213a76fd496f7dbbfdfafa89d34e02b22dfac/orjson-3.12.0-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:747843254519dd43b93eee3153a19e5a509334320c4d2f823ec879232db5c796", size = 224133, upload-time = "2026-08-14T16:12:00.607Z" }, - { url = "https://files.pythonhosted.org/packages/58/ab/d9221d4a2b085b073fcddc91728d490f20b9cf010c62c2f42371ab997695/orjson-3.12.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.whl", hash = "sha256:7c2ad193c8004254f34b499f3bd2c80f043d10754aff2b38f93da574f4883f98", size = 113669, upload-time = "2026-08-14T16:12:02.126Z" }, - { url = "https://files.pythonhosted.org/packages/15/12/644cbbcabb26df61d9ef0c66e6f2bf8b687cc7b66137597f2858951f1952/orjson-3.12.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:bc7a872f03522d90e0429e6c0c5cd23084f767bedcb4c58048eec19294613344", size = 130410, upload-time = "2026-08-14T16:12:03.503Z" }, - { url = "https://files.pythonhosted.org/packages/14/6d/e3a8c34d687895aecd8b267a01c46106eb98d8424a83bfa7bacb723854f6/orjson-3.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18a87929f31d94a77f7dc93cf527e91f39ce7fe7813d588a4de2507efd32a387", size = 131101, upload-time = "2026-08-14T16:12:04.918Z" }, - { url = "https://files.pythonhosted.org/packages/75/20/930824c07685c22af23f26818ed3853b0270488a412b6ab757904b7f787b/orjson-3.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9683ee9ea0659da64f36574ef675b8a86330c34c19ea75db1fb93c3ff99e0ef", size = 131479, upload-time = "2026-08-14T16:12:06.11Z" }, - { url = "https://files.pythonhosted.org/packages/4c/a6/22e863bbbe8917aa292e33e0db597000f9a07eb5e6f52efed623fa16bae1/orjson-3.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:103b5db66aa53c1f9e88c2524be4f383e831ba7dfd5f9f5af6336a177c622f11", size = 135865, upload-time = "2026-08-14T16:12:07.392Z" }, - { url = "https://files.pythonhosted.org/packages/50/a0/ceb5008914a65e9a19a46a09d94bc67a74d120209fdfa772750023ceb377/orjson-3.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd57d79aefa3f84eec851d6de7a366795b9345cfaf17f82b4820430a7a5fa241", size = 127843, upload-time = "2026-08-14T16:12:08.607Z" }, - { url = "https://files.pythonhosted.org/packages/12/3d/61c6b3b84c250cb09cb7229701ff77e4d763773ad7f577d0b6abf2892664/orjson-3.12.0-cp310-cp310-win32.whl", hash = "sha256:3dbce9b6b3074b31a5d5dd322a9c4e5b16f206091ece4194c2e36952847a105e", size = 128293, upload-time = "2026-08-14T16:12:09.819Z" }, - { url = "https://files.pythonhosted.org/packages/ce/0e/ea0f4a563253b6363195a4f704123c6bfbf156641bd3be5a75de81c5e917/orjson-3.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:3bb17a06f9bd15237b3216c044209fe92597379124018cfc196fbb846cde64df", size = 122216, upload-time = "2026-08-14T16:12:11.261Z" }, { url = "https://files.pythonhosted.org/packages/75/1a/a7075a8e8b0d3f5097d17ac3099017104b6b7b42012041147995d5b2da05/orjson-3.12.0-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a94f0f0c6fcbb2b5bd9734c57a489c7584a732bbdf04a39e8c83b861e9d03e92", size = 223409, upload-time = "2026-08-14T16:12:12.654Z" }, { url = "https://files.pythonhosted.org/packages/05/34/c2eb3b2900e5597db7841a4c6416ac2d90081bd956b02d4dd1833fa2b96b/orjson-3.12.0-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:a696529ec96a90d9a5f9570207efe403c8b08f8e4aa2783ee3403511e2fdfa10", size = 124015, upload-time = "2026-08-14T16:12:14.025Z" }, { url = "https://files.pythonhosted.org/packages/1c/df/b49081766a75b6a37b3d33bdc0a39e492abab8441dd25e3e1998e7b83fcb/orjson-3.12.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.whl", hash = "sha256:e4ac5059baab4b3acbd99485de019ff8cda0fdf34b61fa74f7197a53db78bfe8", size = 113471, upload-time = "2026-08-14T16:12:15.81Z" }, @@ -1158,17 +996,6 @@ name = "psycopg-binary" version = "3.3.6" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/92/00350a66de0af05e41d01aa3134e3970045e816afed3f99d58ec1abe15b2/psycopg_binary-3.3.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7beb3e41c9a1e509f3ed85263386588cbe3e975aa67be21f79f44fd35ffaeefc", size = 4728682, upload-time = "2026-09-18T13:15:36.605Z" }, - { url = "https://files.pythonhosted.org/packages/91/fc/afa9c7fd316a469af7ede6ebb020eac482f5d827fae57d5310c9bc0c41ae/psycopg_binary-3.3.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa73160077345ec21b3f51e8e24b3de2e99586217e497629326eb9b2ea88c52e", size = 4777111, upload-time = "2026-09-18T13:15:46.566Z" }, - { url = "https://files.pythonhosted.org/packages/f2/44/7c1e015f1bc56b36ff1369f09e852b2d83ccefd5a669a42633a916cdedc4/psycopg_binary-3.3.6-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f87dbdc42e78ee0f7ea180c03f8c78e80a949e373066629bd90fefff10552dff", size = 5592755, upload-time = "2026-09-18T13:15:52.886Z" }, - { url = "https://files.pythonhosted.org/packages/3b/ae/314a251ca918cdac380bce1b87839ade9355382ea749e6ef3ba75ba0c09f/psycopg_binary-3.3.6-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a9348c5b43a3bb5ef8c2e89d5237c9c87eeafb01d338c84a7aebbc5cd0313299", size = 5267949, upload-time = "2026-09-18T13:16:00.53Z" }, - { url = "https://files.pythonhosted.org/packages/b6/9f/3bb0cfe9bb0f31ca57cf486ddc8c9ac51251aed8181bf88ff870b2623105/psycopg_binary-3.3.6-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a52991594ac4db888c7d39bccef331797e30cb31a95cae02cf2607f83a42dc2", size = 6862403, upload-time = "2026-09-18T13:16:10.385Z" }, - { url = "https://files.pythonhosted.org/packages/c4/d6/7032c10309c3155e9b24300fdcc9a1afa539cfd20ce52fdef74a46f10161/psycopg_binary-3.3.6-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ea8beeb5541780b4b50b462eeacbc4f594ce3b911dc20c81c75f267876f71d2", size = 5107271, upload-time = "2026-09-18T13:16:16.843Z" }, - { url = "https://files.pythonhosted.org/packages/61/cc/79add2cf92684cf1a81da134b32caa662c25c72d0cc905d181ef4455f834/psycopg_binary-3.3.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:198a48e68cc99ccac03ba95ac857e73aa66f3bf6be77019fafb0832a05f7ad03", size = 4627984, upload-time = "2026-09-18T13:16:23.889Z" }, - { url = "https://files.pythonhosted.org/packages/c9/48/6dfb14f9350c14af6a2edb3c31262051b8cd94e2186e4b831e46dbbe8cd9/psycopg_binary-3.3.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fa34eb47969297471db7b7f193622c7e3ee839ec05abd05f1fe104d5b1b1dcf4", size = 4322054, upload-time = "2026-09-18T13:16:29.33Z" }, - { url = "https://files.pythonhosted.org/packages/29/35/2982338716a91cbb4dfc866be015be4457ee8106a445aabf3d1fb6a270e0/psycopg_binary-3.3.6-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:b979a42815410432420275412633960807178b1ce26591a16ce06e78a5bd4bb2", size = 4048471, upload-time = "2026-09-18T13:16:34.119Z" }, - { url = "https://files.pythonhosted.org/packages/24/e1/171b1db1542c5f76a678b7ee0a7800bebc9735a0a03417c76cf948bfd63c/psycopg_binary-3.3.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:889e42acec10450185e0cdfb396f375e2c1a8d7737c114830a7fde4654f59e30", size = 4353931, upload-time = "2026-09-18T13:16:38.692Z" }, - { url = "https://files.pythonhosted.org/packages/08/89/4424e62a944eef40bd9326ada4ae23802b28eab6502af91e84ef7bba74fb/psycopg_binary-3.3.6-cp310-cp310-win_amd64.whl", hash = "sha256:cbd5f73073ed19c378d4c35499db1e3e703a5b1a324e521204065967bfaa7a18", size = 3674362, upload-time = "2026-09-18T13:16:44.454Z" }, { url = "https://files.pythonhosted.org/packages/70/86/b71166048974d49c6d136b2ed1c0e5bec0b974d8c4de5cbce7e86a9e412a/psycopg_binary-3.3.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:be4f9b3c9338ac5dd217c5847e21521b396c8117f78dc420d495a5c49bbef874", size = 4728002, upload-time = "2026-09-18T13:16:53.393Z" }, { url = "https://files.pythonhosted.org/packages/12/1d/1e06c0de7ed5aed898acb87544eac6ef0bc7d752a67ec6e5d6b835e9b40c/psycopg_binary-3.3.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f0535693ce476a722b718b002d5d2c27d47e71ca945276ac194409c98e74c492", size = 4775403, upload-time = "2026-09-18T13:16:58.939Z" }, { url = "https://files.pythonhosted.org/packages/84/02/2ffcbc43f8e4bbc38e5286a22013bcac01898d13cd38325f60dd5428a8af/psycopg_binary-3.3.6-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3c9e663b2e800e3218994cf948c11bcc2844e6491b34aa80d089baf6531827bf", size = 5594145, upload-time = "2026-09-18T13:17:08.515Z" }, @@ -1262,12 +1089,10 @@ version = "9.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } wheels = [ @@ -1305,20 +1130,11 @@ name = "questdb" version = "4.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "numpy", version = "2.5.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/15/2a/2480940b8ee3946208d0f15bfd2d8c0fe29dcfbd18ef28a0a87a31c51cad/questdb-4.1.0.tar.gz", hash = "sha256:d899daf474bf66c57dd3f6a8e9bb1f928430b5e5bd115b10bddb418c0330aaec", size = 76967528, upload-time = "2025-11-28T19:50:39.762Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/df/a813d3c617459577b42cd3270b19a1a40ea959e55632db2bf70410c358a0/questdb-4.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:035cd3ea995914cefb0afbd2c5e1da562ac8543b5f65d129392ad855e03bc2d5", size = 3145865, upload-time = "2025-11-28T19:49:26.396Z" }, - { url = "https://files.pythonhosted.org/packages/70/76/ead6fb84f84d016def3504c7290646388a3782cf1b6b3375b0ea99010e36/questdb-4.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b41a572d20e83166d6b6d99fcfd8c6a7669f8cef8f6d7e98587b285aba19fc22", size = 3227326, upload-time = "2025-11-28T19:49:28.135Z" }, - { url = "https://files.pythonhosted.org/packages/77/55/ddba247a0b32ccf5b94651279bb429dd197ed59c49297a6b3a6c4c87fe91/questdb-4.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7106dac082442ebb1b518649651f151db3589e2892fc8a9c082087c02f240c", size = 5569343, upload-time = "2025-11-28T19:49:29.772Z" }, - { url = "https://files.pythonhosted.org/packages/c0/93/38372faa0593678d3ffec213dec180beb46cb4371f80844d51931ecee372/questdb-4.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:7b37b1010c2233dedcfa5641ccc1113e73cc1ac95563827b2bc09f0d5f2a999c", size = 5934745, upload-time = "2025-11-28T19:49:31.528Z" }, - { url = "https://files.pythonhosted.org/packages/ae/ba/c996fde15eb72cc9e2eefb37687052d057fcf1ecf762aa55214bebd6ec87/questdb-4.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91a9720d74d2f79574127762fcbbe192ec2491ea7a5c99463be578c221ff2e82", size = 5595221, upload-time = "2025-11-28T19:49:33.264Z" }, - { url = "https://files.pythonhosted.org/packages/f6/15/73e89a745cad0c0f397aea7bbc5a1ff1e68cddf756a59ea733c5cea517a0/questdb-4.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2785a8d33b910cf4f98dc5b9cc29c3a250e915cc6dea137424fe3671496b51d6", size = 5976944, upload-time = "2025-11-28T19:49:35.114Z" }, - { url = "https://files.pythonhosted.org/packages/2f/c2/aa7dc069526fe9cab188dcebda76c5acb6ca27b9ecaf3e95a1acfd72768a/questdb-4.1.0-cp310-cp310-win32.whl", hash = "sha256:bb4d653f4048d4ff51629038d6a685c4a3cbbd2cff31e47fb8fd022eebbd8528", size = 1741279, upload-time = "2025-11-28T19:49:36.708Z" }, - { url = "https://files.pythonhosted.org/packages/cf/fb/d49fe0a96aa61c9ed8ad1c85bc9011b1a25e1df9b552df196e8998200efb/questdb-4.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:a16513450562f0a7d37c73672645835c18f6b52fdac95accd28a50c48c46424c", size = 2019796, upload-time = "2025-11-28T19:49:38.466Z" }, { url = "https://files.pythonhosted.org/packages/b4/7a/115d4fad3380e54918877f0df4a1272b3113d1d3c6d9d8acb3378cec7487/questdb-4.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54ea64fa965e2392ac085db367b405fdd130fc0b3db1f9cc6087b5c643cadf3f", size = 3146030, upload-time = "2025-11-28T19:49:39.643Z" }, { url = "https://files.pythonhosted.org/packages/0b/a5/24f24c66797ef90dddbdd6c228a5ca385b9e8256e66d4ddc386076b13597/questdb-4.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbe9211d5d8ef4f8ebef66d985a86f8a8c585b311b6720960b8360a185ded310", size = 3227205, upload-time = "2025-11-28T19:49:41.018Z" }, { url = "https://files.pythonhosted.org/packages/ad/2b/5978c3c24818974837e0456d60c5838e3fbb63aea877076de3870d90324a/questdb-4.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5db7bb38055332d06b18e024ea5c55dec72ecebc110b111b89f8f243993e6f7", size = 5626309, upload-time = "2025-11-28T19:49:42.992Z" }, @@ -1353,8 +1169,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/75/c7/d19fdd4edcc91b1f6e66f9dc7c8dfd66967b7b800ca59180c75ef8b2b546/questdb-4.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae54862ac73bcfb7b1d17771693872e04f2659b04180bdf24259f46012b0bb66", size = 3252602, upload-time = "2025-11-28T19:50:26.922Z" }, { url = "https://files.pythonhosted.org/packages/08/2a/b80fc90836c975f26443fcf9e0ab672abfe3f4283c3421456242b46012b4/questdb-4.1.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:b7f9f437f594b88c7e4c6cf9c683c809ecd5f2020446d82be47e4f12e0295cfd", size = 5921142, upload-time = "2025-11-28T19:50:28.369Z" }, { url = "https://files.pythonhosted.org/packages/37/b1/6c22a6c6425c3e7a0d578526db2b8ea2e534f9b4cc3aa6e2f1c5878f6081/questdb-4.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bee0c5df4513e6c30f9d24fd3feedc08f0528b3daa990bed4eb31deebceffa85", size = 5965328, upload-time = "2025-11-28T19:50:30.107Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ac/558f4338a137e5c5a9b4baed8930704edc84815fa12999dac854c36ebe68/questdb-4.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03005857b35a0c2c5f1f984726543a73b3f99cf8606745b098dd8a8863959f72", size = 4536803, upload-time = "2025-11-28T19:50:31.515Z" }, - { url = "https://files.pythonhosted.org/packages/48/22/456d8e667501ef06cef9b972026b9a0794f2f07e1d906b6bf8fc2624a122/questdb-4.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4e3b7575a25b297997c4c2ead91708f2b6a75168e62b2361db2ef9f3a4465279", size = 4883935, upload-time = "2025-11-28T19:50:33.154Z" }, { url = "https://files.pythonhosted.org/packages/c5/09/48ba7f3740bd2df1737f1c321ab3d299747b80e7398d44a20eb9f8d6c7ac/questdb-4.1.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2272624a5645d956b7940733420d4929f8447780f5ae91f681ba6baa648833c", size = 4536068, upload-time = "2025-11-28T19:50:34.939Z" }, { url = "https://files.pythonhosted.org/packages/5d/51/ce9990e6eaf1f2c99928e60f26e18fa47e08b6d4b2f73566e8ed03f6d904/questdb-4.1.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4bb2ca14152c8d04a8a46e04105b47f2291cef17aa69b3c9697fb5dee3fb0728", size = 4883545, upload-time = "2025-11-28T19:50:36.369Z" }, ] @@ -1450,60 +1264,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] -[[package]] -name = "tomli" -version = "2.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, - { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, - { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, - { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, - { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, - { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, - { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, - { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, - { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, - { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, - { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, - { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, - { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, - { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, - { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, - { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, - { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, - { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, - { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, - { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, - { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, - { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, - { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, - { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, - { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, - { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, - { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, - { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, - { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, - { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, - { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, - { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, - { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, - { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, - { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, - { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, - { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, - { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, - { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, - { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, -] - [[package]] name = "ty" version = "0.0.81" @@ -1579,9 +1339,6 @@ version = "6.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390, upload-time = "2024-11-01T14:06:24.793Z" }, - { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389, upload-time = "2024-11-01T14:06:27.112Z" }, - { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020, upload-time = "2024-11-01T14:06:29.876Z" }, { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, @@ -1591,8 +1348,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, - { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902, upload-time = "2024-11-01T14:06:53.119Z" }, - { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380, upload-time = "2024-11-01T14:06:55.19Z" }, { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, @@ -1611,15 +1366,6 @@ version = "16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/74/221f58decd852f4b59cc3354cccaf87e8ef695fede361d03dc9a7396573b/websockets-16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04cdd5d2d1dacbad0a7bf36ccbcd3ccd5a30ee188f2560b7a62a30d14107b31a", size = 177343, upload-time = "2026-01-10T09:22:21.28Z" }, - { url = "https://files.pythonhosted.org/packages/19/0f/22ef6107ee52ab7f0b710d55d36f5a5d3ef19e8a205541a6d7ffa7994e5a/websockets-16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8ff32bb86522a9e5e31439a58addbb0166f0204d64066fb955265c4e214160f0", size = 175021, upload-time = "2026-01-10T09:22:22.696Z" }, - { url = "https://files.pythonhosted.org/packages/10/40/904a4cb30d9b61c0e278899bf36342e9b0208eb3c470324a9ecbaac2a30f/websockets-16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:583b7c42688636f930688d712885cf1531326ee05effd982028212ccc13e5957", size = 175320, upload-time = "2026-01-10T09:22:23.94Z" }, - { url = "https://files.pythonhosted.org/packages/9d/2f/4b3ca7e106bc608744b1cdae041e005e446124bebb037b18799c2d356864/websockets-16.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7d837379b647c0c4c2355c2499723f82f1635fd2c26510e1f587d89bc2199e72", size = 183815, upload-time = "2026-01-10T09:22:25.469Z" }, - { url = "https://files.pythonhosted.org/packages/86/26/d40eaa2a46d4302becec8d15b0fc5e45bdde05191e7628405a19cf491ccd/websockets-16.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df57afc692e517a85e65b72e165356ed1df12386ecb879ad5693be08fac65dde", size = 185054, upload-time = "2026-01-10T09:22:27.101Z" }, - { url = "https://files.pythonhosted.org/packages/b0/ba/6500a0efc94f7373ee8fefa8c271acdfd4dca8bd49a90d4be7ccabfc397e/websockets-16.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2b9f1e0d69bc60a4a87349d50c09a037a2607918746f07de04df9e43252c77a3", size = 184565, upload-time = "2026-01-10T09:22:28.293Z" }, - { url = "https://files.pythonhosted.org/packages/04/b4/96bf2cee7c8d8102389374a2616200574f5f01128d1082f44102140344cc/websockets-16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:335c23addf3d5e6a8633f9f8eda77efad001671e80b95c491dd0924587ece0b3", size = 183848, upload-time = "2026-01-10T09:22:30.394Z" }, - { url = "https://files.pythonhosted.org/packages/02/8e/81f40fb00fd125357814e8c3025738fc4ffc3da4b6b4a4472a82ba304b41/websockets-16.0-cp310-cp310-win32.whl", hash = "sha256:37b31c1623c6605e4c00d466c9d633f9b812ea430c11c8a278774a1fde1acfa9", size = 178249, upload-time = "2026-01-10T09:22:32.083Z" }, - { url = "https://files.pythonhosted.org/packages/b4/5f/7e40efe8df57db9b91c88a43690ac66f7b7aa73a11aa6a66b927e44f26fa/websockets-16.0-cp310-cp310-win_amd64.whl", hash = "sha256:8e1dab317b6e77424356e11e99a432b7cb2f3ec8c5ab4dabbcee6add48f72b35", size = 178685, upload-time = "2026-01-10T09:22:33.345Z" }, { url = "https://files.pythonhosted.org/packages/f2/db/de907251b4ff46ae804ad0409809504153b3f30984daf82a1d84a9875830/websockets-16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8", size = 177340, upload-time = "2026-01-10T09:22:34.539Z" }, { url = "https://files.pythonhosted.org/packages/f3/fa/abe89019d8d8815c8781e90d697dec52523fb8ebe308bf11664e8de1877e/websockets-16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad", size = 175022, upload-time = "2026-01-10T09:22:36.332Z" }, { url = "https://files.pythonhosted.org/packages/58/5d/88ea17ed1ded2079358b40d31d48abe90a73c9e5819dbcde1606e991e2ad/websockets-16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d", size = 175319, upload-time = "2026-01-10T09:22:37.602Z" }, @@ -1679,17 +1425,6 @@ version = "2.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/42/a6/6375d56c44d590ef24acf0f8f5bf7ed768ff7a510b959306ec412611e90f/wrapt-2.4.1.tar.gz", hash = "sha256:fd6390aab9e8aa40c52eff3c180f098e8d9f5894b1fd4c4fd2c207067b33ed16", size = 164597, upload-time = "2026-09-10T23:12:16.811Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/45/fe4524dea5a15a6f64522745a96618fb2f874c11c4060848abacc4f85232/wrapt-2.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7aaff952dd6930fc87b52d44bf72ac8426e45e90058fe0f2da446889738eff44", size = 97739, upload-time = "2026-09-10T23:09:36.872Z" }, - { url = "https://files.pythonhosted.org/packages/e2/cb/08025a4402bd6f34ac7c07e4d5c75e4f32e595cd7424d697c6fce1663bc3/wrapt-2.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8d67b916f2f777a6d31067e842598e059f1a0e29022c86454564fc9efb9a0c19", size = 98237, upload-time = "2026-09-10T23:09:38.82Z" }, - { url = "https://files.pythonhosted.org/packages/3c/e9/2c1a482052cfabd6906887096993099afa2db738e7597c30e4f2b9922718/wrapt-2.4.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2945f4bce1518e09eb25458dbd09800f7aa3fee81a5a5cefe66c4e82fe8cb69c", size = 217028, upload-time = "2026-09-10T23:09:40.259Z" }, - { url = "https://files.pythonhosted.org/packages/fb/0d/867f5a1955de8e04edfbdf32891376443629d94c3e31ae2ea2ba101d6d31/wrapt-2.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a7ce62ee24eddb76c317ec790c44f4fbe9f34ee0a5dae37b30c65a2b8f3e3604", size = 219323, upload-time = "2026-09-10T23:09:41.701Z" }, - { url = "https://files.pythonhosted.org/packages/42/21/af01e7d55ce47df290e60cc4c0acccd439ccb95f30be63e46ba013e4f212/wrapt-2.4.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0cbee8d00840ac89846f6567c75506260a15fbb4dc74de180678fafe09458d47", size = 208024, upload-time = "2026-09-10T23:09:43.318Z" }, - { url = "https://files.pythonhosted.org/packages/89/24/9ae249d4922408cb28bc31e8dec86e918350261cf61e38fd8bbfff8bfd66/wrapt-2.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b78dd8d058468156003ee8c212dab334b6eea18cd9c5db3b81f6c90a9408afcc", size = 217712, upload-time = "2026-09-10T23:09:44.739Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a7/34b1e65e490ae886b057ac813e86e16399b7dae91166b5bde5fc9f86c2ee/wrapt-2.4.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4d48f1720569b4f6e2df97783fd270554abc4c6ebd74b2e5f15e5110283aaf78", size = 206245, upload-time = "2026-09-10T23:09:46.07Z" }, - { url = "https://files.pythonhosted.org/packages/bb/e5/8b5af45e8e7dc102b78a40b077f071466a0f584898fe57ce181bbca2572b/wrapt-2.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:de5d2d7f12557c9e994b4037330efa5700fccb9f2b9df0bd4ccf384eaf73c254", size = 206937, upload-time = "2026-09-10T23:09:47.328Z" }, - { url = "https://files.pythonhosted.org/packages/b7/47/06e483462e90a50250f51da3ffa1f1c67e457910078b36aad55805202886/wrapt-2.4.1-cp310-cp310-win32.whl", hash = "sha256:5c0217b8c12952bf4d137a19ff2c61cc9b626f52c09c43f0289769c9f5f808aa", size = 93405, upload-time = "2026-09-10T23:09:48.64Z" }, - { url = "https://files.pythonhosted.org/packages/2a/01/c200bbabb0c46a431c9d965fff78e6bf08c1598fa970bdf105362aeba969/wrapt-2.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:0aacc1af512e040fb0b3c4593a8bded9aaa04235025f08a54eda9d8c1103d3c6", size = 98454, upload-time = "2026-09-10T23:09:49.771Z" }, - { url = "https://files.pythonhosted.org/packages/e3/04/c7eace579b4c397aa3651c550c216b05d3561cff56bcbeb726c8ab3faf4b/wrapt-2.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:6f32a45d0e883918387aabf5384952e5a93ae40be0a6fb5f1eddc8281af4c714", size = 95247, upload-time = "2026-09-10T23:09:51.119Z" }, { url = "https://files.pythonhosted.org/packages/c6/c6/5e08ef1e8ad5ff518354db77b7a303666c7e0652e2a569116b5ccb72b690/wrapt-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b6ea396edcfb305698f44ef0a47b9adaca15d30386ce093ca606844f776d7236", size = 97984, upload-time = "2026-09-10T23:09:52.569Z" }, { url = "https://files.pythonhosted.org/packages/4f/ec/e77ba77fdce732f39522382a6a9b968e5abf3471f352d51670120534e271/wrapt-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b86bfe741840cec6d8d5858b1eb53a325f564f08d7e6fb5694981961edcec230", size = 98241, upload-time = "2026-09-10T23:09:53.72Z" }, { url = "https://files.pythonhosted.org/packages/7b/af/c54bd0bf32ef3c5f6d2d50af6bd9d88c040ef53d9f8e113e065337d76788/wrapt-2.4.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8ec7aeb92e956810eedc268fe75f8c11f05d6c3d864d0995a53eb6623b3b6a51", size = 226167, upload-time = "2026-09-10T23:09:54.946Z" }, diff --git a/scripts/license_audit/license_audit.py b/scripts/license_audit/license_audit.py index e7917429ae..768d8ac79c 100755 --- a/scripts/license_audit/license_audit.py +++ b/scripts/license_audit/license_audit.py @@ -609,16 +609,8 @@ def reachable(roots: set[str], graph: dict[str, set[str]]) -> set[str]: def load_toml(path: Path) -> dict: - try: - import tomllib - except ModuleNotFoundError: # Python 3.10 - try: - import tomli as tomllib # type: ignore[no-redef] - except ModuleNotFoundError as exc: - raise AuditError( - f"cannot parse {path}: Python 3.11+ (tomllib) or the tomli " - f"package is required" - ) from exc + import tomllib + with path.open("rb") as handle: return tomllib.load(handle) From eab2995303f0c2beb3de3db1331743889421aa5f Mon Sep 17 00:00:00 2001 From: Jason Thomas Date: Thu, 22 Oct 2026 15:28:15 -0600 Subject: [PATCH 2/5] Drop python 3.15 for now --- .github/scripts/check_tool_versions.py.lock | 20 ++------------------ .github/workflows/api_tests.yml | 2 +- CLAUDE.md | 4 ++-- openc3.code-workspace | 3 +++ openc3/python/README-DEV.md | 2 +- openc3/python/pyproject.toml | 1 - 6 files changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/scripts/check_tool_versions.py.lock b/.github/scripts/check_tool_versions.py.lock index a8946713cd..d3fd8dc8eb 100644 --- a/.github/scripts/check_tool_versions.py.lock +++ b/.github/scripts/check_tool_versions.py.lock @@ -1,6 +1,6 @@ version = 1 -revision = 3 -requires-python = ">=3.10" +revision = 5 +requires-python = ">=3.11" [manifest] requirements = [{ name = "requests", specifier = "==2.34.2" }] @@ -20,22 +20,6 @@ version = "3.5.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e5/3f/143b048436775b0f76ac3eec145c019e8173ccc2885c8f20319b996d5e83/charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3", size = 171764, upload-time = "2026-08-15T08:20:44.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/aa/554e2614f38fc34c58ff1d0911ae8535ad2516440d5482d76fe59f1088b0/charset_normalizer-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa", size = 369072, upload-time = "2026-08-15T08:16:22.964Z" }, - { url = "https://files.pythonhosted.org/packages/03/6d/439231dfc3ccfa6f8c06477b7da2219cbd41a2de3d49084df8ec7b5100f2/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda", size = 251142, upload-time = "2026-08-15T08:16:24.81Z" }, - { url = "https://files.pythonhosted.org/packages/55/53/7d819bd23a00ef45039146fa2cce1daa2f0771e758c5653ee1f6edac91ed/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45", size = 240714, upload-time = "2026-08-15T08:16:26.392Z" }, - { url = "https://files.pythonhosted.org/packages/b2/2c/45847198c16f4b38090cc7423b2b6a9008e438704d8ab413211832498d31/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab", size = 279637, upload-time = "2026-08-15T08:16:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/69/2b/d8be3523ddf9f0b0f3e56d1359034aa10653a4d11564c697f802b4775766/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a", size = 276543, upload-time = "2026-08-15T08:16:29.399Z" }, - { url = "https://files.pythonhosted.org/packages/32/cd/4f564b8f132de25db594efc706897069f016790cea63a5669c9df2675f64/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3", size = 261644, upload-time = "2026-08-15T08:16:30.722Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e3/38b975422534a608f98c360e79c2f07c763d66dd4272300d45fb1fee54b0/charset_normalizer-3.5.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb", size = 259609, upload-time = "2026-08-15T08:16:32.248Z" }, - { url = "https://files.pythonhosted.org/packages/87/bd/fbc24d825c66f1c74f6ccdea3742c3d8354a4888e86d1315a197fee69061/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f", size = 252457, upload-time = "2026-08-15T08:16:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2d/918d0e98a0e679469ed05bb2d90c2088b4d315bb612969d8499f76fb5210/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea", size = 242240, upload-time = "2026-08-15T08:16:35.396Z" }, - { url = "https://files.pythonhosted.org/packages/20/c8/c36f6e0b2dfec351bd38cbc05362697e58bcd073d7dbd95154290c9714ce/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f", size = 280308, upload-time = "2026-08-15T08:16:36.825Z" }, - { url = "https://files.pythonhosted.org/packages/ca/7b/311b3e02e8c4092400c449c850a760d8c45d900983c83a70cc07208c551d/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182", size = 258679, upload-time = "2026-08-15T08:16:38.22Z" }, - { url = "https://files.pythonhosted.org/packages/b9/90/082cc45599c392f28c036a497f49e0634041a785fc3849c80ccf396d096f/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa", size = 277221, upload-time = "2026-08-15T08:16:39.62Z" }, - { url = "https://files.pythonhosted.org/packages/58/ad/b9aecf38d805cbcf84fa94f14c5d972a16561e20296a11dc799a5dcf3763/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818", size = 263799, upload-time = "2026-08-15T08:16:40.885Z" }, - { url = "https://files.pythonhosted.org/packages/b7/23/b38a20598d5a825f85d9d7636860e56ff0db1479f86497a6e485aa9326f7/charset_normalizer-3.5.1-cp310-cp310-win32.whl", hash = "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20", size = 182037, upload-time = "2026-08-15T08:16:42.198Z" }, - { url = "https://files.pythonhosted.org/packages/d2/21/83fffb77864408b8bf0fe1ca603926401d6f8775a8e150b39aacc9958f8a/charset_normalizer-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d", size = 206030, upload-time = "2026-08-15T08:16:43.787Z" }, - { url = "https://files.pythonhosted.org/packages/86/2e/b93135b5034b1157fb29554b0d06d4844ce62282f0e0a14036f93d7ee2e7/charset_normalizer-3.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5", size = 185092, upload-time = "2026-08-15T08:16:45.177Z" }, { url = "https://files.pythonhosted.org/packages/6a/b6/034f6802e9c3f6418966cfabb7db8c9252cc2429c5098f41cc43af804149/charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30", size = 363585, upload-time = "2026-08-15T08:16:46.646Z" }, { url = "https://files.pythonhosted.org/packages/d5/fa/6a7e2a7c4b5451912b8c417732df79574354443592a88d616de03da66ae5/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488", size = 251189, upload-time = "2026-08-15T08:16:48.287Z" }, { url = "https://files.pythonhosted.org/packages/a4/c8/ab42b07cfd82e919f427fcfaa7c41abae8242833ad1aad66d42bae40b669/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22", size = 239724, upload-time = "2026-08-15T08:16:49.67Z" }, diff --git a/.github/workflows/api_tests.yml b/.github/workflows/api_tests.yml index df545da82d..9f6c662c98 100644 --- a/.github/workflows/api_tests.yml +++ b/.github/workflows/api_tests.yml @@ -140,7 +140,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.11", "3.12", "3.13", "3.14"] permissions: contents: read diff --git a/CLAUDE.md b/CLAUDE.md index 1eedb5d0a1..a2c43eb968 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -202,7 +202,7 @@ PWDEBUG=1 pnpm test:parallel --headed # Debug mode - **Ruby 3.4** - Backend APIs and core library - **Rails 7.2** - REST APIs with AnyCable for WebSockets -- **Python 3.11-3.15** - Alternative scripting language +- **Python 3.11-3.14** - Alternative scripting language - **UV** - Python package manager (fast Rust-based replacement for pip/poetry) - **Ruff** - Python linter and formatter (fast Rust-based replacement for flake8/black) - **Vue.js 3 + Vuetify 3** - Frontend UI framework @@ -229,7 +229,7 @@ PWDEBUG=1 pnpm test:parallel --headed # Debug mode - **Line Length**: 120 - **Target Python**: 3.11 (minimum ruff target for backwards compatibility) - **Docker Python**: 3.12 (used in Alpine/UBI base images) -- **Supported Versions**: 3.11, 3.12, 3.13, 3.14, 3.15 (Docker version ±1) +- **Supported Versions**: 3.11, 3.12, 3.13, 3.14 (Docker version ±1) - **Config**: `openc3/python/pyproject.toml` - **Lockfile**: `openc3/python/uv.lock` (replaces poetry.lock) - **Python Version**: `openc3/python/.python-version` (default: 3.12) diff --git a/openc3.code-workspace b/openc3.code-workspace index a5e9a77013..e1fc00dc38 100644 --- a/openc3.code-workspace +++ b/openc3.code-workspace @@ -27,6 +27,9 @@ { "path": "../openc3-news", }, + { + "path": "../openc3-cosmos-fprime", + }, ], "settings": { "rubyLsp.bundleGemfile": "openc3/Gemfile", diff --git a/openc3/python/README-DEV.md b/openc3/python/README-DEV.md index f6968b9eca..decf3c5c92 100644 --- a/openc3/python/README-DEV.md +++ b/openc3/python/README-DEV.md @@ -161,7 +161,7 @@ openc3/python/ ## Python Version Support -This library supports Python 3.11 through 3.15. The library uses environment markers to install version-specific dependencies (e.g., different numpy versions for different Python versions). +This library supports Python 3.11 through 3.14. The library uses environment markers to install version-specific dependencies (e.g., different numpy versions for different Python versions). ## Code Style diff --git a/openc3/python/pyproject.toml b/openc3/python/pyproject.toml index fab8fb8e62..94f3e69e81 100644 --- a/openc3/python/pyproject.toml +++ b/openc3/python/pyproject.toml @@ -25,7 +25,6 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", - "Programming Language :: Python :: 3.15", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Embedded Systems", ] From 5d110b003114c0cbcb443a1f7a407cbae2c4dcdd Mon Sep 17 00:00:00 2001 From: "Matthew J. Cosgriff" Date: Fri, 23 Oct 2026 09:16:28 -0600 Subject: [PATCH 3/5] refactor(python): use 3.11 builtins for UTC and TimeoutError - Replace timezone.utc with datetime.UTC in examples, demo INST2 procedures and tsdb integration tests, dropping unused imports - Replace asyncio.TimeoutError with the builtin TimeoutError it aliases since 3.11, in host_interface_microservice and tests - Relock tools/generate_singleton_stubs.py.lock and ty_report.py.lock for requires-python >=3.11, removing the 3.10-only tomli Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com --- .../throughput_server/throughput_server.py | 2 +- .../targets/INST2/procedures/calendar.py | 6 +- .../targets/INST2/procedures/streaming.py | 4 +- .../examples/cosmos_web_socket_example.py | 6 +- .../host_interface_microservice.py | 2 +- .../microservices/test_bridge_microservice.py | 2 +- .../test_interface_microservice.py | 2 +- openc3/python/test/test_helper.py | 2 +- .../tools/generate_singleton_stubs.py.lock | 79 +------------------ openc3/python/tools/ty_report.py.lock | 4 +- .../tsdb/helpers/questdb_writer.py | 4 +- .../test/integration/tsdb/insert_test_data.py | 6 +- .../tsdb/python/test_tsdb_roundtrip.py | 6 +- 13 files changed, 25 insertions(+), 100 deletions(-) diff --git a/examples/throughput_server/throughput_server.py b/examples/throughput_server/throughput_server.py index f706dc8837..57eba658b6 100644 --- a/examples/throughput_server/throughput_server.py +++ b/examples/throughput_server/throughput_server.py @@ -104,7 +104,7 @@ async def handle(self) -> None: self._buffer += data await self._process_buffer() - except asyncio.TimeoutError: + except TimeoutError: # No data, continue loop (allows checking self.running) continue except ConnectionResetError: diff --git a/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/calendar.py b/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/calendar.py index 2b21831784..aa43d8f819 100644 --- a/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/calendar.py +++ b/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/calendar.py @@ -11,7 +11,7 @@ set_timeline_color("PythonTL", "#4287f5") print(get_timeline("PythonTL")) #=> {'name': 'PythonTL', 'color': '#4287f5', 'execute': True, 'shard': 0, 'scope': 'DEFAULT', 'updated_at': 1737129508391137136} -now = datetime.datetime.now(datetime.timezone.utc) +now = datetime.datetime.now(datetime.UTC) start = now + datetime.timedelta(hours=1) stop = start + datetime.timedelta(hours=1) act1 = create_timeline_activity("PythonTL", kind="reserve", start=start, stop=stop) @@ -45,8 +45,8 @@ # "events"=>[{"time"=>1737128761, "event"=>"created"}], "recurring"=>{}} # Update act2 with a custom title and notes -new_start = datetime.datetime.fromtimestamp(act2['start'], tz=datetime.timezone.utc) -new_stop = datetime.datetime.fromtimestamp(act2['stop'], tz=datetime.timezone.utc) + datetime.timedelta(minutes=30) +new_start = datetime.datetime.fromtimestamp(act2['start'], tz=datetime.UTC) +new_stop = datetime.datetime.fromtimestamp(act2['stop'], tz=datetime.UTC) + datetime.timedelta(minutes=30) updated = update_timeline_activity("PythonTL", id=act2['start'], kind="COMMAND", start=new_start, stop=new_stop, diff --git a/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/streaming.py b/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/streaming.py index 64aa9f4d38..b944cdb421 100644 --- a/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/streaming.py +++ b/openc3-cosmos-init/plugins/packages/openc3-cosmos-demo/targets/INST2/procedures/streaming.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone, timedelta +from datetime import UTC, datetime, timedelta from openc3.script.web_socket_api import StreamingWebSocketApi @@ -17,7 +17,7 @@ print(api.read()) # Warning this saves all data to RAM. Do not use for large queries -now = datetime.now(timezone.utc) +now = datetime.now(UTC) data = StreamingWebSocketApi.read_all( items=[ "DECOM__TLM__INST__HEALTH_STATUS__TEMP1__CONVERTED", diff --git a/openc3/python/examples/cosmos_web_socket_example.py b/openc3/python/examples/cosmos_web_socket_example.py index 0333c7ef87..195ce9ca96 100644 --- a/openc3/python/examples/cosmos_web_socket_example.py +++ b/openc3/python/examples/cosmos_web_socket_example.py @@ -1,5 +1,5 @@ import os -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta # Example Use @@ -43,7 +43,7 @@ # Warning this saves all data to RAM. Do not use for large queries -now = datetime.now(timezone.utc) +now = datetime.now(UTC) data = StreamingWebSocketApi.read_all( items=[ "DECOM__TLM__INST__HEALTH_STATUS__TEMP1__CONVERTED", @@ -55,7 +55,7 @@ print(data) -now = datetime.now(timezone.utc) +now = datetime.now(UTC) with MessagesWebSocketApi( history_count=0, start_time=to_nsec_from_epoch(now - timedelta(seconds=3600)), diff --git a/openc3/python/openc3/microservices/host_interface_microservice.py b/openc3/python/openc3/microservices/host_interface_microservice.py index f2e975d093..b0dde16846 100644 --- a/openc3/python/openc3/microservices/host_interface_microservice.py +++ b/openc3/python/openc3/microservices/host_interface_microservice.py @@ -425,7 +425,7 @@ async def _send_status(self, send): self._status_ping.clear() line = (json.dumps({"type": "status", "status": self._status_snapshot()}) + "\n").encode() await send.write_all(line) - with contextlib.suppress(asyncio.TimeoutError): + with contextlib.suppress(TimeoutError): await asyncio.wait_for(self._status_ping.wait(), timeout=STATUS_INTERVAL) def _status_snapshot(self): diff --git a/openc3/python/test/microservices/test_bridge_microservice.py b/openc3/python/test/microservices/test_bridge_microservice.py index 6025f44b7d..04e70dc0aa 100644 --- a/openc3/python/test/microservices/test_bridge_microservice.py +++ b/openc3/python/test/microservices/test_bridge_microservice.py @@ -134,7 +134,7 @@ async def test_read_request_has_a_timeout(self): recv = FakeRecv() with ( patch("openc3.microservices.bridge_microservice.REQUEST_TIMEOUT", 0.01), - self.assertRaises(asyncio.TimeoutError), + self.assertRaises(TimeoutError), ): await self.service._read_request(recv) diff --git a/openc3/python/test/microservices/test_interface_microservice.py b/openc3/python/test/microservices/test_interface_microservice.py index c861bea74a..35fb864b87 100644 --- a/openc3/python/test/microservices/test_interface_microservice.py +++ b/openc3/python/test/microservices/test_interface_microservice.py @@ -216,7 +216,7 @@ def test_creates_an_interface_updates_status_and_starts_cmd_thread(self): # def test_preserves_existing_packet_counts(self): # # Initialize the telemetry topic with a non-zero RECEIVED_COUNT # for _, packet in System.telemetry.packets("INST").items(): - # packet.received_time = datetime.now(timezone.utc) + # packet.received_time = datetime.now(UTC) # packet.received_count = 10 # TelemetryTopic.write_packet(packet, scope="DEFAULT") # im = InterfaceMicroservice("DEFAULT__INTERFACE__INST_INT") diff --git a/openc3/python/test/test_helper.py b/openc3/python/test/test_helper.py index 55d7b389eb..359265a543 100644 --- a/openc3/python/test/test_helper.py +++ b/openc3/python/test/test_helper.py @@ -90,7 +90,7 @@ def setup_system(targets=None): json.dumps(packet.as_json()), ) packet = System.telemetry.packet(target_name, packet_name) - # packet.received_time = datetime.now(timezone.utc) + # packet.received_time = datetime.now(UTC) json_hash = {} for item in packet.sorted_items: # Initialize all items to None like TargetModel::update_store does in Ruby diff --git a/openc3/python/tools/generate_singleton_stubs.py.lock b/openc3/python/tools/generate_singleton_stubs.py.lock index 223acf6f3b..5c8b70dde8 100644 --- a/openc3/python/tools/generate_singleton_stubs.py.lock +++ b/openc3/python/tools/generate_singleton_stubs.py.lock @@ -1,6 +1,6 @@ version = 1 -revision = 3 -requires-python = ">=3.10" +revision = 5 +requires-python = ">=3.11" resolution-markers = [ "python_full_version >= '3.15'", "python_full_version < '3.15'", @@ -82,20 +82,6 @@ version = "0.15.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/36/9b/356320fbae2ac8467e21c5e73e1389c80468e4998c62cc7d3536cc51b614/librt-0.15.0.tar.gz", hash = "sha256:4e66cbe84437497d951b799d3e1551291b6fb3d643820a7014b3655d57a59162", size = 214338, upload-time = "2026-08-07T10:49:42.663Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/12/e2e9ca532cf5a0e08c9489826c4a35c6958c92ba0313fda70e8c6c3912be/librt-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1a49adf16a7c9d9646816c2946135527197b6fcf4347c7b8b761cf1bfbf4489", size = 148673, upload-time = "2026-08-07T10:46:22.569Z" }, - { url = "https://files.pythonhosted.org/packages/6d/7c/02005e23478bd5950618d9712e0fd2b4c511657857f3efd8ba6a5feabcdd/librt-0.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81a398f45b45a59200e13cd5ad1ae1d3f44334de98b148331afe2cdfee701c52", size = 153547, upload-time = "2026-08-07T10:46:23.931Z" }, - { url = "https://files.pythonhosted.org/packages/a0/90/d8848a735f5642077fc4b3b4bebcdb08edf10178e3add45597f5201a368f/librt-0.15.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4eafbaff06b9563f8b1c850621ce51605de05208e09d4d71ce490bc972b7b9e8", size = 494355, upload-time = "2026-08-07T10:46:25.122Z" }, - { url = "https://files.pythonhosted.org/packages/e1/0b/8604f41ea02feace490e9e405a338a15f9905369f55b239a9ce31c946f24/librt-0.15.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b0411b4066db926b80258c60dcb0e6db4c9cee312eab45b7e8866b17ddf9ada1", size = 485459, upload-time = "2026-08-07T10:46:26.447Z" }, - { url = "https://files.pythonhosted.org/packages/a0/ac/84153bda1ce0da609182527ab92b40d961809e544eefdc5a1c2422971416/librt-0.15.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:febb1ce6cac545a54e6b769982824e955a700fdd9fbf3a08a3d82c990968b57d", size = 498398, upload-time = "2026-08-07T10:46:27.701Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3a/5ca6cd282b2c244bec8ec84102e09773264e9c02891d56ab3a8f0e4d7083/librt-0.15.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b230acc1c3bfe2d6f2627ba2b95dc92e58aa494600e9722d0e6ccbc931e59702", size = 515474, upload-time = "2026-08-07T10:46:28.9Z" }, - { url = "https://files.pythonhosted.org/packages/73/d3/bd34110234779eb843c6ed66aba7c9b2091d3dd85989f1fb9922f564cb7a/librt-0.15.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6da110e5f314c19ab8478464d02ae18808ae73d522c15260fa4918acdcd64da9", size = 509484, upload-time = "2026-08-07T10:46:30.124Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6c/43c3f7f071d71631a7daa3b835ef2168ea39f20692d81464d4e47fbaa6d6/librt-0.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eab9208b00ca55bf75983ec99f7bf13acc746a36102e98953addaad7f7ea1e1b", size = 532534, upload-time = "2026-08-07T10:46:31.511Z" }, - { url = "https://files.pythonhosted.org/packages/c5/1c/b854adf036ea817c40408873a5b794d65a91d9f0f39826f2ad2a2d5d7f48/librt-0.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6c013cd3a1721e69e14380ada97eaa4b7b0cdf1c6b96fa765d4ea47c875088db", size = 537087, upload-time = "2026-08-07T10:46:32.734Z" }, - { url = "https://files.pythonhosted.org/packages/25/5c/c9a890e244e7dd725d3bd8b560e41f0aec787eaf343b46956a290ab7b841/librt-0.15.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:567b1c430f8bd560e689421468278ac5941bab4a05303b5d95b6ae10db03f451", size = 536575, upload-time = "2026-08-07T10:46:33.965Z" }, - { url = "https://files.pythonhosted.org/packages/5f/c5/c8e70b60b704299555f55db468eb46b1c81bfc60201ffbfe20407d89870c/librt-0.15.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:29c4cab9df457b19672c39be7f384ebb2bc925c4e2684b8780c222b43eb36389", size = 517142, upload-time = "2026-08-07T10:46:35.577Z" }, - { url = "https://files.pythonhosted.org/packages/56/d1/767a90c41f5d381b3195bc88ac0ec4afda35777c9c781e1f9848fedd965e/librt-0.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bccbd8e5b0bffb7106cf18eb1baa3d7194b1cebb3b4b1cdbd4bdb19382a6ee6c", size = 558714, upload-time = "2026-08-07T10:46:36.829Z" }, - { url = "https://files.pythonhosted.org/packages/f9/b4/3c0624b8dc8301ab808f2b3a910995bcabe28df070fb9a0e5505ae997dae/librt-0.15.0-cp310-cp310-win32.whl", hash = "sha256:8ae493ed5f659a7761c43d42f183db514536073ded9bcf671d2d1df47e29a07e", size = 104426, upload-time = "2026-08-07T10:46:38.594Z" }, - { url = "https://files.pythonhosted.org/packages/31/98/e91c0382304bedb2db9c6801897319a9dcb68daac5e975819b562362f20d/librt-0.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc25fb356d0c7810bb49ff3df908ad1fda6995d660ab099ded69244ed7ab6053", size = 125057, upload-time = "2026-08-07T10:46:40.052Z" }, { url = "https://files.pythonhosted.org/packages/59/52/06790ced2ac7117f890c21bda43c39c958ec82aa665c0718e821d33ff939/librt-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:823b92cf3c18ecd08afc70c42473888b41b6e8ef5046f3b82c05c154a2fa3d22", size = 148039, upload-time = "2026-08-07T10:46:41.165Z" }, { url = "https://files.pythonhosted.org/packages/e7/1d/8e150b7fc449a1f33c8a760965cc1f43b14fc1577d9d0b50ab2701420e74/librt-0.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70bc1b602cf59917e8f0c7a2cbc8bcc6fbc14d5486136b00707a79619121d63", size = 153067, upload-time = "2026-08-07T10:46:42.418Z" }, { url = "https://files.pythonhosted.org/packages/51/87/a162bc5a66a35599dc619ecb215145f4de7d68e886b479b6d12593139f7c/librt-0.15.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:814ff83a25b5fce8b9c80c4dd803153fb5c5599fc74db9e022466938368957ef", size = 493087, upload-time = "2026-08-07T10:46:43.657Z" }, @@ -215,17 +201,10 @@ dependencies = [ { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, { name = "mypy-extensions" }, { name = "pathspec" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/6a/878cc1097d4035f82bd516658d0c528d2a9955bc7b363afcbd0b07fea11b/mypy-2.3.1.tar.gz", hash = "sha256:47c1b1207258513a9d93495f69c8be9de73916186f0e52703e8c461b7a623419", size = 3992554, upload-time = "2026-08-15T03:03:38.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/b9/de8f67e12d721cdcc8ba6cfc440b989a4ba4dfabe4402ae94dfdd8bb30a4/mypy-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:57a936373fc690c43a8cd7e7e12a35148e4ec5aa7698ad7fc0a9f918bdc5be41", size = 14015541, upload-time = "2026-08-15T03:01:53.104Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8a/9e746ab012c67ed8ea3232a613716c306ee8c0b5682c80d8103b4f04568e/mypy-2.3.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d00d769056bde2f4e69c175071eba45cfb44fa1ed92bdfbfe64a93e0543b0cf0", size = 14248142, upload-time = "2026-08-15T03:02:43.201Z" }, - { url = "https://files.pythonhosted.org/packages/f7/5c/c99ff2d8d0e2c53393e32dfe22d9aa43a5d959d30db46c786dafd24527d3/mypy-2.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2166b29228835e1f88ff411e96639e6ca3c7fdde84b62ec211f70f86b4051167", size = 15193309, upload-time = "2026-08-15T03:01:28.714Z" }, - { url = "https://files.pythonhosted.org/packages/64/39/124638f745243faae1ff4b37d5426fe41c0f0454535edc82fe8102b56a3c/mypy-2.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83d36c2924df7426333abe7faf4724a7e1aab0d9fd41625e81b4683034b80c13", size = 15498246, upload-time = "2026-08-15T03:02:46.29Z" }, - { url = "https://files.pythonhosted.org/packages/b2/83/31c0781e243836505c0fb5f4e865487d6df1023e4ad959f4ebd4b84a0226/mypy-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:f12fdb70459d0060dea40b29e52163a961b156106d68d57882a6a9f648983a53", size = 11155028, upload-time = "2026-08-15T03:01:39.08Z" }, - { url = "https://files.pythonhosted.org/packages/a0/ab/bc2eb0129e72d7d7d93d5e981a78084a9abefda7efa732a7e02f97d6e27d/mypy-2.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:e099200a1b1b1223a4951f0a90cbff1b8c91b250ba599dab1f7217a628144d90", size = 10151438, upload-time = "2026-08-15T03:02:19.04Z" }, { url = "https://files.pythonhosted.org/packages/a4/be/c624d4241484f37dc62839e177ab607a9b8b3e96f0866544ca99e8e41d51/mypy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94f04929f1c44c35fb0061e912087edaf504acede963a4a7d00680bd089d8531", size = 13936739, upload-time = "2026-08-15T03:03:26.475Z" }, { url = "https://files.pythonhosted.org/packages/53/84/e3cf72f90dce5960871c82551c8fba6da05fc1018f79be41c047bd126bdd/mypy-2.3.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5d716048611e85ca9eefb2e1baa5d73ede389b5820ded260ea27c757d667af8", size = 14166460, upload-time = "2026-08-15T03:01:50.565Z" }, { url = "https://files.pythonhosted.org/packages/4a/ff/6b97d58aa0f79a5ab9b472db1f6d6df1b11a51d74d0c08ab3760d3a613ba/mypy-2.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b091a455111214cb5c9d54a57b9618e9a49f9fe2a42e4e1ac86e9d104ed96ce8", size = 15100476, upload-time = "2026-08-15T03:03:12.079Z" }, @@ -316,60 +295,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/a0/50787329e4f20bf9dc9f6230015d46ec69c51a97ace5bc202dae4755365d/ruff-0.16.8-py3-none-win_arm64.whl", hash = "sha256:d075e820af612102ce217f07cc93e69f9490b10ec13ea85fa87bd03d996cef8a", size = 10386316, upload-time = "2026-09-16T15:54:43.332Z" }, ] -[[package]] -name = "tomli" -version = "2.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, - { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, - { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, - { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, - { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, - { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, - { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, - { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, - { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, - { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, - { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, - { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, - { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, - { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, - { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, - { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, - { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, - { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, - { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, - { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, - { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, - { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, - { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, - { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, - { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, - { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, - { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, - { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, - { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, - { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, - { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, - { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, - { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, - { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, - { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, - { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, - { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, - { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, - { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, - { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, - { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, - { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, -] - [[package]] name = "typing-extensions" version = "4.16.0" diff --git a/openc3/python/tools/ty_report.py.lock b/openc3/python/tools/ty_report.py.lock index a02a6a37fd..7a74d64646 100644 --- a/openc3/python/tools/ty_report.py.lock +++ b/openc3/python/tools/ty_report.py.lock @@ -1,3 +1,3 @@ version = 1 -revision = 3 -requires-python = ">=3.10" +revision = 5 +requires-python = ">=3.11" diff --git a/openc3/test/integration/tsdb/helpers/questdb_writer.py b/openc3/test/integration/tsdb/helpers/questdb_writer.py index 5f8ee4dde1..96f7a1e41b 100644 --- a/openc3/test/integration/tsdb/helpers/questdb_writer.py +++ b/openc3/test/integration/tsdb/helpers/questdb_writer.py @@ -43,7 +43,7 @@ import os import sys import time -from datetime import datetime, timezone +from datetime import UTC, datetime # Add openc3 python path for imports # Path: openc3/test/integration/tsdb/helpers -> openc3/python @@ -78,7 +78,7 @@ def ts_to_iso(ts_ns: int) -> str: """Convert nanosecond timestamp to ISO string for QuestDB queries.""" ts_us = ts_ns // 1000 ts_s = ts_us / 1_000_000 - return datetime.fromtimestamp(ts_s, tz=timezone.utc).strftime( + return datetime.fromtimestamp(ts_s, tz=UTC).strftime( "%Y-%m-%dT%H:%M:%S.%fZ" ) diff --git a/openc3/test/integration/tsdb/insert_test_data.py b/openc3/test/integration/tsdb/insert_test_data.py index a84906c597..7567435ad4 100644 --- a/openc3/test/integration/tsdb/insert_test_data.py +++ b/openc3/test/integration/tsdb/insert_test_data.py @@ -18,7 +18,7 @@ import math import random import sys -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta import psycopg @@ -134,11 +134,11 @@ def main(): if earliest: # Ensure timezone-aware if earliest.tzinfo is None: - earliest = earliest.replace(tzinfo=timezone.utc) + earliest = earliest.replace(tzinfo=UTC) print(f"Earliest existing timestamp: {earliest.isoformat()}") start_time = earliest - timedelta(seconds=args.interval) else: - start_time = datetime.now(timezone.utc) + start_time = datetime.now(UTC) print(f"Table empty, starting from now: {start_time.isoformat()}") end_time = start_time - timedelta(hours=args.hours) diff --git a/openc3/test/integration/tsdb/python/test_tsdb_roundtrip.py b/openc3/test/integration/tsdb/python/test_tsdb_roundtrip.py index 1a8ca6130f..5e47c0b25e 100644 --- a/openc3/test/integration/tsdb/python/test_tsdb_roundtrip.py +++ b/openc3/test/integration/tsdb/python/test_tsdb_roundtrip.py @@ -28,7 +28,7 @@ import sys import time import pytest -from datetime import datetime, timezone +from datetime import UTC, datetime from unittest.mock import patch # Add openc3 python path for imports @@ -54,7 +54,7 @@ def ts_to_iso(ts_ns: int) -> str: """Convert nanosecond timestamp to ISO string, truncating to microseconds to match QuestDB storage.""" ts_us = ts_ns // 1000 ts_s = ts_us / 1_000_000 - return datetime.fromtimestamp(ts_s, tz=timezone.utc).strftime( + return datetime.fromtimestamp(ts_s, tz=UTC).strftime( "%Y-%m-%dT%H:%M:%S.%fZ" ) @@ -652,7 +652,7 @@ def run_timestamp_test( ), f"Expected ISO 8601 format at index {i}, got {actual}" # Verify the formatted string can be parsed back to approximately the same time parsed = datetime.strptime(actual, "%Y-%m-%dT%H:%M:%S.%fZ") - parsed_ts = parsed.replace(tzinfo=timezone.utc).timestamp() + parsed_ts = parsed.replace(tzinfo=UTC).timestamp() assert ( abs(parsed_ts - expected_ts_seconds) < 0.001 ), f"Timestamp formatted mismatch at index {i}: expected {expected_ts_seconds}, got {actual}" From 7473e91d940735c2774876ab190c06982ac5f5b6 Mon Sep 17 00:00:00 2001 From: Matthew Cosgriff Date: Fri, 23 Oct 2026 13:35:09 -0600 Subject: [PATCH 4/5] Update openc3/python/pyproject.toml 3.15 is not support yet so don't allow it Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- openc3/python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openc3/python/pyproject.toml b/openc3/python/pyproject.toml index 94f3e69e81..24d4ea4051 100644 --- a/openc3/python/pyproject.toml +++ b/openc3/python/pyproject.toml @@ -6,7 +6,7 @@ authors = [{ name = "Support", email = "support@openc3.com" }] maintainers = [{ name = "OpenC3 Support", email = "support@openc3.com" }] license = "LicenseRef-OpenC3-Builders-License" license-files = ["LICENSE.md"] -requires-python = ">=3.11,<4.0" +requires-python = ">=3.11,<3.15" readme = "README.md" keywords = [ "cosmos", From 0e971d11817b4f7f7dd6cc16f608ae9c318cc2c1 Mon Sep 17 00:00:00 2001 From: "Matthew J. Cosgriff" Date: Fri, 23 Oct 2026 14:06:22 -0600 Subject: [PATCH 5/5] fix(cli): use core operator image for hostsetup probe - Switch run_hostsetup from the enterprise operator image on repos.openc3.com to openc3inc/openc3-operator on docker.io, reading OPENC3_REGISTRY, OPENC3_NAMESPACE and OPENC3_TAG Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com --- openc3.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openc3.sh b/openc3.sh index e8e6f14157..6ef6cb2c3e 100755 --- a/openc3.sh +++ b/openc3.sh @@ -394,10 +394,10 @@ run_hostsetup() { return 0 fi - local repo="${OPENC3_ENTERPRISE_REGISTRY:-repos.openc3.com}" - local namespace="${OPENC3_ENTERPRISE_NAMESPACE:-openc3}" - local tag="${OPENC3_ENTERPRISE_TAG:-latest}" - local image="$repo/$namespace/openc3-enterprise-operator:$tag" + local repo="${OPENC3_REGISTRY:-docker.io}" + local namespace="${OPENC3_NAMESPACE:-openc3inc}" + local tag="${OPENC3_TAG:-latest}" + local image="$repo/$namespace/openc3-operator:$tag" # Unprivileged probe. vm.max_map_count (mmc) and transparent huge pages (thp) # are not namespaced, so any container reads the host's (or the Docker VM's) values.