4

a type warning started popping up today in some of my code after I upgraded the version of mypy that I was using. There doesnt seem to be too much literature on the subject, so hoping someone here can help me out!

I have a MetaClass defined like the following...

 from __future__ import annotations


 class MyMetaClass(type):                                                                                                                                

     def __new__(mcs,                                                                  
                 name: str,                                                            
                 bases: Tuple[type, ...],                                              
                 namespace: Dict[str, Any],                                                                                     
                 ) -> MyMetaClass:                                             

         # Custom code... doesnt matter
         # ...
         # ...

         return type.__new__(mcs, name, bases, namespace)

Today, mypy started spitting out the following error...

error: Incompatible return value type (got "type", expected "MyMetaClass")

Ive tried the following iterations of the return statement, all with no success...

return super().__new__(mcs, name, bases, namespace)
return super(MyMetaClass, mcs).__new__(mcs, name, bases, namespace)

Any suggestions on how to get around this warning? I ended up settling for a cast... but it feels like there has to be something better.

return cast(MyMetaClass, super().__new__(mcs, name, bases, namespace))
ruohola
  • 21,987
  • 6
  • 62
  • 97
wakey
  • 2,283
  • 4
  • 31
  • 58
  • Just to be clear, does your class's source file begin with `from __future__ import annotations` to allow you to postpone annotation evaluation in the first place? – ShadowRanger Sep 26 '19 at 19:47
  • I strongly suspect this is actually a duplicate of [Can you annotate return type when value is instance of cls?](https://stackoverflow.com/q/39205527/364696). Not 100% though, can you try out the solution there? – ShadowRanger Sep 26 '19 at 20:04
  • @ShadowRanger yes it does! Will include it in the snippet above On your other suggestion, I'm still getting an error if I use a ```T = TypeVar('T', bound='MyMetaClass')```, now its ```Incompatible return value type (got "type", expected "T")``` – wakey Sep 30 '19 at 13:40

1 Answers1

0

The problem is that you didn't annotate the mcs parameter, so it's impossible to know what type super().__new__ will return.

Neil G
  • 32,138
  • 39
  • 156
  • 257
  • 1
    Hey Niel -- good to revisit this. In my copy of `python 3.11.1` mypy no longer complains about the above snippet. I'm assuming whatever underlying issue has since been fixed since Sept 2019. – wakey Jul 24 '23 at 05:12
  • 1
    @wakey Oh that makes sense, they probably implicitly type the first parameter to be `type[Self]` or something. Anyway, thanks for your question. I had to look this up, and this was the first hit. – Neil G Jul 24 '23 at 07:12