diff --git a/.evergreen/scripts/generate_config.py b/.evergreen/scripts/generate_config.py index 270f9be75a..58299f7f33 100644 --- a/.evergreen/scripts/generate_config.py +++ b/.evergreen/scripts/generate_config.py @@ -748,19 +748,19 @@ def make_task(topology, auth, ssl, sync, python, extra_tags=(), **extra_vars): # The pinned pr tasks: the boundary Pythons per server version, stable as CPYTHONS changes. for version, combos in sorted(SERVER_VERSION_PR_PYTHONS.items()): for (topology, auth, ssl), python in sorted(combos.items()): - for sync in SYNCS: - tasks.append( - make_task( - topology, - auth, - ssl, - sync, - python, - extra_tags=("pr", version), - VERSION=version, - COVERAGE="1", - ) + tasks.extend( + make_task( + topology, + auth, + ssl, + sync, + python, + extra_tags=("pr", version), + VERSION=version, + COVERAGE="1", ) + for sync in SYNCS + ) return tasks diff --git a/bson/son.py b/bson/son.py index 1f09bed1ae..2dce98bf4b 100644 --- a/bson/son.py +++ b/bson/son.py @@ -68,9 +68,7 @@ def __new__(cls: type[SON[_Key, _Value]], *args: Any, **kwargs: Any) -> SON[_Key return instance def __repr__(self) -> str: - result = [] - for key in self.__keys: - result.append(f"({key!r}, {self[key]!r})") + result = [f"({key!r}, {self[key]!r})" for key in self.__keys] return "SON([{}])".format(", ".join(result)) def __setitem__(self, key: _Key, value: _Value) -> None: diff --git a/gridfs/asynchronous/grid_file.py b/gridfs/asynchronous/grid_file.py index abc7a918de..b601b8338b 100644 --- a/gridfs/asynchronous/grid_file.py +++ b/gridfs/asynchronous/grid_file.py @@ -2016,10 +2016,7 @@ async def to_list(self, length: int | None = None) -> list[AsyncGridOut]: return [x async for x in self] # noqa: C416,RUF100 if length < 1: raise ValueError("to_list() length must be greater than 0") - ret = [] - for _ in range(length): - ret.append(await self.next()) - return ret + return [await self.next() for _ in range(length)] __anext__ = next diff --git a/gridfs/synchronous/grid_file.py b/gridfs/synchronous/grid_file.py index 731b2d722a..52b4caaa28 100644 --- a/gridfs/synchronous/grid_file.py +++ b/gridfs/synchronous/grid_file.py @@ -1996,10 +1996,7 @@ def to_list(self, length: int | None = None) -> list[GridOut]: return [x for x in self] # noqa: C416,RUF100 if length < 1: raise ValueError("to_list() length must be greater than 0") - ret = [] - for _ in range(length): - ret.append(self.next()) - return ret + return [self.next() for _ in range(length)] __next__ = next diff --git a/pymongo/asynchronous/command_cursor.py b/pymongo/asynchronous/command_cursor.py index 7cb454a68d..370ef98af3 100644 --- a/pymongo/asynchronous/command_cursor.py +++ b/pymongo/asynchronous/command_cursor.py @@ -183,8 +183,9 @@ async def _next_batch(self, result: list, total: int | None = None) -> bool: # result.extend(self._data) self._data.clear() else: + # A list comprehension here is slower or uses more memory. for _ in range(min(len(self._data), total)): - result.append(self._data.popleft()) + result.append(self._data.popleft()) # noqa: PERF401 return True else: return False diff --git a/pymongo/asynchronous/cursor.py b/pymongo/asynchronous/cursor.py index 52b5572c08..b0b4abfc94 100644 --- a/pymongo/asynchronous/cursor.py +++ b/pymongo/asynchronous/cursor.py @@ -395,8 +395,9 @@ async def _next_batch(self, result: list, total: int | None = None) -> bool: # result.extend(self._data) self._data.clear() else: + # A list comprehension here is slower or uses more memory. for _ in range(min(len(self._data), total)): - result.append(self._data.popleft()) + result.append(self._data.popleft()) # noqa: PERF401 return True else: return False diff --git a/pymongo/client_options.py b/pymongo/client_options.py index f9dc402574..aed6db0dca 100644 --- a/pymongo/client_options.py +++ b/pymongo/client_options.py @@ -101,24 +101,27 @@ def _parse_ssl_options(options: Mapping[str, Any], is_sync: bool) -> tuple[SSLCo allow_invalid_hostnames = options.get("tlsallowinvalidhostnames", False) disable_ocsp_endpoint_check = options.get("tlsdisableocspendpointcheck", False) - enabled_tls_opts = [] - for opt in ( - "tlscertificatekeyfile", - "tlscertificatekeyfilepassword", - "tlscafile", - "tlscrlfile", - ): - # Any non-null value of these options implies tls=True. - if options.get(opt): - enabled_tls_opts.append(opt) - for opt in ( - "tlsallowinvalidcertificates", - "tlsallowinvalidhostnames", - "tlsdisableocspendpointcheck", - ): - # A value of False for these options implies tls=True. - if opt in options and not options[opt]: - enabled_tls_opts.append(opt) + # Any non-null value of these options implies tls=True. + enabled_tls_opts = [ + opt + for opt in ( + "tlscertificatekeyfile", + "tlscertificatekeyfilepassword", + "tlscafile", + "tlscrlfile", + ) + if options.get(opt) + ] + # A value of False for these options implies tls=True. + enabled_tls_opts.extend( + opt + for opt in ( + "tlsallowinvalidcertificates", + "tlsallowinvalidhostnames", + "tlsdisableocspendpointcheck", + ) + if opt in options and not options[opt] + ) if enabled_tls_opts: if use_tls is None: diff --git a/pymongo/common.py b/pymongo/common.py index 106c63ab03..81e3fa6d9b 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -1120,8 +1120,7 @@ def __new__(cls, *version: int) -> Self: def _padded(cls, iter: Any, length: int, padding: int = 0) -> list[int]: as_list = list(iter) if len(as_list) < length: - for _ in range(length - len(as_list)): - as_list.append(padding) + as_list.extend(padding for _ in range(length - len(as_list))) return as_list @classmethod diff --git a/pymongo/encryption_options.py b/pymongo/encryption_options.py index 094d0e0bcd..acc3df348a 100644 --- a/pymongo/encryption_options.py +++ b/pymongo/encryption_options.py @@ -324,17 +324,17 @@ def __init__( @property def document(self) -> dict[str, Any]: - doc = {} - for k, v in [ - ("sparsity", int64.Int64(self.sparsity) if self.sparsity else None), - ("trimFactor", self.trim_factor), - ("precision", self.precision), - ("min", self.min), - ("max", self.max), - ]: - if v is not None: - doc[k] = v - return doc + return { + k: v + for k, v in [ + ("sparsity", int64.Int64(self.sparsity) if self.sparsity else None), + ("trimFactor", self.trim_factor), + ("precision", self.precision), + ("min", self.min), + ("max", self.max), + ] + if v is not None + } class StringOpts: @@ -366,17 +366,17 @@ def __init__( @property def document(self) -> dict[str, Any]: - doc = {} - for k, v in [ - ("substring", self.substring), - ("prefix", self.prefix), - ("suffix", self.suffix), - ("caseSensitive", self.case_sensitive), - ("diacriticSensitive", self.diacritic_sensitive), - ]: - if v is not None: - doc[k] = v - return doc + return { + k: v + for k, v in [ + ("substring", self.substring), + ("prefix", self.prefix), + ("suffix", self.suffix), + ("caseSensitive", self.case_sensitive), + ("diacriticSensitive", self.diacritic_sensitive), + ] + if v is not None + } class SubstringOpts(TypedDict): diff --git a/pymongo/synchronous/command_cursor.py b/pymongo/synchronous/command_cursor.py index 8f8c2961fb..43a8ce73ee 100644 --- a/pymongo/synchronous/command_cursor.py +++ b/pymongo/synchronous/command_cursor.py @@ -179,8 +179,9 @@ def _next_batch(self, result: list, total: int | None = None) -> bool: # type: result.extend(self._data) self._data.clear() else: + # A list comprehension here is slower or uses more memory. for _ in range(min(len(self._data), total)): - result.append(self._data.popleft()) + result.append(self._data.popleft()) # noqa: PERF401 return True else: return False diff --git a/pymongo/synchronous/cursor.py b/pymongo/synchronous/cursor.py index 32e03ee9cf..b492372932 100644 --- a/pymongo/synchronous/cursor.py +++ b/pymongo/synchronous/cursor.py @@ -393,8 +393,9 @@ def _next_batch(self, result: list, total: int | None = None) -> bool: # type: result.extend(self._data) self._data.clear() else: + # A list comprehension here is slower or uses more memory. for _ in range(min(len(self._data), total)): - result.append(self._data.popleft()) + result.append(self._data.popleft()) # noqa: PERF401 return True else: return False diff --git a/pymongo/uri_parser_shared.py b/pymongo/uri_parser_shared.py index da567cb12d..f4af8c20fc 100644 --- a/pymongo/uri_parser_shared.py +++ b/pymongo/uri_parser_shared.py @@ -631,6 +631,5 @@ def _make_options_case_sensitive(options: _CaseInsensitiveDictionary) -> dict[st if option.lower() in options: case_sensitive[option] = options[option] options.pop(option) - for k, v in options.items(): - case_sensitive[k] = v + case_sensitive.update(options) return case_sensitive diff --git a/pyproject.toml b/pyproject.toml index 1d4023d14d..3aaf4e7465 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -219,6 +219,7 @@ extend-select = [ "EXE", # flake8-executable "ASYNC", # flake8-async "TC", # flake8-type-checking + "PERF", # perflint "D202", # pydocstyle: no blank lines between docstring and function body. "D209", # pydocstyle: closing quotes go on their own line. "D301", # pydocstyle: docstrings containing \ are defined as string literals. diff --git a/test/asynchronous/test_auth.py b/test/asynchronous/test_auth.py index 72085d62dd..02aaa326c6 100644 --- a/test/asynchronous/test_auth.py +++ b/test/asynchronous/test_auth.py @@ -239,9 +239,7 @@ async def test_gssapi_threaded(self): except OperationFailure: raise SkipTest("User must be able to write.") - threads = [] - for _ in range(4): - threads.append(AutoAuthenticateThread(collection)) + threads = [AutoAuthenticateThread(collection) for _ in range(4)] for thread in threads: thread.start() for thread in threads: @@ -661,9 +659,7 @@ async def test_scram_threaded(self): # The first thread to call find() will authenticate client = await self.async_rs_or_single_client() coll = client.db.coll - threads = [] - for _ in range(4): - threads.append(AutoAuthenticateThread(coll)) + threads = [AutoAuthenticateThread(coll) for _ in range(4)] for thread in threads: thread.start() for thread in threads: diff --git a/test/asynchronous/test_auth_oidc.py b/test/asynchronous/test_auth_oidc.py index e4e4422b59..12cb69eac2 100644 --- a/test/asynchronous/test_auth_oidc.py +++ b/test/asynchronous/test_auth_oidc.py @@ -826,9 +826,7 @@ async def target(): for _ in range(100): await client.test.coll.find_one() - tasks = [] - for i in range(10): - tasks.append(ConcurrentRunner(target=target)) + tasks = [ConcurrentRunner(target=target) for _ in range(10)] for t in tasks: await t.start() for t in tasks: diff --git a/test/asynchronous/test_bulk.py b/test/asynchronous/test_bulk.py index 51f447ed30..907f837d57 100644 --- a/test/asynchronous/test_bulk.py +++ b/test/asynchronous/test_bulk.py @@ -310,8 +310,7 @@ async def test_bulk_max_message_size(self): {"_id": 3, "l": "s" * (_16_MB - 10000)}, ] # Fill in the remaining ~10000 bytes with small documents. - for i in range(4, 10000): - docs.append({"_id": i}) + docs.extend({"_id": i} for i in range(4, 10000)) result = await self.coll.insert_many(docs) self.assertEqual(len(docs), len(result.inserted_ids)) diff --git a/test/asynchronous/test_change_stream.py b/test/asynchronous/test_change_stream.py index cba8d51a72..a2cfa8c67a 100644 --- a/test/asynchronous/test_change_stream.py +++ b/test/asynchronous/test_change_stream.py @@ -90,9 +90,7 @@ async def generate_invalidate_event(self, change_stream): def generate_unique_collnames(self, numcolls): """Generate numcolls collection names unique to a test.""" - collnames = [] - for idx in range(1, numcolls + 1): - collnames.append(self.id() + "_" + str(idx)) + collnames = [self.id() + "_" + str(idx) for idx in range(1, numcolls + 1)] return collnames async def get_resume_token(self, invalidate=False): diff --git a/test/asynchronous/test_client_bulk_write.py b/test/asynchronous/test_client_bulk_write.py index 85236a2346..0ec667467b 100644 --- a/test/asynchronous/test_client_bulk_write.py +++ b/test/asynchronous/test_client_bulk_write.py @@ -98,18 +98,18 @@ async def test_3_batch_splits_if_num_operations_too_large(self): listener = OvertCommandListener() client = await self.async_rs_or_single_client(event_listeners=[listener]) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append(InsertOne(namespace="db.coll", document={"a": "b"})) + models = [ + InsertOne(namespace="db.coll", document={"a": "b"}) + for _ in range(self.max_write_batch_size + 1) + ] self.addAsyncCleanup(client.db["coll"].drop) result = await client.bulk_write(models=models) self.assertEqual(result.inserted_count, self.max_write_batch_size + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -122,25 +122,23 @@ async def test_4_batch_splits_if_ops_payload_too_large(self): listener = OvertCommandListener() client = await self.async_rs_or_single_client(event_listeners=[listener]) - models = [] num_models = int(self.max_message_size_bytes / self.max_bson_object_size + 1) b_repeated = "b" * (self.max_bson_object_size - 500) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] self.addAsyncCleanup(client.db["coll"].drop) result = await client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -166,14 +164,13 @@ async def test_5_collects_write_concern_errors_across_batches(self): }, } async with self.fail_point(fail_command): - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"a": "b"}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": "b"}, ) + for _ in range(self.max_write_batch_size + 1) + ] self.addAsyncCleanup(client.db["coll"].drop) with self.assertRaises(ClientBulkWriteException) as context: @@ -184,10 +181,9 @@ async def test_5_collects_write_concern_errors_across_batches(self): context.exception.partial_result.inserted_count, self.max_write_batch_size + 1 ) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) @async_client_context.require_version_min(8, 0, 0, -24) @@ -200,23 +196,21 @@ async def test_6_collects_write_errors_across_batches_unordered(self): await collection.drop() await collection.insert_one(document={"_id": 1}) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"_id": 1}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"_id": 1}, ) + for _ in range(self.max_write_batch_size + 1) + ] with self.assertRaises(ClientBulkWriteException) as context: await client.bulk_write(models=models, ordered=False) self.assertEqual(len(context.exception.write_errors), self.max_write_batch_size + 1) # type: ignore[arg-type] - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) @async_client_context.require_version_min(8, 0, 0, -24) @@ -229,23 +223,21 @@ async def test_6_collects_write_errors_across_batches_ordered(self): await collection.drop() await collection.insert_one(document={"_id": 1}) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"_id": 1}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"_id": 1}, ) + for _ in range(self.max_write_batch_size + 1) + ] with self.assertRaises(ClientBulkWriteException) as context: await client.bulk_write(models=models, ordered=True) self.assertEqual(len(context.exception.write_errors), 1) # type: ignore[arg-type] - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 1) @async_client_context.require_version_min(8, 0, 0, -24) @@ -422,15 +414,14 @@ async def _setup_namespace_test_models(self): num_models = ops_bytes // self.max_bson_object_size remainder_bytes = ops_bytes % self.max_bson_object_size - models = [] b_repeated = "b" * (self.max_bson_object_size - _OPERATION_DOC_BYTES) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] if remainder_bytes >= _NAMESPACE_DOC_BYTES: num_models += 1 b_repeated = "b" * (remainder_bytes - _OPERATION_DOC_BYTES) @@ -460,10 +451,9 @@ async def test_11_no_batch_splits_if_new_namespace_is_not_too_large(self): result = await client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 1) event = bulk_write_events[0] @@ -493,10 +483,9 @@ async def test_11_batch_splits_if_new_namespace_is_too_large(self): result = await client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -652,16 +641,15 @@ async def test_timeout_in_multi_batch_bulk_write(self): "data": {"failCommands": ["bulkWrite"], "blockConnection": True, "blockTimeMS": 1010}, } async with self.fail_point(fail_command): - models = [] num_models = int(self.max_message_size_bytes / self.max_bson_object_size + 1) b_repeated = "b" * (self.max_bson_object_size - _OVERHEAD) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] listener = OvertCommandListener() client = await self.async_rs_or_single_client( @@ -678,8 +666,7 @@ async def test_timeout_in_multi_batch_bulk_write(self): await client.bulk_write(models=models) self.assertIsInstance(context.exception.error, NetworkTimeout) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) diff --git a/test/asynchronous/test_concurrency.py b/test/asynchronous/test_concurrency.py index a3588d6848..ebb5218318 100644 --- a/test/asynchronous/test_concurrency.py +++ b/test/asynchronous/test_concurrency.py @@ -37,7 +37,6 @@ async def _task(self, client): "PYTHON-5861: $where is too slow on macOS CI", ) async def test_concurrency(self): - tasks = [] iterations = 5 client = await self.async_single_client() @@ -52,8 +51,7 @@ async def test_concurrency(self): sequential_time = time.time() - start start = time.time() - for i in range(iterations): - tasks.append(self._task(client)) + tasks = [self._task(client) for _ in range(iterations)] await asyncio.gather(*tasks) concurrent_time = time.time() - start diff --git a/test/asynchronous/test_custom_types.py b/test/asynchronous/test_custom_types.py index 437b9ed73c..4fb4717e0f 100644 --- a/test/asynchronous/test_custom_types.py +++ b/test/asynchronous/test_custom_types.py @@ -145,9 +145,7 @@ def test_encode_decode_roundtrip(self): @no_type_check def test_decode_all(self): - documents = [] - for dec in range(3): - documents.append({"average": Decimal(f"56.4{dec}")}) + documents = [{"average": Decimal(f"56.4{dec}")} for dec in range(3)] bsonstream = b"" for doc in documents: diff --git a/test/asynchronous/test_discovery_and_monitoring.py b/test/asynchronous/test_discovery_and_monitoring.py index 3d4c0b8e1b..e686dd1926 100644 --- a/test/asynchronous/test_discovery_and_monitoring.py +++ b/test/asynchronous/test_discovery_and_monitoring.py @@ -355,9 +355,7 @@ async def insert_command(i): except AutoReconnect: pass - tasks = [] - for i in range(N_TASKS): - tasks.append(ConcurrentRunner(target=insert_command, args=(i,))) + tasks = [ConcurrentRunner(target=insert_command, args=(i,)) for i in range(N_TASKS)] for t in tasks: await t.start() for t in tasks: @@ -538,9 +536,7 @@ async def target(): pass # Run 100 parallel operations that contend for connections. - tasks = [] - for _ in range(100): - tasks.append(ConcurrentRunner(target=target)) + tasks = [ConcurrentRunner(target=target) for _ in range(100)] for t in tasks: await t.start() for t in tasks: diff --git a/test/asynchronous/unified_format.py b/test/asynchronous/unified_format.py index cbeb819ef2..edcc43ad3c 100644 --- a/test/asynchronous/unified_format.py +++ b/test/asynchronous/unified_format.py @@ -1176,10 +1176,9 @@ def _testOperation_assertSessionUnpinned(self, spec): self.assertIsNone(session._transaction.pinned_address) def __get_last_two_command_lsids(self, listener): - cmd_started_events = [] - for event in reversed(listener.events): - if isinstance(event, CommandStartedEvent): - cmd_started_events.append(event) + cmd_started_events = [ + event for event in reversed(listener.events) if isinstance(event, CommandStartedEvent) + ] if len(cmd_started_events) < 2: self.fail( "Needed 2 CommandStartedEvents to compare lsids, got %s" % (len(cmd_started_events)) diff --git a/test/test_auth.py b/test/test_auth.py index bf363267dc..40b3bc93be 100644 --- a/test/test_auth.py +++ b/test/test_auth.py @@ -239,9 +239,7 @@ def test_gssapi_threaded(self): except OperationFailure: raise SkipTest("User must be able to write.") - threads = [] - for _ in range(4): - threads.append(AutoAuthenticateThread(collection)) + threads = [AutoAuthenticateThread(collection) for _ in range(4)] for thread in threads: thread.start() for thread in threads: @@ -657,9 +655,7 @@ def test_scram_threaded(self): # The first thread to call find() will authenticate client = self.rs_or_single_client() coll = client.db.coll - threads = [] - for _ in range(4): - threads.append(AutoAuthenticateThread(coll)) + threads = [AutoAuthenticateThread(coll) for _ in range(4)] for thread in threads: thread.start() for thread in threads: diff --git a/test/test_auth_oidc.py b/test/test_auth_oidc.py index e08ad91805..b2aa48e58f 100644 --- a/test/test_auth_oidc.py +++ b/test/test_auth_oidc.py @@ -826,9 +826,7 @@ def target(): for _ in range(100): client.test.coll.find_one() - tasks = [] - for i in range(10): - tasks.append(ConcurrentRunner(target=target)) + tasks = [ConcurrentRunner(target=target) for _ in range(10)] for t in tasks: t.start() for t in tasks: diff --git a/test/test_bulk.py b/test/test_bulk.py index 15035f4783..fd24a2496e 100644 --- a/test/test_bulk.py +++ b/test/test_bulk.py @@ -310,8 +310,7 @@ def test_bulk_max_message_size(self): {"_id": 3, "l": "s" * (_16_MB - 10000)}, ] # Fill in the remaining ~10000 bytes with small documents. - for i in range(4, 10000): - docs.append({"_id": i}) + docs.extend({"_id": i} for i in range(4, 10000)) result = self.coll.insert_many(docs) self.assertEqual(len(docs), len(result.inserted_ids)) diff --git a/test/test_change_stream.py b/test/test_change_stream.py index 004e997df1..9d29a80a44 100644 --- a/test/test_change_stream.py +++ b/test/test_change_stream.py @@ -90,9 +90,7 @@ def generate_invalidate_event(self, change_stream): def generate_unique_collnames(self, numcolls): """Generate numcolls collection names unique to a test.""" - collnames = [] - for idx in range(1, numcolls + 1): - collnames.append(self.id() + "_" + str(idx)) + collnames = [self.id() + "_" + str(idx) for idx in range(1, numcolls + 1)] return collnames def get_resume_token(self, invalidate=False): diff --git a/test/test_client_bulk_write.py b/test/test_client_bulk_write.py index a7bf8ee777..ef2cdec8c7 100644 --- a/test/test_client_bulk_write.py +++ b/test/test_client_bulk_write.py @@ -98,18 +98,18 @@ def test_3_batch_splits_if_num_operations_too_large(self): listener = OvertCommandListener() client = self.rs_or_single_client(event_listeners=[listener]) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append(InsertOne(namespace="db.coll", document={"a": "b"})) + models = [ + InsertOne(namespace="db.coll", document={"a": "b"}) + for _ in range(self.max_write_batch_size + 1) + ] self.addCleanup(client.db["coll"].drop) result = client.bulk_write(models=models) self.assertEqual(result.inserted_count, self.max_write_batch_size + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -122,25 +122,23 @@ def test_4_batch_splits_if_ops_payload_too_large(self): listener = OvertCommandListener() client = self.rs_or_single_client(event_listeners=[listener]) - models = [] num_models = int(self.max_message_size_bytes / self.max_bson_object_size + 1) b_repeated = "b" * (self.max_bson_object_size - 500) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] self.addCleanup(client.db["coll"].drop) result = client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -166,14 +164,13 @@ def test_5_collects_write_concern_errors_across_batches(self): }, } with self.fail_point(fail_command): - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"a": "b"}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": "b"}, ) + for _ in range(self.max_write_batch_size + 1) + ] self.addCleanup(client.db["coll"].drop) with self.assertRaises(ClientBulkWriteException) as context: @@ -184,10 +181,9 @@ def test_5_collects_write_concern_errors_across_batches(self): context.exception.partial_result.inserted_count, self.max_write_batch_size + 1 ) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) @client_context.require_version_min(8, 0, 0, -24) @@ -200,23 +196,21 @@ def test_6_collects_write_errors_across_batches_unordered(self): collection.drop() collection.insert_one(document={"_id": 1}) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"_id": 1}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"_id": 1}, ) + for _ in range(self.max_write_batch_size + 1) + ] with self.assertRaises(ClientBulkWriteException) as context: client.bulk_write(models=models, ordered=False) self.assertEqual(len(context.exception.write_errors), self.max_write_batch_size + 1) # type: ignore[arg-type] - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) @client_context.require_version_min(8, 0, 0, -24) @@ -229,23 +223,21 @@ def test_6_collects_write_errors_across_batches_ordered(self): collection.drop() collection.insert_one(document={"_id": 1}) - models = [] - for _ in range(self.max_write_batch_size + 1): - models.append( - InsertOne( - namespace="db.coll", - document={"_id": 1}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"_id": 1}, ) + for _ in range(self.max_write_batch_size + 1) + ] with self.assertRaises(ClientBulkWriteException) as context: client.bulk_write(models=models, ordered=True) self.assertEqual(len(context.exception.write_errors), 1) # type: ignore[arg-type] - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 1) @client_context.require_version_min(8, 0, 0, -24) @@ -418,15 +410,14 @@ def _setup_namespace_test_models(self): num_models = ops_bytes // self.max_bson_object_size remainder_bytes = ops_bytes % self.max_bson_object_size - models = [] b_repeated = "b" * (self.max_bson_object_size - _OPERATION_DOC_BYTES) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] if remainder_bytes >= _NAMESPACE_DOC_BYTES: num_models += 1 b_repeated = "b" * (remainder_bytes - _OPERATION_DOC_BYTES) @@ -456,10 +447,9 @@ def test_11_no_batch_splits_if_new_namespace_is_not_too_large(self): result = client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 1) event = bulk_write_events[0] @@ -489,10 +479,9 @@ def test_11_batch_splits_if_new_namespace_is_too_large(self): result = client.bulk_write(models=models) self.assertEqual(result.inserted_count, num_models + 1) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) first_event, second_event = bulk_write_events @@ -648,16 +637,15 @@ def test_timeout_in_multi_batch_bulk_write(self): "data": {"failCommands": ["bulkWrite"], "blockConnection": True, "blockTimeMS": 1010}, } with self.fail_point(fail_command): - models = [] num_models = int(self.max_message_size_bytes / self.max_bson_object_size + 1) b_repeated = "b" * (self.max_bson_object_size - _OVERHEAD) - for _ in range(num_models): - models.append( - InsertOne( - namespace="db.coll", - document={"a": b_repeated}, - ) + models = [ + InsertOne( + namespace="db.coll", + document={"a": b_repeated}, ) + for _ in range(num_models) + ] listener = OvertCommandListener() client = self.rs_or_single_client( @@ -674,8 +662,7 @@ def test_timeout_in_multi_batch_bulk_write(self): client.bulk_write(models=models) self.assertIsInstance(context.exception.error, NetworkTimeout) - bulk_write_events = [] - for event in listener.started_events: - if event.command_name == "bulkWrite": - bulk_write_events.append(event) + bulk_write_events = [ + event for event in listener.started_events if event.command_name == "bulkWrite" + ] self.assertEqual(len(bulk_write_events), 2) diff --git a/test/test_custom_types.py b/test/test_custom_types.py index 1605ed6dd2..c395c64ccf 100644 --- a/test/test_custom_types.py +++ b/test/test_custom_types.py @@ -145,9 +145,7 @@ def test_encode_decode_roundtrip(self): @no_type_check def test_decode_all(self): - documents = [] - for dec in range(3): - documents.append({"average": Decimal(f"56.4{dec}")}) + documents = [{"average": Decimal(f"56.4{dec}")} for dec in range(3)] bsonstream = b"" for doc in documents: diff --git a/test/test_discovery_and_monitoring.py b/test/test_discovery_and_monitoring.py index 934d525e29..7407f61664 100644 --- a/test/test_discovery_and_monitoring.py +++ b/test/test_discovery_and_monitoring.py @@ -355,9 +355,7 @@ def insert_command(i): except AutoReconnect: pass - tasks = [] - for i in range(N_TASKS): - tasks.append(ConcurrentRunner(target=insert_command, args=(i,))) + tasks = [ConcurrentRunner(target=insert_command, args=(i,)) for i in range(N_TASKS)] for t in tasks: t.start() for t in tasks: @@ -535,9 +533,7 @@ def target(): pass # Run 100 parallel operations that contend for connections. - tasks = [] - for _ in range(100): - tasks.append(ConcurrentRunner(target=target)) + tasks = [ConcurrentRunner(target=target) for _ in range(100)] for t in tasks: t.start() for t in tasks: diff --git a/test/unified_format.py b/test/unified_format.py index bb8ff71506..809b92b258 100644 --- a/test/unified_format.py +++ b/test/unified_format.py @@ -1167,10 +1167,9 @@ def _testOperation_assertSessionUnpinned(self, spec): self.assertIsNone(session._transaction.pinned_address) def __get_last_two_command_lsids(self, listener): - cmd_started_events = [] - for event in reversed(listener.events): - if isinstance(event, CommandStartedEvent): - cmd_started_events.append(event) + cmd_started_events = [ + event for event in reversed(listener.events) if isinstance(event, CommandStartedEvent) + ] if len(cmd_started_events) < 2: self.fail( "Needed 2 CommandStartedEvents to compare lsids, got %s" % (len(cmd_started_events)) diff --git a/tools/generate_sbom_requirements.py b/tools/generate_sbom_requirements.py index aa8d5579ca..ad6fa2cd48 100644 --- a/tools/generate_sbom_requirements.py +++ b/tools/generate_sbom_requirements.py @@ -23,14 +23,12 @@ def collect_files(root: Path) -> list[Path]: Returns: list[Path]: A list of Paths to requirement files to include in the SBOM. """ - files = [] - # requirements.txt + all requirements/**/*.txt - for p in [root / "requirements.txt", *root.glob("requirements/**/*.txt")]: - if p.is_file() and p.name not in EXCLUDED_NAMES: - files.append(p) - - return files + return [ + p + for p in [root / "requirements.txt", *root.glob("requirements/**/*.txt")] + if p.is_file() and p.name not in EXCLUDED_NAMES + ] def write_combined_req_files(root: Path, files: list[Path], outname: str) -> Path: