2020-12-13

11: Mending Any mypy Stub in the 'typeshed' Repository

<The previous article in this series | The table of contents of this series | The next article in this series>

There may be some mistakes in the 'typeshed' repository. Here is how to mend them.

Topics


About: the Python programming language
About: mypy

The table of contents of this article


Starting Context


  • The reader has a basic knowledge on the Python programming language.
  • The reader has a basic knowledge on mypy.

Target Context


  • The reader will know how to mend any mypy stub in the 'typeshed' repository.

Orientation


The minimum sufficient technique for doing static type checking in Python with mypy has been introduced in a previous article.


Main Body


1: The Stub for 'memoryview' Seems to Be Mistaken, as of mypy 0.782


Hypothesizer 7
This code is flagged by mypy 0.782.

@Python Source Code

class ClassA:
	def methodA (a_this: "ClassA", a_memoryView: memoryview) -> None:
		a_memoryView [0] = 1


The message is this.

@Output
error: No overload variant of "__setitem__" of "memoryview" matches argument types "int", "int"
note: Possible overload variants:
note:     def __setitem__(self, slice, memoryview) -> None
note:     def __setitem__(self, int, bytes) -> None
note:     def __setitem__(self, slice, Sequence[bytes]) -> None

. . . Really?

'def __setitem__(self, int, bytes) -> None' seems odd to me: while the 2nd argument should be the index where the datum (pointed by the 3rd argument) is meant to be put, should the 3rd argument be 'bytes'? That construct is promoting code like 'a_memoryView [0] = b'ABC'', which, of course, would cause a run-time error.

I think that '__setitem__(self, int, int)' should be allowed.


2: Some Mistakes Can Sneak In There Because . . .


Hypothesizer 7
Some mistakes can sneak into the 'typeshed' repository, because the stubs there are hand-made retrofits: they are not any part of the source code or deterministically derived from the source code.


3: There Does Not Seem to Be Any Way to Mend the Stub By Adding an Overriding Stub File


Hypothesizer 7
My 1st expectation was that I could add a correct stub file that takes precedence over the 'typeshed' repository, at an arbitrary location.

That way would let me distribute the correct stub with my project.

Unfortunately, that seems not being allowed.


4: A Way: Directly Mending the Stub File


Hypothesizer 7
As the stub file is a text file under the 'Lib/site-packages/mypy/typeshed' directory in the Python product directory, I can directly mend the file.

For 'memoryview', the file is 'stdlib/2and3/builtins.pyi'.

A disadvantage of the way is that each development environment has to be mended separately.


5: Another Way: Having a Custom 'typeshed' Repository


Hypothesizer 7
Although I cannot override the default 'typeshed' repository with an added file at an arbitrary location, I can replace the whole default 'typeshed' repository with a whole custom 'typeshed' repository.

What I have to do is to copy the default 'typeshed' repository directory to somewhere (which is the custom 'typeshed' repository directory), mend some stub files under the custom 'typeshed' repository directory, and specify the custom 'typeshed' repository directory with the '--custom-typeshed-dir' flag in the 'mypy' command.

An advantage of the way is that I can distribute the custom 'typeshed' repository with my project (my build script will automatically use the custom 'typeshed' repository).

A disadvantage of the way is that I have to maintain the custom 'typeshed' repository update with mypy updates.


6: A Dirty End Run for My Case


Hypothesizer 7
In fact, my real case was when I created a 'wx.DataObject' subclass for clipboard handling: the 'GetDataHere' method takes a 'memoryview' argument.

My dirty end run is to use 'bytearray' instead of 'memoryview' as the type annotation, which works only because wxPython is excluded from my mypy checking (as wxPython does not provide the stubs).

Or a more undesirable end run is to use the 'Any' type, disabling type checking for the argument.


References


<The previous article in this series | The table of contents of this series | The next article in this series>