1

I often have a situation where I make the assignment with exec, like so:

 ...
 exec(
     "someClassInstance = someMapper({someInfo})".format(someInfo=someInfo),
     globals(),
 )

Where someClassInfo is an instance of SomeClass. and then I use someClassInstance, like so:

...
someVar = someClassInstance.someMethod()  # type: ignore

All of that works just fine and I accomplish what I want.

But, from a reading perspective and from the IDE's (in my case, emacs+pyright) perspective, the (non-run-time) type of someClassInstance is not known.

So, I add that "# type: ignore".

But, instead, I want to somehow use python 3's type hinting to make it known that someClassInstance is of type SomeClass (or one of its ancestors).

Is that possible?

Mohsen Banan
  • 85
  • 1
  • 5
  • 2
    It would almost certainly be better to *not* use `exec` to create the instance in the first place, even without bringing type-hinting into the mix. – chepner Oct 07 '21 at 22:41
  • For example, 'SomeClass' is coming in as a string from the command-line. And it needs to be created with exec. It is not a question of "better to not use". – Mohsen Banan Oct 08 '21 at 00:35
  • 1
    You don't need `exec` for this. `someClassInstance = getattr(__main__, cls)()`. Even better, `d = {'SomeClass': SomeClass}; someClassInstance = d[cls]()`. – chepner Oct 08 '21 at 01:02
  • 1
    If you don't find out the value of `cls` until runtime, you can't provide a *static* type hint for `someClassInstance`. – chepner Oct 08 '21 at 01:04
  • I may not know the value of cls until runtime, but I know its ancestors, and if I knew how, I could provide a static type hint for that ancestor; for example. – Mohsen Banan Oct 08 '21 at 01:51

1 Answers1

0

If you type

cast(type, value1)

then the result will be exactly the same as value, but you have told the type checker that its type is the indicated type, and that it just has to believe you.

From the documentation:

typing.cast(typ, val)

Cast a value to a type.

This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don’t check anything (we want this to be as fast as possible).

Frank Yellin
  • 9,127
  • 1
  • 12
  • 22
  • Back to the example. What we want to cast is ```someClassInstance``` which is assigned with exec. So, it is undefined. – Mohsen Banan Oct 11 '21 at 21:25
  • If I was to do a ```typing.cast(SomeClass, someClassInstance)``` I would get a "someClassInstance is undefined". You see, the title says: "After exec Assignment". – Mohsen Banan Oct 11 '21 at 21:34
  • After some experimentation, I think there is something that works. I can put a: ```global someClassInstance; someClassInstance = typing.cast(SomeClass, None)``` before the exec() block. But is this the best way? – Mohsen Banan Oct 12 '21 at 01:38