folkerschamel,
@folkerschamel@mastodon.social avatar

@ketmorco @zenforyen @diazona @bk1e @askonomm @cazabon @ado @kevin

This unsolved challenge bugs me:
How can I add type hints to the following class

class D:
def init(self, t):
self._t = t
def getattr(self, n):
def m(*args):
print("a")
getattr(self._t, n)(*args)
print("b")
return m

so that can detect type bugs like the following?

class Q:
def f(self, x: int):
print(x)
q = Q()
d = D(q)
d.f(2.0)

ketmorco,
@ketmorco@fosstodon.org avatar

@folkerschamel @zenforyen @diazona @bk1e @askonomm @cazabon @ado @kevin

My answer is perhaps somewhat snarky, but: don't.

Typing, like tests, are a tool to communicate. If you can't write a meaningful test, don't. And if you can't provide a meaningful type, don't.

The only thing worse than no test is a bad test, and the only thing worse than not having type hints is having bad ones.

If a hint doesn't tell the caller something important, then it's not a hint, it's just noise and lies.

bk1e,
@bk1e@mastodon.social avatar

@folkerschamel @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin Is this what your create_wrapper_for_handing_over_to_thread_pool does? I meant to ask.

It seems like the type system can describe forwarding individual functions/methods but cannot yet describe an object that forwards all attributes/methods to another object.

folkerschamel,
@folkerschamel@mastodon.social avatar
orsinium,
@orsinium@fosstodon.org avatar

@folkerschamel @ketmorco @zenforyen @diazona @bk1e @askonomm @cazabon @ado @kevin

If I understand correctly what this code does, you can't. Proxy types aren't natively supported by Python typing, at least not without dirty hacks:

https://github.com/python/mypy/issues/5523

folkerschamel,
@folkerschamel@mastodon.social avatar

@orsinium @ketmorco @zenforyen @diazona @bk1e @askonomm @cazabon @ado @kevin

It seems that the case I describe is even harder, since both https://github.com/python/mypy/issues/5523 and https://github.com/python/mypy/issues/2087 seem to be only about proxies for accessing attributes, not methods, right?

What would be a dirty hack?

I can imagine (ugly) solutions by forcing the user to define an interface base class for Q and creating a factory function for D, as indicated in https://mastodon.social/@folkerschamel/110888560820113321 ...

orsinium,
@orsinium@fosstodon.org avatar

@folkerschamel @ketmorco @zenforyen @diazona @bk1e @askonomm @cazabon @ado @kevin

A dirty hack I can think of right away is to lie about types:

d: Q = D(q) # type: ignore

Or make a constructor to ignore type error in only one place:

T = TypeVar('T')
def new_d(q: T) -> T:
return D(q) # type: ignore

bk1e,
@bk1e@mastodon.social avatar

@orsinium @folkerschamel @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin You can also use typing.cast() to lie about types. I've used this to substitute fake implementations of classes in tests.

One case this doesn't handle well is a wrapper that has attributes/methods of its own. If you lie and say an instance of D is actually an instance of Q, then you can't call D-specific methods on a Q without casting back to D.

folkerschamel,
@folkerschamel@mastodon.social avatar

@bk1e @orsinium @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin

You could define an interface class returned by the wrapper factory function. But it seems at some point you still have to lie about the type.

bk1e,
@bk1e@mastodon.social avatar

@folkerschamel @orsinium @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin Could the proxy inspect the attribute to determine whether it's a method or something else?

folkerschamel,
@folkerschamel@mastodon.social avatar

@bk1e @orsinium @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin

You mean at runtime or at static-type-check time?

bk1e,
@bk1e@mastodon.social avatar

@folkerschamel @orsinium @ketmorco @zenforyen @diazona @askonomm @cazabon @ado @kevin At runtime, if the attribute value is callable, wrap it with a wrapper function, else return the original attribute value. I think the type hints for the wrapper function should be similar to those for a decorator.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • python
  • ngwrru68w68
  • rosin
  • GTA5RPClips
  • osvaldo12
  • love
  • Youngstown
  • slotface
  • khanakhh
  • everett
  • kavyap
  • mdbf
  • DreamBathrooms
  • thenastyranch
  • magazineikmin
  • anitta
  • InstantRegret
  • normalnudes
  • tacticalgear
  • cubers
  • ethstaker
  • modclub
  • cisconetworking
  • Durango
  • provamag3
  • tester
  • Leos
  • megavids
  • JUstTest
  • All magazines