Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions .evergreen/scripts/test_generate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def all_variants():

def variant_selects(variant, task):
"""Whether the variant's task selectors match the task: "." selects a
tag, "!" negates the token that follows, a bare token names a task."""
tag, "!" negates the token that follows, a bare token names a task.
"""
tags = task.tags or []
for ref in variant.tasks:
includes, excludes, names = [], [], []
Expand Down Expand Up @@ -75,7 +76,8 @@ def variant_selects(variant, task):
def test_pr_tasks_pin_max_version():
"""Task-level pins: pr tasks pin MAX_VERSION (the "latest" nightly is
unstable); the explicit 4.4 min-deps pin is the exception. Variant-merged
pins are checked by test_pr_tasks_effectively_pin_max_version."""
pins are checked by test_pr_tasks_effectively_pin_max_version.
"""
offenders = [
(task.name, task_vars(task).get("VERSION"))
for task in pr_tasks()
Expand All @@ -91,7 +93,8 @@ def test_pr_tasks_effectively_pin_max_version():
"""Effective pins: a pr task without its own VERSION var inherits the
selecting variant's version, so every pr task that runs a server must
resolve to MAX_VERSION once variant expansions merge in. The explicit
4.4 min-deps pin is the exception."""
4.4 min-deps pin is the exception.
"""
tasks = [task for task in all_tasks() if "pr" in (task.tags or [])]
offenders = []
for variant in all_variants():
Expand All @@ -117,7 +120,8 @@ def test_server_version_pr_tasks_selected_once():
create_server_version_variants(), not from the selections: a variant
missing its PR selector would otherwise drop from both sides and the
comparison would pass. Variants outside the family must not select these
tasks (the sanitizer variant pins MAX_VERSION for its own mongod)."""
tasks (the sanitizer variant pins MAX_VERSION for its own mongod).
"""
sv_tasks = [task for task in pr_tasks() if "server-version" in (task.tags or [])]
sv_variants = generate_config.create_server_version_variants()
offenders = {}
Expand All @@ -138,7 +142,8 @@ def test_server_version_pr_tasks_selected_once():

def test_pr_tasks_cover_version_boundaries():
"""PRs test the server version boundaries: the newest numbered server
with every Python boundary, the min server with its min-Python floor."""
with every Python boundary, the min server with its min-Python floor.
"""
for version, pythons in (
(
generate_config_utils.MAX_VERSION,
Expand All @@ -160,7 +165,8 @@ def test_pr_tasks_cover_version_boundaries():

def test_server_version_rotated_tasks_keep_coverage():
"""Per-commit coverage for this family rides the rotated boundary-Python
tasks, not the pr tasks (which run only on MAX_VERSION)."""
tasks, not the pr tasks (which run only on MAX_VERSION).
"""
family = [task for task in all_tasks() if "server-version" in (task.tags or [])]
cov = [task for task in family if task_vars(task).get("COVERAGE") == "1"]
assert any("pr" not in (task.tags or []) for task in cov), (
Expand Down Expand Up @@ -194,7 +200,8 @@ def test_pr_min_deps_tasks_also_run_coverage():
def test_standard_family_pr_budget():
"""Patch-build PR budget: at most 5 pr-tagged test-standard tasks (the
pre-pin baseline), at most 3 on Python 3.14+ (the ubuntu22 compression
filter)."""
filter).
"""
tasks = [task for task in pr_tasks() if "test-standard" in (task.tags or [])]
assert len(tasks) <= 5, f"too many test-standard PR tasks: {[t.name for t in tasks]}"
newer = [
Expand All @@ -210,7 +217,8 @@ def test_standard_family_pr_budget():

def test_pr_tasks_run_coverage():
"""Pr tasks that pin a server version run with COVERAGE=1; no-cov
companions and infrastructure tasks (no VERSION) are exempt."""
companions and infrastructure tasks (no VERSION) are exempt.
"""
offenders = [
task.name
for task in pr_tasks()
Expand All @@ -224,7 +232,8 @@ def test_pr_tasks_run_coverage():
def test_rotated_tasks_keep_nightly_coverage():
"""Batch coverage rides the rotation independently of the pr tasks:
rotated "latest" tasks and max-Python auth-aws tasks keep COVERAGE=1
(min-deps excepted)."""
(min-deps excepted).
"""
offenders = []
for task in all_tasks():
tags = task.tags or []
Expand Down Expand Up @@ -272,7 +281,8 @@ def test_rotated_tasks_keep_nightly_coverage():
def test_non_standard_cov_tasks_have_no_cov_companions():
"""Each non-standard coverage task also emits a no-cov companion, so the
macOS/Win64 encryption variants (which filter .cov) have a task to
activate in patch builds."""
activate in patch builds.
"""
no_cov = {task.name for task in all_tasks() if "test-non-standard-no-cov" in (task.tags or [])}
for task in all_tasks():
if "test-non-standard-no-cov" in (task.tags or []):
Expand All @@ -286,7 +296,8 @@ def test_sanitizer_task_wiring():
"""PYTHON-6048: one pr-tagged sanitizer task, selected by exactly one
variant that pins MAX_VERSION and runs on a large host for ASan's memory
headroom. VERSION stays off the task so it is exempt
from the pr COVERAGE rule (coverage under ASan is not useful)."""
from the pr COVERAGE rule (coverage under ASan is not useful).
"""
tasks = [task for task in all_tasks() if "sanitizer" in (task.tags or [])]
assert len(tasks) == 1
task = tasks[0]
Expand Down
3 changes: 1 addition & 2 deletions bson/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ def _bson_to_dict(data: Any, opts: CodecOptions[_DocumentType]) -> _DocumentType


def gen_list_name() -> Generator[bytes, None, None]:
"""Generate "keys" for encoded lists in the sequence
r"""Generate "keys" for encoded lists in the sequence
b"0\x00", b"1\x00", b"2\x00", ...

The first 1000 keys are returned from a pre-built cache. All
Expand Down Expand Up @@ -951,7 +951,6 @@ def _name_value_to_bson(
in_fallback_call: bool = False,
) -> bytes:
"""Encode a single name, value pair."""

was_integer_overflow = False

# First see if the type is already cached. KeyError will only ever
Expand Down
1 change: 0 additions & 1 deletion bson/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,6 @@ def as_vector(self, return_numpy: bool = False) -> BinaryVector:

.. versionadded:: 4.10
"""

if self.subtype != VECTOR_SUBTYPE:
raise ValueError(f"Cannot decode subtype {self.subtype} as a vector")

Expand Down
4 changes: 2 additions & 2 deletions bson/codec_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class CodecOptions(_BaseCodecOptions):
"""Encapsulates options used encoding and / or decoding BSON."""

def __init__(self, *args, **kwargs):
"""Encapsulates options used encoding and / or decoding BSON.
r"""Encapsulates options used encoding and / or decoding BSON.

The `document_class` option is used to define a custom type for use
decoding BSON documents. Access to the underlying raw BSON bytes for
Expand All @@ -298,7 +298,7 @@ def __init__(self, *args, **kwargs):
>>> coll = db.get_collection('test', codec_options=codec_options)
>>> doc = coll.find_one()
>>> doc.raw
'\\x16\\x00\\x00\\x00\\x07_id\\x00[0\\x165\\x91\\x10\\xea\\x14\\xe8\\xc5\\x8b\\x93\\x00'
'\x16\x00\x00\x00\x07_id\x00[0\x165\x91\x10\xea\x14\xe8\xc5\x8b\x93\x00'

The document class can be any type that inherits from
:class:`~collections.abc.MutableMapping`::
Expand Down
3 changes: 2 additions & 1 deletion bson/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def __init__(self, message: str, document: Any | None = None) -> None:
def document(self) -> Any:
"""The invalid document that caused the error.

..versionadded:: 4.16"""
.. versionadded:: 4.16
"""
return self._document


Expand Down
2 changes: 1 addition & 1 deletion bson/json_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tools for using Python's :mod:`json` module with BSON documents.
r"""Tools for using Python's :mod:`json` module with BSON documents.

This module provides two helper methods `dumps` and `loads` that wrap the
native :mod:`json` methods and provide explicit BSON conversion to and from
Expand Down
3 changes: 2 additions & 1 deletion fuzz/build_corpus.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ def seed_boundary_documents(zw: zipfile.ZipFile) -> None:

def seed_large_document(zw: zipfile.ZipFile) -> None:
"""Seed one ~500 KB document; without it, libFuzzer's max_len default
keeps mutation below the size where large-input paths live."""
keeps mutation below the size where large-input paths live.
"""
doc = {
"long_string": "a" * (256 * 1024),
"many_fields": {f"f{i:05d}": i for i in range(5_000)},
Expand Down
4 changes: 2 additions & 2 deletions gridfs/asynchronous/grid_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -1766,9 +1766,9 @@ def seekable(self) -> bool:
return True

def __aiter__(self) -> AsyncGridOut:
"""Return an iterator over all of this file's data.
r"""Return an iterator over all of this file's data.

The iterator will return lines (delimited by ``b'\\n'``) of
The iterator will return lines (delimited by ``b'\n'``) of
:class:`bytes`. This can be useful when serving files
using a webserver that handles such an iterator efficiently.

Expand Down
1 change: 0 additions & 1 deletion gridfs/grid_file_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def _a_grid_in_property(
closed_only: bool | None = False,
) -> Any:
"""Create a GridIn property."""

warn_str = ""
if docstring.startswith("DEPRECATED,"):
warn_str = (
Expand Down
4 changes: 2 additions & 2 deletions gridfs/synchronous/grid_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -1748,9 +1748,9 @@ def seekable(self) -> bool:
return True

def __iter__(self) -> GridOut:
"""Return an iterator over all of this file's data.
r"""Return an iterator over all of this file's data.

The iterator will return lines (delimited by ``b'\\n'``) of
The iterator will return lines (delimited by ``b'\n'``) of
:class:`bytes`. This can be useful when serving files
using a webserver that handles such an iterator efficiently.

Expand Down
3 changes: 2 additions & 1 deletion pymongo/_asyncio_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

"""Lock and Condition classes vendored from https://github.com/python/cpython/blob/main/Lib/asyncio/locks.py
to port 3.13 fixes to older versions of Python.
Can be removed once we drop Python 3.12 support."""
Can be removed once we drop Python 3.12 support.
"""

from __future__ import annotations

Expand Down
4 changes: 2 additions & 2 deletions pymongo/asynchronous/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -1220,11 +1220,11 @@ async def list_collection_names(
comment: Any | None = None,
**kwargs: Any,
) -> list[str]:
"""Get a list of all the collection names in this database.
r"""Get a list of all the collection names in this database.

For example, to list all non-system collections::

filter = {"name": {"$regex": r"^(?!system\\.)"}}
filter = {"name": {"$regex": r"^(?!system\.)"}}
db.list_collection_names(filter=filter)

:param session: a
Expand Down
2 changes: 0 additions & 2 deletions pymongo/asynchronous/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,6 @@ def append_metadata(self, driver_info: DriverInfo) -> None:

.. versionadded:: 4.14
"""

if not isinstance(driver_info, DriverInfo):
raise TypeError(
f"driver_info must be an instance of DriverInfo, not {type(driver_info)}"
Expand Down Expand Up @@ -2122,7 +2121,6 @@ async def _retryable_read(
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
:param operation_id: Stable operation id shared across retries, defaults to None
"""

# Ensure that the client supports retrying on reads and there is no session in
# transaction, otherwise, we will not support retry behavior for this call.
retryable = bool(
Expand Down
3 changes: 2 additions & 1 deletion pymongo/pool_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@

def get_container_env_info() -> dict[str, str]:
"""Returns the runtime and orchestrator of a container.
If neither value is present, the metadata client.env.container field will be omitted."""
If neither value is present, the metadata client.env.container field will be omitted.
"""
container = {}

if Path(DOCKER_ENV_PATH).exists():
Expand Down
4 changes: 2 additions & 2 deletions pymongo/synchronous/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,11 +1217,11 @@ def list_collection_names(
comment: Any | None = None,
**kwargs: Any,
) -> list[str]:
"""Get a list of all the collection names in this database.
r"""Get a list of all the collection names in this database.

For example, to list all non-system collections::

filter = {"name": {"$regex": r"^(?!system\\.)"}}
filter = {"name": {"$regex": r"^(?!system\.)"}}
db.list_collection_names(filter=filter)

:param session: a
Expand Down
2 changes: 0 additions & 2 deletions pymongo/synchronous/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,6 @@ def append_metadata(self, driver_info: DriverInfo) -> None:

.. versionadded:: 4.14
"""

if not isinstance(driver_info, DriverInfo):
raise TypeError(
f"driver_info must be an instance of DriverInfo, not {type(driver_info)}"
Expand Down Expand Up @@ -2116,7 +2115,6 @@ def _retryable_read(
:param is_aggregate_write: If this is a aggregate operation with a write, defaults to False.
:param operation_id: Stable operation id shared across retries, defaults to None
"""

# Ensure that the client supports retrying on reads and there is no session in
# transaction, otherwise, we will not support retry behavior for this call.
retryable = bool(
Expand Down
4 changes: 1 addition & 3 deletions pymongo/topology_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,7 @@ def reset(self) -> TopologyDescription:
)

def server_descriptions(self) -> dict[_Address, ServerDescription]:
"""dict of (address,
:class:`~pymongo.server_description.ServerDescription`).
"""
"""Return a dict of (address, :class:`~pymongo.server_description.ServerDescription`)."""
return self._server_descriptions.copy()

@property
Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ extend-select = [
"EXE", # flake8-executable
"ASYNC", # flake8-async
"TC", # flake8-type-checking
"D202", # pydocstyle: no blank lines between docstring and function body.
"D209", # pydocstyle: closing quotes go on their own line.
"D301", # pydocstyle: docstrings containing \ are defined as string literals.
"D403", # pydocstyle: docstrings start with a capital letter.
]
ignore = [
"PLR", # Design related pylint codes
Expand Down Expand Up @@ -257,6 +261,7 @@ exclude = []
flake8-unused-arguments.ignore-variadic-names = true
isort.required-imports = ["from __future__ import annotations"]
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$"
pydocstyle.convention = "pep257"

[tool.ruff.lint.per-file-ignores]
"pymongo/__init__.py" = ["E402"]
Expand Down
6 changes: 0 additions & 6 deletions test/asynchronous/test_index_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ class TestSearchIndexProse(SearchIndexIntegrationBase):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_1(self):
"""Driver can successfully create and list search indexes."""

# Create a new search index on ``self.coll0`` with the ``createSearchIndex`` helper. Use the following definition:
model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}}
resp = await self.coll0.create_search_index(model)
Expand All @@ -204,7 +203,6 @@ async def test_case_1(self):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_2(self):
"""Driver can successfully create multiple indexes in batch."""

# Create two new search indexes on ``self.coll0`` with the ``createSearchIndexes`` helper.
name1 = "test-search-index-1"
name2 = "test-search-index-2"
Expand Down Expand Up @@ -239,7 +237,6 @@ async def test_case_2(self):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_3(self):
"""Driver can successfully drop search indexes."""

# Create a new search index on ``self.coll0``.
model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}}
resp = await self.coll0.create_search_index(model)
Expand All @@ -258,7 +255,6 @@ async def test_case_3(self):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_4(self):
"""Driver can update a search index."""

# Create a new search index on ``self.coll0``.
model = {"name": _NAME, "definition": {"mappings": {"dynamic": False}}}
resp = await self.coll0.create_search_index(model)
Expand Down Expand Up @@ -299,7 +295,6 @@ async def test_case_5(self):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_6(self):
"""Driver can successfully create and list search indexes with non-default readConcern and writeConcern."""

# Apply a write concern ``WriteConcern(w=1)`` and a read concern with ``ReadConcern(level="majority")`` to ``self.coll0``.
coll0 = self.coll0.with_options(
write_concern=WriteConcern(w="1"), read_concern=ReadConcern(level="majority")
Expand All @@ -325,7 +320,6 @@ async def test_case_6(self):
@flaky(reason="PYTHON-6056", affects_cpython_linux=True)
async def test_case_7(self):
"""Driver handles index types."""

# Use these search and vector search definitions for indexes.
search_definition = {"mappings": {"dynamic": False}}
vector_search_definition = {
Expand Down
3 changes: 2 additions & 1 deletion test/asynchronous/test_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ async def test_cleanup_executors_on_client_close(self):
@async_client_context.require_sync
def test_no_thread_start_runtime_err_on_shutdown(self):
"""Test we silence noisy runtime errors fired when the AsyncMongoClient spawns a new thread
on process shutdown."""
on process shutdown.
"""
command = [
sys.executable,
"-c",
Expand Down
1 change: 0 additions & 1 deletion test/asynchronous/test_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ def test_ssl_session_cache(self):
@unittest.skipUnless(_IS_SYNC, "Tests sync wrap_socket path only")
def test_tls_session_reused_on_second_connection(self):
"""Cached TLS session is passed to wrap_socket on subsequent connections."""

fake_session = object()
cache: list = [fake_session]

Expand Down
1 change: 0 additions & 1 deletion test/test_bson.py
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,6 @@ def assertRepr(self, obj):

def test_binaryvector_repr(self):
"""Tests of repr(BinaryVector)"""

data = [1 / 127, -7 / 6]
one = BinaryVector(data, BinaryVectorDtype.FLOAT32)
self.assertEqual(
Expand Down
Loading
Loading