# Python library: optionally support numpy types without depending on numpy

## Question:

## Context

We develop a Python library that contains a function expecting a numlike parameter. We specify this in our signature and make use of python type hints:

```
def cool(value: float | int | List[float | int])
```

## Problem & Goal

During runtime, we noticed it’s fine to pass in numpy number types as well, e.g. `np.float16(1.2345)`

. So we thought: why not incorporate "numpy number types" into our signature as this would be beneficial for the community that will use our library.

However, we don’t want `numpy`

as dependency in our project. We’d like to only signify in the method signature that we can take a `float`

, `int`

, a list of them OR any "numpy number type". If the user hasn’t installed `numpy`

on their system, they should still be able to use our library and just ignore that they could possibly pass in a "numpy number type" as well.

_{We don’t want to depend on numpy as we don’t use it in our library (except for allowing their types in our method signature). So why include it in our dependency graph? There’s no reason to do so. One dependency less is better.}

## Additional requirements/context

- We search for an answer that is compatible with all Python versions
`>=3.8`

. - (The answer should work with
`setuptools>=69.0`

.) - The answer should be such that we get proper IntelliSense (
`Ctrl + Space`

) when typing`cool(`

in an IDE, e.g. VSCode. - This is what our
`pyproject.toml`

looks like.

## Efforts

- We’ve noticed the option
`[project.optional-dependencies]`

for the`pyproject.toml`

file, see here. However, it remains unclear how this optional dependencies declaration helps us in providing optional`numpy`

datatypes in our method signatures. `numpy`

provides the`numpy.typing`

type annotations. Is it somehow possible to only depend on this subpackage?- We did search on search engines and found this SO question, however our question is more specific with regards to how we can only use
*types*from another module. We also found this SO question, but despite having "optional" in its title, it’s not about*optional*numpy types.

## Answers:

Defer evaluation of annotations, and only import numpy conditionally.

```
from __future__ import annotations
import typing as t
if t.TYPE_CHECKING:
import numpy as np
def cool(value: int | np.floating | etc ...):
...
```

Now the numpy dependency is only necessary when type-checking.

See PEP 563 – Postponed Evaluation of Annotations

### Side-questions..

`numpy`

provides the`numpy.typing`

type annotations. Is it somehow possible to only depend on this subpackage?

No, this is not possible.

We’ve noticed the option

`[project.optional-dependencies]`

for the`pyproject.toml`

file …

It doesn’t really help you much here. It could still be useful if you wanted "extra" dependencies which the user can opt-in for, e.g.:

```
pip install mypkg # install with required dependencies
pip install mypkg[typing] # install with extra dependencies such as numpy
```

Then you could use this to easily install the package along with the soft-deps in your CI, for example.