diff --git a/docs-requirements.txt b/docs-requirements.txt index a4bb031506..ed371ed9c9 100644 --- a/docs-requirements.txt +++ b/docs-requirements.txt @@ -1,3 +1,4 @@ +gevent shibuya sphinx==7.2.6 sphinx-autodoc-typehints[type_comments]>=1.8.0 diff --git a/linter-requirements.txt b/linter-requirements.txt index 289df0cd7f..5bfb2ef0ca 100644 --- a/linter-requirements.txt +++ b/linter-requirements.txt @@ -3,8 +3,11 @@ black flake8==5.0.4 # flake8 depends on pyflakes>=3.0.0 and this dropped support for Python 2 "# type:" comments types-certifi types-protobuf +types-gevent +types-greenlet types-redis types-setuptools +types-webob pymongo # There is no separate types module. loguru # There is no separate types module. flake8-bugbear diff --git a/sentry_sdk/integrations/_wsgi_common.py b/sentry_sdk/integrations/_wsgi_common.py index 6e6705a7d3..8b2a8526c0 100644 --- a/sentry_sdk/integrations/_wsgi_common.py +++ b/sentry_sdk/integrations/_wsgi_common.py @@ -16,6 +16,7 @@ from typing import Any from typing import Dict from typing import Mapping + from typing import MutableMapping from typing import Optional from typing import Union from sentry_sdk._types import Event @@ -114,7 +115,7 @@ def content_length(self): return 0 def cookies(self): - # type: () -> Dict[str, Any] + # type: () -> MutableMapping[str, Any] raise NotImplementedError() def raw_data(self): diff --git a/sentry_sdk/integrations/pyramid.py b/sentry_sdk/integrations/pyramid.py index 523ee4b5ec..e16826069b 100644 --- a/sentry_sdk/integrations/pyramid.py +++ b/sentry_sdk/integrations/pyramid.py @@ -30,8 +30,8 @@ from typing import Callable from typing import Dict from typing import Optional - from webob.cookies import RequestCookies # type: ignore - from webob.compat import cgi_FieldStorage # type: ignore + from webob.cookies import RequestCookies + from webob.request import _FieldStorageWithFile from sentry_sdk.utils import ExcInfo from sentry_sdk._types import Event, EventProcessor @@ -186,7 +186,7 @@ def form(self): } def files(self): - # type: () -> Dict[str, cgi_FieldStorage] + # type: () -> Dict[str, _FieldStorageWithFile] return { key: value for key, value in self.request.POST.items() @@ -194,7 +194,7 @@ def files(self): } def size_of_file(self, postdata): - # type: (cgi_FieldStorage) -> int + # type: (_FieldStorageWithFile) -> int file = postdata.file try: return os.fstat(file.fileno()).st_size diff --git a/sentry_sdk/profiler.py b/sentry_sdk/profiler.py index 1da4202d07..1fe8588a77 100644 --- a/sentry_sdk/profiler.py +++ b/sentry_sdk/profiler.py @@ -62,6 +62,7 @@ from typing import Set from typing import Sequence from typing import Tuple + from typing import Type from typing_extensions import TypedDict import sentry_sdk.tracing @@ -129,9 +130,10 @@ try: - from gevent.monkey import get_original # type: ignore - from gevent.threadpool import ThreadPool # type: ignore + from gevent.monkey import get_original + from gevent.threadpool import ThreadPool as _ThreadPool + ThreadPool = _ThreadPool # type: Optional[Type[_ThreadPool]] thread_sleep = get_original("time", "sleep") except ImportError: thread_sleep = time.sleep @@ -923,7 +925,7 @@ def __init__(self, frequency): # used to signal to the thread that it should stop self.running = False - self.thread = None # type: Optional[ThreadPool] + self.thread = None # type: Optional[_ThreadPool] self.pid = None # type: Optional[int] # This intentionally uses the gevent patched threading.Lock. @@ -960,7 +962,7 @@ def ensure_running(self): self.pid = pid self.running = True - self.thread = ThreadPool(1) + self.thread = ThreadPool(1) # type: ignore[misc] try: self.thread.spawn(self.run) except RuntimeError: diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index a89a63bf5d..a84f2eb3de 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -54,6 +54,8 @@ Union, ) + from gevent.hub import Hub + import sentry_sdk.integrations from sentry_sdk._types import Event, ExcInfo @@ -1182,8 +1184,8 @@ def _is_contextvars_broken(): Returns whether gevent/eventlet have patched the stdlib in a way where thread locals are now more "correct" than contextvars. """ try: - import gevent # type: ignore - from gevent.monkey import is_object_patched # type: ignore + import gevent + from gevent.monkey import is_object_patched # Get the MAJOR and MINOR version numbers of Gevent version_tuple = tuple( @@ -1209,7 +1211,7 @@ def _is_contextvars_broken(): pass try: - import greenlet # type: ignore + import greenlet from eventlet.patcher import is_monkey_patched # type: ignore greenlet_version = parse_version(greenlet.__version__) @@ -1794,12 +1796,14 @@ def now(): from gevent.monkey import is_module_patched except ImportError: - def get_gevent_hub(): - # type: () -> Any + # it's not great that the signatures are different, get_hub can't return None + # consider adding an if TYPE_CHECKING to change the signature to Optional[Hub] + def get_gevent_hub(): # type: ignore[misc] + # type: () -> Optional[Hub] return None - def is_module_patched(*args, **kwargs): - # type: (*Any, **Any) -> bool + def is_module_patched(mod_name): + # type: (str) -> bool # unable to import from gevent means no modules have been patched return False