sentry-python icon indicating copy to clipboard operation
sentry-python copied to clipboard

Replace `ClientConstructor` with a `TypedDict`

Open szokeasaurusrex opened this issue 1 year ago • 0 comments

We currently use ClientConstructor to trick mypy (and other static analyzers) into believing that Client.__init__ takes many typed parameters, rather than untyped **kwargs. The current solution is somewhat hacky, as it separates the Client class's actual implementation into a separate _Client class.

We could instead define a TypedDict with the parameters accepted in Client.__init__'s **kwargs, and type the **kwargs with this TypedDict. I have already implemented similar functionality for start_transaction in https://github.com/getsentry/sentry-python/pull/2796.

Advantages of switching to a TypedDict include:

  • Code is clearer, since we are not fooling mypy with hacky workarounds.
  • mypy enforces the **kwargs's types within Client.__init__. Currently, **kwargs is recognized as a dict[str, Any], which is type-unsafe.
  • mypy currently incorrectly recognizes the arguments in ClientConstructor as all being valid positional arguments, when in reality, only the dsn may be provided as a positional argument. Providing any other arguments as positional arguments results in a TypeError. With a TypedDict, mypy is aware that the arguments must be passed as keyword arguments.

Disadvantages of switching to a TypedDict:

  • The current solution allows us to indicate the default value's of the arguments, when they are not provided. Specifying default values may not be possible with a TypedDict.

szokeasaurusrex avatar Mar 13 '24 15:03 szokeasaurusrex