diff --git a/pyproject.toml b/pyproject.toml index 14e3d2f..b253de9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,8 +25,8 @@ dependencies = [ "soundevent[audio,geometry,plot]>=2.10.0", "soundfile>=0.12.1", "tensorboard>=2.16.2", - "torch>=1.13.1", - "torchaudio>=1.13.1", + "torch>=2.0.0", + "torchaudio>=2.0.0", "xarray>=2024.0.0", ] requires-python = ">=3.10,<3.14" diff --git a/src/batdetect2/models/blocks.py b/src/batdetect2/models/blocks.py index ccce61c..9d81d4b 100644 --- a/src/batdetect2/models/blocks.py +++ b/src/batdetect2/models/blocks.py @@ -70,11 +70,16 @@ __all__ = [ "FreqCoordConvUpBlock", "StandardConvUpBlock", "SelfAttention", + "EfficientSelfAttention", + "VerticalMean", "ConvConfig", + "EfficientSelfAttentionConfig", "FreqCoordConvDownConfig", "StandardConvDownConfig", "FreqCoordConvUpConfig", "StandardConvUpConfig", + "VerticalConvConfig", + "VerticalMeanConfig", "LayerConfig", "build_layer", ] @@ -145,8 +150,8 @@ class SelfAttentionConfig(BaseConfig): attention_channels : int Dimensionality of the query, key, and value projections. temperature : float - Scaling factor applied to the weighted values before the final - linear projection. Defaults to ``1``. + Divisor applied together with ``attention_channels`` when scaling + dot-product attention logits. Defaults to ``1``. """ name: Literal["SelfAttention"] = "SelfAttention" @@ -306,6 +311,126 @@ class SelfAttention(Block): ) +class EfficientSelfAttentionConfig(BaseConfig): + """Configuration for an ``EfficientSelfAttention`` block. + + Attributes + ---------- + name : str + Discriminator field; always ``"EfficientSelfAttention"``. + attention_channels : int + Dimensionality of the query, key, and value projections. + temperature : float + Divisor applied together with ``attention_channels`` when scaling + dot-product attention logits. Defaults to ``1``. + """ + + name: Literal["EfficientSelfAttention"] = "EfficientSelfAttention" + attention_channels: int + temperature: float = 1.0 + + +class EfficientSelfAttention(Block): + """An optimized self-attention block operating along the time axis. + + Applies a scaled dot-product self-attention mechanism across the time + steps of an input feature map. This version uses a fused QKV linear + projection and PyTorch's native scaled dot-product attention (SDPA) + for optimal memory usage and execution speed. + + Parameters + ---------- + in_channels : int + Number of input channels (features per time step). + attention_channels : int + Dimensionality of the query, key, and value projections. + temperature : float, default=1.0 + Divisor applied together with ``attention_channels`` when scaling + the dot-product scores before softmax. + + Attributes + ---------- + qkv_proj : nn.Linear + Fused linear projection for queries, keys, and values. + pro_fun : nn.Linear + Final linear projection applied to the attended values. + temperature : float + Scaling divisor used when computing attention scores. + att_dim : int + Dimensionality of the attention space (``attention_channels``). + """ + + def __init__( + self, + in_channels: int, + attention_channels: int, + temperature: float = 1.0, + ): + super().__init__() + self.in_channels = in_channels + self.out_channels = in_channels + self.temperature = temperature + self.att_dim = attention_channels + self.output_channels = in_channels + + self.qkv_proj = nn.Linear(in_channels, 3 * attention_channels) + self.pro_fun = nn.Linear(attention_channels, in_channels) + + self.scale_factor = 1.0 / (self.temperature * self.att_dim) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + """Apply self-attention along the time dimension.""" + x = x.squeeze(2).permute(0, 2, 1) + + # Single projection pass + qkv = self.qkv_proj(x) + + # Split along the last dimension into Q, K, V + query, key, value = torch.chunk(qkv, 3, dim=-1) + + att = F.scaled_dot_product_attention( + query, + key, + value, + attn_mask=None, + dropout_p=0.0, + is_causal=False, + scale=self.scale_factor, + ) + + op = self.pro_fun(att) + + return op.permute(0, 2, 1).unsqueeze(2) + + def compute_attention_weights(self, x: torch.Tensor) -> torch.Tensor: + """Return the softmax attention weight matrix. + + Useful for visualising which time steps attend to which others. + """ + x = x.squeeze(2).permute(0, 2, 1) + + qkv = self.qkv_proj(x) + query, key, _ = torch.chunk(qkv, 3, dim=-1) + + kk_qq = torch.bmm(key, query.permute(0, 2, 1)) * self.scale_factor + att_weights = F.softmax(kk_qq, dim=1) + + return att_weights + + @block_registry.register(EfficientSelfAttentionConfig) + @staticmethod + def from_config( + config: EfficientSelfAttentionConfig, + input_channels: int, + input_height: int, + ) -> "EfficientSelfAttention": + return EfficientSelfAttention( + in_channels=input_channels, + attention_channels=config.attention_channels, + temperature=config.temperature, + ) + + class ConvConfig(BaseConfig): """Configuration for a basic ConvBlock.""" @@ -460,6 +585,10 @@ class VerticalConv(Block): """ return F.relu_(self.bn(self.conv(x))) + def get_output_height(self, input_height: int) -> int: + """Return the collapsed output height.""" + return 1 + @block_registry.register(VerticalConvConfig) @staticmethod def from_config( @@ -474,6 +603,94 @@ class VerticalConv(Block): ) +class VerticalMeanConfig(BaseConfig): + """Configuration for a ``VerticalMean`` block. + + Attributes + ---------- + name : str + Discriminator field; always ``"VerticalMean"``. + """ + + name: Literal["VerticalMean"] = "VerticalMean" + """Discriminator field indicating the block type.""" + + channels: int + """Number of output channels.""" + + +class VerticalMean(Block): + """Mean pooling block operating along the height dimension. + + Applies a 2D mean pooling operation, followed by a 2D convolution, + followed by a batch normalization and ReLU activation. + + Sequence: Mean Pool -> Conv -> BN -> ReLU. + + Parameters + ---------- + in_channels : int + Number of channels in the input tensor. + out_channels : int + Number of output channels after the mean pooling. + input_height : int + The height (H dimension) of the input tensor. The convolutional kernel + will be sized `(1, 1)`. + """ + + def __init__( + self, + in_channels: int, + out_channels: int, + input_height: int, + ): + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.input_height = input_height + self.conv = nn.Conv2d( + in_channels, + out_channels, + kernel_size=(1, 1), + padding=0, + ) + self.batch_norm = nn.BatchNorm2d(out_channels) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + """Apply avg pooling -> Conv -> BN -> ReLU. + + Parameters + ---------- + x : torch.Tensor + Input tensor, shape `(B, C_in, H, W)`. + + Returns + ------- + torch.Tensor + Output tensor, shape `(B, C_out, 1, W)`. + """ + x = x.mean(dim=2, keepdim=True) + x = self.conv(x) + return F.relu(self.batch_norm(x), inplace=True) + + def get_output_height(self, input_height: int) -> int: + """Return the collapsed output height.""" + return 1 + + @block_registry.register(VerticalMeanConfig) + @staticmethod + def from_config( + config: VerticalMeanConfig, + input_channels: int, + input_height: int, + ): + return VerticalMean( + in_channels=input_channels, + out_channels=config.channels, + input_height=input_height, + ) + + class FreqCoordConvDownConfig(BaseConfig): """Configuration for a FreqCoordConvDownBlock.""" @@ -951,13 +1168,16 @@ LayerConfig = Annotated[ | FreqCoordConvUpConfig | StandardConvUpConfig | SelfAttentionConfig + | EfficientSelfAttentionConfig + | VerticalConvConfig + | VerticalMeanConfig | LayerGroupConfig, Field(discriminator="name"), ] """Type alias for the discriminated union of block configuration models.""" -class LayerGroup(nn.Module): +class LayerGroup(Block): """Sequential chain of blocks that acts as a single composite block. Wraps multiple ``Block`` instances in an ``nn.Sequential`` container, diff --git a/src/batdetect2/models/bottleneck.py b/src/batdetect2/models/bottleneck.py index 9b2154a..5dd2630 100644 --- a/src/batdetect2/models/bottleneck.py +++ b/src/batdetect2/models/bottleneck.py @@ -21,14 +21,18 @@ This module provides: from typing import Annotated, List import torch -from pydantic import Field +from pydantic import Field, model_validator from torch import nn from batdetect2.core.configs import BaseConfig from batdetect2.models.blocks import ( Block, + EfficientSelfAttentionConfig, SelfAttentionConfig, VerticalConv, + VerticalConvConfig, + VerticalMean, + VerticalMeanConfig, build_layer, ) from batdetect2.models.types import BottleneckProtocol @@ -94,6 +98,7 @@ class Bottleneck(Block): in_channels: int, out_channels: int, bottleneck_channels: int | None = None, + frequency_aggregator: Block | None = None, layers: List[torch.nn.Module] | None = None, ) -> None: """Initialise the Bottleneck layer. @@ -125,11 +130,14 @@ class Bottleneck(Block): ) self.layers = nn.ModuleList(layers or []) - self.conv_vert = VerticalConv( - in_channels=in_channels, - out_channels=self.bottleneck_channels, - input_height=input_height, - ) + if frequency_aggregator is None: + frequency_aggregator = VerticalConv( + in_channels=in_channels, + out_channels=self.bottleneck_channels, + input_height=input_height, + ) + + self.conv_vert = frequency_aggregator def forward(self, x: torch.Tensor) -> torch.Tensor: """Process the encoder's bottleneck features. @@ -160,12 +168,19 @@ class Bottleneck(Block): BottleneckLayerConfig = Annotated[ - SelfAttentionConfig, + SelfAttentionConfig | EfficientSelfAttentionConfig, Field(discriminator="name"), ] """Type alias for the discriminated union of block configs usable in the Bottleneck.""" +FrequencyAggregationLayerConfig = Annotated[ + (VerticalConvConfig | VerticalMeanConfig), + Field(discriminator="name"), +] +"""Type alias for the discriminated union of block configs usable in the FrequencyAggregation.""" + + class BottleneckConfig(BaseConfig): """Configuration for the bottleneck component. @@ -182,17 +197,79 @@ class BottleneckConfig(BaseConfig): """ channels: int + frequency_aggregation: FrequencyAggregationLayerConfig | None = None layers: List[BottleneckLayerConfig] = Field(default_factory=list) + @model_validator(mode="after") + def set_default_frequency_aggregation(self) -> "BottleneckConfig": + """Default frequency aggregation to the bottleneck channel count.""" + if self.frequency_aggregation is None: + self.frequency_aggregation = VerticalConvConfig( + channels=self.channels + ) + + return self + DEFAULT_BOTTLENECK_CONFIG: BottleneckConfig = BottleneckConfig( channels=256, + frequency_aggregation=VerticalConvConfig(channels=256), layers=[ SelfAttentionConfig(attention_channels=256), ], ) +def build_frequency_aggregation( + input_height: int, + in_channels: int, + config: FrequencyAggregationLayerConfig, +) -> Block: + """Build a block for aggregating frequency information. + + Parameters + ---------- + input_height : int + Height (number of frequency bins) of the input tensor from the + encoder. Must be positive. + in_channels : int + Number of channels in the input tensor from the encoder. Must be + positive. + config : FrequencyAggregationLayerConfig, optional + Configuration specifying the output channel count and any + additional layers. Uses ``VerticalConvConfig`` if ``None``. + + Returns + ------- + Block + An initialised ``VerticalConv`` module. + + Raises + ------ + AssertionError + If any configured layer changes the height of the feature map + (bottleneck layers must preserve height so that it can be restored + by repetition). + """ + if config.name == "VerticalConv": + return VerticalConv( + in_channels=in_channels, + out_channels=config.channels, + input_height=input_height, + ) + + if config.name == "VerticalMean": + return VerticalMean( + in_channels=in_channels, + out_channels=config.channels, + input_height=input_height, + ) + + raise NotImplementedError( + f"Unknown frequency aggregation layer: {config.name}" + ) + + def build_bottleneck( input_height: int, in_channels: int, @@ -231,13 +308,26 @@ def build_bottleneck( by repetition). """ config = config or DEFAULT_BOTTLENECK_CONFIG + frequency_aggregation = config.frequency_aggregation + if frequency_aggregation is None: + raise ValueError("frequency_aggregation must be configured.") - current_channels = in_channels - current_height = input_height + frequency_aggregator = build_frequency_aggregation( + input_height=input_height, + in_channels=in_channels, + config=frequency_aggregation, + ) + + current_channels = frequency_aggregator.out_channels + current_height = frequency_aggregator.get_output_height(input_height) + assert current_height == 1, ( + "Bottleneck frequency aggregation should collapse spectrogram height" + ) layers = [] for layer_config in config.layers: + previous_height = current_height layer = build_layer( input_height=current_height, in_channels=current_channels, @@ -245,7 +335,7 @@ def build_bottleneck( ) current_height = layer.get_output_height(current_height) current_channels = layer.out_channels - assert current_height == input_height, ( + assert current_height == previous_height, ( "Bottleneck layers should not change the spectrogram height" ) layers.append(layer) @@ -253,6 +343,7 @@ def build_bottleneck( return Bottleneck( input_height=input_height, in_channels=in_channels, - out_channels=config.channels, + out_channels=current_channels, + frequency_aggregator=frequency_aggregator, layers=layers, ) diff --git a/tests/test_model.py b/tests/test_model.py index 43b6eac..d729ac9 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -10,6 +10,8 @@ from hypothesis import strategies as st from batdetect2 import api from batdetect2.detector import parameters +from batdetect2.models.backbones import UNetBackboneConfig +from batdetect2.train import load_model_from_checkpoint @settings(deadline=None, max_examples=5) @@ -72,3 +74,16 @@ def test_can_import_model_without_pickle_on_test_data( model=model_with_pickle, ) assert predictions_without_pickle == predictions_with_pickle + + +def test_bundled_checkpoint_loads_with_current_config_schema() -> None: + """Bundled checkpoints remain loadable after config schema changes.""" + model, configs = load_model_from_checkpoint() + + assert model.class_names + assert isinstance(configs.model.architecture, UNetBackboneConfig) + frequency_aggregation = ( + configs.model.architecture.bottleneck.frequency_aggregation + ) + assert frequency_aggregation is not None + assert frequency_aggregation.name diff --git a/tests/test_models/test_blocks.py b/tests/test_models/test_blocks.py index 57315d5..e862ef9 100644 --- a/tests/test_models/test_blocks.py +++ b/tests/test_models/test_blocks.py @@ -4,6 +4,8 @@ import torch from batdetect2.models.blocks import ( ConvBlock, ConvConfig, + EfficientSelfAttention, + EfficientSelfAttentionConfig, FreqCoordConvDownBlock, FreqCoordConvDownConfig, FreqCoordConvUpBlock, @@ -18,6 +20,8 @@ from batdetect2.models.blocks import ( StandardConvUpConfig, VerticalConv, VerticalConvConfig, + VerticalMean, + VerticalMeanConfig, build_layer, ) @@ -99,6 +103,20 @@ def test_vertical_conv_forward_shape(dummy_input): assert block.out_channels == out_channels +def test_vertical_mean_forward_shape(dummy_input): + """Test that VerticalMean collapses the height dimension to 1.""" + in_channels = dummy_input.size(1) + input_height = dummy_input.size(2) + out_channels = 32 + + block = VerticalMean(in_channels, out_channels, input_height) + output = block(dummy_input) + + assert output.shape == (2, out_channels, 1, 32) + assert block.out_channels == out_channels + assert block.get_output_height(input_height) == 1 + + def test_self_attention_forward_shape(dummy_bottleneck_input): """Test that SelfAttention maintains the exact shape.""" in_channels = dummy_bottleneck_input.size(1) @@ -113,6 +131,20 @@ def test_self_attention_forward_shape(dummy_bottleneck_input): assert block.out_channels == in_channels +def test_efficient_self_attention_forward_shape(dummy_bottleneck_input): + """Test that EfficientSelfAttention maintains the exact shape.""" + in_channels = dummy_bottleneck_input.size(1) + attention_channels = 32 + + block = EfficientSelfAttention( + in_channels=in_channels, attention_channels=attention_channels + ) + output = block(dummy_bottleneck_input) + + assert output.shape == dummy_bottleneck_input.shape + assert block.out_channels == in_channels + + def test_self_attention_weights(dummy_bottleneck_input): """Test that attention weights sum to 1 over the time sequence.""" in_channels = dummy_bottleneck_input.size(1) @@ -131,6 +163,51 @@ def test_self_attention_weights(dummy_bottleneck_input): assert torch.allclose(sum_weights, torch.ones_like(sum_weights), atol=1e-5) +def test_efficient_self_attention_matches_self_attention_with_copied_weights( + dummy_bottleneck_input, +): + """Temporarily compare efficient and original attention outputs.""" + in_channels = dummy_bottleneck_input.size(1) + attention_channels = 32 + + block = SelfAttention( + in_channels=in_channels, + attention_channels=attention_channels, + ) + efficient_block = EfficientSelfAttention( + in_channels=in_channels, + attention_channels=attention_channels, + ) + + # Match the fused QKV projection to the original separate projections. + with torch.no_grad(): + efficient_block.qkv_proj.weight[:attention_channels].copy_( + block.query_fun.weight + ) + efficient_block.qkv_proj.bias[:attention_channels].copy_( + block.query_fun.bias + ) + efficient_block.qkv_proj.weight[ + attention_channels : 2 * attention_channels + ].copy_(block.key_fun.weight) + efficient_block.qkv_proj.bias[ + attention_channels : 2 * attention_channels + ].copy_(block.key_fun.bias) + efficient_block.qkv_proj.weight[2 * attention_channels :].copy_( + block.value_fun.weight + ) + efficient_block.qkv_proj.bias[2 * attention_channels :].copy_( + block.value_fun.bias + ) + efficient_block.pro_fun.weight.copy_(block.pro_fun.weight) + efficient_block.pro_fun.bias.copy_(block.pro_fun.bias) + + output = block(dummy_bottleneck_input) + efficient_output = efficient_block(dummy_bottleneck_input) + + torch.testing.assert_close(output, efficient_output) + + @pytest.mark.parametrize( "layer_config, expected_type", [ @@ -140,7 +217,12 @@ def test_self_attention_weights(dummy_bottleneck_input): (FreqCoordConvDownConfig(out_channels=32), FreqCoordConvDownBlock), (FreqCoordConvUpConfig(out_channels=32), FreqCoordConvUpBlock), (SelfAttentionConfig(attention_channels=32), SelfAttention), + ( + EfficientSelfAttentionConfig(attention_channels=32), + EfficientSelfAttention, + ), (VerticalConvConfig(channels=32), VerticalConv), + (VerticalMeanConfig(channels=32), VerticalMean), ], ) def test_build_layer_factory(layer_config, expected_type): diff --git a/tests/test_models/test_bottleneck.py b/tests/test_models/test_bottleneck.py new file mode 100644 index 0000000..46d9b39 --- /dev/null +++ b/tests/test_models/test_bottleneck.py @@ -0,0 +1,55 @@ +import torch + +from batdetect2.models.blocks import ( + SelfAttention, + SelfAttentionConfig, + VerticalMeanConfig, +) +from batdetect2.models.bottleneck import ( + Bottleneck, + BottleneckConfig, + build_bottleneck, +) + + +def test_bottleneck_layers_use_frequency_aggregation_channels() -> None: + """Layers after frequency aggregation are built for aggregated channels.""" + config = BottleneckConfig( + channels=128, + frequency_aggregation=VerticalMeanConfig(channels=128), + layers=[SelfAttentionConfig(attention_channels=32)], + ) + + bottleneck = build_bottleneck( + input_height=8, + in_channels=64, + config=config, + ) + + assert isinstance(bottleneck, Bottleneck) + attention = bottleneck.layers[0] + assert isinstance(attention, SelfAttention) + assert attention.in_channels == 128 + + output = bottleneck(torch.randn(2, 64, 8, 10)) + + assert output.shape == (2, 128, 8, 10) + + +def test_bottleneck_default_frequency_aggregation_matches_channels() -> None: + """Minimal configs keep advertised and actual output channels in sync.""" + config = BottleneckConfig(channels=128, layers=[]) + + bottleneck = build_bottleneck( + input_height=8, + in_channels=64, + config=config, + ) + + assert isinstance(bottleneck, Bottleneck) + assert bottleneck.out_channels == 128 + assert bottleneck.conv_vert.out_channels == 128 + + output = bottleneck(torch.randn(2, 64, 8, 10)) + + assert output.shape == (2, bottleneck.out_channels, 8, 10) diff --git a/uv.lock b/uv.lock index 0a68e27..4d50e3e 100644 --- a/uv.lock +++ b/uv.lock @@ -453,7 +453,7 @@ wheels = [ [[package]] name = "batdetect2" -version = "2.0.0b1" +version = "2.0.0b2" source = { editable = "." } dependencies = [ { name = "click" }, @@ -557,8 +557,8 @@ requires-dist = [ { name = "soundevent", extras = ["audio", "geometry", "plot"], specifier = ">=2.10.0" }, { name = "soundfile", specifier = ">=0.12.1" }, { name = "tensorboard", specifier = ">=2.16.2" }, - { name = "torch", specifier = ">=1.13.1" }, - { name = "torchaudio", specifier = ">=1.13.1" }, + { name = "torch", specifier = ">=2.0.0" }, + { name = "torchaudio", specifier = ">=2.0.0" }, { name = "xarray", specifier = ">=2024.0.0" }, ] @@ -626,10 +626,10 @@ name = "bitsandbytes" version = "0.49.2" 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' and sys_platform == 'darwin') or (python_full_version < '3.11' and sys_platform == 'linux') or (python_full_version < '3.11' and sys_platform == 'win32')" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform == 'linux') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, - { name = "packaging", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, - { name = "torch", marker = "sys_platform == 'darwin' or sys_platform == 'linux' or sys_platform == 'win32'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "packaging" }, + { name = "torch" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/d8/7d/f1fe0992334b18cd8494f89aeec1dcc674635584fcd9f115784fea3a1d05/bitsandbytes-0.49.2-py3-none-macosx_14_0_arm64.whl", hash = "sha256:87be5975edeac5396d699ecbc39dfc47cf2c026daaf2d5852a94368611a6823f", size = 131940, upload-time = "2026-02-16T21:26:04.572Z" }, @@ -1070,7 +1070,7 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/54/eb9bfc647b19f2009dd5c7f5ec51c4e6ca831725f1aea7a993034f483147/contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54", size = 13466130, upload-time = "2025-04-15T17:47:53.79Z" } wheels = [ @@ -1151,7 +1151,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -1345,7 +1345,7 @@ name = "cuda-bindings" version = "13.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cuda-pathfinder", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "cuda-pathfinder" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/1a/fe/7351d7e586a8b4c9f89731bfe4cf0148223e8f9903ff09571f78b3fb0682/cuda_bindings-13.2.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b395f79cb89ce0cd8effff07c4a1e20101b873c256a1aeb286e8fd7bd0f556", size = 5744254, upload-time = "2026-03-11T00:12:29.798Z" }, @@ -1376,37 +1376,37 @@ wheels = [ [package.optional-dependencies] cublas = [ - { name = "nvidia-cublas", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cublas" }, ] cudart = [ - { name = "nvidia-cuda-runtime", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime" }, ] cufft = [ - { name = "nvidia-cufft", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cufft" }, ] cufile = [ - { name = "nvidia-cufile", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cufile" }, ] cupti = [ - { name = "nvidia-cuda-cupti", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti" }, ] curand = [ - { name = "nvidia-curand", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-curand" }, ] cusolver = [ - { name = "nvidia-cusolver", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cusolver" }, ] cusparse = [ - { name = "nvidia-cusparse", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cusparse" }, ] nvjitlink = [ - { name = "nvidia-nvjitlink", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink" }, ] nvrtc = [ - { name = "nvidia-cuda-nvrtc", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc" }, ] nvtx = [ - { name = "nvidia-nvtx", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-nvtx" }, ] [[package]] @@ -1875,7 +1875,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] 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 = [ @@ -2417,7 +2417,7 @@ name = "gunicorn" version = "25.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "packaging", marker = "platform_machine != 'ARM64' or sys_platform != 'win32'" }, + { name = "packaging" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c4/f4/e78fa054248fab913e2eab0332c6c2cb07421fca1ce56d8fe43b6aef57a4/gunicorn-25.3.0.tar.gz", hash = "sha256:f74e1b2f9f76f6cd1ca01198968bd2dd65830edc24b6e8e4d78de8320e2fe889", size = 634883, upload-time = "2026-03-27T00:00:26.092Z" } wheels = [ @@ -2638,17 +2638,17 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version < '3.11'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "jedi", marker = "python_full_version < '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version < '3.11'" }, - { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "stack-data", marker = "python_full_version < '3.11'" }, - { name = "traitlets", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/40/18/f8598d287006885e7136451fdea0755af4ebcbfe342836f24deefaed1164/ipython-8.39.0.tar.gz", hash = "sha256:4110ae96012c379b8b6db898a07e186c40a2a1ef5d57a7fa83166047d9da7624", size = 5513971, upload-time = "2026-03-27T10:02:13.94Z" } wheels = [ @@ -2674,18 +2674,18 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version >= '3.11'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" }, - { name = "jedi", marker = "python_full_version >= '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" }, - { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" }, - { name = "psutil", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "stack-data", marker = "python_full_version >= '3.11'" }, - { name = "traitlets", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version == '3.11.*'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "psutil" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/87cda5842cf5c31837c06ddb588e11c3c35d8ece89b7a0108c06b8c9b00a/ipython-9.13.0.tar.gz", hash = "sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967", size = 4430549, upload-time = "2026-04-24T12:24:55.221Z" } wheels = [ @@ -2697,7 +2697,7 @@ name = "ipython-pygments-lexers" version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ @@ -3460,7 +3460,7 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version < '3.11'" }, + { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ @@ -3486,7 +3486,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version >= '3.11'" }, + { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } wheels = [ @@ -3961,12 +3961,12 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "jinja2", marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "mdit-py-plugins", marker = "python_full_version < '3.11'" }, - { name = "pyyaml", marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } }, + { name = "jinja2" }, + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } wheels = [ @@ -3992,12 +3992,12 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "jinja2", marker = "python_full_version >= '3.11'" }, - { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "mdit-py-plugins", marker = "python_full_version >= '3.11'" }, - { name = "pyyaml", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "jinja2" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } @@ -4086,9 +4086,9 @@ resolution-markers = [ "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'", ] dependencies = [ - { name = "certifi", marker = "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'" }, - { name = "cftime", marker = "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and platform_machine == 'ARM64' and sys_platform == 'win32'" }, + { name = "certifi" }, + { name = "cftime" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/76/7bc801796dee752c1ce9cd6935564a6ee79d5c9d9ef9192f57b156495a35/netcdf4-1.7.3.tar.gz", hash = "sha256:83f122fc3415e92b1d4904fd6a0898468b5404c09432c34beb6b16c533884673", size = 836095, upload-time = "2025-10-13T18:38:00.76Z" } @@ -4114,8 +4114,8 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "certifi", marker = "python_full_version >= '3.11' or platform_machine != 'ARM64' or sys_platform != 'win32'" }, - { name = "cftime", marker = "python_full_version >= '3.11' or platform_machine != 'ARM64' or sys_platform != 'win32'" }, + { name = "certifi" }, + { name = "cftime" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and platform_machine != 'ARM64') or (python_full_version < '3.11' and sys_platform != 'win32')" }, { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] @@ -4427,7 +4427,7 @@ name = "nvidia-cudnn-cu13" version = "9.19.0.56" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cublas" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/f1/84/26025437c1e6b61a707442184fa0c03d083b661adf3a3eecfd6d21677740/nvidia_cudnn_cu13-9.19.0.56-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:6ed29ffaee1176c612daf442e4dd6cfeb6a0caa43ddcbeb59da94953030b1be4", size = 433781201, upload-time = "2026-02-03T20:40:53.805Z" }, @@ -4439,7 +4439,7 @@ name = "nvidia-cufft" version = "12.0.0.61" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" }, @@ -4469,9 +4469,9 @@ name = "nvidia-cusolver" version = "12.0.4.66" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-cublas", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, - { name = "nvidia-cusparse", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, - { name = "nvidia-nvjitlink", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-cublas" }, + { name = "nvidia-cusparse" }, + { name = "nvidia-nvjitlink" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" }, @@ -4483,7 +4483,7 @@ name = "nvidia-cusparse" version = "12.6.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "nvidia-nvjitlink", marker = "(platform_machine != 'ARM64' and sys_platform == 'win32') or sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" }, @@ -4762,8 +4762,8 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "types-pytz", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "types-pytz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/92/5d/be23854a73fda69f1dbdda7bc10fbd6f930bd1fa87aaec389f00c901c1e8/pandas_stubs-2.3.3.260113.tar.gz", hash = "sha256:076e3724bcaa73de78932b012ec64b3010463d377fa63116f4e6850643d93800", size = 116131, upload-time = "2026-01-13T22:30:16.704Z" } wheels = [ @@ -4789,7 +4789,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/27/1d/297ff2c7ea50a768a2247621d6451abb2a07c0e9be7ca6d36ebe371658e5/pandas_stubs-3.0.0.260204.tar.gz", hash = "sha256:bf9294b76352effcffa9cb85edf0bed1339a7ec0c30b8e1ac3d66b4228f1fbc3", size = 109383, upload-time = "2026-02-04T15:17:17.247Z" } wheels = [ @@ -4828,7 +4828,7 @@ name = "pexpect" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "ptyprocess", marker = "platform_machine != 'ARM64' or sys_platform != 'win32'" }, + { name = "ptyprocess" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ @@ -5311,14 +5311,14 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "accessible-pygments", marker = "python_full_version < '3.11'" }, - { name = "babel", marker = "python_full_version < '3.11'" }, - { name = "beautifulsoup4", marker = "python_full_version < '3.11'" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "pygments" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/67/ea/3ab478cccacc2e8ef69892c42c44ae547bae089f356c4b47caf61730958d/pydata_sphinx_theme-0.15.4.tar.gz", hash = "sha256:7762ec0ac59df3acecf49fd2f889e1b4565dbce8b88b2e29ee06fdd90645a06d", size = 2400673, upload-time = "2024-06-25T19:28:45.041Z" } wheels = [ @@ -5344,14 +5344,14 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "accessible-pygments", marker = "python_full_version >= '3.11'" }, - { name = "babel", marker = "python_full_version >= '3.11'" }, - { name = "beautifulsoup4", marker = "python_full_version >= '3.11'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "pygments" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/00/20/bb50f9de3a6de69e6abd6b087b52fa2418a0418b19597601605f855ad044/pydata_sphinx_theme-0.16.1.tar.gz", hash = "sha256:a08b7f0b7f70387219dc659bff0893a7554d5eb39b59d3b8ef37b8401b7642d7", size = 2412693, upload-time = "2024-12-17T10:53:39.537Z" } wheels = [ @@ -5390,7 +5390,7 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "cffi", marker = "python_full_version < '3.11'" }, + { name = "cffi" }, ] sdist = { url = "https://files.pythonhosted.org/packages/2e/ea/762d00f6f518423cd889e39b12028844cc95f91a6413cf7136e184864821/pygit2-1.18.2.tar.gz", hash = "sha256:eca87e0662c965715b7f13491d5e858df2c0908341dee9bde2bc03268e460f55", size = 797200, upload-time = "2025-08-16T13:52:36.853Z" } wheels = [ @@ -5451,7 +5451,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "cffi", marker = "python_full_version >= '3.11'" }, + { name = "cffi" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3a/a4/10ce00feef5c43eddacab19ae6610c4d4ef3ab77e544e9ee938772cd1c17/pygit2-1.19.2.tar.gz", hash = "sha256:cbeb3dbca9ca6ee3d5ea5d02f5e844c2d6084a2d5d6621e3e06aa2b11c645bfd", size = 803448, upload-time = "2026-03-29T14:57:27.565Z" } wheels = [ @@ -5880,15 +5880,15 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "affine", marker = "python_full_version < '3.12'" }, - { name = "attrs", marker = "python_full_version < '3.12'" }, - { name = "certifi", marker = "python_full_version < '3.12'" }, - { name = "click", marker = "python_full_version < '3.12'" }, - { name = "click-plugins", marker = "python_full_version < '3.12'" }, - { name = "cligj", marker = "python_full_version < '3.12'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "affine" }, + { name = "attrs" }, + { name = "certifi" }, + { name = "click" }, + { name = "click-plugins" }, + { name = "cligj" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version != '3.11.*'" }, { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "pyparsing", marker = "python_full_version < '3.12'" }, + { name = "pyparsing" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/fa/fce8dc9f09e5bc6520b6fc1b4ecfa510af9ca06eb42ad7bdff9c9b8989d0/rasterio-1.4.4.tar.gz", hash = "sha256:c95424e2c7f009b8f7df1095d645c52895cd332c0c2e1b4c2e073ea28b930320", size = 445004, upload-time = "2025-12-12T18:01:08.971Z" } wheels = [ @@ -5938,13 +5938,13 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "affine", marker = "python_full_version >= '3.12'" }, - { name = "attrs", marker = "python_full_version >= '3.12'" }, - { name = "certifi", marker = "python_full_version >= '3.12'" }, - { name = "click", marker = "python_full_version >= '3.12'" }, - { name = "cligj", marker = "python_full_version >= '3.12'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "pyparsing", marker = "python_full_version >= '3.12'" }, + { name = "affine" }, + { name = "attrs" }, + { name = "certifi" }, + { name = "click" }, + { name = "cligj" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, + { name = "pyparsing" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f6/88/edb4b66b6cb2c13f123af5a3896bf70c0cbe73ab3cd4243cb4eb0212a0f6/rasterio-1.5.0.tar.gz", hash = "sha256:1e0ea56b02eea4989b36edf8e58a5a3ef40e1b7edcb04def2603accd5ab3ee7b", size = 452184, upload-time = "2026-01-05T16:06:47.169Z" } wheels = [ @@ -6228,10 +6228,10 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "joblib", marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "threadpoolctl", marker = "python_full_version < '3.11'" }, + { name = "joblib" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" } }, + { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } wheels = [ @@ -6281,10 +6281,10 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "joblib", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "threadpoolctl", marker = "python_full_version >= '3.11'" }, + { name = "joblib" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" } }, + { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } wheels = [ @@ -6325,7 +6325,7 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } wheels = [ @@ -6395,7 +6395,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [ @@ -6748,23 +6748,23 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.11'" }, - { name = "babel", marker = "python_full_version < '3.11'" }, - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "imagesize", marker = "python_full_version < '3.11'" }, - { name = "jinja2", marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "requests", marker = "python_full_version < '3.11'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11'" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } wheels = [ @@ -6782,23 +6782,23 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version == '3.11.*'" }, - { name = "babel", marker = "python_full_version == '3.11.*'" }, - { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "imagesize", marker = "python_full_version == '3.11.*'" }, - { name = "jinja2", marker = "python_full_version == '3.11.*'" }, - { name = "packaging", marker = "python_full_version == '3.11.*'" }, - { name = "pygments", marker = "python_full_version == '3.11.*'" }, - { name = "requests", marker = "python_full_version == '3.11.*'" }, - { name = "roman-numerals", marker = "python_full_version == '3.11.*'" }, - { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ @@ -6820,23 +6820,23 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ @@ -6854,12 +6854,12 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "starlette", marker = "python_full_version < '3.11'" }, - { name = "uvicorn", marker = "python_full_version < '3.11'" }, - { name = "watchfiles", marker = "python_full_version < '3.11'" }, - { name = "websockets", marker = "python_full_version < '3.11'" }, + { name = "colorama" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023, upload-time = "2024-10-02T23:15:30.172Z" } wheels = [ @@ -6885,13 +6885,13 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "colorama" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "starlette", marker = "python_full_version >= '3.11'" }, - { name = "uvicorn", marker = "python_full_version >= '3.11'" }, - { name = "watchfiles", marker = "python_full_version >= '3.11'" }, - { name = "websockets", marker = "python_full_version >= '3.11'" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e0/3c/a59a3a453d4133777f7ed2e83c80b7dc817d43c74b74298ca0af869662ad/sphinx_autobuild-2025.8.25.tar.gz", hash = "sha256:9cf5aab32853c8c31af572e4fecdc09c997e2b8be5a07daf2a389e270e85b213", size = 15200, upload-time = "2025-08-25T18:44:55.436Z" } wheels = [ @@ -6909,7 +6909,7 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/26/f0/43c6a5ff3e7b08a8c3b32f81b859f1b518ccc31e45f22e2b41ced38be7b9/sphinx_autodoc_typehints-3.0.1.tar.gz", hash = "sha256:b9b40dd15dee54f6f810c924f863f9cf1c54f9f3265c495140ea01be7f44fa55", size = 36282, upload-time = "2025-01-16T18:25:30.958Z" } wheels = [ @@ -6927,7 +6927,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/1d/f6/bdd93582b2aaad2cfe9eb5695a44883c8bc44572dd3c351a947acbb13789/sphinx_autodoc_typehints-3.6.1.tar.gz", hash = "sha256:fa0b686ae1b85965116c88260e5e4b82faec3687c2e94d6a10f9b36c3743e2fe", size = 37563, upload-time = "2026-01-02T15:23:46.543Z" } wheels = [ @@ -6949,7 +6949,7 @@ resolution-markers = [ "python_full_version == '3.12.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/75/75/9a5695b3d3b848a43cfe91c7d7d3c5ab543eb3bc5c2a12ffaf5003a2a4f6/sphinx_autodoc_typehints-3.10.2.tar.gz", hash = "sha256:34db651eb14343ba16bd9c03e0f5093971f9bbd3cc6b0a1470adecd578940b9c", size = 74241, upload-time = "2026-04-15T22:09:48.87Z" } wheels = [ @@ -6967,8 +6967,8 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "pydata-sphinx-theme", version = "0.15.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pydata-sphinx-theme", version = "0.15.4", source = { registry = "https://pypi.org/simple" } }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/45/19/d002ed96bdc7738c15847c730e1e88282d738263deac705d5713b4d8fa94/sphinx_book_theme-1.1.4.tar.gz", hash = "sha256:73efe28af871d0a89bd05856d300e61edce0d5b2fbb7984e84454be0fedfe9ed", size = 439188, upload-time = "2025-02-20T16:32:32.581Z" } wheels = [ @@ -6994,8 +6994,8 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "pydata-sphinx-theme", version = "0.16.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "pydata-sphinx-theme", version = "0.16.1", source = { registry = "https://pypi.org/simple" } }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/f7/154786f3cfb7692cd7acc24b6dfe4dcd1146b66f376b17df9e47125555e9/sphinx_book_theme-1.2.0.tar.gz", hash = "sha256:4a7ebfc7da4395309ac942ddfc38fbec5c5254c3be22195e99ad12586fbda9e3", size = 443962, upload-time = "2026-03-09T23:20:30.442Z" } @@ -7163,8 +7163,8 @@ name = "standard-aifc" version = "3.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "audioop-lts", marker = "python_full_version >= '3.13'" }, - { name = "standard-chunk", marker = "python_full_version >= '3.13'" }, + { name = "audioop-lts" }, + { name = "standard-chunk" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c4/53/6050dc3dde1671eb3db592c13b55a8005e5040131f7509cef0215212cb84/standard_aifc-3.13.0.tar.gz", hash = "sha256:64e249c7cb4b3daf2fdba4e95721f811bde8bdfc43ad9f936589b7bb2fae2e43", size = 15240, upload-time = "2024-10-30T16:01:31.772Z" } wheels = [ @@ -7185,7 +7185,7 @@ name = "standard-sunau" version = "3.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "audioop-lts", marker = "python_full_version >= '3.13'" }, + { name = "audioop-lts" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/e3/ce8d38cb2d70e05ffeddc28bb09bad77cfef979eb0a299c9117f7ed4e6a9/standard_sunau-3.13.0.tar.gz", hash = "sha256:b319a1ac95a09a2378a8442f403c66f4fd4b36616d6df6ae82b8e536ee790908", size = 9368, upload-time = "2024-10-30T16:01:41.626Z" } wheels = [ @@ -7924,9 +7924,9 @@ resolution-markers = [ "python_full_version < '3.11' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "pandas", marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "pandas" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/ec/e50d833518f10b0c24feb184b209bb6856f25b919ba8c1f89678b930b1cd/xarray-2025.6.1.tar.gz", hash = "sha256:a84f3f07544634a130d7dc615ae44175419f4c77957a7255161ed99c69c7c8b0", size = 3003185, upload-time = "2025-06-12T03:04:09.099Z" } wheels = [ @@ -7952,9 +7952,9 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32'", ] dependencies = [ - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "packaging", marker = "python_full_version >= '3.11'" }, - { name = "pandas", marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" } }, + { name = "packaging" }, + { name = "pandas" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4b/a6/6fe936a798a3a38a79c7422d1a31afd2e9a14690fcb0ccff96bc01f04bf2/xarray-2026.4.0.tar.gz", hash = "sha256:c4ac9a01a945d90d5b1628e2af045099a9d4943536d4f2ee3ae963c3b222d15b", size = 3132311, upload-time = "2026-04-13T19:45:36.688Z" } wheels = [