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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions codegen/build-oas.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,123 @@ generate_client() {
sed -i '' "s/bool, date, datetime, dict, float, int, list, str, none_type/bool, dict, float, int, list, str, none_type/g" "$file"
done

# Fix invalid dict type annotations in return types and casts
# Replace {str: (bool, dict, float, int, list, str, none_type)} with Dict[str, Any]
find "${build_dir}" -name "*.py" | while IFS= read -r file; do
# Need to escape the braces and parentheses for sed
sed -i '' 's/{str: (bool, dict, float, int, list, str, none_type)}/Dict[str, Any]/g' "$file"
done

# Remove globals() assignments from TYPE_CHECKING blocks
# These should only be in lazy_import() functions, not in TYPE_CHECKING blocks
find "${build_dir}" -name "*.py" | while IFS= read -r file; do
python3 <<PYTHON_SCRIPT
import sys

with open('$file', 'r') as f:
lines = f.readlines()

in_type_checking = False
output_lines = []
i = 0
while i < len(lines):
line = lines[i]
if 'if TYPE_CHECKING:' in line:
in_type_checking = True
output_lines.append(line)
i += 1
# Skip blank line after 'if TYPE_CHECKING:' if present
if i < len(lines) and lines[i].strip() == '':
i += 1
# Process lines until we hit a blank line or 'def lazy_import'
while i < len(lines):
next_line = lines[i]
stripped = next_line.strip()
if stripped == '' or stripped.startswith('def lazy_import'):
in_type_checking = False
break
# Only include lines that are imports, not globals() assignments
if not stripped.startswith('globals('):
output_lines.append(next_line)
i += 1
continue
output_lines.append(line)
i += 1

with open('$file', 'w') as f:
f.writelines(output_lines)
PYTHON_SCRIPT
done

# Remove unused type: ignore[misc] comments from __new__ methods
# The explicit type annotation is sufficient for mypy
find "${build_dir}" -name "*.py" | while IFS= read -r file; do
sed -i '' 's/instance: T = super().__new__(cls, \*args, \*\*kwargs) # type: ignore\[misc\]/instance: T = super().__new__(cls, *args, **kwargs)/g' "$file"
done

# Fix ApplyResult import - move from TYPE_CHECKING to runtime import
# ApplyResult is used in cast() calls which need it at runtime
find "${build_dir}" -name "*_api.py" | while IFS= read -r file; do
python3 <<PYTHON_SCRIPT
with open('$file', 'r') as f:
lines = f.readlines()

# Check if ApplyResult is imported under TYPE_CHECKING
apply_result_in_type_checking = False
apply_result_line_idx = -1
typing_import_idx = -1
type_checking_start_idx = -1
output_lines = []
i = 0

while i < len(lines):
line = lines[i]

# Find typing import line
if 'from typing import' in line and typing_import_idx == -1:
typing_import_idx = len(output_lines)
output_lines.append(line)
i += 1
continue

# Check for TYPE_CHECKING block
if 'if TYPE_CHECKING:' in line:
type_checking_start_idx = len(output_lines)
output_lines.append(line)
i += 1
# Check next line for ApplyResult import
if i < len(lines) and 'from multiprocessing.pool import ApplyResult' in lines[i]:
apply_result_in_type_checking = True
apply_result_line_idx = i
i += 1 # Skip the ApplyResult import line
# Skip blank line if present
if i < len(lines) and lines[i].strip() == '':
i += 1
# Check if TYPE_CHECKING block is now empty
if i < len(lines):
next_line = lines[i]
# If next line is not indented, the TYPE_CHECKING block is empty
if next_line.strip() and not (next_line.startswith(' ') or next_line.startswith('\t')):
# Remove the empty TYPE_CHECKING block
output_lines.pop() # Remove 'if TYPE_CHECKING:'
type_checking_start_idx = -1
continue

output_lines.append(line)
i += 1

# If we found ApplyResult under TYPE_CHECKING, add it after typing import
if apply_result_in_type_checking and typing_import_idx != -1:
# Check if it's not already imported at module level
module_start = ''.join(output_lines[:typing_import_idx+10])
if 'from multiprocessing.pool import ApplyResult' not in module_start:
output_lines.insert(typing_import_idx + 1, 'from multiprocessing.pool import ApplyResult\n')

with open('$file', 'w') as f:
f.writelines(output_lines)
PYTHON_SCRIPT
done

# Copy the generated module to the correct location
rm -rf "${destination}/${module_name}"
mkdir -p "${destination}"
Expand Down
2 changes: 1 addition & 1 deletion codegen/python-oas-templates
38 changes: 28 additions & 10 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
[mypy]
; pretty = True
; disallow_untyped_calls = True
; check_untyped_defs = True
; disallow_untyped_defs = True
; warn_return_any = True
; warn_unused_configs = True
pretty = True
warn_return_any = True
warn_unused_configs = True
warn_redundant_casts = True
warn_unused_ignores = True
check_untyped_defs = True
# disallow_untyped_calls = True # Gradually enable as types are added
# disallow_untyped_defs = True # Gradually enable as types are added
# disallow_incomplete_defs = True # Gradually enable as types are added
no_implicit_optional = True
strict_equality = True

# Per-module options:
# Handle library stub issues
# These libraries have type stubs available but may not always be installed
# or may have incomplete stubs. We suppress these errors to avoid noise.
[mypy-google.api.*]
ignore_missing_imports = True

; [mypy-mycode.foo.*]
; disallow_untyped_defs = True
[mypy-tqdm.*]
ignore_missing_imports = True

[mypy-google.api.*]
[mypy-urllib3.*]
ignore_missing_imports = True

[mypy-grpc.*]
ignore_missing_imports = True

[mypy-aiohttp.*]
ignore_missing_imports = True

[mypy-aiohttp_retry.*]
ignore_missing_imports = True
19 changes: 16 additions & 3 deletions pinecone/admin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,22 @@ def __init__(
self._child_api_client.user_agent = get_user_agent(Config())

# Lazily initialize resources
self._project = None
self._api_key = None
self._organization = None
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
from pinecone.admin.resources import (
ProjectResource,
ApiKeyResource,
OrganizationResource,
)

self._project: Optional[ProjectResource] = None
self._api_key: Optional[ApiKeyResource] = None
self._organization: Optional[OrganizationResource] = None
else:
self._project = None # type: ignore[assignment]
self._api_key = None # type: ignore[assignment]
self._organization = None # type: ignore[assignment]

@property
def project(self):
Expand Down
11 changes: 4 additions & 7 deletions pinecone/config/openapi_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import multiprocessing

from pinecone.exceptions import PineconeApiValueError
from typing import TypedDict
from typing import TypedDict, Optional


class HostSetting(TypedDict):
Expand Down Expand Up @@ -219,7 +219,7 @@ def __deepcopy__(self, memo):
def __setattr__(self, name, value):
object.__setattr__(self, name, value)
if name == "disabled_client_side_validations":
s = set(filter(None, value.split(",")))
s: set[str] = set(filter(None, value.split(",")))
for v in s:
if v not in JSON_SCHEMA_VALIDATION_KEYWORDS:
raise PineconeApiValueError("Invalid keyword: '{0}''".format(v))
Expand Down Expand Up @@ -291,16 +291,13 @@ def debug(self):
return self._debug

@debug.setter
def debug(self, value):
def debug(self, value: bool) -> None:
"""Debug status

:param value: The debug status, True or False.
:type: bool
"""
if hasattr(self, "_debug"):
previous_debug = self._debug
else:
previous_debug = None
previous_debug: Optional[bool] = getattr(self, "_debug", None)
self._debug = value

def enable_http_logging():
Expand Down
Loading