# Type annotations and itk.Image\[...\]

**URL:** <https://discourse.itk.org/t/type-annotations-and-itk-image/4407>\
**Category:** Uncategorized\
**Created:** [September 9, 2021, 12:43pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407 "2021-09-09T12:43:06Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 9, 2021, 12:43pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/1 "2021-09-09T12:43:07Z")

</div>

I am writing some Python code built on itk and other packages. Many of the methods take itk images as arguments.

What is the best way add type annotations for itk images? In most cases I don’t care about the pixel type of the image, but do care about the dimension.

- Is there a corresponding base type in Python for 2D images, or 3D images?
- Or should I use typing.Union and list all the image types I except to receive, like:

```auto
def do_something(img: Union[itk.Image[itk.UC,2], itk.Image[itk.F,2]], a:int, b:float):

```

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [September 9, 2021, 1:19pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/2 "2021-09-09T13:19:22Z")

</div>

@hjmjohnson or @matt.mccormick could best answer this.

---

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 9, 2021, 2:55pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/3 "2021-09-09T14:55:31Z")

</div>

I found `ImageLike` and `ImageBase`, i.e.  
`from itk.support.types import ImageLike, ImageBase`

This seems to be more or less what I want, although the dimension is lost. I guess I could do a Union of images with all valid pixel types.

---

<div class="post-metadata">

**Author:** ![kjweimer](https://discourse.itk.org/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@kjweimer](https://discourse.itk.org/u/kjweimer)\
**Post date:** [September 9, 2021, 5:56pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/4 "2021-09-09T17:56:27Z")

</div>

Hi!  
I’m currently working on generating typehints for ITK’s Python wrapped classes and methods which should help new users understand the package quicker.

While there may not be exactly what you want there is a `itkImageBase2` class that is inherited by all 2 dimensional itk Images in Python regardless of pixel type.

You could try the following:

```auto
from itk.itkImagePython import itkImageBase2
def do_something(img: itkImageBase2, a:int, b:float):
    ...

```

Hope this helps!

---

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 10, 2021, 7:23am UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/5 "2021-09-10T07:23:37Z")

</div>

thanks. that helps

---

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 27, 2021, 12:20pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/6 "2021-09-27T12:20:14Z")

</div>

Hi @kjweimer

I started using pylance/pyright and get errors when I try to use `ImageLike`

```auto
from itk.support.types import ImageLike

def identity(x: ImageLike) -> ImageLike:
    return x

```

Pyright says:

> Expected class type but received “Unknown | Type[ndarray] | Literal[‘itk.ImageBase’]”  
> “Literal[‘itk.ImageBase’]” is not a class

`mypy` does not complain. I don’t understand enough of typing.Literal to figure out why it fails for pylance. Is there a type annotation with the same meaning as `ImageLike` that I could use with pylance (e.g. in vscode)?

Specs:  
Windows 10, Python 3.6, itk 5.2

---

<div class="post-metadata">

**Author:** ![kjweimer](https://discourse.itk.org/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@kjweimer](https://discourse.itk.org/u/kjweimer)\
**Post date:** [September 27, 2021, 7:54pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/7 "2021-09-27T19:54:58Z")

</div>

Hello @dyoll !  
Unfortunately, it seems that the ITK package does not work well with strict type checkers. This is primarily due to the dynamic module generation that is done which means classes like `itk.Image` are not availiable before the code is ran.  
The `itk.ImageLike` type annotation includes literal strings that can make sense to a user but not to the type checker causing the issue.  
You could construct annotations that are similar to those given from ITK but that are compatible with pylance:

```auto
from typing import Any, Union
from itk.itkImagePython import itkImageBase2
from numpy import dtype
from numpy import ndarray as ArrayLike

itkImage = Union[ArrayLike[dtype[Any], dtype[Any]], itkImageBase2]

def identity(x: itkImage) -> itkImage:
    return x

```

However this solution would require you to add another `itkImageBase<Dimension>` variable for each dimension that you would like to support.  
You would also need to ignore the `reportMissingTypeStubs` warning from Pylance, as stubs do not exist for the `itkImagePython` file.  
Let me know if this works for you, if not I can try to look into something else.

---

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 28, 2021, 6:58am UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/8 "2021-09-28T06:58:30Z")

</div>

Hi @kjweimer

Thanks for the suggestion. I tried it but unfortunately it doesn’t work well in combination with the ITK python interface, e.g.

```auto
def as_array(img: Union[itkImageBase2, itkImageBase3]):
  return itk.array_from_numpy(img)

```

yields following error:

> Argument of type “itkImageBase2 | itkImageBase3” cannot be assigned to parameter “image\_or\_filter” of type “Literal[‘itk.ImageBase’, ‘itk.ImageSource’]” in function “GetArrayFromImage”  
> Type “itkImageBase2 | itkImageBase3” cannot be assigned to type “Literal[‘itk.ImageBase’, ‘itk.ImageSource’]”  
> Type “itkImageBase2” cannot be assigned to type “Literal[‘itk.ImageBase’, ‘itk.ImageSource’]”  
> “itkImageBase2” cannot be assigned to type “Literal[‘itk.ImageBase’]”  
> “itkImageBase2” cannot be assigned to type “Literal[‘itk.ImageSource’]”  
> Type “itkImageBase3” cannot be assigned to type “Literal[‘itk.ImageBase’, ‘itk.ImageSource’]”  
> “itkImageBase3” cannot be assigned to type “Literal[‘itk.ImageBase’]”  
> “itkImageBase3” cannot be assigned to type “Literal[‘itk.ImageSource’]”

And following code:

```auto
def resample(img: Union[itkImageBase2, itkImageBase3], target_spacing: Optional[Sequence] = None) -> Union[itkImageBase2, itkImageBase3]:
    dim = img.GetImageDimension()
    interpolator = itk.LinearInterpolateImageFunction.New(img)
    transform = itk.IdentityTransform[itk.D, dim].New()
    ...
    resampled = itk.resample_image_filter(
    ...

```

gives following errors:

> “LinearInterpolateImageFunction” is not a known member of module  
> “IdentityTransform” is not a known member of module  
> “resample\_image\_filter” is not a known member of module

It seems using pyright is not compatible with itk. Are there any plans to go in that direction? Would it help if itk would ship type stubs (I did not find any pyi files)?  
Or would you recommend that I stick to `mypy`, which seems to either skip checking the code, or understand the dynamic types better?

---

<div class="post-metadata">

**Author:** ![kjweimer](https://discourse.itk.org/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@kjweimer](https://discourse.itk.org/u/kjweimer)\
**Post date:** [September 28, 2021, 6:43pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/9 "2021-09-28T18:43:07Z")

</div>

@dyoll Sorry about that.  
I think you are correct in that the current state of ITK is not compatible with Pyright. Unfortunately, you may have to disable it for now.  
My current work includes creating code to generate the type stub (pyi) files for ITK. I am not sure when this will be released but it is getting close to complete. However I am still unsure if ITK will become compatible with Pyright after this change, I will need to add some testing to see if it will be possible.  
I would recommend that you use `mypy` for the meantime until the type stub code change is released.  
Best,  
Kian

---

<div class="post-metadata">

**Author:** ![dyoll](https://discourse.itk.org/user_avatar/discourse.itk.org/dyoll/32/2311_2.png) [@dyoll](https://discourse.itk.org/u/dyoll)\
**Post date:** [September 28, 2021, 7:06pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/10 "2021-09-28T19:06:59Z")

</div>

Hi @kjweimer

Thanks. That sounds promising. In case it helps to set up CI, here is some github action yaml code to run pyright:

```auto
      - uses: actions/setup-node@v2
        with:
          node-version: '16'
      - name: static analysis
        working-directory: my_project
        run: |
          npm install pyright
          pyright 

```

In my repo I added a file called `pyrightconfig.json` with following content:

```auto
{
    "include": [
        "src/",
        "tests/",
    ],
    "exclude": [
        "docs/",
    ],
    "useLibraryCodeForTypes": true,
    "reportPrivateImportUsage": false,
    "reportMissingImports": "warning"
}

```

Thanks, Bryn

---

<div class="post-metadata">

**Author:** ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)\
**Post date:** [October 27, 2021, 1:08pm UTC](https://discourse.itk.org/t/type-annotations-and-itk-image/4407/11 "2021-10-27T13:08:30Z")

</div>

Hi,

> from itk.support.types import ImageLike

> Expected class type but received “Unknown | Type[ndarray] | Literal[‘itk.ImageBase’]”  
> “Literal[‘itk.ImageBase’]” is not a class

> n | Type[ndarray] | Literal[‘itk.ImageBase’]”, “Literal[‘itk.ImageBase’]” is not a class

> Specs:  
> Windows 10, Python 3.6, itk 5.2

The `itk.support.types` uses forward references, and CPython introduced fixes for forward references and other typing fixes in more recent versions. The Literal types mentioned in the error are [supported in Python 3.8](https://www.python.org/dev/peps/pep-0586/). It may help to use a more recent version of CPython. `itk-5.3rc2`, will have Python 3.10 support, which has the best typing support.
