Skip to content

Commit

Permalink
perf: Minor performance improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
  • Loading branch information
Stranger6667 committed May 16, 2024
1 parent bb266a1 commit d12b70e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
21 changes: 16 additions & 5 deletions src/schemathesis/specs/openapi/references.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,32 @@ def resolve_all(self, item: list, recursion_level: int = 0) -> list:

def resolve_all(self, item: JSONType, recursion_level: int = 0) -> JSONType:
"""Recursively resolve all references in the given object."""
resolve = self.resolve_all
if isinstance(item, dict):
ref = item.get("$ref")
if ref is not None and isinstance(ref, str):
with self.resolving(ref) as resolved:
if isinstance(ref, str):
url, resolved = self.resolve(ref)
self.push_scope(url)
try:
# If the next level of recursion exceeds the limit, then we need to copy it explicitly
# In other cases, this method create new objects for mutable types (dict & list)
next_recursion_level = recursion_level + 1
if next_recursion_level > RECURSION_DEPTH_LIMIT:
copied = fast_deepcopy(resolved)
remove_optional_references(copied)
return copied
return self.resolve_all(resolved, next_recursion_level)
return {key: self.resolve_all(sub_item, recursion_level) for key, sub_item in item.items()}
return resolve(resolved, next_recursion_level)
finally:
self.pop_scope()
return {
key: resolve(sub_item, recursion_level) if isinstance(sub_item, (dict, list)) else sub_item
for key, sub_item in item.items()
}
if isinstance(item, list):
return [self.resolve_all(sub_item, recursion_level) for sub_item in item]
return [
self.resolve_all(sub_item, recursion_level) if isinstance(sub_item, (dict, list)) else sub_item
for sub_item in item
]
return item

def resolve_in_scope(self, definition: dict[str, Any], scope: str) -> tuple[list[str], dict[str, Any]]:
Expand Down
12 changes: 6 additions & 6 deletions src/schemathesis/specs/openapi/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,9 @@ def get_response_schema(self, definition: dict[str, Any], scope: str) -> tuple[l
def get_operation_by_id(self, operation_id: str) -> APIOperation:
"""Get an `APIOperation` instance by its `operationId`."""
cache = self._operation_cache
operation = cache.get_operation_by_id(operation_id)
if operation is not None:
return operation
cached = cache.get_operation_by_id(operation_id)
if cached is not None:
return cached
# Operation has not been accessed yet, need to populate the cache
if not cache.has_ids_to_definitions:
self._populate_operation_id_cache(cache)
Expand Down Expand Up @@ -821,9 +821,9 @@ def _init_operation(self, method: str) -> APIOperation:
cache = schema._operation_cache
path = self._path
scope = self._scope
instance = cache.get_operation_by_traversal_key(scope, path, method)
if instance is not None:
return instance
cached = cache.get_operation_by_traversal_key(scope, path, method)
if cached is not None:
return cached
schema.resolver.push_scope(scope)
try:
resolved = schema._resolve_operation(operation)
Expand Down

0 comments on commit d12b70e

Please sign in to comment.