diff --git a/pyproject.toml b/pyproject.toml index d9addafa5..49370b360 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,7 +124,6 @@ ignore = [ "D213", # Multi-line docstring summary should start at the second line "D413", # Missing blank line after last section "EM", # flake8-errmsg - "G004", # Logging statement uses f-string "ISC001", # This rule may cause conflicts when used with the formatter "FIX", # flake8-fixme "PLR0911", # Too many return statements diff --git a/src/apify/_actor.py b/src/apify/_actor.py index 526146cfd..85252d4f9 100644 --- a/src/apify/_actor.py +++ b/src/apify/_actor.py @@ -1682,7 +1682,7 @@ async def metamorph( if not self.configuration.actor_run_id: raise RuntimeError('actor_run_id cannot be None when running on the Apify platform.') - self.log.debug(f'Metamorphing the Actor run into target Actor {target_actor_id!r}.') + self.log.debug('Metamorphing the Actor run into target Actor %r.', target_actor_id) await self.apify_client.run(self.configuration.actor_run_id).metamorph( target_actor_id=target_actor_id, run_input=run_input, @@ -1828,7 +1828,7 @@ async def set_status_message( """ if not self.is_at_home(): title = 'Terminal status message' if is_terminal else 'Status message' - self.log.info(f'[{title}]: {status_message}') + self.log.info('[%s]: %s', title, status_message) return None # If is_at_home() is True, config.actor_run_id is always set @@ -1843,11 +1843,12 @@ async def set_status_message( return await asyncio.wait_for(update, STATUS_MESSAGE_UPDATE_TIMEOUT.total_seconds()) except TimeoutError: self.log.warning( - f'Failed to set status message for Actor run with ID "{run_id}": ' - f'the update timed out after {STATUS_MESSAGE_UPDATE_TIMEOUT.total_seconds():g}s.' + 'Failed to set status message for Actor run with ID "%s": the update timed out after %gs.', + run_id, + STATUS_MESSAGE_UPDATE_TIMEOUT.total_seconds(), ) except Exception as exc: - self.log.warning(f'Failed to set status message for Actor run with ID "{run_id}": {exc}') + self.log.warning('Failed to set status message for Actor run with ID "%s": %s', run_id, exc) return None diff --git a/src/apify/_charging.py b/src/apify/_charging.py index 501bef100..1e6ca472e 100644 --- a/src/apify/_charging.py +++ b/src/apify/_charging.py @@ -354,12 +354,15 @@ async def charge(self, event_name: str, *, count: int = 1, idempotency_key: str # and make the run hit `max_total_charge_usd` early. The key alone decides, as on the platform. if idempotency_key is not None and (previous := self._idempotent_charges.get(idempotency_key)) is not None: if previous.event_name == event_name: - logger.debug(f"Skipped a repeated charge of event '{event_name}' under key '{idempotency_key}'.") + logger.debug("Skipped a repeated charge of event '%s' under key '%s'.", event_name, idempotency_key) repeated_count = previous.charged_count else: logger.warning( - f"Idempotency key '{idempotency_key}' was already used to charge for event " - f"'{previous.event_name}', so the charge of event '{event_name}' is skipped." + "Idempotency key '%s' was already used to charge for event '%s', so the charge of event " + "'%s' is skipped.", + idempotency_key, + previous.event_name, + event_name, ) repeated_count = 0 @@ -402,13 +405,13 @@ async def charge(self, event_name: str, *, count: int = 1, idempotency_key: str count=charged_count, idempotency_key=idempotency_key, ) - logger.debug(f"Charged {charged_count} occurrence(s) of event '{event_name}'.") + logger.debug("Charged %d occurrence(s) of event '%s'.", charged_count, event_name) elif event_name in self._tier_priced_events: logger.warning( - f"Event '{event_name}' is tier-priced and is not chargeable via the pay-per-event API." + "Event '%s' is tier-priced and is not chargeable via the pay-per-event API.", event_name ) else: - logger.warning(f"Attempting to charge for an unknown event '{event_name}'") + logger.warning("Attempting to charge for an unknown event '%s'", event_name) # Count the charge only after the API call succeeds, so a failed call retried under the same key is # counted once. @@ -439,8 +442,11 @@ async def charge(self, event_name: str, *, count: int = 1, idempotency_key: str if charged_count < count: subject = 'instance' if count == 1 else 'instances' logger.info( - f"Charging {count} {subject} of '{event_name}' event would exceed max_total_charge_usd " - f'- only {charged_count} events were charged' + "Charging %d %s of '%s' event would exceed max_total_charge_usd - only %d events were charged", + count, + subject, + event_name, + charged_count, ) return ChargeResult( diff --git a/src/apify/_child_runs.py b/src/apify/_child_runs.py index d91e74da4..4b3bc52de 100644 --- a/src/apify/_child_runs.py +++ b/src/apify/_child_runs.py @@ -206,10 +206,10 @@ async def find_or_start( await self._save(name, record.model_copy(update={'abort_with_parent': abort_with_parent})) if run.status in _RESURRECTABLE_STATUSES: - logger.info(f'Resurrecting child run "{name}"', extra={'run_id': run.id, 'status': run.status}) + logger.info('Resurrecting child run "%s"', name, extra={'run_id': run.id, 'status': run.status}) run = await resurrect_run(run.id) else: - logger.info(f'Reattaching to child run "{name}"', extra={'run_id': run.id, 'status': run.status}) + logger.info('Reattaching to child run "%s"', name, extra={'run_id': run.id, 'status': run.status}) await self.update(name, run) self._clients[name] = client @@ -266,12 +266,12 @@ async def _abort(self, name: str, default_client: ApifyClientAsync) -> None: try: run = await run_client.abort(gracefully=True) except NotFoundError: - logger.debug(f'Child run "{name}" no longer exists', extra={'run_id': record.run_id}) + logger.debug('Child run "%s" no longer exists', name, extra={'run_id': record.run_id}) except Exception: - logger.exception(f'Failed to abort child run "{name}"', extra={'run_id': record.run_id}) + logger.exception('Failed to abort child run "%s"', name, extra={'run_id': record.run_id}) else: if run.status in _ABORTED_STATUSES: - logger.info(f'Aborted child run "{name}" with the parent', extra={'run_id': record.run_id}) + logger.info('Aborted child run "%s" with the parent', name, extra={'run_id': record.run_id}) async def _start( self, diff --git a/src/apify/events/_apify_event_manager.py b/src/apify/events/_apify_event_manager.py index 5588f2b58..b880ae795 100644 --- a/src/apify/events/_apify_event_manager.py +++ b/src/apify/events/_apify_event_manager.py @@ -270,7 +270,9 @@ async def _handle_platform_message(self, message: str | bytes) -> None: if isinstance(parsed_message, UnknownEvent): logger.debug( - f'Unknown message received: event_name={parsed_message.name}, event_data={parsed_message.data}' + 'Unknown message received: event_name=%s, event_data=%s', + parsed_message.name, + parsed_message.data, ) return @@ -296,21 +298,25 @@ def _should_reconnect_after_close( """Log the websocket close and report whether to reconnect (`False` on a non-retryable close code).""" if websocket.close_code in self._NON_RETRYABLE_CLOSE_CODES: logger.error( - f'Connection to platform events websocket was closed with a non-retryable code ' - f'(code={websocket.close_code}, reason={websocket.close_reason!r}); not reconnecting. ' - f'No further platform events will be received for the rest of this run, so migration and ' - f'abort handling (e.g. persisting state before a migration) is now disabled.' + 'Connection to platform events websocket was closed with a non-retryable code ' + '(code=%s, reason=%r); not reconnecting. ' + 'No further platform events will be received for the rest of this run, so migration and ' + 'abort handling (e.g. persisting state before a migration) is now disabled.', + websocket.close_code, + websocket.close_reason, ) return False if connection_lost: logger.warning( - f'Connection to platform events websocket was lost ' - f'(code={websocket.close_code}, reason={websocket.close_reason!r}), reconnecting...' + 'Connection to platform events websocket was lost (code=%s, reason=%r), reconnecting...', + websocket.close_code, + websocket.close_reason, ) else: logger.info( - f'Connection to platform events websocket was closed ' - f'(code={websocket.close_code}, reason={websocket.close_reason!r}), reconnecting...' + 'Connection to platform events websocket was closed (code=%s, reason=%r), reconnecting...', + websocket.close_code, + websocket.close_reason, ) return True diff --git a/src/apify/scrapy/_async_thread.py b/src/apify/scrapy/_async_thread.py index ead5a9d06..7aa90359d 100644 --- a/src/apify/scrapy/_async_thread.py +++ b/src/apify/scrapy/_async_thread.py @@ -127,7 +127,7 @@ def wait_for_submitted(self, timeout: timedelta | None = None) -> None: # Callers rely on the effects having landed, so a timeout has to be visible. if self._submitted: - logger.warning(f'{len(self._submitted)} submitted coroutines did not finish within the timeout.') + logger.warning('%d submitted coroutines did not finish within the timeout.', len(self._submitted)) def close(self, timeout: timedelta | None = None) -> None: """Close the event loop and its thread gracefully. diff --git a/src/apify/scrapy/extensions/_httpcache.py b/src/apify/scrapy/extensions/_httpcache.py index 473235ae8..13c22f41a 100644 --- a/src/apify/scrapy/extensions/_httpcache.py +++ b/src/apify/scrapy/extensions/_httpcache.py @@ -84,7 +84,7 @@ async def open_kvs() -> KeyValueStore: logger.debug("Starting background thread for cache storage's event loop") self._async_thread = AsyncThread(default_timeout=self._async_thread_timeout) - logger.debug(f"Opening cache storage's {kvs_name!r} key value store") + logger.debug("Opening cache storage's %r key value store", kvs_name) try: self._kvs = self._async_thread.run_coro(open_kvs()) @@ -116,7 +116,7 @@ def close_spider(self, _: Spider, current_time: int | None = None) -> None: if current_time is None: current_time = int(time()) - logger.info(f'Cleaning up cache items (max {self._expiration_max_items})') + logger.info('Cleaning up cache items (max %s)', self._expiration_max_items) # Best-effort: a cleanup failure is logged and swallowed (the sweep only reclaims storage, so failing it # must not turn a normal spider close into an error), and `close` always runs in the `finally`, so @@ -190,7 +190,7 @@ def retrieve_response(self, _: Spider, request: Request, current_time: int | Non headers = Headers(data['headers']) body = data['body'] except Exception as exc: - logger.warning(f'Ignoring malformed cache entry {key!r}: {exc}', extra={'request': request}) + logger.warning('Ignoring malformed cache entry %r: %s', key, exc, extra={'request': request}) return None respcls = responsetypes.from_args(headers=headers, url=url, body=body) @@ -250,11 +250,11 @@ async def _expire_kvs(self, current_time: int) -> None: try: gzip_time = read_gzip_time(value) except Exception as exc: - logger.warning(f'Malformed cache item {item.key}: {exc}') + logger.warning('Malformed cache item %s: %s', item.key, exc) await self._kvs.delete_value(item.key) else: if self._expiration_secs < current_time - gzip_time: - logger.debug(f'Expired cache item {item.key}') + logger.debug('Expired cache item %s', item.key) await self._kvs.delete_value(item.key) diff --git a/src/apify/scrapy/middlewares/apify_proxy.py b/src/apify/scrapy/middlewares/apify_proxy.py index 7665bfcfa..6814bf4c4 100644 --- a/src/apify/scrapy/middlewares/apify_proxy.py +++ b/src/apify/scrapy/middlewares/apify_proxy.py @@ -99,8 +99,9 @@ def process_exception( """ if isinstance(exception, TunnelError): Actor.log.warning( - f'ApifyHttpProxyMiddleware: TunnelError occurred for request="{request}", ' - f'reason="{exception}", skipping...' + 'ApifyHttpProxyMiddleware: TunnelError occurred for request="%s", reason="%s", skipping...', + request, + exception, ) async def _get_new_proxy_url(self) -> ParseResult: diff --git a/src/apify/scrapy/requests.py b/src/apify/scrapy/requests.py index 668942272..1d662a057 100644 --- a/src/apify/scrapy/requests.py +++ b/src/apify/scrapy/requests.py @@ -165,13 +165,13 @@ def to_apify_request(scrapy_request: ScrapyRequest, spider: Spider) -> ApifyRequ ) else: logger.warning( - f'Invalid scrapy_request.headers type, not scrapy.http.headers.Headers: {scrapy_request.headers}' + 'Invalid scrapy_request.headers type, not scrapy.http.headers.Headers: %s', scrapy_request.headers ) apify_request = ApifyRequest.from_url(**request_kwargs) except Exception: - logger.exception(f'Conversion of Scrapy request {scrapy_request} to Apify request failed; skipping it.') + logger.exception('Conversion of Scrapy request %s to Apify request failed; skipping it.', scrapy_request) return None # Serialize the Scrapy request as JSON under 'scrapy_request'. Kept outside the broad except above so @@ -181,8 +181,9 @@ def to_apify_request(scrapy_request: ScrapyRequest, spider: Spider) -> ApifyRequ scrapy_request_json = encode_to_json(scrapy_request_dict) except (TypeError, ValueError): logger.exception( - f'Failed to serialize Scrapy request {scrapy_request} for storage on the Apify platform; skipping it. ' - 'Ensure all values in `meta` and `cb_kwargs` are JSON-serializable.' + 'Failed to serialize Scrapy request %s for storage on the Apify platform; skipping it. ' + 'Ensure all values in `meta` and `cb_kwargs` are JSON-serializable.', + scrapy_request, ) return None diff --git a/src/apify/scrapy/scheduler.py b/src/apify/scrapy/scheduler.py index 9247da028..2695040af 100644 --- a/src/apify/scrapy/scheduler.py +++ b/src/apify/scrapy/scheduler.py @@ -108,9 +108,10 @@ def open(self, spider: Spider) -> Deferred[None] | None: if self._crawler is None: logger.warning( - f'{ApifyScheduler.__qualname__} was built without a crawler, so it cannot see what Scrapy is ' + '%s was built without a crawler, so it cannot see what Scrapy is ' 'still working on. Every request is marked as handled the moment it is handed over, and an ' - 'interrupted run loses whatever was in flight. Build it with `from_crawler` to avoid that.' + 'interrupted run loses whatever was in flight. Build it with `from_crawler` to avoid that.', + ApifyScheduler.__qualname__, ) else: self._verify_engine_internals() @@ -153,7 +154,7 @@ def close(self, reason: str) -> None: Args: reason: The reason for closing the spider. """ - logger.debug(f'Closing {self.__class__.__name__} due to {reason}...') + logger.debug('Closing %s due to %s...', self.__class__.__name__, reason) self._closed = True # Without an initialized Actor (never initialized, or exited already) there is nothing to unregister from. @@ -183,7 +184,8 @@ def close(self, reason: str) -> None: for (apify_request, _), outcome in zip(self._requests_in_flight, outcomes, strict=True): if outcome is not None: logger.error( - f'Failed to reclaim the request {apify_request} in the request queue.', + 'Failed to reclaim the request %s in the request queue.', + apify_request, exc_info=outcome, ) @@ -202,7 +204,7 @@ def close(self, reason: str) -> None: logger.exception('Exception occurred while shutting down.') finally: - logger.debug(f'{self.__class__.__name__} closed successfully.') + logger.debug('%s closed successfully.', self.__class__.__name__) def has_pending_requests(self) -> bool: """Check if the scheduler has any pending requests. @@ -248,7 +250,7 @@ def enqueue_request(self, request: Request) -> bool: apify_request = to_apify_request(request, spider=self.spider) if apify_request is None: - logger.warning(f'Request {request} could not be converted to Apify request; skipping it.') + logger.warning('Request %s could not be converted to Apify request; skipping it.', request) return False if not isinstance(self._rq, RequestQueue): @@ -300,7 +302,9 @@ def next_request(self) -> Request | None: try: scrapy_request = to_scrapy_request(apify_request, spider=self.spider) except Exception as exc: - logger.warning(f'Failed to convert Apify request {apify_request} to a Scrapy request; skipping it: {exc}') + logger.warning( + 'Failed to convert Apify request %s to a Scrapy request; skipping it: %s', apify_request, exc + ) try: self._async_thread.run_coro(self._rq.mark_request_as_handled(apify_request)) except Exception: @@ -334,8 +338,10 @@ async def _on_migrating(self, event_data: EventMigratingData) -> None: remaining = event_data.time_remaining deadline = '' if remaining is None else f' in {remaining.total_seconds():.0f} seconds' logger.info( - f'The Actor run is migrating{deadline}: no more requests are handed out to Scrapy, and the ' - f'{len(self._requests_in_flight)} request(s) it holds are marked as handled as they finish.' + 'The Actor run is migrating%s: no more requests are handed out to Scrapy, and the ' + '%d request(s) it holds are marked as handled as they finish.', + deadline, + len(self._requests_in_flight), ) await self._settle_requests_in_flight() @@ -348,8 +354,8 @@ async def _on_aborting(self) -> None: the abort would leave all of them pending, their items already pushed. """ logger.info( - f'The Actor run is being aborted: the {len(self._requests_in_flight)} request(s) Scrapy holds are marked ' - 'as handled as they finish.' + 'The Actor run is being aborted: the %d request(s) Scrapy holds are marked as handled as they finish.', + len(self._requests_in_flight), ) await self._settle_requests_in_flight() @@ -433,7 +439,7 @@ def _resolve_finished_requests(self, *, wait: bool) -> None: else: self._pending_marks.append((finished, self._async_thread.submit_coro(marks))) except Exception: - logger.exception(f'Failed to mark {len(finished)} request(s) as handled in the request queue.') + logger.exception('Failed to mark %d request(s) as handled in the request queue.', len(finished)) unresolved.extend(finished) self._requests_in_flight = unresolved @@ -462,7 +468,7 @@ def _collect_failed_marks(self, *, wait: bool) -> list[InFlightRequest]: if not future.done(): pending.append((requests, future)) elif future.cancelled(): - logger.error(f'Marking {len(requests)} request(s) as handled was cancelled before it finished.') + logger.error('Marking %d request(s) as handled was cancelled before it finished.', len(requests)) failed.extend(requests) else: # `_gather_failures` reports a failed update in its result rather than raising, so an exception @@ -470,7 +476,7 @@ def _collect_failed_marks(self, *, wait: bool) -> list[InFlightRequest]: try: outcomes = future.result() except Exception: - logger.exception(f'Failed to mark {len(requests)} request(s) as handled in the request queue.') + logger.exception('Failed to mark %d request(s) as handled in the request queue.', len(requests)) failed.extend(requests) else: failed.extend(self._failed_marks(requests, outcomes)) @@ -490,7 +496,8 @@ def _failed_marks( for (apify_request, scrapy_request), outcome in zip(requests, outcomes, strict=True): if outcome is not None: logger.error( - f'Failed to mark the request {apify_request} as handled in the request queue.', + 'Failed to mark the request %s as handled in the request queue.', + apify_request, exc_info=outcome, ) failed.append((apify_request, scrapy_request)) diff --git a/src/apify/storage_clients/_apify/_alias_resolving.py b/src/apify/storage_clients/_apify/_alias_resolving.py index 39fa3b995..daab9cb5d 100644 --- a/src/apify/storage_clients/_apify/_alias_resolving.py +++ b/src/apify/storage_clients/_apify/_alias_resolving.py @@ -239,7 +239,7 @@ async def store_mapping(self, storage_id: str) -> None: # Store the mapping back in the KVS. await default_kvs_client.set_record(key=self._ALIAS_MAPPING_KEY, value=value) except Exception as exc: - logger.warning(f'Error storing alias mapping for {self._alias}: {exc}') + logger.warning('Error storing alias mapping for %s: %s', self._alias, exc) @cached_property def _storage_key(self) -> str: diff --git a/src/apify/storage_clients/_apify/_request_queue_shared_client.py b/src/apify/storage_clients/_apify/_request_queue_shared_client.py index 22cc6f090..95fa031a5 100644 --- a/src/apify/storage_clients/_apify/_request_queue_shared_client.py +++ b/src/apify/storage_clients/_apify/_request_queue_shared_client.py @@ -222,9 +222,10 @@ async def add_batch_of_requests( await resolve_awaited_in_flight(awaited_in_flight, api_response) logger.debug( - f'Tried to add new requests: {len(new_requests)}, ' - f'succeeded to add new requests: {len(api_response.processed_requests) - len(already_present_requests)}, ' - f'skipped already present requests: {len(already_present_requests)}' + 'Tried to add new requests: %d, succeeded to add new requests: %d, skipped already present requests: %d', + len(new_requests), + len(api_response.processed_requests) - len(already_present_requests), + len(already_present_requests), ) # Update assumed total count for newly added requests. @@ -349,7 +350,7 @@ async def mark_request_as_handled(self, request: Request) -> ProcessedRequest | hydrated_request=request, ) except Exception: - logger.exception(f'Error marking request {request.unique_key} as handled.') + logger.exception('Error marking request %s as handled.', request.unique_key) return None else: return processed_request @@ -396,7 +397,7 @@ async def reclaim_request( self._should_check_for_forefront_requests = True except Exception: - logger.exception(f'Error reclaiming request {request.unique_key}') + logger.exception('Error reclaiming request %s', request.unique_key) return None else: return processed_request @@ -532,12 +533,12 @@ async def _ensure_lock_window( lock_duration=self._DEFAULT_LOCK_TIME, ) except Exception as exc: - logger.debug(f'Failed to prolong the lock of request {request_id}, skipping it: {exc!s}') + logger.debug('Failed to prolong the lock of request %s, skipping it: %s', request_id, exc) return False # `None` means the lock was not (re)acquired; skip the request rather than process it without a lock. if lock_info is None: - logger.debug(f'Lock of request {request_id} could not be re-acquired, skipping it') + logger.debug('Lock of request %s could not be re-acquired, skipping it', request_id) return False if (cached := self._requests_cache.get(request_id)) is not None: @@ -583,7 +584,7 @@ async def _get_or_hydrate_request(self, request_id: str) -> Request | None: lock_expires_at=cached_entry.lock_expires_at if cached_entry else None, ) except Exception as exc: - logger.debug(f'Error fetching request {request_id}: {exc!s}') + logger.debug('Error fetching request %s: %s', request_id, exc) return None else: return request @@ -630,7 +631,7 @@ async def _list_head( """ # Return from cache if available and we're not checking for new forefront requests if self._queue_head and not self._should_check_for_forefront_requests: - logger.debug(f'Using cached queue head with {len(self._queue_head)} requests') + logger.debug('Using cached queue head with %d requests', len(self._queue_head)) # Create a list of requests from the cached queue head items = [] for request_id in list(self._queue_head)[:limit]: diff --git a/src/apify/storage_clients/_apify/_request_queue_single_client.py b/src/apify/storage_clients/_apify/_request_queue_single_client.py index dfe4632c5..7e4d40f49 100644 --- a/src/apify/storage_clients/_apify/_request_queue_single_client.py +++ b/src/apify/storage_clients/_apify/_request_queue_single_client.py @@ -287,7 +287,7 @@ async def mark_request_as_handled(self, request: Request) -> ProcessedRequest | processed_request = await self._update_request(request) except Exception: - logger.exception(f'Error marking request {request.unique_key} as handled.') + logger.exception('Error marking request %s as handled.', request.unique_key) return None else: return processed_request @@ -333,7 +333,7 @@ async def reclaim_request( self.metadata.pending_request_count += 1 except Exception: - logger.exception(f'Error reclaiming request {request.unique_key}') + logger.exception('Error reclaiming request %s', request.unique_key) return None else: return processed_request diff --git a/src/apify/storage_clients/_file_system/_key_value_store_client.py b/src/apify/storage_clients/_file_system/_key_value_store_client.py index bfce86a74..f8cd47a03 100644 --- a/src/apify/storage_clients/_file_system/_key_value_store_client.py +++ b/src/apify/storage_clients/_file_system/_key_value_store_client.py @@ -122,7 +122,7 @@ async def _create_missing_metadata_for_input_file(key: str, record_path: Path) - try: content = await asyncio.to_thread(record_path.read_bytes) except FileNotFoundError: - logger.warning(f'Input file disappeared from path: "{record_path}"') + logger.warning('Input file disappeared from path: "%s"', record_path) return # Figure out the metadata from the file content diff --git a/tests/e2e/test_actor_lifecycle.py b/tests/e2e/test_actor_lifecycle.py index 32e910af7..f5ca66917 100644 --- a/tests/e2e/test_actor_lifecycle.py +++ b/tests/e2e/test_actor_lifecycle.py @@ -141,11 +141,11 @@ async def main() -> None: @crawler.router.default_handler async def default_handler(context: BasicCrawlingContext) -> None: - context.log.info(f'Processing {context.request.url} ...') + context.log.info('Processing %s ...', context.request.url) # Simulate migration through reboot if context.request.url == requests[1] and first_run: - context.log.info(f'Reclaiming {context.request.url} ...') + context.log.info('Reclaiming %s ...', context.request.url) rq = await crawler.get_request_manager() await rq.reclaim_request(context.request) await Actor.reboot() diff --git a/tests/e2e/test_scrapy/actor_source/spider_delayed_chain.py b/tests/e2e/test_scrapy/actor_source/spider_delayed_chain.py index 074b784ba..f6a359395 100644 --- a/tests/e2e/test_scrapy/actor_source/spider_delayed_chain.py +++ b/tests/e2e/test_scrapy/actor_source/spider_delayed_chain.py @@ -21,7 +21,7 @@ class MarkInFlightMiddleware: """Downloader middleware that logs `IN_FLIGHT_LOG_MARKER` for every request it sees.""" def process_request(self, request: Request) -> None: - logger.info(f'{IN_FLIGHT_LOG_MARKER}: {request.url}') + logger.info('%s: %s', IN_FLIGHT_LOG_MARKER, request.url) class DelayedChainSpider(Spider): diff --git a/tests/e2e/test_scrapy/actor_source/spider_in_flight.py b/tests/e2e/test_scrapy/actor_source/spider_in_flight.py index d1b1b3e46..c645c9144 100644 --- a/tests/e2e/test_scrapy/actor_source/spider_in_flight.py +++ b/tests/e2e/test_scrapy/actor_source/spider_in_flight.py @@ -21,7 +21,7 @@ class MarkInFlightMiddleware: """Downloader middleware that logs `IN_FLIGHT_LOG_MARKER` for every request it sees.""" def process_request(self, request: Request) -> None: - logger.info(f'{IN_FLIGHT_LOG_MARKER}: {request.url}') + logger.info('%s: %s', IN_FLIGHT_LOG_MARKER, request.url) class InFlightSpider(Spider): diff --git a/tests/e2e/test_scrapy/actor_source/spider_reboot.py b/tests/e2e/test_scrapy/actor_source/spider_reboot.py index f3ca35d0c..1454d0dca 100644 --- a/tests/e2e/test_scrapy/actor_source/spider_reboot.py +++ b/tests/e2e/test_scrapy/actor_source/spider_reboot.py @@ -35,7 +35,7 @@ def __init__(self) -> None: def process_request(self, request: Request) -> None: if self._reboot is None: - logger.info(f'Handing the request over to the downloader: {request.url}') + logger.info('Handing the request over to the downloader: %s', request.url) self._reboot = asyncio.ensure_future(self._reboot_once()) async def _reboot_once(self) -> None: diff --git a/tests/integration/test_request_queue.py b/tests/integration/test_request_queue.py index 71d3681e1..f2c7d46ed 100644 --- a/tests/integration/test_request_queue.py +++ b/tests/integration/test_request_queue.py @@ -1061,7 +1061,7 @@ async def test_crawler_run_request_queue_variant_stats( @crawler.router.default_handler async def default_handler(context: BasicCrawlingContext) -> None: - context.log.info(f'Processing {context.request.url} ...') + context.log.info('Processing %s ...', context.request.url) await crawler.run([Request.from_url(f'https://example.com/{i}') for i in range(requests)]) diff --git a/tests/unit/actor/test_actor_lifecycle.py b/tests/unit/actor/test_actor_lifecycle.py index 07ad55b7b..99b93999e 100644 --- a/tests/unit/actor/test_actor_lifecycle.py +++ b/tests/unit/actor/test_actor_lifecycle.py @@ -462,7 +462,7 @@ async def test_actor_fail_prevents_further_execution(caplog: pytest.LogCaptureFi assert len(exit_records) == 1 assert exit_records[0].levelno == logging.INFO - status_records = [r for r in caplog.records if r.msg == '[Terminal status message]: cde'] + status_records = [r for r in caplog.records if r.getMessage() == '[Terminal status message]: cde'] assert len(status_records) == 1 assert status_records[0].levelno == logging.INFO