Skip to content

Commit

Permalink
Merge branch 'master' into async-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahStapp authored Nov 12, 2024
2 parents f6e35d9 + 63c3f8a commit 92b7946
Show file tree
Hide file tree
Showing 36 changed files with 1,410 additions and 398 deletions.
454 changes: 223 additions & 231 deletions .evergreen/generated_configs/variants.yml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions .evergreen/scripts/configure-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ export PROJECT="$project"
export PIP_QUIET=1
EOT

# Skip CSOT tests on non-linux platforms.
if [ "$(uname -s)" != "Linux" ]; then
echo "export SKIP_CSOT_TESTS=1" >> $SCRIPT_DIR/env.sh
fi

# Add these expansions to make it easier to call out tests scripts from the EVG yaml
cat <<EOT > expansion.yml
DRIVERS_TOOLS: "$DRIVERS_TOOLS"
Expand Down
525 changes: 452 additions & 73 deletions .evergreen/scripts/generate_config.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref }}
persist-credentials: false
- uses: actions/setup-python@v5

# Initializes the CodeQL tools for scanning.
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ inputs.ref }}

- uses: actions/setup-python@v5
Expand Down Expand Up @@ -106,6 +107,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ inputs.ref }}

- uses: actions/setup-python@v5
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "3.9"
Expand Down Expand Up @@ -55,6 +57,8 @@ jobs:
name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- if: ${{ matrix.python-version == '3.13t' }}
name: Setup free-threaded Python
uses: deadsnakes/action@v3.2.0
Expand Down Expand Up @@ -99,6 +103,8 @@ jobs:
name: DocTest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Python
uses: actions/setup-python@v5
with:
Expand All @@ -121,6 +127,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
cache: 'pip'
Expand All @@ -139,6 +147,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
cache: 'pip'
Expand All @@ -160,6 +170,8 @@ jobs:
python: ["3.9", "3.11"]
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: "${{matrix.python}}"
Expand All @@ -177,6 +189,8 @@ jobs:
name: "Make an sdist"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
cache: 'pip'
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: GitHub Actions Security Analysis with zizmor 🌈

on:
push:
branches: ["master"]
pull_request:
branches: ["**"]

jobs:
zizmor:
name: zizmor latest via Cargo
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Get zizmor
run: cargo install zizmor
- name: Run zizmor 🌈
run: zizmor --format sarif . > results.sarif
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: zizmor
28 changes: 20 additions & 8 deletions bson/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import struct
from dataclasses import dataclass
from enum import Enum
from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, Type, Union
from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, Type, Union, overload
from uuid import UUID

"""Tools for representing BSON binary data.
Expand Down Expand Up @@ -195,7 +195,7 @@ class UuidRepresentation:


VECTOR_SUBTYPE = 9
"""**(BETA)** BSON binary subtype for densely packed vector data.
"""BSON binary subtype for densely packed vector data.
.. versionadded:: 4.10
"""
Expand All @@ -207,7 +207,7 @@ class UuidRepresentation:


class BinaryVectorDtype(Enum):
"""**(BETA)** Datatypes of vector subtype.
"""Datatypes of vector subtype.
:param FLOAT32: (0x27) Pack list of :class:`float` as float32
:param INT8: (0x03) Pack list of :class:`int` in [-128, 127] as signed int8
Expand All @@ -229,7 +229,7 @@ class BinaryVectorDtype(Enum):

@dataclass
class BinaryVector:
"""**(BETA)** Vector of numbers along with metadata for binary interoperability.
"""Vector of numbers along with metadata for binary interoperability.
.. versionadded:: 4.10
"""

Expand All @@ -256,7 +256,7 @@ class Binary(bytes):
the difference between what should be considered binary data and
what should be considered a string when we encode to BSON.
**(BETA)** Subtype 9 provides a space-efficient representation of 1-dimensional vector data.
Subtype 9 provides a space-efficient representation of 1-dimensional vector data.
Its data is prepended with two bytes of metadata.
The first (dtype) describes its data type, such as float32 or int8.
The second (padding) prescribes the number of bits to ignore in the final byte.
Expand All @@ -278,7 +278,7 @@ class Binary(bytes):
Support any bytes-like type that implements the buffer protocol.
.. versionchanged:: 4.10
**(BETA)** Addition of vector subtype.
Addition of vector subtype.
"""

_type_marker = 5
Expand Down Expand Up @@ -397,14 +397,26 @@ def as_uuid(self, uuid_representation: int = UuidRepresentation.STANDARD) -> UUI
f"cannot decode subtype {self.subtype} to {UUID_REPRESENTATION_NAMES[uuid_representation]}"
)

@classmethod
@overload
def from_vector(cls: Type[Binary], vector: BinaryVector) -> Binary:
...

@classmethod
@overload
def from_vector(
cls: Type[Binary], vector: list[int, float], dtype: BinaryVectorDtype, padding: int = 0
) -> Binary:
...

@classmethod
def from_vector(
cls: Type[Binary],
vector: Union[BinaryVector, list[int, float]],
dtype: Optional[BinaryVectorDtype] = None,
padding: Optional[int] = None,
) -> Binary:
"""**(BETA)** Create a BSON :class:`~bson.binary.Binary` of Vector subtype.
"""Create a BSON :class:`~bson.binary.Binary` of Vector subtype.
To interpret the representation of the numbers, a data type must be included.
See :class:`~bson.binary.BinaryVectorDtype` for available types and descriptions.
Expand Down Expand Up @@ -447,7 +459,7 @@ def from_vector(
return cls(metadata + data, subtype=VECTOR_SUBTYPE)

def as_vector(self) -> BinaryVector:
"""**(BETA)** From the Binary, create a list of numbers, along with dtype and padding.
"""From the Binary, create a list of numbers, along with dtype and padding.
:return: BinaryVector
Expand Down
9 changes: 1 addition & 8 deletions pymongo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@

from pymongo import _csot
from pymongo._version import __version__, get_version_string, version_tuple
from pymongo.asynchronous.mongo_client import AsyncMongoClient
from pymongo.common import MAX_SUPPORTED_WIRE_VERSION, MIN_SUPPORTED_WIRE_VERSION, has_c
from pymongo.cursor import CursorType
from pymongo.operations import (
Expand All @@ -104,14 +105,6 @@
from pymongo.synchronous.mongo_client import MongoClient
from pymongo.write_concern import WriteConcern

try:
from pymongo.asynchronous.mongo_client import AsyncMongoClient
except Exception as e:
# PYTHON-4781: Importing asyncio can fail on Windows.
import warnings as _warnings

_warnings.warn(f"Failed to import Async PyMongo: {e!r}", ImportWarning, stacklevel=2)

version = __version__
"""Current version of PyMongo."""

Expand Down
2 changes: 1 addition & 1 deletion pymongo/asynchronous/auth_oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _get_authenticator(
properties = credentials.mechanism_properties

# Validate that the address is allowed.
if not properties.environment:
if properties.human_callback is not None:
found = False
allowed_hosts = properties.allowed_hosts
for patt in allowed_hosts:
Expand Down
18 changes: 10 additions & 8 deletions pymongo/asynchronous/bulk.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,18 +140,18 @@ def add_update(
self,
selector: Mapping[str, Any],
update: Union[Mapping[str, Any], _Pipeline],
multi: bool = False,
upsert: bool = False,
multi: bool,
upsert: Optional[bool],
collation: Optional[Mapping[str, Any]] = None,
array_filters: Optional[list[Mapping[str, Any]]] = None,
hint: Union[str, dict[str, Any], None] = None,
sort: Optional[Mapping[str, Any]] = None,
) -> None:
"""Create an update document and add it to the list of ops."""
validate_ok_for_update(update)
cmd: dict[str, Any] = dict( # noqa: C406
[("q", selector), ("u", update), ("multi", multi), ("upsert", upsert)]
)
cmd: dict[str, Any] = {"q": selector, "u": update, "multi": multi}
if upsert is not None:
cmd["upsert"] = upsert
if collation is not None:
self.uses_collation = True
cmd["collation"] = collation
Expand All @@ -173,14 +173,16 @@ def add_replace(
self,
selector: Mapping[str, Any],
replacement: Mapping[str, Any],
upsert: bool = False,
upsert: Optional[bool],
collation: Optional[Mapping[str, Any]] = None,
hint: Union[str, dict[str, Any], None] = None,
sort: Optional[Mapping[str, Any]] = None,
) -> None:
"""Create a replace document and add it to the list of ops."""
validate_ok_for_replace(replacement)
cmd = {"q": selector, "u": replacement, "multi": False, "upsert": upsert}
cmd: dict[str, Any] = {"q": selector, "u": replacement}
if upsert is not None:
cmd["upsert"] = upsert
if collation is not None:
self.uses_collation = True
cmd["collation"] = collation
Expand All @@ -200,7 +202,7 @@ def add_delete(
hint: Union[str, dict[str, Any], None] = None,
) -> None:
"""Create a delete document and add it to the list of ops."""
cmd = {"q": selector, "limit": limit}
cmd: dict[str, Any] = {"q": selector, "limit": limit}
if collation is not None:
self.uses_collation = True
cmd["collation"] = collation
Expand Down
16 changes: 1 addition & 15 deletions pymongo/asynchronous/client_bulk.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,13 @@ def __init__(
self.bypass_doc_val = bypass_document_validation
self.comment = comment
self.verbose_results = verbose_results

self.ops: list[tuple[str, Mapping[str, Any]]] = []
self.namespaces: list[str] = []
self.idx_offset: int = 0
self.total_ops: int = 0

self.executed = False
self.uses_upsert = False
self.uses_collation = False
self.uses_array_filters = False
self.uses_hint_update = False
self.uses_hint_delete = False
self.uses_sort = False

self.is_retryable = self.client.options.retry_writes
self.retrying = False
self.started_retryable_write = False
Expand All @@ -144,7 +137,7 @@ def add_update(
namespace: str,
selector: Mapping[str, Any],
update: Union[Mapping[str, Any], _Pipeline],
multi: bool = False,
multi: bool,
upsert: Optional[bool] = None,
collation: Optional[Mapping[str, Any]] = None,
array_filters: Optional[list[Mapping[str, Any]]] = None,
Expand All @@ -160,19 +153,16 @@ def add_update(
"multi": multi,
}
if upsert is not None:
self.uses_upsert = True
cmd["upsert"] = upsert
if array_filters is not None:
self.uses_array_filters = True
cmd["arrayFilters"] = array_filters
if hint is not None:
self.uses_hint_update = True
cmd["hint"] = hint
if collation is not None:
self.uses_collation = True
cmd["collation"] = collation
if sort is not None:
self.uses_sort = True
cmd["sort"] = sort
if multi:
# A bulk_write containing an update_many is not retryable.
Expand Down Expand Up @@ -200,16 +190,13 @@ def add_replace(
"multi": False,
}
if upsert is not None:
self.uses_upsert = True
cmd["upsert"] = upsert
if hint is not None:
self.uses_hint_update = True
cmd["hint"] = hint
if collation is not None:
self.uses_collation = True
cmd["collation"] = collation
if sort is not None:
self.uses_sort = True
cmd["sort"] = sort
self.ops.append(("replace", cmd))
self.namespaces.append(namespace)
Expand All @@ -226,7 +213,6 @@ def add_delete(
"""Create a delete document and add it to the list of ops."""
cmd = {"delete": -1, "filter": selector, "multi": multi}
if hint is not None:
self.uses_hint_delete = True
cmd["hint"] = hint
if collation is not None:
self.uses_collation = True
Expand Down
Loading

0 comments on commit 92b7946

Please sign in to comment.