diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000000..e5bc58921a --- /dev/null +++ b/.flake8 @@ -0,0 +1,30 @@ +[flake8] +max-line-length = 100 +enable-extensions = G +extend-ignore = + G200, G202, + # black adds spaces around ':' + E203, + # E501 line too long (let black handle line length) + E501 + # B305 `.next()` is not a thing on Python 3 + B305 +per-file-ignores = + # E402 module level import not at top of file + pymongo/__init__.py: E402 + + # G004 Logging statement uses f-string + pymongo/event_loggers.py: G004 + + # E402 module level import not at top of file + # B011 Do not call assert False since python -O removes these calls + # F405 'Foo' may be undefined, or defined from star imports + # E741 ambiguous variable name + # B007 Loop control variable 'foo' not used within the loop body + # F403 'from foo import *' used; unable to detect undefined names + # B001 Do not use bare `except:` + # E722 do not use bare 'except' + # E731 do not assign a lambda expression, use a def + # F811 redefinition of unused 'foo' from line XXX + # F841 local variable 'foo' is assigned to but never used + test/*: E402, B011, F405, E741, B007, F403, B001, E722, E731, F811, F841 diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index 4b5f762786..046915b04a 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -31,6 +31,8 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: 'setup.py' - name: Start MongoDB uses: supercharge/mongodb-github-action@1.7.0 with: @@ -53,6 +55,8 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: 'setup.py' - name: Install dependencies run: | python -m pip install -U pip mypy diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b20ad7ae55..5c1e92f5b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.1.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -24,17 +24,36 @@ repos: args: [--line-length=100] - repo: https://github.com/PyCQA/isort - rev: 5.7.0 + rev: 5.10.1 hooks: - id: isort files: \.py$ args: [--profile=black] +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.9.2 + hooks: + - id: flake8 + additional_dependencies: [ + 'flake8-bugbear==20.1.4', + 'flake8-logging-format==0.6.0', + 'flake8-implicit-str-concat==0.2.0', + ] + # We use the Python version instead of the original version which seems to require Docker # https://github.com/koalaman/shellcheck-precommit - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.8.0.1 + rev: v0.8.0.4 hooks: - id: shellcheck name: shellcheck args: ["--severity=warning"] + +- repo: https://github.com/sirosen/check-jsonschema + rev: 0.11.0 + hooks: + - id: check-jsonschema + name: "Check GitHub Workflows" + files: ^\.github/workflows/ + types: [yaml] + args: ["--schemafile", "https://json.schemastore.org/github-workflow"] diff --git a/bson/__init__.py b/bson/__init__.py index d9124d1b32..a287db1801 100644 --- a/bson/__init__.py +++ b/bson/__init__.py @@ -84,7 +84,7 @@ cast, ) -from bson.binary import ( +from bson.binary import ( # noqa: F401 ALL_UUID_SUBTYPES, CSHARP_LEGACY, JAVA_LEGACY, @@ -513,7 +513,7 @@ def _bson_to_dict(data: Any, opts: Any) -> Any: if _USE_C: - _bson_to_dict = _cbson._bson_to_dict + _bson_to_dict = _cbson._bson_to_dict # noqa: F811 _PACK_FLOAT = struct.Struct(" bytes: """Make a 'C' string, checking for embedded NUL characters.""" if isinstance(string, bytes): if b"\x00" in string: - raise InvalidDocument("BSON keys / regex patterns must not " "contain a NUL character") + raise InvalidDocument("BSON keys / regex patterns must not contain a NUL character") try: _utf_8_decode(string, None, True) return string + b"\x00" except UnicodeError: - raise InvalidStringData("strings in documents must be valid " "UTF-8: %r" % string) + raise InvalidStringData("strings in documents must be valid UTF-8: %r" % string) else: if "\x00" in string: - raise InvalidDocument("BSON keys / regex patterns must not " "contain a NUL character") + raise InvalidDocument("BSON keys / regex patterns must not contain a NUL character") return cast(bytes, _utf_8_encode(string)[0]) + b"\x00" @@ -562,7 +562,7 @@ def _make_c_string(string: Union[str, bytes]) -> bytes: _utf_8_decode(string, None, True) return string + b"\x00" except UnicodeError: - raise InvalidStringData("strings in documents must be valid " "UTF-8: %r" % string) + raise InvalidStringData("strings in documents must be valid UTF-8: %r" % string) else: return cast(bytes, _utf_8_encode(string)[0]) + b"\x00" @@ -571,7 +571,7 @@ def _make_name(string: str) -> bytes: """Make a 'C' string suitable for a BSON key.""" # Keys can only be text in python 3. if "\x00" in string: - raise InvalidDocument("BSON keys / regex patterns must not " "contain a NUL character") + raise InvalidDocument("BSON keys / regex patterns must not contain a NUL character") return cast(bytes, _utf_8_encode(string)[0]) + b"\x00" @@ -846,7 +846,7 @@ def _name_value_to_bson( def _element_to_bson(key: Any, value: Any, check_keys: bool, opts: Any) -> bytes: """Encode a single key, value pair.""" if not isinstance(key, str): - raise InvalidDocument("documents must have only string keys, " "key was %r" % (key,)) + raise InvalidDocument("documents must have only string keys, key was %r" % (key,)) if check_keys: if key.startswith("$"): raise InvalidDocument("key %r must not start with '$'" % (key,)) @@ -876,7 +876,7 @@ def _dict_to_bson(doc: Any, check_keys: bool, opts: Any, top_level: bool = True) if _USE_C: - _dict_to_bson = _cbson._dict_to_bson + _dict_to_bson = _cbson._dict_to_bson # noqa: F811 def _millis_to_datetime(millis: int, opts: Any) -> datetime.datetime: @@ -1032,7 +1032,7 @@ def decode_all( if _USE_C: - decode_all = _cbson.decode_all + decode_all = _cbson.decode_all # noqa: F811 def _decode_selective(rawdoc: Any, fields: Any, codec_options: Any) -> Mapping[Any, Any]: diff --git a/bson/binary.py b/bson/binary.py index e20bf87af3..93c43ee40c 100644 --- a/bson/binary.py +++ b/bson/binary.py @@ -260,7 +260,7 @@ def from_uuid( if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( - "uuid_representation must be a value " "from bson.binary.UuidRepresentation" + "uuid_representation must be a value from bson.binary.UuidRepresentation" ) if uuid_representation == UuidRepresentation.UNSPECIFIED: @@ -310,7 +310,7 @@ def as_uuid(self, uuid_representation: int = UuidRepresentation.STANDARD) -> UUI if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( - "uuid_representation must be a value from " "bson.binary.UuidRepresentation" + "uuid_representation must be a value from bson.binary.UuidRepresentation" ) if uuid_representation == UuidRepresentation.UNSPECIFIED: diff --git a/bson/codec_options.py b/bson/codec_options.py index b43a0275d8..8e5f97df30 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -23,12 +23,10 @@ Any, Callable, Dict, - Generic, Iterable, MutableMapping, Optional, Type, - TypeVar, Union, cast, ) @@ -312,10 +310,10 @@ def __new__( raise TypeError("tz_aware must be True or False") if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( - "uuid_representation must be a value " "from bson.binary.UuidRepresentation" + "uuid_representation must be a value from bson.binary.UuidRepresentation" ) if not isinstance(unicode_decode_error_handler, (str, None)): # type: ignore - raise ValueError("unicode_decode_error_handler must be a string " "or None") + raise ValueError("unicode_decode_error_handler must be a string or None") if tzinfo is not None: if not isinstance(tzinfo, datetime.tzinfo): raise TypeError("tzinfo must be an instance of datetime.tzinfo") diff --git a/bson/dbref.py b/bson/dbref.py index 773c95f59d..7849435f23 100644 --- a/bson/dbref.py +++ b/bson/dbref.py @@ -35,7 +35,7 @@ def __init__( collection: str, id: Any, database: Optional[str] = None, - _extra: Mapping[str, Any] = {}, + _extra: Optional[Mapping[str, Any]] = None, **kwargs: Any ) -> None: """Initialize a new :class:`DBRef`. @@ -63,7 +63,7 @@ def __init__( self.__collection = collection self.__id = id self.__database = database - kwargs.update(_extra) + kwargs.update(_extra or {}) self.__kwargs = kwargs @property diff --git a/bson/json_util.py b/bson/json_util.py index 3cdf701f70..99dbc62609 100644 --- a/bson/json_util.py +++ b/bson/json_util.py @@ -283,7 +283,7 @@ def __new__( self.json_mode = json_mode if self.json_mode == JSONMode.RELAXED: if strict_number_long: - raise ValueError("Cannot specify strict_number_long=True with" " JSONMode.RELAXED") + raise ValueError("Cannot specify strict_number_long=True with JSONMode.RELAXED") if datetime_representation not in (None, DatetimeRepresentation.ISO8601): raise ValueError( "datetime_representation must be DatetimeRepresentation." @@ -296,7 +296,7 @@ def __new__( self.strict_uuid = True elif self.json_mode == JSONMode.CANONICAL: if strict_number_long not in (None, True): - raise ValueError("Cannot specify strict_number_long=False with" " JSONMode.RELAXED") + raise ValueError("Cannot specify strict_number_long=False with JSONMode.RELAXED") if datetime_representation not in (None, DatetimeRepresentation.NUMBERLONG): raise ValueError( "datetime_representation must be DatetimeRepresentation." @@ -581,11 +581,9 @@ def _parse_canonical_binary(doc: Any, json_options: JSONOptions) -> Union[Binary if not isinstance(b64, str): raise TypeError("$binary base64 must be a string: %s" % (doc,)) if not isinstance(subtype, str) or len(subtype) > 2: - raise TypeError("$binary subType must be a string at most 2 " "characters: %s" % (doc,)) + raise TypeError("$binary subType must be a string at most 2 characters: %s" % (doc,)) if len(binary) != 2: - raise TypeError( - '$binary must include only "base64" and "subType" ' "components: %s" % (doc,) - ) + raise TypeError('$binary must include only "base64" and "subType" components: %s' % (doc,)) data = base64.b64decode(b64.encode()) return _binary_or_uuid(data, int(subtype, 16), json_options) @@ -686,7 +684,7 @@ def _parse_canonical_regex(doc: Any) -> Regex: opts = regex["options"] if not isinstance(opts, str): raise TypeError( - "Bad $regularExpression options, options must be " "string, was type %s" % (type(opts)) + "Bad $regularExpression options, options must be string, was type %s" % (type(opts)) ) return Regex(regex["pattern"], opts) diff --git a/bson/objectid.py b/bson/objectid.py index 7413fd497b..24d25d0377 100644 --- a/bson/objectid.py +++ b/bson/objectid.py @@ -204,7 +204,7 @@ def __validate(self, oid: Any) -> None: _raise_invalid_id(oid) else: raise TypeError( - "id must be an instance of (bytes, str, ObjectId), " "not %s" % (type(oid),) + "id must be an instance of (bytes, str, ObjectId), not %s" % (type(oid),) ) @property diff --git a/bson/raw_bson.py b/bson/raw_bson.py index c102b367a2..ca7207f0a2 100644 --- a/bson/raw_bson.py +++ b/bson/raw_bson.py @@ -51,8 +51,7 @@ overhead of decoding or encoding BSON. """ -from collections.abc import Mapping as _Mapping -from typing import Any, ItemsView, Iterator, Mapping, Optional, cast +from typing import Any, ItemsView, Iterator, Mapping, Optional from bson import _get_object_size, _raw_to_dict from bson.codec_options import _RAW_BSON_DOCUMENT_MARKER diff --git a/bson/tz_util.py b/bson/tz_util.py index 43ae52ccff..8106c77b40 100644 --- a/bson/tz_util.py +++ b/bson/tz_util.py @@ -15,7 +15,7 @@ """Timezone related utilities for BSON.""" from datetime import datetime, timedelta, tzinfo -from typing import Any, Optional, Tuple, Union +from typing import Optional, Tuple, Union ZERO: timedelta = timedelta(0) diff --git a/doc/conf.py b/doc/conf.py index 3f74a11d60..c2f97dabfe 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -9,7 +9,7 @@ sys.path[0:0] = [os.path.abspath("..")] -import pymongo +import pymongo # noqa # -- General configuration ----------------------------------------------------- diff --git a/green_framework_test.py b/green_framework_test.py index 610845a9f6..d638d9b014 100644 --- a/green_framework_test.py +++ b/green_framework_test.py @@ -59,7 +59,7 @@ def run(framework_name, *args): # Run the tests. sys.argv[:] = ["setup.py", "test"] + list(args) - import setup + import setup # noqa def main(): @@ -87,7 +87,7 @@ def main(): list_frameworks() sys.exit() else: - assert False, "unhandled option" + raise AssertionError("unhandled option") if not args: print(usage) diff --git a/gridfs/__init__.py b/gridfs/__init__.py index 22b28af1a7..73425a9e53 100644 --- a/gridfs/__init__.py +++ b/gridfs/__init__.py @@ -35,11 +35,10 @@ ) from pymongo import ASCENDING, DESCENDING from pymongo.client_session import ClientSession -from pymongo.collation import Collation from pymongo.collection import Collection -from pymongo.common import UNAUTHORIZED_CODES, validate_string +from pymongo.common import validate_string from pymongo.database import Database -from pymongo.errors import ConfigurationError, OperationFailure +from pymongo.errors import ConfigurationError from pymongo.read_preferences import _ServerMode from pymongo.write_concern import WriteConcern @@ -83,7 +82,7 @@ def __init__(self, database: Database, collection: str = "fs"): database = _clear_entity_type_registry(database) if not database.write_concern.acknowledged: - raise ConfigurationError("database must use " "acknowledged write_concern") + raise ConfigurationError("database must use acknowledged write_concern") self.__collection = database[collection] self.__files = self.__collection.files diff --git a/gridfs/grid_file.py b/gridfs/grid_file.py index 93a97158ae..b290fc68b0 100644 --- a/gridfs/grid_file.py +++ b/gridfs/grid_file.py @@ -17,7 +17,7 @@ import io import math import os -from typing import Any, Iterable, List, Mapping, Optional, cast +from typing import Any, Iterable, List, Mapping, Optional from bson.binary import Binary from bson.int64 import Int64 @@ -172,10 +172,10 @@ def __init__( :attr:`~pymongo.collection.Collection.write_concern` """ if not isinstance(root_collection, Collection): - raise TypeError("root_collection must be an " "instance of Collection") + raise TypeError("root_collection must be an instance of Collection") if not root_collection.write_concern.acknowledged: - raise ConfigurationError("root_collection must use " "acknowledged write_concern") + raise ConfigurationError("root_collection must use acknowledged write_concern") _disallow_transactions(session) # Handle alternative naming @@ -240,7 +240,7 @@ def closed(self) -> bool: "uploadDate", "Date that this file was uploaded.", closed_only=True ) md5: Optional[str] = _grid_in_property( - "md5", "MD5 of the contents of this file " "if an md5 sum was created.", closed_only=True + "md5", "MD5 of the contents of this file if an md5 sum was created.", closed_only=True ) _buffer: io.BytesIO @@ -356,7 +356,7 @@ def write(self, data: Any) -> None: try: data = data.encode(self.encoding) except AttributeError: - raise TypeError("must specify an encoding for file in " "order to write str") + raise TypeError("must specify an encoding for file in order to write str") read = io.BytesIO(data).read if self._buffer.tell() > 0: @@ -365,7 +365,7 @@ def write(self, data: Any) -> None: if space: try: to_write = read(space) - except: + except BaseException: self.abort() raise self._buffer.write(to_write) @@ -447,7 +447,7 @@ def __init__( from the server. Metadata is fetched when first needed. """ if not isinstance(root_collection, Collection): - raise TypeError("root_collection must be an " "instance of Collection") + raise TypeError("root_collection must be an instance of Collection") _disallow_transactions(session) root_collection = _clear_entity_type_registry(root_collection) @@ -477,7 +477,7 @@ def __init__( "metadata", "Metadata attached to this file." ) md5: Optional[str] = _grid_out_property( - "md5", "MD5 of the contents of this file " "if an md5 sum was created." + "md5", "MD5 of the contents of this file if an md5 sum was created." ) _file: Any @@ -886,7 +886,6 @@ def __init__( def next(self) -> GridOut: """Get next GridOut object from cursor.""" _disallow_transactions(self.session) - # Work around "super is not iterable" issue in Python 3.x next_file = super(GridOutCursor, self).next() return GridOut(self.__root_collection, file_document=next_file, session=self.session) diff --git a/pymongo/__init__.py b/pymongo/__init__.py index f8baa91971..9581068036 100644 --- a/pymongo/__init__.py +++ b/pymongo/__init__.py @@ -69,11 +69,14 @@ def get_version_string() -> str: """Current version of PyMongo.""" -from pymongo.collection import ReturnDocument -from pymongo.common import MAX_SUPPORTED_WIRE_VERSION, MIN_SUPPORTED_WIRE_VERSION -from pymongo.cursor import CursorType -from pymongo.mongo_client import MongoClient -from pymongo.operations import ( +from pymongo.collection import ReturnDocument # noqa: F401 +from pymongo.common import ( # noqa: F401 + MAX_SUPPORTED_WIRE_VERSION, + MIN_SUPPORTED_WIRE_VERSION, +) +from pymongo.cursor import CursorType # noqa: F401 +from pymongo.mongo_client import MongoClient # noqa: F401 +from pymongo.operations import ( # noqa: F401 DeleteMany, DeleteOne, IndexModel, @@ -82,14 +85,14 @@ def get_version_string() -> str: UpdateMany, UpdateOne, ) -from pymongo.read_preferences import ReadPreference -from pymongo.write_concern import WriteConcern +from pymongo.read_preferences import ReadPreference # noqa: F401 +from pymongo.write_concern import WriteConcern # noqa: F401 def has_c() -> bool: """Is the C extension installed?""" try: - from pymongo import _cmessage # type: ignore[attr-defined] + from pymongo import _cmessage # type: ignore[attr-defined] # noqa: F401 return True except ImportError: diff --git a/pymongo/aggregation.py b/pymongo/aggregation.py index 51be0dfa81..e190fefc56 100644 --- a/pymongo/aggregation.py +++ b/pymongo/aggregation.py @@ -43,7 +43,7 @@ def __init__( ): if "explain" in options: raise ConfigurationError( - "The explain option is not supported. " "Use Database.command instead." + "The explain option is not supported. Use Database.command instead." ) self._target = target diff --git a/pymongo/auth.py b/pymongo/auth.py index 0a4e7e7324..3d259335b0 100644 --- a/pymongo/auth.py +++ b/pymongo/auth.py @@ -121,7 +121,7 @@ def _build_credentials_tuple(mech, source, user, passwd, extra, database): if passwd is not None: raise ConfigurationError("Passwords are not supported by MONGODB-X509") if source is not None and source != "$external": - raise ValueError("authentication source must be " "$external or None for MONGODB-X509") + raise ValueError("authentication source must be $external or None for MONGODB-X509") # Source is always $external, user can be None. return MongoCredential(mech, "$external", user, None, None, None) elif mech == "MONGODB-AWS": @@ -129,7 +129,7 @@ def _build_credentials_tuple(mech, source, user, passwd, extra, database): raise ConfigurationError("username without a password is not supported by MONGODB-AWS") if source is not None and source != "$external": raise ConfigurationError( - "authentication source must be " "$external or None for MONGODB-AWS" + "authentication source must be $external or None for MONGODB-AWS" ) properties = extra.get("authmechanismproperties", {}) @@ -302,7 +302,7 @@ def _authenticate_gssapi(credentials, sock_info): """Authenticate using GSSAPI.""" if not HAVE_KERBEROS: raise ConfigurationError( - 'The "kerberos" module must be ' "installed to use GSSAPI authentication." + 'The "kerberos" module must be installed to use GSSAPI authentication.' ) try: @@ -351,7 +351,7 @@ def _authenticate_gssapi(credentials, sock_info): # 0 == continue, 1 == complete, -1 == error # Only authGSSClientStep can return 0. if kerberos.authGSSClientStep(ctx, "") != 0: - raise OperationFailure("Unknown kerberos " "failure in step function.") + raise OperationFailure("Unknown kerberos failure in step function.") # Start a SASL conversation with mongod/s # Note: pykerberos deals with base64 encoded byte strings. @@ -372,7 +372,7 @@ def _authenticate_gssapi(credentials, sock_info): for _ in range(10): result = kerberos.authGSSClientStep(ctx, str(response["payload"])) if result == -1: - raise OperationFailure("Unknown kerberos " "failure in step function.") + raise OperationFailure("Unknown kerberos failure in step function.") payload = kerberos.authGSSClientResponse(ctx) or "" @@ -388,15 +388,15 @@ def _authenticate_gssapi(credentials, sock_info): if result == kerberos.AUTH_GSS_COMPLETE: break else: - raise OperationFailure("Kerberos " "authentication failed to complete.") + raise OperationFailure("Kerberos authentication failed to complete.") # Once the security context is established actually authenticate. # See RFC 4752, Section 3.1, last two paragraphs. if kerberos.authGSSClientUnwrap(ctx, str(response["payload"])) != 1: - raise OperationFailure("Unknown kerberos " "failure during GSS_Unwrap step.") + raise OperationFailure("Unknown kerberos failure during GSS_Unwrap step.") if kerberos.authGSSClientWrap(ctx, kerberos.authGSSClientResponse(ctx), username) != 1: - raise OperationFailure("Unknown kerberos " "failure during GSS_Wrap step.") + raise OperationFailure("Unknown kerberos failure during GSS_Wrap step.") payload = kerberos.authGSSClientResponse(ctx) cmd = SON( diff --git a/pymongo/bulk.py b/pymongo/bulk.py index fae55a5c10..c736bd7d6f 100644 --- a/pymongo/bulk.py +++ b/pymongo/bulk.py @@ -26,7 +26,6 @@ from pymongo.collation import validate_collation_or_none from pymongo.common import ( validate_is_document_type, - validate_is_mapping, validate_ok_for_replace, validate_ok_for_update, ) @@ -476,7 +475,7 @@ def execute_no_results(self, sock_info, generator, write_concern): # Cannot have both unacknowledged writes and bypass document validation. if self.bypass_doc_val: raise OperationFailure( - "Cannot set bypass_document_validation with" " unacknowledged write concern" + "Cannot set bypass_document_validation with unacknowledged write concern" ) if self.ordered: @@ -488,7 +487,7 @@ def execute(self, write_concern, session): if not self.ops: raise InvalidOperation("No operations to execute") if self.executed: - raise InvalidOperation("Bulk operations can " "only be executed once.") + raise InvalidOperation("Bulk operations can only be executed once.") self.executed = True write_concern = write_concern or self.collection.write_concern session = _validate_session_write_concern(session, write_concern) diff --git a/pymongo/change_stream.py b/pymongo/change_stream.py index 50f6f72b73..d054046bda 100644 --- a/pymongo/change_stream.py +++ b/pymongo/change_stream.py @@ -15,7 +15,7 @@ """Watch changes on a collection, a database, or the entire cluster.""" import copy -from typing import TYPE_CHECKING, Any, Dict, Generic, Iterator, Mapping, Optional, Union +from typing import TYPE_CHECKING, Any, Dict, Generic, Mapping, Optional, Union from bson import _bson_to_dict from bson.raw_bson import RawBSONDocument @@ -363,7 +363,7 @@ def try_next(self) -> Optional[_DocumentType]: except KeyError: self.close() raise InvalidOperation( - "Cannot provide resume functionality when the resume " "token is missing." + "Cannot provide resume functionality when the resume token is missing." ) # If this is the last change document from the current batch, cache the diff --git a/pymongo/client_session.py b/pymongo/client_session.py index 44381c0241..4cf41b2c70 100644 --- a/pymongo/client_session.py +++ b/pymongo/client_session.py @@ -192,7 +192,7 @@ def __init__( ) -> None: if snapshot: if causal_consistency: - raise ConfigurationError("snapshot reads do not support " "causal_consistency=True") + raise ConfigurationError("snapshot reads do not support causal_consistency=True") causal_consistency = False elif causal_consistency is None: causal_consistency = True @@ -717,7 +717,7 @@ def start_transaction( self._check_ended() if self.options.snapshot: - raise InvalidOperation("Transactions are not supported in " "snapshot sessions") + raise InvalidOperation("Transactions are not supported in snapshot sessions") if self.in_transaction: raise InvalidOperation("Transaction already in progress") @@ -885,7 +885,7 @@ def advance_operation_time(self, operation_time: Timestamp) -> None: another `ClientSession` instance. """ if not isinstance(operation_time, Timestamp): - raise TypeError("operation_time must be an instance " "of bson.timestamp.Timestamp") + raise TypeError("operation_time must be an instance of bson.timestamp.Timestamp") self._advance_operation_time(operation_time) def _process_response(self, reply): diff --git a/pymongo/collation.py b/pymongo/collation.py index aef480b932..5bc73c07c8 100644 --- a/pymongo/collation.py +++ b/pymongo/collation.py @@ -221,4 +221,4 @@ def validate_collation_or_none( return value.document if isinstance(value, dict): return value - raise TypeError("collation must be a dict, an instance of collation.Collation, " "or None.") + raise TypeError("collation must be a dict, an instance of collation.Collation, or None.") diff --git a/pymongo/collection.py b/pymongo/collection.py index a61c905d29..8de1fbeeaa 100644 --- a/pymongo/collection.py +++ b/pymongo/collection.py @@ -29,7 +29,6 @@ Union, ) -from bson.code import Code from bson.codec_options import CodecOptions from bson.objectid import ObjectId from bson.raw_bson import RawBSONDocument @@ -204,11 +203,11 @@ def __init__( if not name or ".." in name: raise InvalidName("collection names cannot be empty") if "$" in name and not (name.startswith("oplog.$main") or name.startswith("$cmd")): - raise InvalidName("collection names must not " "contain '$': %r" % name) + raise InvalidName("collection names must not contain '$': %r" % name) if name[0] == "." or name[-1] == ".": - raise InvalidName("collection names must not start " "or end with '.': %r" % name) + raise InvalidName("collection names must not start or end with '.': %r" % name) if "\x00" in name: - raise InvalidName("collection names must not contain the " "null character") + raise InvalidName("collection names must not contain the null character") collation = validate_collation_or_none(kwargs.pop("collation", None)) self.__database: Database[_DocumentType] = database @@ -1873,7 +1872,7 @@ def gen_indexes(): for index in indexes: if not isinstance(index, IndexModel): raise TypeError( - "%r is not an instance of " "pymongo.operations.IndexModel" % (index,) + "%r is not an instance of pymongo.operations.IndexModel" % (index,) ) document = index.document names.append(document["name"]) @@ -2725,7 +2724,7 @@ def __find_and_modify( common.validate_is_mapping("filter", filter) if not isinstance(return_document, bool): raise ValueError( - "return_document must be " "ReturnDocument.BEFORE or ReturnDocument.AFTER" + "return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER" ) collation = validate_collation_or_none(kwargs.pop("collation", None)) cmd = SON([("findAndModify", self.__name), ("query", filter), ("new", return_document)]) @@ -2751,7 +2750,7 @@ def _find_and_modify(session, sock_info, retryable_write): if array_filters is not None: if not acknowledged: raise ConfigurationError( - "arrayFilters is unsupported for unacknowledged " "writes." + "arrayFilters is unsupported for unacknowledged writes." ) cmd["arrayFilters"] = list(array_filters) if hint is not None: diff --git a/pymongo/command_cursor.py b/pymongo/command_cursor.py index 2adc389baf..d10e23f957 100644 --- a/pymongo/command_cursor.py +++ b/pymongo/command_cursor.py @@ -15,7 +15,7 @@ """CommandCursor class to iterate over command results.""" from collections import deque -from typing import TYPE_CHECKING, Any, Generic, Iterator, Mapping, Optional, Tuple +from typing import TYPE_CHECKING, Any, Generic, Iterator, Mapping, Optional from bson import _convert_raw_document_lists_to_streams from pymongo.cursor import _CURSOR_CLOSED_ERRORS, _SocketManager diff --git a/pymongo/common.py b/pymongo/common.py index 769b277cf3..5255468b5a 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -30,7 +30,6 @@ Tuple, Type, Union, - cast, ) from urllib.parse import unquote_plus @@ -180,7 +179,7 @@ def validate_boolean_or_string(option: str, value: Any) -> bool: """Validates that value is True, False, 'true', or 'false'.""" if isinstance(value, str): if value not in ("true", "false"): - raise ValueError("The value of %s must be " "'true' or 'false'" % (option,)) + raise ValueError("The value of %s must be 'true' or 'false'" % (option,)) return value == "true" return validate_boolean(option, value) @@ -193,7 +192,7 @@ def validate_integer(option: str, value: Any) -> int: try: return int(value) except ValueError: - raise ValueError("The value of %s must be " "an integer" % (option,)) + raise ValueError("The value of %s must be an integer" % (option,)) raise TypeError("Wrong type for %s, value must be an integer" % (option,)) @@ -201,7 +200,7 @@ def validate_positive_integer(option: str, value: Any) -> int: """Validate that 'value' is a positive integer, which does not include 0.""" val = validate_integer(option, value) if val <= 0: - raise ValueError("The value of %s must be " "a positive integer" % (option,)) + raise ValueError("The value of %s must be a positive integer" % (option,)) return val @@ -209,7 +208,7 @@ def validate_non_negative_integer(option: str, value: Any) -> int: """Validate that 'value' is a positive integer or 0.""" val = validate_integer(option, value) if val < 0: - raise ValueError("The value of %s must be " "a non negative integer" % (option,)) + raise ValueError("The value of %s must be a non negative integer" % (option,)) return val @@ -242,7 +241,7 @@ def validate_string(option: str, value: Any) -> str: """Validates that 'value' is an instance of `str`.""" if isinstance(value, str): return value - raise TypeError("Wrong type for %s, value must be an instance of " "str" % (option,)) + raise TypeError("Wrong type for %s, value must be an instance of str" % (option,)) def validate_string_or_none(option: str, value: Any) -> Optional[str]: @@ -261,7 +260,7 @@ def validate_int_or_basestring(option: str, value: Any) -> Union[int, str]: return int(value) except ValueError: return value - raise TypeError("Wrong type for %s, value must be an " "integer or a string" % (option,)) + raise TypeError("Wrong type for %s, value must be an integer or a string" % (option,)) def validate_non_negative_int_or_basestring(option: Any, value: Any) -> Union[int, str]: @@ -275,7 +274,7 @@ def validate_non_negative_int_or_basestring(option: Any, value: Any) -> Union[in return value return validate_non_negative_integer(option, val) raise TypeError( - "Wrong type for %s, value must be an " "non negative integer or a string" % (option,) + "Wrong type for %s, value must be an non negative integer or a string" % (option,) ) @@ -294,7 +293,7 @@ def validate_positive_float(option: str, value: Any) -> float: # float('inf') doesn't work in 2.4 or 2.5 on Windows, so just cap floats at # one billion - this is a reasonable approximation for infinity if not 0 < value < 1e9: - raise ValueError("%s must be greater than 0 and " "less than one billion" % (option,)) + raise ValueError("%s must be greater than 0 and less than one billion" % (option,)) return value @@ -402,7 +401,7 @@ def validate_read_preference_tags(name: str, value: Any) -> List[Dict[str, str]] tags[unquote_plus(key)] = unquote_plus(val) tag_sets.append(tags) except Exception: - raise ValueError("%r not a valid " "value for %s" % (tag_set, name)) + raise ValueError("%r not a valid value for %s" % (tag_set, name)) return tag_sets @@ -735,7 +734,7 @@ def validate_auth_option(option: str, value: Any) -> Tuple[str, Any]: """Validate optional authentication parameters.""" lower, value = validate(option, value) if lower not in _AUTH_OPTIONS: - raise ConfigurationError("Unknown " "authentication option: %s" % (option,)) + raise ConfigurationError("Unknown authentication option: %s" % (option,)) return option, value @@ -762,12 +761,12 @@ def get_validated_options( validated_options: MutableMapping[str, Any] if isinstance(options, _CaseInsensitiveDictionary): validated_options = _CaseInsensitiveDictionary() - get_normed_key = lambda x: x - get_setter_key = lambda x: options.cased_key(x) + get_normed_key = lambda x: x # noqa: E731 + get_setter_key = lambda x: options.cased_key(x) # noqa: E731 else: validated_options = {} - get_normed_key = lambda x: x.lower() - get_setter_key = lambda x: x + get_normed_key = lambda x: x.lower() # noqa: E731 + get_setter_key = lambda x: x # noqa: E731 for opt, value in options.items(): normed_key = get_normed_key(opt) @@ -804,9 +803,7 @@ def __init__( ) -> None: if not isinstance(codec_options, CodecOptions): - raise TypeError( - "codec_options must be an instance of " "bson.codec_options.CodecOptions" - ) + raise TypeError("codec_options must be an instance of bson.codec_options.CodecOptions") self.__codec_options = codec_options if not isinstance(read_preference, _ServerMode): @@ -819,14 +816,12 @@ def __init__( if not isinstance(write_concern, WriteConcern): raise TypeError( - "write_concern must be an instance of " "pymongo.write_concern.WriteConcern" + "write_concern must be an instance of pymongo.write_concern.WriteConcern" ) self.__write_concern = write_concern if not isinstance(read_concern, ReadConcern): - raise TypeError( - "read_concern must be an instance of " "pymongo.read_concern.ReadConcern" - ) + raise TypeError("read_concern must be an instance of pymongo.read_concern.ReadConcern") self.__read_concern = read_concern @property diff --git a/pymongo/compression_support.py b/pymongo/compression_support.py index 72cc232867..ed7021494f 100644 --- a/pymongo/compression_support.py +++ b/pymongo/compression_support.py @@ -82,7 +82,7 @@ def validate_compressors(dummy, value): def validate_zlib_compression_level(option, value): try: level = int(value) - except: + except Exception: raise TypeError("%s must be an integer, not %r." % (option, value)) if level < -1 or level > 9: raise ValueError("%s must be between -1 and 9, not %d." % (option, level)) diff --git a/pymongo/cursor.py b/pymongo/cursor.py index be4b998d31..02f1905df3 100644 --- a/pymongo/cursor.py +++ b/pymongo/cursor.py @@ -25,7 +25,6 @@ Iterable, List, Mapping, - MutableMapping, Optional, Sequence, Tuple, @@ -277,7 +276,7 @@ def __init__( # Exhaust cursor support if cursor_type == CursorType.EXHAUST: if self.__collection.database.client.is_mongos: - raise InvalidOperation("Exhaust cursors are " "not supported by mongos") + raise InvalidOperation("Exhaust cursors are not supported by mongos") if limit: raise InvalidOperation("Can't use limit and exhaust together.") self.__exhaust = True @@ -509,7 +508,7 @@ def add_option(self, mask: int) -> "Cursor[_DocumentType]": if self.__limit: raise InvalidOperation("Can't use limit and exhaust together.") if self.__collection.database.client.is_mongos: - raise InvalidOperation("Exhaust cursors are " "not supported by mongos") + raise InvalidOperation("Exhaust cursors are not supported by mongos") self.__exhaust = True self.__query_flags |= mask @@ -730,14 +729,14 @@ def __getitem__(self, index): skip = 0 if index.start is not None: if index.start < 0: - raise IndexError("Cursor instances do not support " "negative indices") + raise IndexError("Cursor instances do not support negative indices") skip = index.start if index.stop is not None: limit = index.stop - skip if limit < 0: raise IndexError( - "stop index must be greater than start " "index for slice %r" % index + "stop index must be greater than start index for slice %r" % index ) if limit == 0: self.__empty = True @@ -750,7 +749,7 @@ def __getitem__(self, index): if isinstance(index, int): if index < 0: - raise IndexError("Cursor instances do not support negative " "indices") + raise IndexError("Cursor instances do not support negative indices") clone = self.clone() clone.skip(index + self.__skip) clone.limit(-1) # use a hard limit @@ -758,7 +757,7 @@ def __getitem__(self, index): for doc in clone: return doc raise IndexError("no such item for Cursor instance") - raise TypeError("index %r cannot be applied to Cursor " "instances" % index) + raise TypeError("index %r cannot be applied to Cursor instances" % index) def max_scan(self, max_scan: Optional[int]) -> "Cursor[_DocumentType]": """**DEPRECATED** - Limit the number of documents to scan when diff --git a/pymongo/daemon.py b/pymongo/daemon.py index 53141751ac..4fdf147a59 100644 --- a/pymongo/daemon.py +++ b/pymongo/daemon.py @@ -70,7 +70,7 @@ def _spawn_daemon(args): _silence_resource_warning(popen) except FileNotFoundError as exc: warnings.warn( - f"Failed to start {args[0]}: is it on your $PATH?\n" f"Original exception: {exc}", + f"Failed to start {args[0]}: is it on your $PATH?\nOriginal exception: {exc}", RuntimeWarning, stacklevel=2, ) @@ -96,7 +96,7 @@ def _spawn(args): ) except FileNotFoundError as exc: warnings.warn( - f"Failed to start {args[0]}: is it on your $PATH?\n" f"Original exception: {exc}", + f"Failed to start {args[0]}: is it on your $PATH?\nOriginal exception: {exc}", RuntimeWarning, stacklevel=2, ) diff --git a/pymongo/database.py b/pymongo/database.py index e6633ed230..f92dbc8aed 100644 --- a/pymongo/database.py +++ b/pymongo/database.py @@ -47,7 +47,7 @@ def _check_name(name): for invalid_char in [" ", ".", "$", "/", "\\", "\x00", '"']: if invalid_char in name: - raise InvalidName("database names cannot contain the " "character %r" % invalid_char) + raise InvalidName("database names cannot contain the character %r" % invalid_char) if TYPE_CHECKING: @@ -966,7 +966,7 @@ def validate_collection( name = name.name if not isinstance(name, str): - raise TypeError("name_or_collection must be an instance of str or " "Collection") + raise TypeError("name_or_collection must be an instance of str or Collection") cmd = SON([("validate", name), ("scandata", scandata), ("full", full)]) if comment is not None: cmd["comment"] = comment @@ -988,7 +988,7 @@ def validate_collection( if "result" in res: info = res["result"] if info.find("exception") != -1 or info.find("corrupt") != -1: - raise CollectionInvalid("%s invalid: " "%s" % (name, info)) + raise CollectionInvalid("%s invalid: %s" % (name, info)) elif not res.get("valid", False): valid = False break diff --git a/pymongo/encryption.py b/pymongo/encryption.py index 4a6653f959..9616ac89cd 100644 --- a/pymongo/encryption.py +++ b/pymongo/encryption.py @@ -21,7 +21,7 @@ try: from pymongocrypt.auto_encrypter import AutoEncrypter - from pymongocrypt.errors import MongoCryptError + from pymongocrypt.errors import MongoCryptError # noqa: F401 from pymongocrypt.explicit_encrypter import ExplicitEncrypter from pymongocrypt.mongocrypt import MongoCryptOptions from pymongocrypt.state_machine import MongoCryptCallback @@ -440,9 +440,7 @@ def __init__( ) if not isinstance(codec_options, CodecOptions): - raise TypeError( - "codec_options must be an instance of " "bson.codec_options.CodecOptions" - ) + raise TypeError("codec_options must be an instance of bson.codec_options.CodecOptions") self._kms_providers = kms_providers self._key_vault_namespace = key_vault_namespace diff --git a/pymongo/encryption_options.py b/pymongo/encryption_options.py index c206b4c8b5..2ac12bc4b4 100644 --- a/pymongo/encryption_options.py +++ b/pymongo/encryption_options.py @@ -14,11 +14,10 @@ """Support for automatic client-side field level encryption.""" -import copy from typing import TYPE_CHECKING, Any, List, Mapping, Optional try: - import pymongocrypt + import pymongocrypt # noqa: F401 _HAVE_PYMONGOCRYPT = True except ImportError: diff --git a/pymongo/errors.py b/pymongo/errors.py index a98a5a7fb8..4a167383ca 100644 --- a/pymongo/errors.py +++ b/pymongo/errors.py @@ -15,7 +15,7 @@ """Exceptions raised by PyMongo.""" from typing import Any, Iterable, List, Mapping, Optional, Sequence, Tuple, Union -from bson.errors import * +from bson.errors import InvalidDocument try: # CPython 3.7+ diff --git a/pymongo/event_loggers.py b/pymongo/event_loggers.py index 0b92d9fa2b..248dfb17bd 100644 --- a/pymongo/event_loggers.py +++ b/pymongo/event_loggers.py @@ -43,25 +43,25 @@ class CommandLogger(monitoring.CommandListener): def started(self, event: monitoring.CommandStartedEvent) -> None: logging.info( - "Command {0.command_name} with request id " - "{0.request_id} started on server " - "{0.connection_id}".format(event) + f"Command {event.command_name} with request id " + f"{event.request_id} started on server " + f"{event.connection_id}" ) def succeeded(self, event: monitoring.CommandSucceededEvent) -> None: logging.info( - "Command {0.command_name} with request id " - "{0.request_id} on server {0.connection_id} " - "succeeded in {0.duration_micros} " - "microseconds".format(event) + f"Command {event.command_name} with request id " + f"{event.request_id} on server {event.connection_id} " + f"succeeded in {event.duration_micros} " + "microseconds" ) def failed(self, event: monitoring.CommandFailedEvent) -> None: logging.info( - "Command {0.command_name} with request id " - "{0.request_id} on server {0.connection_id} " - "failed in {0.duration_micros} " - "microseconds".format(event) + f"Command {event.command_name} with request id " + f"{event.request_id} on server {event.connection_id} " + f"failed in {event.duration_micros} " + "microseconds" ) @@ -77,7 +77,7 @@ class ServerLogger(monitoring.ServerListener): """ def opened(self, event: monitoring.ServerOpeningEvent) -> None: - logging.info("Server {0.server_address} added to topology " "{0.topology_id}".format(event)) + logging.info(f"Server {event.server_address} added to topology {event.topology_id}") def description_changed(self, event: monitoring.ServerDescriptionChangedEvent) -> None: previous_server_type = event.previous_description.server_type @@ -85,15 +85,13 @@ def description_changed(self, event: monitoring.ServerDescriptionChangedEvent) - if new_server_type != previous_server_type: # server_type_name was added in PyMongo 3.4 logging.info( - "Server {0.server_address} changed type from " - "{0.previous_description.server_type_name} to " - "{0.new_description.server_type_name}".format(event) + f"Server {event.server_address} changed type from " + f"{event.previous_description.server_type_name} to " + f"{event.new_description.server_type_name}" ) def closed(self, event: monitoring.ServerClosedEvent) -> None: - logging.warning( - "Server {0.server_address} removed from topology " "{0.topology_id}".format(event) - ) + logging.warning(f"Server {event.server_address} removed from topology {event.topology_id}") class HeartbeatLogger(monitoring.ServerHeartbeatListener): @@ -108,19 +106,19 @@ class HeartbeatLogger(monitoring.ServerHeartbeatListener): """ def started(self, event: monitoring.ServerHeartbeatStartedEvent) -> None: - logging.info("Heartbeat sent to server " "{0.connection_id}".format(event)) + logging.info(f"Heartbeat sent to server {event.connection_id}") def succeeded(self, event: monitoring.ServerHeartbeatSucceededEvent) -> None: # The reply.document attribute was added in PyMongo 3.4. logging.info( - "Heartbeat to server {0.connection_id} " + f"Heartbeat to server {event.connection_id} " "succeeded with reply " - "{0.reply.document}".format(event) + f"{event.reply.document}" ) def failed(self, event: monitoring.ServerHeartbeatFailedEvent) -> None: logging.warning( - "Heartbeat to server {0.connection_id} " "failed with error {0.reply}".format(event) + f"Heartbeat to server {event.connection_id} failed with error {event.reply}" ) @@ -136,20 +134,18 @@ class TopologyLogger(monitoring.TopologyListener): """ def opened(self, event: monitoring.TopologyOpenedEvent) -> None: - logging.info("Topology with id {0.topology_id} " "opened".format(event)) + logging.info(f"Topology with id {event.topology_id} opened") def description_changed(self, event: monitoring.TopologyDescriptionChangedEvent) -> None: - logging.info( - "Topology description updated for " "topology id {0.topology_id}".format(event) - ) + logging.info(f"Topology description updated for topology id {event.topology_id}") previous_topology_type = event.previous_description.topology_type new_topology_type = event.new_description.topology_type if new_topology_type != previous_topology_type: # topology_type_name was added in PyMongo 3.4 logging.info( - "Topology {0.topology_id} changed type from " - "{0.previous_description.topology_type_name} to " - "{0.new_description.topology_type_name}".format(event) + f"Topology {event.topology_id} changed type from " + f"{event.previous_description.topology_type_name} to " + f"{event.new_description.topology_type_name}" ) # The has_writable_server and has_readable_server methods # were added in PyMongo 3.4. @@ -159,7 +155,7 @@ def description_changed(self, event: monitoring.TopologyDescriptionChangedEvent) logging.warning("No readable servers available.") def closed(self, event: monitoring.TopologyClosedEvent) -> None: - logging.info("Topology with id {0.topology_id} " "closed".format(event)) + logging.info(f"Topology with id {event.topology_id} closed") class ConnectionPoolLogger(monitoring.ConnectionPoolListener): @@ -181,53 +177,45 @@ class ConnectionPoolLogger(monitoring.ConnectionPoolListener): """ def pool_created(self, event: monitoring.PoolCreatedEvent) -> None: - logging.info("[pool {0.address}] pool created".format(event)) + logging.info(f"[pool {event.address}] pool created") def pool_ready(self, event): - logging.info("[pool {0.address}] pool ready".format(event)) + logging.info(f"[pool {event.address}] pool ready") def pool_cleared(self, event: monitoring.PoolClearedEvent) -> None: - logging.info("[pool {0.address}] pool cleared".format(event)) + logging.info(f"[pool {event.address}] pool cleared") def pool_closed(self, event: monitoring.PoolClosedEvent) -> None: - logging.info("[pool {0.address}] pool closed".format(event)) + logging.info(f"[pool {event.address}] pool closed") def connection_created(self, event: monitoring.ConnectionCreatedEvent) -> None: - logging.info( - "[pool {0.address}][conn #{0.connection_id}] " "connection created".format(event) - ) + logging.info(f"[pool {event.address}][conn #{event.connection_id}] connection created") def connection_ready(self, event: monitoring.ConnectionReadyEvent) -> None: logging.info( - "[pool {0.address}][conn #{0.connection_id}] " - "connection setup succeeded".format(event) + f"[pool {event.address}][conn #{event.connection_id}] connection setup succeeded" ) def connection_closed(self, event: monitoring.ConnectionClosedEvent) -> None: logging.info( - "[pool {0.address}][conn #{0.connection_id}] " - "connection closed, reason: " - "{0.reason}".format(event) + f"[pool {event.address}][conn #{event.connection_id}] " + f'connection closed, reason: "{event.reason}"' ) def connection_check_out_started( self, event: monitoring.ConnectionCheckOutStartedEvent ) -> None: - logging.info("[pool {0.address}] connection check out " "started".format(event)) + logging.info(f"[pool {event.address}] connection check out started") def connection_check_out_failed(self, event: monitoring.ConnectionCheckOutFailedEvent) -> None: - logging.info( - "[pool {0.address}] connection check out " "failed, reason: {0.reason}".format(event) - ) + logging.info(f"[pool {event.address}] connection check out failed, reason: {event.reason}") def connection_checked_out(self, event: monitoring.ConnectionCheckedOutEvent) -> None: logging.info( - "[pool {0.address}][conn #{0.connection_id}] " - "connection checked out of pool".format(event) + f"[pool {event.address}][conn #{event.connection_id}] connection checked out of pool" ) def connection_checked_in(self, event: monitoring.ConnectionCheckedInEvent) -> None: logging.info( - "[pool {0.address}][conn #{0.connection_id}] " - "connection checked into pool".format(event) + f"[pool {event.address}][conn #{event.connection_id}] connection checked into pool" ) diff --git a/pymongo/helpers.py b/pymongo/helpers.py index f12c1e1655..8311aafa8f 100644 --- a/pymongo/helpers.py +++ b/pymongo/helpers.py @@ -86,9 +86,7 @@ def _index_list(key_or_list, direction=None): if isinstance(key_or_list, abc.ItemsView): return list(key_or_list) elif not isinstance(key_or_list, (list, tuple)): - raise TypeError( - "if no direction is specified, " "key_or_list must be an instance of list" - ) + raise TypeError("if no direction is specified, key_or_list must be an instance of list") return key_or_list @@ -104,7 +102,7 @@ def _index_document(index_list): "mean %r?" % list(index_list.items()) ) elif not isinstance(index_list, (list, tuple)): - raise TypeError("must use a list of (key, direction) pairs, " "not: " + repr(index_list)) + raise TypeError("must use a list of (key, direction) pairs, not: " + repr(index_list)) if not len(index_list): raise ValueError("key_or_list must not be the empty list") @@ -237,11 +235,11 @@ def _fields_list_to_dict(fields, option_name): if isinstance(fields, (abc.Sequence, abc.Set)): if not all(isinstance(field, str) for field in fields): raise TypeError( - "%s must be a list of key names, each an " "instance of str" % (option_name,) + "%s must be a list of key names, each an instance of str" % (option_name,) ) return dict.fromkeys(fields, 1) - raise TypeError("%s must be a mapping or " "list of key names" % (option_name,)) + raise TypeError("%s must be a mapping or list of key names" % (option_name,)) def _handle_exception(): diff --git a/pymongo/message.py b/pymongo/message.py index 18cf0a6bf3..92d59c3ebd 100644 --- a/pymongo/message.py +++ b/pymongo/message.py @@ -638,7 +638,7 @@ def _op_msg_uncompressed(flags, command, identifier, docs, opts): if _use_c: - _op_msg_uncompressed = _cmessage._op_msg + _op_msg_uncompressed = _cmessage._op_msg # noqa: F811 def _op_msg(flags, command, dbname, read_preference, opts, ctx=None): @@ -712,7 +712,7 @@ def _query_uncompressed( if _use_c: - _query_uncompressed = _cmessage._query_message + _query_uncompressed = _cmessage._query_message # noqa: F811 def _query( @@ -754,7 +754,7 @@ def _get_more_uncompressed(collection_name, num_to_return, cursor_id): if _use_c: - _get_more_uncompressed = _cmessage._get_more_message + _get_more_uncompressed = _cmessage._get_more_message # noqa: F811 def _get_more(collection_name, num_to_return, cursor_id, ctx=None): @@ -1085,7 +1085,7 @@ def _encode_batched_op_msg(operation, command, docs, ack, opts, ctx): if _use_c: - _encode_batched_op_msg = _cmessage._encode_batched_op_msg + _encode_batched_op_msg = _cmessage._encode_batched_op_msg # noqa: F811 def _batched_op_msg_compressed(operation, command, docs, ack, opts, ctx): @@ -1120,7 +1120,7 @@ def _batched_op_msg(operation, command, docs, ack, opts, ctx): if _use_c: - _batched_op_msg = _cmessage._batched_op_msg + _batched_op_msg = _cmessage._batched_op_msg # noqa: F811 def _do_batched_op_msg(namespace, operation, command, docs, opts, ctx): @@ -1149,7 +1149,7 @@ def _encode_batched_write_command(namespace, operation, command, docs, opts, ctx if _use_c: - _encode_batched_write_command = _cmessage._encode_batched_write_command + _encode_batched_write_command = _cmessage._encode_batched_write_command # noqa: F811 def _batched_write_command_impl(namespace, operation, command, docs, opts, ctx, buf): @@ -1348,7 +1348,7 @@ def __init__(self, flags, payload_document): self.flags = flags self.payload_document = payload_document - def raw_response(self, cursor_id=None, user_fields={}): + def raw_response(self, cursor_id=None, user_fields={}): # noqa: B006 """ cursor_id is ignored user_fields is used to determine which fields must not be decoded @@ -1395,12 +1395,12 @@ def unpack(cls, msg): flags, first_payload_type, first_payload_size = cls.UNPACK_FROM(msg) if flags != 0: if flags & cls.CHECKSUM_PRESENT: - raise ProtocolError("Unsupported OP_MSG flag checksumPresent: " "0x%x" % (flags,)) + raise ProtocolError("Unsupported OP_MSG flag checksumPresent: 0x%x" % (flags,)) if flags ^ cls.MORE_TO_COME: raise ProtocolError("Unsupported OP_MSG flags: 0x%x" % (flags,)) if first_payload_type != 0: - raise ProtocolError("Unsupported OP_MSG payload type: " "0x%x" % (first_payload_type,)) + raise ProtocolError("Unsupported OP_MSG payload type: 0x%x" % (first_payload_type,)) if len(msg) != first_payload_size + 5: raise ProtocolError("Unsupported OP_MSG reply: >1 section") diff --git a/pymongo/mongo_client.py b/pymongo/mongo_client.py index e9fa932ff1..9414d71962 100644 --- a/pymongo/mongo_client.py +++ b/pymongo/mongo_client.py @@ -52,7 +52,6 @@ cast, ) -import bson from bson.codec_options import DEFAULT_CODEC_OPTIONS, CodecOptions, TypeRegistry from bson.son import SON from bson.timestamp import Timestamp @@ -687,7 +686,7 @@ def __init__( srv_service_name = keyword_opts.get("srvservicename") srv_max_hosts = keyword_opts.get("srvmaxhosts") if len([h for h in host if "/" in h]) > 1: - raise ConfigurationError("host must not contain multiple MongoDB " "URIs") + raise ConfigurationError("host must not contain multiple MongoDB URIs") for entity in host: # A hostname can only include a-z, 0-9, '-' and '.'. If we find a '/' # it must be a URI, @@ -1165,7 +1164,7 @@ def _get_socket(self, server, session): and sock_info.max_wire_version < 8 ): raise ConfigurationError( - "Auto-encryption requires a minimum MongoDB version " "of 4.2" + "Auto-encryption requires a minimum MongoDB version of 4.2" ) yield sock_info @@ -1229,7 +1228,7 @@ def _socket_from_server(self, read_preference, server, session): def _socket_for_reads(self, read_preference, session): assert read_preference is not None, "read_preference must not be None" - topology = self._get_topology() + _ = self._get_topology() server = self._select_server(read_preference, session) return self._socket_from_server(read_preference, server, session) @@ -1814,7 +1813,7 @@ def drop_database( name = name.name if not isinstance(name, str): - raise TypeError("name_or_database must be an instance " "of str or a Database") + raise TypeError("name_or_database must be an instance of str or a Database") with self._socket_for_writes(session) as sock_info: self[name]._command( diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 6a3ed6d07e..4798542dc7 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -633,7 +633,7 @@ def __init__( super(CommandStartedEvent, self).__init__( command_name, request_id, connection_id, operation_id, service_id=service_id ) - cmd_name, cmd_doc = command_name.lower(), command[command_name] + cmd_name = command_name.lower() if cmd_name in _SENSITIVE_COMMANDS or _is_speculative_authenticate(cmd_name, command): self.__cmd: Mapping[str, Any] = {} else: @@ -651,7 +651,7 @@ def database_name(self) -> str: return self.__db def __repr__(self): - return ("<%s %s db: %r, command: %r, operation_id: %s, " "service_id: %s>") % ( + return ("<%s %s db: %r, command: %r, operation_id: %s, service_id: %s>") % ( self.__class__.__name__, self.connection_id, self.database_name, @@ -708,7 +708,7 @@ def reply(self) -> _DocumentOut: return self.__reply def __repr__(self): - return ("<%s %s command: %r, operation_id: %s, duration_micros: %s, " "service_id: %s>") % ( + return ("<%s %s command: %r, operation_id: %s, duration_micros: %s, service_id: %s>") % ( self.__class__.__name__, self.connection_id, self.command_name, diff --git a/pymongo/network.py b/pymongo/network.py index db952af731..01dca0b835 100644 --- a/pymongo/network.py +++ b/pymongo/network.py @@ -210,10 +210,10 @@ def receive_message(sock_info, request_id, max_message_size=MAX_MESSAGE_SIZE): # No request_id for exhaust cursor "getMore". if request_id is not None: if request_id != response_to: - raise ProtocolError("Got response id %r but expected " "%r" % (response_to, request_id)) + raise ProtocolError("Got response id %r but expected %r" % (response_to, request_id)) if length <= 16: raise ProtocolError( - "Message length (%r) not longer than standard " "message header size (16)" % (length,) + "Message length (%r) not longer than standard message header size (16)" % (length,) ) if length > max_message_size: raise ProtocolError( @@ -231,7 +231,7 @@ def receive_message(sock_info, request_id, max_message_size=MAX_MESSAGE_SIZE): try: unpack_reply = _UNPACK_REPLY[op_code] except KeyError: - raise ProtocolError("Got opcode %r but expected " "%r" % (op_code, _UNPACK_REPLY.keys())) + raise ProtocolError("Got opcode %r but expected %r" % (op_code, _UNPACK_REPLY.keys())) return unpack_reply(data) @@ -272,7 +272,7 @@ def _receive_data_on_socket(sock_info, length, deadline): try: wait_for_read(sock_info, deadline) chunk_length = sock_info.sock.recv_into(mv[bytes_read:]) - except (IOError, OSError) as exc: + except (IOError, OSError) as exc: # noqa: B014 if _errno_from_exception(exc) == errno.EINTR: continue raise diff --git a/pymongo/periodic_executor.py b/pymongo/periodic_executor.py index 5bb08ec23f..2c3727a7a3 100644 --- a/pymongo/periodic_executor.py +++ b/pymongo/periodic_executor.py @@ -124,7 +124,7 @@ def _run(self): if not self._target(): self._stopped = True break - except: + except BaseException: with self._lock: self._stopped = True self._thread_will_exit = True diff --git a/pymongo/pool.py b/pymongo/pool.py index 61945e2d5b..09709ffbf4 100644 --- a/pymongo/pool.py +++ b/pymongo/pool.py @@ -72,7 +72,7 @@ def is_ip_address(address): try: ipaddress.ip_address(address) return True - except (ValueError, UnicodeError): + except (ValueError, UnicodeError): # noqa: B014 return False @@ -857,9 +857,7 @@ def validate_session(self, client, session): """ if session: if session._client is not client: - raise InvalidOperation( - "Can only use session with the MongoClient that" " started it" - ) + raise InvalidOperation("Can only use session with the MongoClient that started it") def close_socket(self, reason): """Close this connection with a reason.""" @@ -963,7 +961,7 @@ def _create_connection(address, options): # Check if dealing with a unix domain socket if host.endswith(".sock"): if not hasattr(socket, "AF_UNIX"): - raise ConnectionFailure("UNIX-sockets are not supported " "on this system") + raise ConnectionFailure("UNIX-sockets are not supported on this system") sock = socket.socket(socket.AF_UNIX) # SOCK_CLOEXEC not supported for Unix sockets. _set_non_inheritable_non_atomic(sock.fileno()) @@ -1045,7 +1043,7 @@ def _configured_socket(address, options): # Raise _CertificateError directly like we do after match_hostname # below. raise - except (IOError, OSError, _SSLError) as exc: + except (IOError, OSError, _SSLError) as exc: # noqa: B014 sock.close() # We raise AutoReconnect for transient and permanent SSL handshake # failures alike. Permanent handshake failures, like protocol @@ -1246,8 +1244,8 @@ def update_is_writable(self, is_writable): """ self.is_writable = is_writable with self.lock: - for socket in self.sockets: - socket.update_is_writable(self.is_writable) + for _socket in self.sockets: + _socket.update_is_writable(self.is_writable) def reset(self, service_id=None): self._reset(close=False, service_id=service_id) @@ -1386,7 +1384,7 @@ def get_socket(self, handler=None): listeners.publish_connection_checked_out(self.address, sock_info.id) try: yield sock_info - except: + except BaseException: # Exception in caller. Ensure the connection gets returned. # Note that when pinned is True, the session owns the # connection and it is responsible for checking the connection @@ -1433,7 +1431,7 @@ def _get_socket(self): self.address, ConnectionCheckOutFailedReason.POOL_CLOSED ) raise _PoolClosedError( - "Attempted to check out a connection from closed connection " "pool" + "Attempted to check out a connection from closed connection pool" ) with self.lock: diff --git a/pymongo/pyopenssl_context.py b/pymongo/pyopenssl_context.py index 9e4c5cab40..eae38daef8 100644 --- a/pymongo/pyopenssl_context.py +++ b/pymongo/pyopenssl_context.py @@ -75,7 +75,7 @@ def _is_ip_address(address): try: _ip_address(address) return True - except (ValueError, UnicodeError): + except (ValueError, UnicodeError): # noqa: B014 return False @@ -145,7 +145,7 @@ def sendall(self, buf, flags=0): # XXX: It's not clear if this can actually happen. PyOpenSSL # doesn't appear to have any interrupt handling, nor any interrupt # errors for OpenSSL connections. - except (IOError, OSError) as exc: + except (IOError, OSError) as exc: # noqa: B014 if _errno_from_exception(exc) == _EINTR: continue raise diff --git a/pymongo/read_preferences.py b/pymongo/read_preferences.py index 02a2e88bf0..5ce2fbafcc 100644 --- a/pymongo/read_preferences.py +++ b/pymongo/read_preferences.py @@ -49,8 +49,7 @@ def _validate_tag_sets(tag_sets): raise TypeError(("Tag sets %r invalid, must be a sequence") % (tag_sets,)) if len(tag_sets) == 0: raise ValueError( - ("Tag sets %r invalid, must be None or contain at least one set of" " tags") - % (tag_sets,) + ("Tag sets %r invalid, must be None or contain at least one set of tags") % (tag_sets,) ) for tags in tag_sets: @@ -500,10 +499,10 @@ def make_read_preference( ) -> _ServerMode: if mode == _PRIMARY: if tag_sets not in (None, [{}]): - raise ConfigurationError("Read preference primary " "cannot be combined with tags") + raise ConfigurationError("Read preference primary cannot be combined with tags") if max_staleness != -1: raise ConfigurationError( - "Read preference primary cannot be " "combined with maxStalenessSeconds" + "Read preference primary cannot be combined with maxStalenessSeconds" ) return Primary() return _ALL_READ_PREFERENCES[mode](tag_sets, max_staleness) # type: ignore diff --git a/pymongo/results.py b/pymongo/results.py index 127f574184..1cbb614bf3 100644 --- a/pymongo/results.py +++ b/pymongo/results.py @@ -13,7 +13,7 @@ # limitations under the License. """Result class definitions.""" -from typing import Any, Dict, List, Mapping, Optional, Sequence, cast +from typing import Any, Dict, List, Optional, cast from pymongo.errors import InvalidOperation diff --git a/pymongo/server.py b/pymongo/server.py index be1e7da89c..f26f473c32 100644 --- a/pymongo/server.py +++ b/pymongo/server.py @@ -21,7 +21,6 @@ from pymongo.helpers import _check_command_response from pymongo.message import _convert_exception, _OpMsg from pymongo.response import PinnedResponse, Response -from pymongo.server_type import SERVER_TYPE _CURSOR_DOC_FIELDS = {"cursor": {"firstBatch": 1, "nextBatch": 1}} diff --git a/pymongo/server_description.py b/pymongo/server_description.py index 6b2a71df0b..47e27c531b 100644 --- a/pymongo/server_description.py +++ b/pymongo/server_description.py @@ -15,7 +15,7 @@ """Represent one server the driver is connected to.""" import time -from typing import Any, Dict, Mapping, Optional, Set, Tuple, cast +from typing import Any, Dict, Mapping, Optional, Set, Tuple from bson import EPOCH_NAIVE from bson.objectid import ObjectId diff --git a/pymongo/socket_checker.py b/pymongo/socket_checker.py index 70c12f0699..420953db2e 100644 --- a/pymongo/socket_checker.py +++ b/pymongo/socket_checker.py @@ -17,7 +17,7 @@ import errno import select import sys -from typing import Any, Optional, Union +from typing import Any, Optional # PYTHON-2320: Jython does not fully support poll on SSL sockets, # https://bugs.jython.org/issue2900 diff --git a/pymongo/ssl_context.py b/pymongo/ssl_context.py index e546105141..148bef936d 100644 --- a/pymongo/ssl_context.py +++ b/pymongo/ssl_context.py @@ -31,10 +31,10 @@ # Base Exception class SSLError = _ssl.SSLError -from ssl import SSLContext +from ssl import SSLContext # noqa: F401,E402 if hasattr(_ssl, "VERIFY_CRL_CHECK_LEAF"): - from ssl import VERIFY_CRL_CHECK_LEAF + from ssl import VERIFY_CRL_CHECK_LEAF # noqa: F401 # Python 3.7 uses OpenSSL's hostname matching implementation # making it the obvious version to start using SSLConext.check_hostname. # Python 3.6 might have been a good version, but it suffers diff --git a/pymongo/ssl_support.py b/pymongo/ssl_support.py index 7b5417fefa..06ef7ef185 100644 --- a/pymongo/ssl_support.py +++ b/pymongo/ssl_support.py @@ -34,7 +34,7 @@ # CPython ssl module constants to configure certificate verification # at a high level. This is legacy behavior, but requires us to # import the ssl module even if we're only using it for this purpose. - import ssl as _stdlibssl + import ssl as _stdlibssl # noqa from ssl import CERT_NONE, CERT_REQUIRED HAS_SNI = _ssl.HAS_SNI @@ -79,7 +79,7 @@ def get_ssl_context( if _ssl.IS_PYOPENSSL: raise ConfigurationError("tlsCRLFile cannot be used with PyOpenSSL") # Match the server's behavior. - setattr(ctx, "verify_flags", getattr(_ssl, "VERIFY_CRL_CHECK_LEAF", 0)) + setattr(ctx, "verify_flags", getattr(_ssl, "VERIFY_CRL_CHECK_LEAF", 0)) # noqa ctx.load_verify_locations(crlfile) if ca_certs is not None: ctx.load_verify_locations(ca_certs) diff --git a/pymongo/typings.py b/pymongo/typings.py index 263b591e24..19d92b2381 100644 --- a/pymongo/typings.py +++ b/pymongo/typings.py @@ -17,13 +17,11 @@ TYPE_CHECKING, Any, Dict, - List, Mapping, MutableMapping, Optional, Sequence, Tuple, - Type, TypeVar, Union, ) diff --git a/pymongo/uri_parser.py b/pymongo/uri_parser.py index 3417c4954e..fa44dd8569 100644 --- a/pymongo/uri_parser.py +++ b/pymongo/uri_parser.py @@ -15,19 +15,8 @@ """Tools to parse and validate a MongoDB URI.""" import re -import sys import warnings -from typing import ( - Any, - Dict, - List, - Mapping, - MutableMapping, - Optional, - Tuple, - Union, - cast, -) +from typing import Any, Dict, List, Mapping, MutableMapping, Optional, Tuple, Union from urllib.parse import unquote_plus from pymongo.client_options import _parse_ssl_options @@ -107,7 +96,7 @@ def parse_ipv6_literal_host( """ if entity.find("]") == -1: raise ValueError( - "an IPv6 address literal must be " "enclosed in '[' and ']' according " "to RFC 2732." + "an IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732." ) i = entity.find("]:") if i == -1: @@ -196,7 +185,7 @@ def _handle_security_options(options): if tlsinsecure is not None: for opt in _IMPLICIT_TLSINSECURE_OPTS: if opt in options: - err_msg = "URI options %s and %s cannot be specified " "simultaneously." + err_msg = "URI options %s and %s cannot be specified simultaneously." raise InvalidURI( err_msg % (options.cased_key("tlsinsecure"), options.cased_key(opt)) ) @@ -205,7 +194,7 @@ def _handle_security_options(options): tlsallowinvalidcerts = options.get("tlsallowinvalidcertificates") if tlsallowinvalidcerts is not None: if "tlsdisableocspendpointcheck" in options: - err_msg = "URI options %s and %s cannot be specified " "simultaneously." + err_msg = "URI options %s and %s cannot be specified simultaneously." raise InvalidURI( err_msg % ("tlsallowinvalidcertificates", options.cased_key("tlsdisableocspendpointcheck")) @@ -218,7 +207,7 @@ def _handle_security_options(options): if tlscrlfile is not None: for opt in ("tlsinsecure", "tlsallowinvalidcertificates", "tlsdisableocspendpointcheck"): if options.get(opt) is True: - err_msg = "URI option %s=True cannot be specified when " "CRL checking is enabled." + err_msg = "URI option %s=True cannot be specified when CRL checking is enabled." raise InvalidURI(err_msg % (opt,)) if "ssl" in options and "tls" in options: @@ -231,7 +220,7 @@ def truth_value(val): return val if truth_value(options.get("ssl")) != truth_value(options.get("tls")): - err_msg = "Can not specify conflicting values for URI options %s " "and %s." + err_msg = "Can not specify conflicting values for URI options %s and %s." raise InvalidURI(err_msg % (options.cased_key("ssl"), options.cased_key("tls"))) return options @@ -252,7 +241,7 @@ def _handle_option_deprecations(options): if mode == "renamed": newoptname = message if newoptname in options: - warn_msg = "Deprecated option '%s' ignored in favor of " "'%s'." + warn_msg = "Deprecated option '%s' ignored in favor of '%s'." warnings.warn( warn_msg % (options.cased_key(optname), options.cased_key(newoptname)), DeprecationWarning, @@ -378,7 +367,7 @@ def split_hosts(hosts: str, default_port: Optional[int] = DEFAULT_PORT) -> List[ nodes = [] for entity in hosts.split(","): if not entity: - raise ConfigurationError("Empty host " "(or extra comma in host list).") + raise ConfigurationError("Empty host (or extra comma in host list).") port = default_port # Unix socket entities don't have ports if entity.endswith(".sock"): @@ -486,7 +475,7 @@ def parse_uri( scheme_free = uri[SRV_SCHEME_LEN:] else: raise InvalidURI( - "Invalid URI scheme: URI must " "begin with '%s' or '%s'" % (SCHEME, SRV_SCHEME) + "Invalid URI scheme: URI must begin with '%s' or '%s'" % (SCHEME, SRV_SCHEME) ) if not scheme_free: @@ -504,7 +493,7 @@ def parse_uri( path_part = "" if not path_part and "?" in host_part: - raise InvalidURI("A '/' is required between " "the host list and any options.") + raise InvalidURI("A '/' is required between the host list and any options.") if path_part: dbase, _, opts = path_part.partition("?") @@ -528,9 +517,7 @@ def parse_uri( hosts = host_part if "/" in hosts: - raise InvalidURI( - "Any '/' in a unix domain socket must be" " percent-encoded: %s" % host_part - ) + raise InvalidURI("Any '/' in a unix domain socket must be percent-encoded: %s" % host_part) hosts = unquote_plus(hosts) fqdn = None @@ -538,11 +525,11 @@ def parse_uri( if is_srv: if options.get("directConnection"): raise ConfigurationError( - "Cannot specify directConnection=true with " "%s URIs" % (SRV_SCHEME,) + "Cannot specify directConnection=true with %s URIs" % (SRV_SCHEME,) ) nodes = split_hosts(hosts, default_port=None) if len(nodes) != 1: - raise InvalidURI("%s URIs must include one, " "and only one, hostname" % (SRV_SCHEME,)) + raise InvalidURI("%s URIs must include one, and only one, hostname" % (SRV_SCHEME,)) fqdn, port = nodes[0] if port is not None: raise InvalidURI("%s URIs must not include a port number" % (SRV_SCHEME,)) @@ -557,7 +544,7 @@ def parse_uri( parsed_dns_options = split_options(dns_options, validate, warn, normalize) if set(parsed_dns_options) - _ALLOWED_TXT_OPTS: raise ConfigurationError( - "Only authSource, replicaSet, and loadBalanced are " "supported from DNS" + "Only authSource, replicaSet, and loadBalanced are supported from DNS" ) for opt, val in parsed_dns_options.items(): if opt not in options: @@ -570,11 +557,11 @@ def parse_uri( options["tls"] = True if validate else "true" elif not is_srv and options.get("srvServiceName") is not None: raise ConfigurationError( - "The srvServiceName option is only allowed " "with 'mongodb+srv://' URIs" + "The srvServiceName option is only allowed with 'mongodb+srv://' URIs" ) elif not is_srv and srv_max_hosts: raise ConfigurationError( - "The srvMaxHosts option is only allowed " "with 'mongodb+srv://' URIs" + "The srvMaxHosts option is only allowed with 'mongodb+srv://' URIs" ) else: nodes = split_hosts(hosts, default_port=default_port) diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index fea912d569..ced71d0488 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -73,7 +73,7 @@ def __init__( if not isinstance(fsync, bool): raise TypeError("fsync must be True or False") if j and fsync: - raise ConfigurationError("Can't set both j " "and fsync at the same time") + raise ConfigurationError("Can't set both j and fsync at the same time") self.__document["fsync"] = fsync if w == 0 and j is True: diff --git a/setup.py b/setup.py index 5dbbdde22b..699ced1f85 100755 --- a/setup.py +++ b/setup.py @@ -10,11 +10,10 @@ # Hack to silence atexit traceback in some Python versions try: - import multiprocessing + import multiprocessing # noqa: F401 except ImportError: pass -from setuptools import __version__ as _setuptools_version from setuptools import setup if sys.version_info[:2] < (3, 10): @@ -41,7 +40,7 @@ try: try: readme_content = f.read() - except: + except BaseException: readme_content = "" finally: f.close() @@ -152,7 +151,7 @@ def run(self): try: os.makedirs(path) - except: + except BaseException: pass sphinx_args = ["-E", "-b", mode, "doc", path] @@ -169,7 +168,7 @@ def run(self): raise RuntimeError("documentation step '%s' failed" % (mode,)) sys.stdout.write( - "\nDocumentation step '%s' performed, results here:\n" " %s/\n" % (mode, path) + "\nDocumentation step '%s' performed, results here:\n %s/\n" % (mode, path) ) @@ -232,7 +231,7 @@ def run(self): self.warning_message % ( "Extension modules", - "There was an issue with " "your platform configuration" " - see above.", + "There was an issue with your platform configuration - see above.", ) ) @@ -246,8 +245,8 @@ def build_extension(self, ext): warnings.warn( self.warning_message % ( - "The %s extension " "module" % (name,), - "The output above " "this warning shows how " "the compilation " "failed.", + "The %s extension module" % (name,), + "The output above this warning shows how the compilation failed.", ) ) diff --git a/test/__init__.py b/test/__init__.py index d75c011547..be0825025a 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -20,7 +20,6 @@ import socket import sys import threading -import time import traceback import unittest import warnings @@ -34,7 +33,7 @@ HAVE_XML = False try: - import ipaddress + import ipaddress # noqa HAVE_IPADDRESS = True except ImportError: @@ -667,7 +666,7 @@ def require_secondary_read_pref(self): """ return self._require( lambda: self.supports_secondary_read_pref, - "This cluster does not support secondary read " "preference", + "This cluster does not support secondary read preference", ) def require_no_replica_set(self, func): @@ -757,7 +756,7 @@ def is_topology_type(self, topologies): return True return False - def require_cluster_type(self, topologies=[]): + def require_cluster_type(self, topologies=[]): # noqa """Run a test only if the client is connected to a cluster that conforms to one of the specified topologies. Acceptable topologies are 'single', 'replicaset', and 'sharded'.""" @@ -825,7 +824,7 @@ def require_server_resolvable(self, func): """Run a test only if the hostname 'server' is resolvable.""" return self._require( lambda: self.server_is_resolvable, - "No hosts entry for 'server'. Cannot validate " "hostname in the certificate", + "No hosts entry for 'server'. Cannot validate hostname in the certificate", func=func, ) @@ -1125,9 +1124,9 @@ def test_cases(suite): # Helper method to workaround https://bugs.python.org/issue21724 def clear_warning_registry(): """Clear the __warningregistry__ for all modules.""" - for name, module in list(sys.modules.items()): + for _, module in list(sys.modules.items()): if hasattr(module, "__warningregistry__"): - setattr(module, "__warningregistry__", {}) + setattr(module, "__warningregistry__", {}) # noqa class SystemCertsPatcher(object): diff --git a/test/atlas/test_connection.py b/test/atlas/test_connection.py index cad2b10683..a1eb97edee 100644 --- a/test/atlas/test_connection.py +++ b/test/atlas/test_connection.py @@ -25,7 +25,7 @@ from pymongo.ssl_support import HAS_SNI try: - import dns + import dns # noqa HAS_DNS = True except ImportError: @@ -120,7 +120,7 @@ def test_uniqueness(self): duplicates = [names for names in uri_to_names.values() if len(names) > 1] self.assertFalse( duplicates, - "Error: the following env variables have " "duplicate values: %s" % (duplicates,), + "Error: the following env variables have duplicate values: %s" % (duplicates,), ) diff --git a/test/mockupdb/test_cluster_time.py b/test/mockupdb/test_cluster_time.py index e6d8c2126c..cb06a129d2 100644 --- a/test/mockupdb/test_cluster_time.py +++ b/test/mockupdb/test_cluster_time.py @@ -28,7 +28,7 @@ def cluster_time_conversation(self, callback, replies): server = MockupDB() # First test all commands include $clusterTime with wire version 6. - responder = server.autoresponds( + _ = server.autoresponds( "ismaster", { "minWireVersion": 0, diff --git a/test/mockupdb/test_handshake.py b/test/mockupdb/test_handshake.py index c9799fa21e..39188e8ad0 100644 --- a/test/mockupdb/test_handshake.py +++ b/test/mockupdb/test_handshake.py @@ -33,7 +33,7 @@ def test_hello_with_option(self, protocol, **kwargs): def respond(r): # Only save the very first request from the driver. - if self.handshake_req == None: + if self.handshake_req is None: self.handshake_req = r load_balanced_kwargs = {"serviceId": ObjectId()} if kwargs.get("loadBalanced") else {} return r.reply( @@ -261,7 +261,7 @@ def responder(request): self.addCleanup(client.close) self.assertRaises(OperationFailure, client.db.collection.find_one, {"a": 1}) self.assertTrue( - self.found_auth_msg, "Could not find authentication " "command with correct protocol" + self.found_auth_msg, "Could not find authentication command with correct protocol" ) diff --git a/test/mockupdb/test_list_indexes.py b/test/mockupdb/test_list_indexes.py index 2bdbd7b910..20764e6e5a 100644 --- a/test/mockupdb/test_list_indexes.py +++ b/test/mockupdb/test_list_indexes.py @@ -16,7 +16,7 @@ import unittest -from mockupdb import MockupDB, OpGetMore, going +from mockupdb import MockupDB, going from bson import SON from pymongo import MongoClient diff --git a/test/mockupdb/test_mixed_version_sharded.py b/test/mockupdb/test_mixed_version_sharded.py index ce91794ee4..d5fb9913cc 100644 --- a/test/mockupdb/test_mixed_version_sharded.py +++ b/test/mockupdb/test_mixed_version_sharded.py @@ -18,7 +18,7 @@ import unittest from queue import Queue -from mockupdb import MockupDB, OpMsg, go +from mockupdb import MockupDB, go from operations import upgrades from pymongo import MongoClient diff --git a/test/mockupdb/test_mongos_command_read_mode.py b/test/mockupdb/test_mongos_command_read_mode.py index d2c3bfc1b0..b7f8532e38 100644 --- a/test/mockupdb/test_mongos_command_read_mode.py +++ b/test/mockupdb/test_mongos_command_read_mode.py @@ -15,10 +15,9 @@ import itertools import unittest -from mockupdb import MockupDB, OpMsg, go, going +from mockupdb import MockupDB, OpMsg, going from operations import operations -from bson import SON from pymongo import MongoClient, ReadPreference from pymongo.read_preferences import ( _MONGOS_MODES, diff --git a/test/mockupdb/test_network_disconnect_primary.py b/test/mockupdb/test_network_disconnect_primary.py index dcf5256fac..ea13a3b042 100755 --- a/test/mockupdb/test_network_disconnect_primary.py +++ b/test/mockupdb/test_network_disconnect_primary.py @@ -13,7 +13,6 @@ # limitations under the License. import unittest -from queue import Queue from mockupdb import Future, MockupDB, OpReply, going, wait_until diff --git a/test/mockupdb/test_slave_okay_single.py b/test/mockupdb/test_slave_okay_single.py index 98cd1f2706..07cd6c7448 100644 --- a/test/mockupdb/test_slave_okay_single.py +++ b/test/mockupdb/test_slave_okay_single.py @@ -48,15 +48,9 @@ def test(self): ismaster_with_version["minWireVersion"] = 2 ismaster_with_version["maxWireVersion"] = 6 self.server.autoresponds("ismaster", **ismaster_with_version) - if operation.op_type == "always-use-secondary": - slave_ok = True - elif operation.op_type == "may-use-secondary": - slave_ok = mode != "primary" or server_type != "mongos" - elif operation.op_type == "must-use-primary": - slave_ok = server_type != "mongos" - else: - assert False, "unrecognized op_type %r" % operation.op_type - + self.assertIn( + operation.op_type, ("always-use-secondary", "may-use-secondary", "must-use-primary") + ) pref = make_read_preference(read_pref_mode_from_name(mode), tag_sets=None) client = MongoClient(self.server.uri, read_preference=pref) diff --git a/test/mod_wsgi_test/mod_wsgi_test.wsgi b/test/mod_wsgi_test/mod_wsgi_test.wsgi index bfd1c4bab0..7c7b24cb70 100644 --- a/test/mod_wsgi_test/mod_wsgi_test.wsgi +++ b/test/mod_wsgi_test/mod_wsgi_test.wsgi @@ -25,7 +25,7 @@ repository_path = os.path.normpath(os.path.join(this_path, '..', '..')) sys.path.insert(0, repository_path) import pymongo -from pymongo.hello import HelloCompat +from pymongo.hello import HelloCompat # noqa from pymongo.mongo_client import MongoClient client = MongoClient() @@ -33,7 +33,7 @@ collection = client.test.test ndocs = 20 collection.drop() collection.insert_many([{'i': i} for i in range(ndocs)]) -client.close() # Discard main thread's request socket. +client.close() # Discard main thread's request socket. client = MongoClient() collection = client.test.test diff --git a/test/ocsp/test_ocsp.py b/test/ocsp/test_ocsp.py index cce846feac..a0770afefa 100644 --- a/test/ocsp/test_ocsp.py +++ b/test/ocsp/test_ocsp.py @@ -40,7 +40,7 @@ def _connect(options): - uri = ("mongodb://localhost:27017/?serverSelectionTimeoutMS=%s" "&tlsCAFile=%s&%s") % ( + uri = ("mongodb://localhost:27017/?serverSelectionTimeoutMS=%s&tlsCAFile=%s&%s") % ( TIMEOUT_MS, CA_FILE, options, diff --git a/test/test_auth.py b/test/test_auth.py index 5abdbef3dc..69ed27bda0 100644 --- a/test/test_auth.py +++ b/test/test_auth.py @@ -21,11 +21,10 @@ sys.path[0:0] = [""] -from test import IntegrationTest, SkipTest, Version, client_context, unittest +from test import IntegrationTest, SkipTest, client_context, unittest from test.utils import ( AllowListEventListener, delay, - get_pool, ignore_deprecations, rs_or_single_client, rs_or_single_client_noauth, @@ -119,14 +118,14 @@ def test_credentials_hashing(self): def test_gssapi_simple(self): assert GSSAPI_PRINCIPAL is not None if GSSAPI_PASS is not None: - uri = "mongodb://%s:%s@%s:%d/?authMechanism=" "GSSAPI" % ( + uri = "mongodb://%s:%s@%s:%d/?authMechanism=GSSAPI" % ( quote_plus(GSSAPI_PRINCIPAL), GSSAPI_PASS, GSSAPI_HOST, GSSAPI_PORT, ) else: - uri = "mongodb://%s@%s:%d/?authMechanism=" "GSSAPI" % ( + uri = "mongodb://%s@%s:%d/?authMechanism=GSSAPI" % ( quote_plus(GSSAPI_PRINCIPAL), GSSAPI_HOST, GSSAPI_PORT, @@ -266,7 +265,7 @@ class TestSASLPlain(unittest.TestCase): @classmethod def setUpClass(cls): if not SASL_HOST or not SASL_USER or not SASL_PASS: - raise SkipTest("Must set SASL_HOST, " "SASL_USER, and SASL_PASS to test SASL") + raise SkipTest("Must set SASL_HOST, SASL_USER, and SASL_PASS to test SASL") def test_sasl_plain(self): @@ -282,7 +281,7 @@ def test_sasl_plain(self): assert SASL_USER is not None assert SASL_PASS is not None - uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;" "authSource=%s" % ( + uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;authSource=%s" % ( quote_plus(SASL_USER), quote_plus(SASL_PASS), SASL_HOST, @@ -305,7 +304,7 @@ def test_sasl_plain(self): ) client.ldap.test.find_one() - uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;" "authSource=%s;replicaSet=%s" % ( + uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;authSource=%s;replicaSet=%s" % ( quote_plus(SASL_USER), quote_plus(SASL_PASS), SASL_HOST, @@ -318,7 +317,7 @@ def test_sasl_plain(self): def test_sasl_plain_bad_credentials(self): def auth_string(user, password): - uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;" "authSource=%s" % ( + uri = "mongodb://%s:%s@%s:%d/?authMechanism=PLAIN;authSource=%s" % ( quote_plus(user), quote_plus(password), SASL_HOST, @@ -484,7 +483,7 @@ def test_scram(self): if client_context.is_rs: host, port = client_context.host, client_context.port - uri = "mongodb://both:pwd@%s:%d/testscram" "?replicaSet=%s" % ( + uri = "mongodb://both:pwd@%s:%d/testscram?replicaSet=%s" % ( host, port, client_context.replica_set_name, @@ -641,7 +640,7 @@ def test_uri_options(self): self.assertTrue(db.command("dbstats")) # Test authSource - uri = "mongodb://user:pass@%s:%d" "/pymongo_test2?authSource=pymongo_test" % (host, port) + uri = "mongodb://user:pass@%s:%d/pymongo_test2?authSource=pymongo_test" % (host, port) client = rs_or_single_client_noauth(uri) self.assertRaises(OperationFailure, client.pymongo_test2.command, "dbstats") self.assertTrue(client.pymongo_test.command("dbstats")) diff --git a/test/test_binary.py b/test/test_binary.py index 6352e93d2c..7d0ef2ce2e 100644 --- a/test/test_binary.py +++ b/test/test_binary.py @@ -19,14 +19,12 @@ import copy import mmap import pickle -import platform import sys import uuid sys.path[0:0] = [""] from test import IntegrationTest, client_context, unittest -from test.utils import ignore_deprecations import bson from bson import decode, encode diff --git a/test/test_bson.py b/test/test_bson.py index 46aa6e5d9a..9bf8df897a 100644 --- a/test/test_bson.py +++ b/test/test_bson.py @@ -204,35 +204,33 @@ def test_basic_validation(self): self.assertInvalid(b"\x07\x00\x00\x00\x02a\x00\x78\x56\x34\x12") self.assertInvalid(b"\x09\x00\x00\x00\x10a\x00\x05\x00") self.assertInvalid(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") - self.assertInvalid(b"\x13\x00\x00\x00\x02foo\x00" b"\x04\x00\x00\x00bar\x00\x00") + self.assertInvalid(b"\x13\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00") self.assertInvalid( - b"\x18\x00\x00\x00\x03foo\x00\x0f\x00\x00" b"\x00\x10bar\x00\xff\xff\xff\x7f\x00\x00" - ) - self.assertInvalid( - b"\x15\x00\x00\x00\x03foo\x00\x0c" b"\x00\x00\x00\x08bar\x00\x01\x00\x00" + b"\x18\x00\x00\x00\x03foo\x00\x0f\x00\x00\x00\x10bar\x00\xff\xff\xff\x7f\x00\x00" ) + self.assertInvalid(b"\x15\x00\x00\x00\x03foo\x00\x0c\x00\x00\x00\x08bar\x00\x01\x00\x00") self.assertInvalid( b"\x1c\x00\x00\x00\x03foo\x00" b"\x12\x00\x00\x00\x02bar\x00" b"\x05\x00\x00\x00baz\x00\x00\x00" ) - self.assertInvalid(b"\x10\x00\x00\x00\x02a\x00" b"\x04\x00\x00\x00abc\xff\x00") + self.assertInvalid(b"\x10\x00\x00\x00\x02a\x00\x04\x00\x00\x00abc\xff\x00") def test_bad_string_lengths(self): - self.assertInvalid(b"\x0c\x00\x00\x00\x02\x00" b"\x00\x00\x00\x00\x00\x00") - self.assertInvalid(b"\x12\x00\x00\x00\x02\x00" b"\xff\xff\xff\xfffoobar\x00\x00") - self.assertInvalid(b"\x0c\x00\x00\x00\x0e\x00" b"\x00\x00\x00\x00\x00\x00") - self.assertInvalid(b"\x12\x00\x00\x00\x0e\x00" b"\xff\xff\xff\xfffoobar\x00\x00") + self.assertInvalid(b"\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00") + self.assertInvalid(b"\x12\x00\x00\x00\x02\x00\xff\xff\xff\xfffoobar\x00\x00") + self.assertInvalid(b"\x0c\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00") + self.assertInvalid(b"\x12\x00\x00\x00\x0e\x00\xff\xff\xff\xfffoobar\x00\x00") self.assertInvalid( - b"\x18\x00\x00\x00\x0c\x00" b"\x00\x00\x00\x00\x00RY\xb5j" b"\xfa[\xd8A\xd6X]\x99\x00" + b"\x18\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00RY\xb5j\xfa[\xd8A\xd6X]\x99\x00" ) self.assertInvalid( b"\x1e\x00\x00\x00\x0c\x00" b"\xff\xff\xff\xfffoobar\x00" b"RY\xb5j\xfa[\xd8A\xd6X]\x99\x00" ) - self.assertInvalid(b"\x0c\x00\x00\x00\r\x00" b"\x00\x00\x00\x00\x00\x00") - self.assertInvalid(b"\x0c\x00\x00\x00\r\x00" b"\xff\xff\xff\xff\x00\x00") + self.assertInvalid(b"\x0c\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00") + self.assertInvalid(b"\x0c\x00\x00\x00\r\x00\xff\xff\xff\xff\x00\x00") self.assertInvalid( b"\x1c\x00\x00\x00\x0f\x00" b"\x15\x00\x00\x00\x00\x00" @@ -393,9 +391,7 @@ def test_invalid_field_name(self): def test_data_timestamp(self): self.assertEqual( {"test": Timestamp(4, 20)}, - decode( - b"\x13\x00\x00\x00\x11\x74\x65\x73\x74\x00\x14" b"\x00\x00\x00\x04\x00\x00\x00\x00" - ), + decode(b"\x13\x00\x00\x00\x11\x74\x65\x73\x74\x00\x14\x00\x00\x00\x04\x00\x00\x00\x00"), ) def test_basic_encode(self): @@ -414,29 +410,29 @@ def test_basic_encode(self): ) self.assertEqual( encode({"mike": 100}), - b"\x0F\x00\x00\x00\x10\x6D\x69\x6B\x65\x00\x64\x00" b"\x00\x00\x00", + b"\x0F\x00\x00\x00\x10\x6D\x69\x6B\x65\x00\x64\x00\x00\x00\x00", ) self.assertEqual( encode({"hello": 1.5}), - b"\x14\x00\x00\x00\x01\x68\x65\x6C\x6C\x6F\x00\x00" b"\x00\x00\x00\x00\x00\xF8\x3F\x00", + b"\x14\x00\x00\x00\x01\x68\x65\x6C\x6C\x6F\x00\x00\x00\x00\x00\x00\x00\xF8\x3F\x00", ) self.assertEqual( encode({"true": True}), b"\x0C\x00\x00\x00\x08\x74\x72\x75\x65\x00\x01\x00" ) self.assertEqual( - encode({"false": False}), b"\x0D\x00\x00\x00\x08\x66\x61\x6C\x73\x65\x00\x00" b"\x00" + encode({"false": False}), b"\x0D\x00\x00\x00\x08\x66\x61\x6C\x73\x65\x00\x00\x00" ) self.assertEqual( encode({"empty": []}), - b"\x11\x00\x00\x00\x04\x65\x6D\x70\x74\x79\x00\x05" b"\x00\x00\x00\x00\x00", + b"\x11\x00\x00\x00\x04\x65\x6D\x70\x74\x79\x00\x05\x00\x00\x00\x00\x00", ) self.assertEqual( encode({"none": {}}), - b"\x10\x00\x00\x00\x03\x6E\x6F\x6E\x65\x00\x05\x00" b"\x00\x00\x00\x00", + b"\x10\x00\x00\x00\x03\x6E\x6F\x6E\x65\x00\x05\x00\x00\x00\x00\x00", ) self.assertEqual( encode({"test": Binary(b"test", 0)}), - b"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00" b"\x00\x00\x00\x74\x65\x73\x74\x00", + b"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00\x00\x00\x00\x74\x65\x73\x74\x00", ) self.assertEqual( encode({"test": Binary(b"test", 2)}), @@ -445,24 +441,24 @@ def test_basic_encode(self): ) self.assertEqual( encode({"test": Binary(b"test", 128)}), - b"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00" b"\x00\x00\x80\x74\x65\x73\x74\x00", + b"\x14\x00\x00\x00\x05\x74\x65\x73\x74\x00\x04\x00\x00\x00\x80\x74\x65\x73\x74\x00", ) self.assertEqual(encode({"test": None}), b"\x0B\x00\x00\x00\x0A\x74\x65\x73\x74\x00\x00") self.assertEqual( encode({"date": datetime.datetime(2007, 1, 8, 0, 30, 11)}), - b"\x13\x00\x00\x00\x09\x64\x61\x74\x65\x00\x38\xBE" b"\x1C\xFF\x0F\x01\x00\x00\x00", + b"\x13\x00\x00\x00\x09\x64\x61\x74\x65\x00\x38\xBE\x1C\xFF\x0F\x01\x00\x00\x00", ) self.assertEqual( encode({"regex": re.compile(b"a*b", re.IGNORECASE)}), - b"\x12\x00\x00\x00\x0B\x72\x65\x67\x65\x78\x00\x61" b"\x2A\x62\x00\x69\x00\x00", + b"\x12\x00\x00\x00\x0B\x72\x65\x67\x65\x78\x00\x61\x2A\x62\x00\x69\x00\x00", ) self.assertEqual( encode({"$where": Code("test")}), - b"\x16\x00\x00\x00\r$where\x00\x05\x00\x00\x00test" b"\x00\x00", + b"\x16\x00\x00\x00\r$where\x00\x05\x00\x00\x00test\x00\x00", ) self.assertEqual( encode({"$field": Code("function(){ return true;}", scope=None)}), - b"+\x00\x00\x00\r$field\x00\x1a\x00\x00\x00" b"function(){ return true;}\x00\x00", + b"+\x00\x00\x00\r$field\x00\x1a\x00\x00\x00function(){ return true;}\x00\x00", ) self.assertEqual( encode({"$field": Code("return function(){ return x; }", scope={"x": False})}), @@ -496,7 +492,7 @@ def test_unknown_type(self): part = "type %r for fieldname 'foo'" % (b"\x14",) docs = [ b"\x0e\x00\x00\x00\x14foo\x00\x01\x00\x00\x00\x00", - (b"\x16\x00\x00\x00\x04foo\x00\x0c\x00\x00\x00\x140" b"\x00\x01\x00\x00\x00\x00\x00"), + (b"\x16\x00\x00\x00\x04foo\x00\x0c\x00\x00\x00\x140\x00\x01\x00\x00\x00\x00\x00"), ( b" \x00\x00\x00\x04bar\x00\x16\x00\x00\x00\x030\x00\x0e\x00\x00" b"\x00\x14foo\x00\x01\x00\x00\x00\x00\x00\x00" @@ -518,7 +514,7 @@ def test_dbpointer(self): # not support creation of the DBPointer type, but will decode # DBPointer to DBRef. - bs = b"\x18\x00\x00\x00\x0c\x00\x01\x00\x00" b"\x00\x00RY\xb5j\xfa[\xd8A\xd6X]\x99\x00" + bs = b"\x18\x00\x00\x00\x0c\x00\x01\x00\x00\x00\x00RY\xb5j\xfa[\xd8A\xd6X]\x99\x00" self.assertEqual({"": DBRef("", ObjectId("5259b56afa5bd841d6585d99"))}, decode(bs)) @@ -785,9 +781,7 @@ def test_bson_regex(self): self.assertEqual(0, bson_re1.flags) doc1 = {"r": bson_re1} - doc1_bson = ( - b"\x11\x00\x00\x00" b"\x0br\x00[\\w-\\.]\x00\x00" b"\x00" # document length # r: regex - ) # document terminator + doc1_bson = b"\x11\x00\x00\x00\x0br\x00[\\w-\\.]\x00\x00\x00" # document length # r: regex # document terminator self.assertEqual(doc1_bson, encode(doc1)) self.assertEqual(doc1, decode(doc1_bson)) @@ -798,9 +792,7 @@ def test_bson_regex(self): doc2_with_re = {"r": re2} doc2_with_bson_re = {"r": bson_re2} - doc2_bson = ( - b"\x11\x00\x00\x00" b"\x0br\x00.*\x00imsux\x00" b"\x00" # document length # r: regex - ) # document terminator + doc2_bson = b"\x11\x00\x00\x00\x0br\x00.*\x00imsux\x00\x00" # document length # r: regex # document terminator self.assertEqual(doc2_bson, encode(doc2_with_re)) self.assertEqual(doc2_bson, encode(doc2_with_bson_re)) @@ -917,7 +909,7 @@ def test_timestamp_comparison(self): def test_timestamp_highorder_bits(self): doc = {"a": Timestamp(0xFFFFFFFF, 0xFFFFFFFF)} - doc_bson = b"\x10\x00\x00\x00" b"\x11a\x00\xff\xff\xff\xff\xff\xff\xff\xff" b"\x00" + doc_bson = b"\x10\x00\x00\x00\x11a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00" self.assertEqual(doc_bson, encode(doc)) self.assertEqual(doc, decode(doc_bson)) diff --git a/test/test_bson_corpus.py b/test/test_bson_corpus.py index 4a46276573..4f8fc7413a 100644 --- a/test/test_bson_corpus.py +++ b/test/test_bson_corpus.py @@ -208,13 +208,13 @@ def run_test(self): # Null bytes are validated when encoding to BSON. if "Null" in description: to_bson(doc) - raise AssertionError("exception not raised for test " "case: " + description) + raise AssertionError("exception not raised for test case: " + description) except (ValueError, KeyError, TypeError, InvalidId, InvalidDocument): pass elif bson_type == "0x05": try: decode_extjson(parse_error_case["string"]) - raise AssertionError("exception not raised for test " "case: " + description) + raise AssertionError("exception not raised for test case: " + description) except (TypeError, ValueError): pass else: diff --git a/test/test_client.py b/test/test_client.py index 0487161b1e..9f01c1c054 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -26,7 +26,6 @@ import sys import threading import time -import warnings from typing import Type, no_type_check sys.path[0:0] = [""] @@ -88,7 +87,6 @@ ServerSelectionTimeoutError, WriteConcernError, ) -from pymongo.hello import HelloCompat from pymongo.mongo_client import MongoClient from pymongo.monitoring import ServerHeartbeatListener, ServerHeartbeatStartedEvent from pymongo.pool import _METADATA, PoolOptions, SocketInfo @@ -99,10 +97,7 @@ from pymongo.settings import TOPOLOGY_TYPE from pymongo.srv_resolver import _HAVE_DNSPYTHON from pymongo.topology import _ErrorContext -from pymongo.topology_description import ( - TopologyDescription, - _updated_topology_description_srv_polling, -) +from pymongo.topology_description import TopologyDescription from pymongo.write_concern import WriteConcern @@ -279,7 +274,7 @@ def test_primary_read_pref_with_tags(self): MongoClient("mongodb://host/?readpreferencetags=dc:east") with self.assertRaises(ConfigurationError): - MongoClient("mongodb://host/?" "readpreference=primary&readpreferencetags=dc:east") + MongoClient("mongodb://host/?readpreference=primary&readpreferencetags=dc:east") def test_read_preference(self): c = rs_or_single_client( @@ -394,7 +389,7 @@ def test_uri_codec_options(self): def test_uri_option_precedence(self): # Ensure kwarg options override connection string options. - uri = "mongodb://localhost/?ssl=true&replicaSet=name" "&readPreference=primary" + uri = "mongodb://localhost/?ssl=true&replicaSet=name&readPreference=primary" c = MongoClient(uri, ssl=False, replicaSet="newname", readPreference="secondaryPreferred") clopts = c._MongoClient__options opts = clopts._options @@ -590,7 +585,7 @@ def test_max_idle_time_checkout(self): with server._pool.get_socket() as sock_info: pass self.assertEqual(1, len(server._pool.sockets)) - time.sleep(1) # Sleep so that the socket becomes stale. + time.sleep(1) # Sleep so that the socket becomes stale. with server._pool.get_socket() as new_sock_info: self.assertNotEqual(sock_info, new_sock_info) @@ -712,7 +707,7 @@ def test_host_w_port(self): def test_repr(self): # Used to test 'eval' below. - import bson + import bson # noqa: F401 client = MongoClient( "mongodb://localhost:27017,localhost:27018/?replicaSet=replset" @@ -723,9 +718,7 @@ def test_repr(self): the_repr = repr(client) self.assertIn("MongoClient(host=", the_repr) - self.assertIn( - "document_class=bson.son.SON, " "tz_aware=False, " "connect=False, ", the_repr - ) + self.assertIn("document_class=bson.son.SON, tz_aware=False, connect=False, ", the_repr) self.assertIn("connecttimeoutms=12345", the_repr) self.assertIn("replicaset='replset'", the_repr) self.assertIn("w=1", the_repr) @@ -744,7 +737,7 @@ def test_repr(self): ) the_repr = repr(client) self.assertIn("MongoClient(host=", the_repr) - self.assertIn("document_class=dict, " "tz_aware=False, " "connect=False, ", the_repr) + self.assertIn("document_class=dict, tz_aware=False, connect=False, ", the_repr) self.assertIn("connecttimeoutms=12345", the_repr) self.assertIn("replicaset='replset'", the_repr) self.assertIn("sockettimeoutms=None", the_repr) @@ -1651,7 +1644,7 @@ def test_service_name_from_kwargs(self): ) self.assertEqual(client._topology_settings.srv_service_name, "customname") client = MongoClient( - "mongodb+srv://user:password@test22.test.build.10gen.cc" "/?srvServiceName=customname", + "mongodb+srv://user:password@test22.test.build.10gen.cc/?srvServiceName=customname", connect=False, ) self.assertEqual(client._topology_settings.srv_service_name, "customname") @@ -1864,7 +1857,7 @@ def test_discover_primary(self): # Fail over. c.kill_host("a:1") c.mock_primary = "b:2" - wait_until(lambda: c.address == ("b", 2), "wait for server " "address to be " "updated") + wait_until(lambda: c.address == ("b", 2), "wait for server address to be updated") # a:1 not longer in nodes. self.assertLess(len(c.nodes), 3) diff --git a/test/test_client_context.py b/test/test_client_context.py index b3eb711087..9ee5b96d61 100644 --- a/test/test_client_context.py +++ b/test/test_client_context.py @@ -49,7 +49,7 @@ def test_enableTestCommands_is_disabled(self): self.assertFalse( client_context.test_commands_enabled, - "enableTestCommands must be disabled when " "PYMONGO_DISABLE_TEST_COMMANDS is set.", + "enableTestCommands must be disabled when PYMONGO_DISABLE_TEST_COMMANDS is set.", ) def test_setdefaultencoding_worked(self): diff --git a/test/test_cmap.py b/test/test_cmap.py index b79f36b803..a2a1d8d214 100644 --- a/test/test_cmap.py +++ b/test/test_cmap.py @@ -16,7 +16,6 @@ import os import sys -import threading import time sys.path[0:0] = [""] @@ -25,7 +24,6 @@ from test.pymongo_mocks import DummyMonitor from test.utils import ( CMAPListener, - OvertCommandListener, TestCreator, camel_to_snake, client_context, diff --git a/test/test_collection.py b/test/test_collection.py index f81c2c2645..d9f51f530d 100644 --- a/test/test_collection.py +++ b/test/test_collection.py @@ -246,8 +246,7 @@ def test_create_indexes_commitQuorum_requires_44(self): db = self.db with self.assertRaisesRegex( ConfigurationError, - "Must be connected to MongoDB 4\.4\+ to use the commitQuorum " - "option for createIndexes", + r"Must be connected to MongoDB 4\.4\+ to use the commitQuorum option for createIndexes", ): db.coll.create_indexes([IndexModel("a")], commitQuorum="majority") @@ -1511,7 +1510,7 @@ def test_aggregation_cursor(self): # batchSize - 1 self.assertEqual(4, len(cursor._CommandCursor__data)) # type: ignore # Exhaust the cursor. There shouldn't be any errors. - for doc in cursor: + for _doc in cursor: pass def test_aggregation_cursor_alive(self): @@ -1898,7 +1897,8 @@ def test_array_filters_validation(self): with self.assertRaises(TypeError): c.update_many({}, {"$set": {"a": 1}}, array_filters={}) # type: ignore[arg-type] with self.assertRaises(TypeError): - c.find_one_and_update({}, {"$set": {"a": 1}}, array_filters={}) # type: ignore[arg-type] + update = {"$set": {"a": 1}} + c.find_one_and_update({}, update, array_filters={}) # type: ignore[arg-type] def test_array_filters_unacknowledged(self): c_w0 = self.db.test.with_options(write_concern=WriteConcern(w=0)) diff --git a/test/test_command_monitoring_legacy.py b/test/test_command_monitoring_legacy.py index ed3d516f97..5d9f2fe3ee 100644 --- a/test/test_command_monitoring_legacy.py +++ b/test/test_command_monitoring_legacy.py @@ -21,12 +21,7 @@ sys.path[0:0] = [""] from test import client_context, unittest -from test.utils import ( - EventListener, - parse_read_preference, - rs_or_single_client, - wait_until, -) +from test.utils import EventListener, parse_read_preference, rs_or_single_client import pymongo from bson import json_util diff --git a/test/test_comment.py b/test/test_comment.py index 1c0e741621..c83428fd70 100644 --- a/test/test_comment.py +++ b/test/test_comment.py @@ -16,23 +16,16 @@ import inspect import sys -from collections import defaultdict from typing import Any, Union sys.path[0:0] = [""] -from test import IntegrationTest, SkipTest, client_context, unittest +from test import IntegrationTest, client_context, unittest from test.utils import EventListener, rs_or_single_client from bson.dbref import DBRef -from pymongo.collection import Collection from pymongo.command_cursor import CommandCursor -from pymongo.database import Database -from pymongo.mongo_client import MongoClient from pymongo.operations import IndexModel -from pymongo.read_concern import ReadConcern -from pymongo.read_preferences import ReadPreference -from pymongo.write_concern import WriteConcern class Empty(object): @@ -47,7 +40,9 @@ def empty(self, *args, **kwargs): class TestComment(IntegrationTest): - def _test_ops(self, helpers, already_supported, listener, db=Empty(), coll=Empty()): + def _test_ops( + self, helpers, already_supported, listener, db=Empty(), coll=Empty() # noqa: B008 + ): results = listener.results for h, args in helpers: c = "testing comment with " + h.__name__ @@ -56,7 +51,7 @@ def _test_ops(self, helpers, already_supported, listener, db=Empty(), coll=Empty results.clear() kwargs = {"comment": cc} if h == coll.rename: - tmp = db.get_collection("temp_temp_temp").drop() + _ = db.get_collection("temp_temp_temp").drop() destruct_coll = db.get_collection("test_temp") destruct_coll.insert_one({}) maybe_cursor = destruct_coll.rename(*args, **kwargs) diff --git a/test/test_crud_v1.py b/test/test_crud_v1.py index c23ce28061..ca4b84c26d 100644 --- a/test/test_crud_v1.py +++ b/test/test_crud_v1.py @@ -19,7 +19,7 @@ sys.path[0:0] = [""] -from test import IntegrationTest, client_context, unittest +from test import IntegrationTest, unittest from test.utils import ( TestCreator, camel_to_snake, diff --git a/test/test_cursor.py b/test/test_cursor.py index 7a80b003df..5b4efcd391 100644 --- a/test/test_cursor.py +++ b/test/test_cursor.py @@ -39,12 +39,7 @@ from pymongo import ASCENDING, DESCENDING from pymongo.collation import Collation from pymongo.cursor import Cursor, CursorType -from pymongo.errors import ( - ConfigurationError, - ExecutionTimeout, - InvalidOperation, - OperationFailure, -) +from pymongo.errors import ExecutionTimeout, InvalidOperation, OperationFailure from pymongo.read_concern import ReadConcern from pymongo.read_preferences import ReadPreference from pymongo.write_concern import WriteConcern @@ -355,7 +350,7 @@ def test_hint(self): ) spec = [("num", DESCENDING)] - index = db.test.create_index(spec) + _ = db.test.create_index(spec) first = next(db.test.find()) self.assertEqual(0, first.get("num")) @@ -763,7 +758,7 @@ def test_where(self): self.assertEqual([8, 9], [a["x"] for a in cursor]) a = db.test.find() - b = a.where("this.x > 3") + _ = a.where("this.x > 3") for _ in a: break self.assertRaises(InvalidOperation, a.where, "this.x < 3") diff --git a/test/test_custom_types.py b/test/test_custom_types.py index 4659a62e62..a7073cde93 100644 --- a/test/test_custom_types.py +++ b/test/test_custom_types.py @@ -545,9 +545,7 @@ def transform_bson(self, value): ) def test_initialize_fail(self): - err_msg = ( - "Expected an instance of TypeEncoder, TypeDecoder, " "or TypeCodec, got .* instead" - ) + err_msg = "Expected an instance of TypeEncoder, TypeDecoder, or TypeCodec, got .* instead" with self.assertRaisesRegex(TypeError, err_msg): TypeRegistry(self.codecs) # type: ignore[arg-type] diff --git a/test/test_data_lake.py b/test/test_data_lake.py index 863b3a4f59..fbf79994d3 100644 --- a/test/test_data_lake.py +++ b/test/test_data_lake.py @@ -28,8 +28,6 @@ rs_or_single_client, ) -from pymongo.auth import MECHANISMS - # Location of JSON test specifications. _TEST_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data_lake") @@ -42,7 +40,7 @@ def test_connected_to_data_lake(self): self.assertTrue( client_context.is_data_lake, - "client context.is_data_lake must be True when " "DATA_LAKE is set", + "client context.is_data_lake must be True when DATA_LAKE is set", ) diff --git a/test/test_database.py b/test/test_database.py index 9a08d971db..8844046ad1 100644 --- a/test/test_database.py +++ b/test/test_database.py @@ -14,22 +14,18 @@ """Test the database module.""" -import datetime import re import sys from typing import Any, List, Mapping sys.path[0:0] = [""] -from test import IntegrationTest, SkipTest, client_context, unittest +from test import IntegrationTest, client_context, unittest from test.test_custom_types import DECIMAL_CODECOPTS from test.utils import ( IMPOSSIBLE_WRITE_CONCERN, - DeprecationFilter, OvertCommandListener, - ignore_deprecations, rs_or_single_client, - server_started_with_auth, wait_until, ) @@ -44,7 +40,6 @@ from pymongo.database import Database from pymongo.errors import ( CollectionInvalid, - ConfigurationError, ExecutionTimeout, InvalidName, OperationFailure, diff --git a/test/test_dbref.py b/test/test_dbref.py index 8e98bd8ce5..281aef473f 100644 --- a/test/test_dbref.py +++ b/test/test_dbref.py @@ -69,7 +69,7 @@ def test_repr(self): self.assertEqual(repr(DBRef("coll", 5, foo="bar")), "DBRef('coll', 5, foo='bar')") self.assertEqual( repr(DBRef("coll", ObjectId("1234567890abcdef12345678"), "foo")), - "DBRef('coll', ObjectId('1234567890abcdef12345678'), " "'foo')", + "DBRef('coll', ObjectId('1234567890abcdef12345678'), 'foo')", ) def test_equality(self): diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 51b168b0a0..d17a0d4166 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -284,7 +284,7 @@ def mock_command(*args, **kwargs): def insert_command(i): try: client.test.command("insert", "test", documents=[{"i": i}]) - except AutoReconnect as exc: + except AutoReconnect: pass threads = [] diff --git a/test/test_dns.py b/test/test_dns.py index d47e115f41..352d05376a 100644 --- a/test/test_dns.py +++ b/test/test_dns.py @@ -77,7 +77,7 @@ def run_test(self): options["tls"] = options.pop("ssl") parsed_options = test_case.get("parsed_options") # See DRIVERS-1324, unless tls is explicitly set to False we need TLS. - needs_tls = not (options and (options.get("ssl") == False or options.get("tls") == False)) + needs_tls = not (options and (options.get("ssl") is False or options.get("tls") is False)) if needs_tls and not client_context.tls: self.skipTest("this test requires a TLS cluster") if not needs_tls and client_context.tls: diff --git a/test/test_encryption.py b/test/test_encryption.py index 31c3dd2bcd..f63127a7be 100644 --- a/test/test_encryption.py +++ b/test/test_encryption.py @@ -718,7 +718,7 @@ class TestDataKeyDoubleEncryption(EncryptionIntegrationTest): MASTER_KEYS = { "aws": { "region": "us-east-1", - "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-" "4bd9-9f25-e30687b580d0", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", }, "azure": { "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", @@ -1259,7 +1259,7 @@ def test_01_aws_region_key(self): { "region": "us-east-1", "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" ), }, ) @@ -1271,7 +1271,7 @@ def test_02_aws_region_key_endpoint(self): { "region": "us-east-1", "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" ), "endpoint": "kms.us-east-1.amazonaws.com", }, @@ -1284,7 +1284,7 @@ def test_03_aws_region_key_endpoint_port(self): { "region": "us-east-1", "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" ), "endpoint": "kms.us-east-1.amazonaws.com:443", }, @@ -1294,9 +1294,7 @@ def test_03_aws_region_key_endpoint_port(self): def test_04_aws_endpoint_invalid_port(self): master_key = { "region": "us-east-1", - "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" - ), + "key": ("arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0"), "endpoint": "kms.us-east-1.amazonaws.com:12345", } with self.assertRaises(EncryptionError) as ctx: @@ -1307,9 +1305,7 @@ def test_04_aws_endpoint_invalid_port(self): def test_05_aws_endpoint_wrong_region(self): master_key = { "region": "us-east-1", - "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" - ), + "key": ("arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0"), "endpoint": "kms.us-east-2.amazonaws.com", } # The full error should be something like: @@ -1323,9 +1319,7 @@ def test_05_aws_endpoint_wrong_region(self): def test_06_aws_endpoint_invalid_host(self): master_key = { "region": "us-east-1", - "key": ( - "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0" - ), + "key": ("arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0"), "endpoint": "doesnotexist.invalid", } with self.assertRaisesRegex(EncryptionError, self.invalid_host_error): @@ -1583,9 +1577,9 @@ def _run_test(self, max_pool_size, auto_encryption_opts): event_listeners=[self.client_listener, self.topology_listener], ) - if auto_encryption_opts._bypass_auto_encryption == True: + if auto_encryption_opts._bypass_auto_encryption is True: self.client_test.db.coll.insert_one({"_id": 0, "encrypted": self.ciphertext}) - elif auto_encryption_opts._bypass_auto_encryption == False: + elif auto_encryption_opts._bypass_auto_encryption is False: client_encrypted.db.coll.insert_one({"_id": 0, "encrypted": "string0"}) else: raise RuntimeError("bypass_auto_encryption must be a bool") @@ -1825,7 +1819,7 @@ def setUp(self): def test_invalid_kms_certificate_expired(self): key = { "region": "us-east-1", - "key": "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "endpoint": "mongodb://127.0.0.1:8000", } # Some examples: @@ -1837,7 +1831,7 @@ def test_invalid_kms_certificate_expired(self): def test_invalid_hostname_in_kms_certificate(self): key = { "region": "us-east-1", - "key": "arn:aws:kms:us-east-1:579766882180:key/" "89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "endpoint": "mongodb://127.0.0.1:8001", } # Some examples: diff --git a/test/test_errors.py b/test/test_errors.py index 8a225b6548..747da48472 100644 --- a/test/test_errors.py +++ b/test/test_errors.py @@ -49,11 +49,11 @@ def _test_unicode_strs(self, exc): if sys.implementation.name == "pypy" and sys.implementation.version < (7, 3, 7): # PyPy used to display unicode in repr differently. self.assertEqual( - "unicode \U0001f40d, full error: {" "'errmsg': 'unicode \\U0001f40d'}", str(exc) + "unicode \U0001f40d, full error: {'errmsg': 'unicode \\U0001f40d'}", str(exc) ) else: self.assertEqual( - "unicode \U0001f40d, full error: {" "'errmsg': 'unicode \U0001f40d'}", str(exc) + "unicode \U0001f40d, full error: {'errmsg': 'unicode \U0001f40d'}", str(exc) ) try: raise exc diff --git a/test/test_examples.py b/test/test_examples.py index 7354ac5be2..ccb48307e4 100644 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -945,9 +945,7 @@ def update_employee_info(session): except (ConnectionFailure, OperationFailure) as exc: # Can retry commit if exc.has_error_label("UnknownTransactionCommitResult"): - print( - "UnknownTransactionCommitResult, retrying " "commit operation ..." - ) + print("UnknownTransactionCommitResult, retrying commit operation ...") continue else: print("Error during commit ...") @@ -970,11 +968,11 @@ def run_transaction_with_retry(txn_func, session): txn_func(session) # performs transaction break except (ConnectionFailure, OperationFailure) as exc: - print("Transaction aborted. Caught exception during " "transaction.") + print("Transaction aborted. Caught exception during transaction.") # If transient error, retry the whole transaction if exc.has_error_label("TransientTransactionError"): - print("TransientTransactionError, retrying" "transaction ...") + print("TransientTransactionError, retrying transaction ...") continue else: raise @@ -1000,7 +998,7 @@ def commit_with_retry(session): except (ConnectionFailure, OperationFailure) as exc: # Can retry commit if exc.has_error_label("UnknownTransactionCommitResult"): - print("UnknownTransactionCommitResult, retrying " "commit operation ...") + print("UnknownTransactionCommitResult, retrying commit operation ...") continue else: print("Error during commit ...") @@ -1036,7 +1034,7 @@ def run_transaction_with_retry(txn_func, session): except (ConnectionFailure, OperationFailure) as exc: # If transient error, retry the whole transaction if exc.has_error_label("TransientTransactionError"): - print("TransientTransactionError, retrying " "transaction ...") + print("TransientTransactionError, retrying transaction ...") continue else: raise @@ -1051,7 +1049,7 @@ def commit_with_retry(session): except (ConnectionFailure, OperationFailure) as exc: # Can retry commit if exc.has_error_label("UnknownTransactionCommitResult"): - print("UnknownTransactionCommitResult, retrying " "commit operation ...") + print("UnknownTransactionCommitResult, retrying commit operation ...") continue else: print("Error during commit ...") @@ -1282,7 +1280,7 @@ def strptime(s): with self.assertRaisesRegex( OperationFailure, - "Provided apiStrict:true, but the command " "count is not in API Version 1", + "Provided apiStrict:true, but the command count is not in API Version 1", ): client.db.command("count", "sales", query={}) # Start Versioned API Example 6 diff --git a/test/test_grid_file.py b/test/test_grid_file.py index 27d82e242b..b9fdeacef7 100644 --- a/test/test_grid_file.py +++ b/test/test_grid_file.py @@ -580,7 +580,7 @@ def test_iterator(self): self.assertEqual([b"hello world"], list(g)) def test_read_unaligned_buffer_size(self): - in_data = b"This is a text that doesn't " b"quite fit in a single 16-byte chunk." + in_data = b"This is a text that doesn't quite fit in a single 16-byte chunk." f = GridIn(self.db.fs, chunkSize=16) f.write(in_data) f.close() diff --git a/test/test_gridfs_bucket.py b/test/test_gridfs_bucket.py index 8b0a9a3936..d9bf0cf058 100644 --- a/test/test_gridfs_bucket.py +++ b/test/test_gridfs_bucket.py @@ -399,7 +399,7 @@ def test_download_to_stream(self): def test_download_to_stream_by_name(self): file1 = BytesIO(b"hello world") # Test with one chunk. - oid = self.fs.upload_from_stream("one_chunk", file1) + _ = self.fs.upload_from_stream("one_chunk", file1) self.assertEqual(1, self.db.fs.chunks.count_documents({})) file2 = BytesIO() self.fs.download_to_stream_by_name("one_chunk", file2) diff --git a/test/test_heartbeat_monitoring.py b/test/test_heartbeat_monitoring.py index cd4a875e9e..a14ab9a3a7 100644 --- a/test/test_heartbeat_monitoring.py +++ b/test/test_heartbeat_monitoring.py @@ -15,7 +15,6 @@ """Test the monitoring of the server heartbeats.""" import sys -import threading sys.path[0:0] = [""] diff --git a/test/test_json_util.py b/test/test_json_util.py index 203542e822..ee5b7abb49 100644 --- a/test/test_json_util.py +++ b/test/test_json_util.py @@ -331,7 +331,7 @@ def test_uuid(self): json_util.dumps(doc, json_options=LEGACY_JSON_OPTIONS), ) self.assertEqual( - '{"uuid": ' '{"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "03"}}', + '{"uuid": {"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "03"}}', json_util.dumps( doc, json_options=STRICT_JSON_OPTIONS.with_options( @@ -340,7 +340,7 @@ def test_uuid(self): ), ) self.assertEqual( - '{"uuid": ' '{"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "04"}}', + '{"uuid": {"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "04"}}', json_util.dumps( doc, json_options=JSONOptions( @@ -351,7 +351,7 @@ def test_uuid(self): self.assertEqual( doc, json_util.loads( - '{"uuid": ' '{"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "03"}}', + '{"uuid": {"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "03"}}', json_options=uuid_legacy_opts, ), ) @@ -364,7 +364,7 @@ def test_uuid(self): self.assertEqual( doc, json_util.loads( - '{"uuid": ' '{"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "04"}}', + '{"uuid": {"$binary": "9HrBC1jMQ3KlZw4CssPUeQ==", "$type": "04"}}', json_options=options, ), ) @@ -420,32 +420,32 @@ def test_binary(self): json_bin_dump = json_util.dumps(md5_type_dict, json_options=LEGACY_JSON_OPTIONS) # Check order. self.assertEqual( - '{"md5": {"$binary": "IG43GK8JL9HRL4DK53HMrA==",' + ' "$type": "05"}}', json_bin_dump + '{"md5": {"$binary": "IG43GK8JL9HRL4DK53HMrA==", "$type": "05"}}', json_bin_dump ) self.assertEqual( md5_type_dict, - json_util.loads('{"md5": {"$type": 5, "$binary":' ' "IG43GK8JL9HRL4DK53HMrA=="}}'), + json_util.loads('{"md5": {"$type": 5, "$binary": "IG43GK8JL9HRL4DK53HMrA=="}}'), ) json_bin_dump = json_util.dumps(custom_type_dict, json_options=LEGACY_JSON_OPTIONS) self.assertIn('"$type": "80"', json_bin_dump) self.assertEqual( custom_type_dict, - json_util.loads('{"custom": {"$type": 128, "$binary":' ' "aGVsbG8="}}'), + json_util.loads('{"custom": {"$type": 128, "$binary": "aGVsbG8="}}'), ) # Handle mongoexport where subtype >= 128 self.assertEqual( 128, - json_util.loads('{"custom": {"$type": "ffffff80", "$binary":' ' "aGVsbG8="}}')[ + json_util.loads('{"custom": {"$type": "ffffff80", "$binary": "aGVsbG8="}}')[ "custom" ].subtype, ) self.assertEqual( 255, - json_util.loads('{"custom": {"$type": "ffffffff", "$binary":' ' "aGVsbG8="}}')[ + json_util.loads('{"custom": {"$type": "ffffffff", "$binary": "aGVsbG8="}}')[ "custom" ].subtype, ) diff --git a/test/test_load_balancer.py b/test/test_load_balancer.py index 547cf327d3..378ae33e03 100644 --- a/test/test_load_balancer.py +++ b/test/test_load_balancer.py @@ -158,7 +158,7 @@ def lock_pool(self): # Wait for the unlock flag. unlock_pool = self.unlock.wait(10) if not unlock_pool: - raise Exception("timed out waiting for unlock signal:" " deadlock?") + raise Exception("timed out waiting for unlock signal: deadlock?") if __name__ == "__main__": diff --git a/test/test_max_staleness.py b/test/test_max_staleness.py index 4c17701133..799083f3b4 100644 --- a/test/test_max_staleness.py +++ b/test/test_max_staleness.py @@ -52,21 +52,21 @@ def test_max_staleness(self): with self.assertRaises(ConfigurationError): # Read pref "primary" can't be used with max staleness. - MongoClient("mongodb://a/?readPreference=primary&" "maxStalenessSeconds=120") + MongoClient("mongodb://a/?readPreference=primary&maxStalenessSeconds=120") client = MongoClient("mongodb://host/?maxStalenessSeconds=-1") self.assertEqual(-1, client.read_preference.max_staleness) - client = MongoClient("mongodb://host/?readPreference=primary&" "maxStalenessSeconds=-1") + client = MongoClient("mongodb://host/?readPreference=primary&maxStalenessSeconds=-1") self.assertEqual(-1, client.read_preference.max_staleness) - client = MongoClient("mongodb://host/?readPreference=secondary&" "maxStalenessSeconds=120") + client = MongoClient("mongodb://host/?readPreference=secondary&maxStalenessSeconds=120") self.assertEqual(120, client.read_preference.max_staleness) - client = MongoClient("mongodb://a/?readPreference=secondary&" "maxStalenessSeconds=1") + client = MongoClient("mongodb://a/?readPreference=secondary&maxStalenessSeconds=1") self.assertEqual(1, client.read_preference.max_staleness) - client = MongoClient("mongodb://a/?readPreference=secondary&" "maxStalenessSeconds=-1") + client = MongoClient("mongodb://a/?readPreference=secondary&maxStalenessSeconds=-1") self.assertEqual(-1, client.read_preference.max_staleness) client = MongoClient(maxStalenessSeconds=-1, readPreference="nearest") @@ -84,9 +84,7 @@ def test_max_staleness_float(self): with warnings.catch_warnings(record=True) as ctx: warnings.simplefilter("always") - client = MongoClient( - "mongodb://host/?maxStalenessSeconds=1.5" "&readPreference=nearest" - ) + client = MongoClient("mongodb://host/?maxStalenessSeconds=1.5&readPreference=nearest") # Option was ignored. self.assertEqual(-1, client.read_preference.max_staleness) @@ -101,7 +99,7 @@ def test_max_staleness_zero(self): with warnings.catch_warnings(record=True) as ctx: warnings.simplefilter("always") - client = MongoClient("mongodb://host/?maxStalenessSeconds=0" "&readPreference=nearest") + client = MongoClient("mongodb://host/?maxStalenessSeconds=0&readPreference=nearest") # Option was ignored. self.assertEqual(-1, client.read_preference.max_staleness) diff --git a/test/test_monitoring.py b/test/test_monitoring.py index 1adb2983e4..0b8200c019 100644 --- a/test/test_monitoring.py +++ b/test/test_monitoring.py @@ -16,19 +16,12 @@ import datetime import sys import time -import warnings from typing import Any sys.path[0:0] = [""] from test import IntegrationTest, client_context, client_knobs, sanitize_cmd, unittest -from test.utils import ( - EventListener, - get_pool, - rs_or_single_client, - single_client, - wait_until, -) +from test.utils import EventListener, rs_or_single_client, single_client, wait_until from bson.int64 import Int64 from bson.objectid import ObjectId @@ -781,7 +774,7 @@ def test_non_bulk_writes(self): # delete_one self.listener.results.clear() - res2 = coll.delete_one({"x": 3}) + _ = coll.delete_one({"x": 3}) results = self.listener.results started = results["started"][0] succeeded = results["succeeded"][0] @@ -1242,19 +1235,19 @@ def test_server_event_repr(self): event = monitoring.ServerOpeningEvent(server_address, topology_id) self.assertEqual( repr(event), - "", + "", ) event = monitoring.ServerDescriptionChangedEvent( "PREV", "NEW", server_address, topology_id # type: ignore[arg-type] ) self.assertEqual( repr(event), - "", + "", ) event = monitoring.ServerClosedEvent(server_address, topology_id) self.assertEqual( repr(event), - "", + "", ) def test_topology_event_repr(self): diff --git a/test/test_mypy.py b/test/test_mypy.py index 5b9746f723..36fe2ed424 100644 --- a/test/test_mypy.py +++ b/test/test_mypy.py @@ -16,7 +16,6 @@ sample client code that uses PyMongo typings.""" import os -import sys import unittest from typing import Any, Dict, Iterable, List diff --git a/test/test_pooling.py b/test/test_pooling.py index 07dbc3643d..00b947f10a 100644 --- a/test/test_pooling.py +++ b/test/test_pooling.py @@ -320,7 +320,7 @@ def test_wait_queue_timeout(self): pool = self.create_pool(max_pool_size=1, wait_queue_timeout=wait_queue_timeout) self.addCleanup(pool.close) - with pool.get_socket() as sock_info: + with pool.get_socket(): start = time.time() with self.assertRaises(ConnectionFailure): with pool.get_socket(): diff --git a/test/test_saslprep.py b/test/test_saslprep.py index 1dd4727181..c07870dad6 100644 --- a/test/test_saslprep.py +++ b/test/test_saslprep.py @@ -24,7 +24,7 @@ class TestSASLprep(unittest.TestCase): def test_saslprep(self): try: - import stringprep + import stringprep # noqa except ImportError: self.assertRaises(TypeError, saslprep, "anything...") # Bytes strings are ignored. diff --git a/test/test_sdam_monitoring_spec.py b/test/test_sdam_monitoring_spec.py index fee751fbdc..d7b3744399 100644 --- a/test/test_sdam_monitoring_spec.py +++ b/test/test_sdam_monitoring_spec.py @@ -98,13 +98,13 @@ def compare_events(expected_dict, actual): ) if not compare_server_descriptions(expected["newDescription"], actual.new_description): - return (False, "New ServerDescription incorrect in" " ServerDescriptionChangedEvent") + return (False, "New ServerDescription incorrect in ServerDescriptionChangedEvent") if not compare_server_descriptions( expected["previousDescription"], actual.previous_description ): return ( False, - "Previous ServerDescription incorrect in" " ServerDescriptionChangedEvent", + "Previous ServerDescription incorrect in ServerDescriptionChangedEvent", ) elif expected_type == "server_closed_event": @@ -125,19 +125,19 @@ def compare_events(expected_dict, actual): if not isinstance(actual, monitoring.TopologyDescriptionChangedEvent): return ( False, - "Expected TopologyDescriptionChangedEvent," " got %s" % (actual.__class__), + "Expected TopologyDescriptionChangedEvent, got %s" % (actual.__class__), ) if not compare_topology_descriptions(expected["newDescription"], actual.new_description): return ( False, - "New TopologyDescription incorrect in " "TopologyDescriptionChangedEvent", + "New TopologyDescription incorrect in TopologyDescriptionChangedEvent", ) if not compare_topology_descriptions( expected["previousDescription"], actual.previous_description ): return ( False, - "Previous TopologyDescription incorrect in" " TopologyDescriptionChangedEvent", + "Previous TopologyDescription incorrect in TopologyDescriptionChangedEvent", ) elif expected_type == "topology_closed_event": diff --git a/test/test_server_description.py b/test/test_server_description.py index 1562711375..bb49141d2f 100644 --- a/test/test_server_description.py +++ b/test/test_server_description.py @@ -170,7 +170,7 @@ def test_all_hosts(self): def test_repr(self): s = parse_hello_response({"ok": 1, "msg": "isdbgrid"}) self.assertEqual( - repr(s), "" + repr(s), "" ) def test_topology_version(self): diff --git a/test/test_session.py b/test/test_session.py index 5a242d6c69..b7aa65a19d 100644 --- a/test/test_session.py +++ b/test/test_session.py @@ -145,7 +145,7 @@ def _test_ops(self, client, *ops): kw = copy.copy(kw) kw["session"] = s with self.assertRaisesRegex( - InvalidOperation, "Can only use session with the MongoClient" " that started it" + InvalidOperation, "Can only use session with the MongoClient that started it" ): f(*args, **kw) diff --git a/test/test_son.py b/test/test_son.py index 69beb81439..5c1f43594d 100644 --- a/test/test_son.py +++ b/test/test_son.py @@ -154,8 +154,8 @@ def test_contains_has(self): self.assertIn(1, test_son) self.assertTrue(2 in test_son, "in failed") self.assertFalse(22 in test_son, "in succeeded when it shouldn't") - self.assertTrue(test_son.has_key(2), "has_key failed") - self.assertFalse(test_son.has_key(22), "has_key succeeded when it shouldn't") + self.assertTrue(test_son.has_key(2), "has_key failed") # noqa + self.assertFalse(test_son.has_key(22), "has_key succeeded when it shouldn't") # noqa def test_clears(self): """ diff --git a/test/test_srv_polling.py b/test/test_srv_polling.py index 6c240d7a78..0b54171dc9 100644 --- a/test/test_srv_polling.py +++ b/test/test_srv_polling.py @@ -96,7 +96,7 @@ class TestSrvPolling(unittest.TestCase): def setUp(self): if not _HAVE_DNSPYTHON: - raise unittest.SkipTest("SRV polling tests require the dnspython " "module") + raise unittest.SkipTest("SRV polling tests require the dnspython module") # Patch timeouts to ensure short rescan SRV interval. self.client_knobs = client_knobs( heartbeat_frequency=WAIT_TIME, @@ -318,7 +318,7 @@ def nodelist_callback(): with SrvPollingKnobs(ttl_time=WAIT_TIME, min_srv_rescan_interval=WAIT_TIME): client = MongoClient( - "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName" "=customname" + "mongodb+srv://test22.test.build.10gen.cc/?srvServiceName=customname" ) with SrvPollingKnobs(nodelist_callback=nodelist_callback): self.assert_nodelist_change(response, client) diff --git a/test/test_ssl.py b/test/test_ssl.py index 7629c1fd88..0c45275fac 100644 --- a/test/test_ssl.py +++ b/test/test_ssl.py @@ -40,12 +40,12 @@ _HAVE_PYOPENSSL = False try: # All of these must be available to use PyOpenSSL - import OpenSSL - import requests - import service_identity + import OpenSSL # noqa + import requests # noqa + import service_identity # noqa # Ensure service_identity>=18.1 is installed - from service_identity.pyopenssl import verify_ip_address + from service_identity.pyopenssl import verify_ip_address # noqa from pymongo.ocsp_support import _load_trusted_ca_certs @@ -79,9 +79,7 @@ class TestClientSSL(unittest.TestCase): - @unittest.skipIf( - HAVE_SSL, "The ssl module is available, can't test what " "happens without it." - ) + @unittest.skipIf(HAVE_SSL, "The ssl module is available, can't test what happens without it.") def test_no_ssl_module(self): # Explicit self.assertRaises(ConfigurationError, MongoClient, ssl=True) @@ -406,7 +404,7 @@ def test_tlsCRLFile_support(self): ) ) - uri_fmt = "mongodb://localhost/?ssl=true&" "tlsCAFile=%s&serverSelectionTimeoutMS=100" + uri_fmt = "mongodb://localhost/?ssl=true&tlsCAFile=%s&serverSelectionTimeoutMS=100" connected(MongoClient(uri_fmt % (CA_PEM,), **self.credentials)) # type: ignore uri_fmt = ( @@ -569,7 +567,7 @@ def test_mongodb_x509_auth(self): else: self.assertEqual(names, ["authenticate", "find"]) - uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % ( + uri = "mongodb://%s@%s:%d/?authMechanism=MONGODB-X509" % ( quote_plus(MONGODB_X509_USERNAME), host, port, @@ -589,7 +587,7 @@ def test_mongodb_x509_auth(self): # No error client.pymongo_test.test.find_one() # Auth should fail if username and certificate do not match - uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % ( + uri = "mongodb://%s@%s:%d/?authMechanism=MONGODB-X509" % ( quote_plus("not the username"), host, port, @@ -617,7 +615,7 @@ def test_mongodb_x509_auth(self): bad_client.pymongo_test.test.find_one() # Invalid certificate (using CA certificate as client certificate) - uri = "mongodb://%s@%s:%d/?authMechanism=" "MONGODB-X509" % ( + uri = "mongodb://%s@%s:%d/?authMechanism=MONGODB-X509" % ( quote_plus(MONGODB_X509_USERNAME), host, port, diff --git a/test/test_threads.py b/test/test_threads.py index 064008ee32..2c73de52e7 100644 --- a/test/test_threads.py +++ b/test/test_threads.py @@ -16,7 +16,7 @@ import threading from test import IntegrationTest, client_context, unittest -from test.utils import joinall, rs_or_single_client +from test.utils import joinall @client_context.require_connection diff --git a/test/test_uri_parser.py b/test/test_uri_parser.py index cfe21169fd..4fa288df44 100644 --- a/test/test_uri_parser.py +++ b/test/test_uri_parser.py @@ -59,11 +59,11 @@ def test_split_hosts(self): ) self.assertEqual( [("/tmp/mongodb-27017.sock", None), ("example.com", 27017)], - split_hosts("/tmp/mongodb-27017.sock," "example.com:27017"), + split_hosts("/tmp/mongodb-27017.sock,example.com:27017"), ) self.assertEqual( [("example.com", 27017), ("/tmp/mongodb-27017.sock", None)], - split_hosts("example.com:27017," "/tmp/mongodb-27017.sock"), + split_hosts("example.com:27017,/tmp/mongodb-27017.sock"), ) self.assertRaises(ValueError, split_hosts, "::1", 27017) self.assertRaises(ValueError, split_hosts, "[::1:27017") @@ -168,11 +168,11 @@ def test_parse_uri(self): res = copy.deepcopy(orig) res["nodelist"] = [("example1.com", 27017), ("example2.com", 27017)] - self.assertEqual(res, parse_uri("mongodb://example1.com:27017," "example2.com:27017")) + self.assertEqual(res, parse_uri("mongodb://example1.com:27017,example2.com:27017")) res = copy.deepcopy(orig) res["nodelist"] = [("localhost", 27017), ("localhost", 27018), ("localhost", 27019)] - self.assertEqual(res, parse_uri("mongodb://localhost," "localhost:27018,localhost:27019")) + self.assertEqual(res, parse_uri("mongodb://localhost,localhost:27018,localhost:27019")) res = copy.deepcopy(orig) res["database"] = "foo" @@ -182,21 +182,17 @@ def test_parse_uri(self): self.assertEqual(res, parse_uri("mongodb://localhost/")) res.update({"database": "test", "collection": "yield_historical.in"}) - self.assertEqual(res, parse_uri("mongodb://" "localhost/test.yield_historical.in")) + self.assertEqual(res, parse_uri("mongodb://localhost/test.yield_historical.in")) res.update({"username": "fred", "password": "foobar"}) - self.assertEqual( - res, parse_uri("mongodb://fred:foobar@localhost/" "test.yield_historical.in") - ) + self.assertEqual(res, parse_uri("mongodb://fred:foobar@localhost/test.yield_historical.in")) res = copy.deepcopy(orig) res["nodelist"] = [("example1.com", 27017), ("example2.com", 27017)] res.update({"database": "test", "collection": "yield_historical.in"}) self.assertEqual( res, - parse_uri( - "mongodb://example1.com:27017,example2.com" ":27017/test.yield_historical.in" - ), + parse_uri("mongodb://example1.com:27017,example2.com:27017/test.yield_historical.in"), ) # Test socket path without escaped characters. @@ -205,14 +201,14 @@ def test_parse_uri(self): # Test with escaped characters. res = copy.deepcopy(orig) res["nodelist"] = [("example2.com", 27017), ("/tmp/mongodb-27017.sock", None)] - self.assertEqual(res, parse_uri("mongodb://example2.com," "%2Ftmp%2Fmongodb-27017.sock")) + self.assertEqual(res, parse_uri("mongodb://example2.com,%2Ftmp%2Fmongodb-27017.sock")) res = copy.deepcopy(orig) res["nodelist"] = [("shoe.sock.pants.co.uk", 27017), ("/tmp/mongodb-27017.sock", None)] res["database"] = "nethers_db" self.assertEqual( res, - parse_uri("mongodb://shoe.sock.pants.co.uk," "%2Ftmp%2Fmongodb-27017.sock/nethers_db"), + parse_uri("mongodb://shoe.sock.pants.co.uk,%2Ftmp%2Fmongodb-27017.sock/nethers_db"), ) res = copy.deepcopy(orig) @@ -242,15 +238,13 @@ def test_parse_uri(self): res = copy.deepcopy(orig) res["nodelist"] = [("example2.com", 27017)] res.update({"database": "test", "collection": "yield_historical.sock"}) - self.assertEqual( - res, parse_uri("mongodb://example2.com:27017" "/test.yield_historical.sock") - ) + self.assertEqual(res, parse_uri("mongodb://example2.com:27017/test.yield_historical.sock")) res = copy.deepcopy(orig) res["nodelist"] = [("/tmp/mongodb-27017.sock", None)] res.update({"database": "test", "collection": "mongodb-27017.sock"}) self.assertEqual( - res, parse_uri("mongodb://%2Ftmp%2Fmongodb-27017.sock" "/test.mongodb-27017.sock") + res, parse_uri("mongodb://%2Ftmp%2Fmongodb-27017.sock/test.mongodb-27017.sock") ) res = copy.deepcopy(orig) @@ -275,9 +269,7 @@ def test_parse_uri(self): res = copy.deepcopy(orig) res.update({"username": "fred", "password": "foobar"}) res.update({"database": "test", "collection": "yield_historical.in"}) - self.assertEqual( - res, parse_uri("mongodb://fred:foobar@localhost/" "test.yield_historical.in") - ) + self.assertEqual(res, parse_uri("mongodb://fred:foobar@localhost/test.yield_historical.in")) res = copy.deepcopy(orig) res["database"] = "test" @@ -294,7 +286,7 @@ def test_parse_uri(self): res["username"] = "user" res["password"] = "password" self.assertEqual( - res, parse_uri("mongodb://user:password@localhost/" "?authMechanism=MONGODB-CR") + res, parse_uri("mongodb://user:password@localhost/?authMechanism=MONGODB-CR") ) res = copy.deepcopy(orig) @@ -305,7 +297,7 @@ def test_parse_uri(self): self.assertEqual( res, parse_uri( - "mongodb://user:password@localhost/foo" "?authSource=bar;authMechanism=MONGODB-CR" + "mongodb://user:password@localhost/foo?authSource=bar;authMechanism=MONGODB-CR" ), ) @@ -313,13 +305,13 @@ def test_parse_uri(self): res["options"] = {"authmechanism": "MONGODB-CR"} res["username"] = "user" res["password"] = "" - self.assertEqual(res, parse_uri("mongodb://user:@localhost/" "?authMechanism=MONGODB-CR")) + self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=MONGODB-CR")) res = copy.deepcopy(orig) res["username"] = "user@domain.com" res["password"] = "password" res["database"] = "foo" - self.assertEqual(res, parse_uri("mongodb://user%40domain.com:password" "@localhost/foo")) + self.assertEqual(res, parse_uri("mongodb://user%40domain.com:password@localhost/foo")) res = copy.deepcopy(orig) res["options"] = {"authmechanism": "GSSAPI"} @@ -328,7 +320,7 @@ def test_parse_uri(self): res["database"] = "foo" self.assertEqual( res, - parse_uri("mongodb://user%40domain.com:password" "@localhost/foo?authMechanism=GSSAPI"), + parse_uri("mongodb://user%40domain.com:password@localhost/foo?authMechanism=GSSAPI"), ) res = copy.deepcopy(orig) @@ -337,7 +329,7 @@ def test_parse_uri(self): res["password"] = "" res["database"] = "foo" self.assertEqual( - res, parse_uri("mongodb://user%40domain.com" "@localhost/foo?authMechanism=GSSAPI") + res, parse_uri("mongodb://user%40domain.com@localhost/foo?authMechanism=GSSAPI") ) res = copy.deepcopy(orig) @@ -410,7 +402,7 @@ def test_parse_uri(self): self.assertRaises( ValueError, parse_uri, - "mongodb://user%40domain.com:password" "@localhost/foo?uuidrepresentation=notAnOption", + "mongodb://user%40domain.com:password@localhost/foo?uuidrepresentation=notAnOption", ) def test_parse_ssl_paths(self): diff --git a/test/unified_format.py b/test/unified_format.py index ba1d063694..6f1e386932 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -826,14 +826,12 @@ def process_error(self, exception, spec): self.match_evaluator.match_result(expect_result, result) else: self.fail( - "expectResult can only be specified with %s " "exceptions" % (BulkWriteError,) + "expectResult can only be specified with %s exceptions" % (BulkWriteError,) ) def __raise_if_unsupported(self, opname, target, *target_types): if not isinstance(target, target_types): - self.fail( - "Operation %s not supported for entity " "of type %s" % (opname, type(target)) - ) + self.fail("Operation %s not supported for entity of type %s" % (opname, type(target))) def __entityOperation_createChangeStream(self, target, *args, **kwargs): if client_context.storage_engine == "mmapv1": @@ -891,7 +889,7 @@ def _collectionOperation_createFindCursor(self, target, *args, **kwargs): def _collectionOperation_listIndexes(self, target, *args, **kwargs): if "batch_size" in kwargs: - self.skipTest("PyMongo does not support batch_size for " "list_indexes") + self.skipTest("PyMongo does not support batch_size for list_indexes") return target.list_indexes(*args, **kwargs) def _sessionOperation_withTransaction(self, target, *args, **kwargs): @@ -1255,7 +1253,7 @@ def generate_test_classes( test_path, module=__name__, class_name_prefix="", - expected_failures=[], + expected_failures=[], # noqa: B006 bypass_test_generation_errors=False, **kwargs ): diff --git a/tools/clean.py b/tools/clean.py index 7196b00e90..0ea31fc3d9 100644 --- a/tools/clean.py +++ b/tools/clean.py @@ -23,24 +23,24 @@ try: os.remove("pymongo/_cmessage.so") os.remove("bson/_cbson.so") -except: +except BaseException: pass try: os.remove("pymongo/_cmessage.pyd") os.remove("bson/_cbson.pyd") -except: +except BaseException: pass try: - from pymongo import _cmessage # type: ignore[attr-defined] + from pymongo import _cmessage # type: ignore[attr-defined] # noqa: F401 sys.exit("could still import _cmessage") except ImportError: pass try: - from bson import _cbson + from bson import _cbson # noqa: F401 sys.exit("could still import _cbson") except ImportError: diff --git a/tools/fail_if_no_c.py b/tools/fail_if_no_c.py index a2d4954789..6cb82eed57 100644 --- a/tools/fail_if_no_c.py +++ b/tools/fail_if_no_c.py @@ -21,8 +21,8 @@ sys.path[0:0] = [""] -import bson -import pymongo +import bson # noqa: E402 +import pymongo # noqa: E402 if not pymongo.has_c() or not bson.has_c(): sys.exit("could not load C extensions")