home / github / issue_comments

Menu
  • Search all tables
  • GraphQL API

issue_comments: 1563318598

This data as json

html_url issue_url id node_id user created_at updated_at author_association body reactions issue performed_via_github_app
https://github.com/simonw/datasette/issues/2078#issuecomment-1563318598 https://api.github.com/repos/simonw/datasette/issues/2078 1563318598 IC_kwDOBm6k_c5dLllG 9599 2023-05-25T18:17:03Z 2023-05-25T18:21:25Z OWNER

I think I want that to return (is_callable, is_async) - so I can both test if the thing can be called AND if it should be awaited in the same operation (without any exceptions).

I tried this: ```python def is_callable(obj): "Returns (is_callable, is_async_callable)" if not callable(obj): return False, False

if isinstance(obj, types.FunctionType):
    return True, asyncio.iscoroutinefunction(obj)

if hasattr(obj, '__call__'):
    return True, asyncio.iscoroutinefunction(obj.__call__)

return False, False

python for thing in ( async_func, non_async_func, AsyncClass(), NotAsyncClass(), ClassNoCall(), AsyncClass, NotAsyncClass, ClassNoCall ): print(thing, is_callable(thing)) And got: <function async_func at 0x1073d5120> (True, True) <function non_async_func at 0x1073d5080> (True, False) <main.AsyncClass object at 0x106cce490> (True, True) <main.NotAsyncClass object at 0x106ccf710> (True, False) <main.ClassNoCall object at 0x106ccc810> (False, False) <class '__main__.AsyncClass'> (True, True) <class '__main__.NotAsyncClass'> (True, False) <class '__main__.ClassNoCall'> (True, False) `` Which is almost right, but I don't like thatAsyncClassis shown as callable (which it is, since it's a class) and awaitable (which it is not - thecall` method may be async but calling the class constructor is not).

So I'm going to detect classes using isinstance(obj, type).

```python def is_callable(obj): "Returns (is_callable, is_async_callable)" if not callable(obj): return False, False

if isinstance(obj, type):
    # It's a class
    return True, False

if isinstance(obj, types.FunctionType):
    return True, asyncio.iscoroutinefunction(obj)

if hasattr(obj, '__call__'):
    return True, asyncio.iscoroutinefunction(obj.__call__)

assert False, "obj {} somehow is callable with no __call__ method".format(obj)

`` I am reasonably confident theAssertionError` can never be raised.

And now: <function async_func at 0x1073d5120> (True, True) <function non_async_func at 0x1073d5080> (True, False) <__main__.AsyncClass object at 0x106ccfa50> (True, True) <__main__.NotAsyncClass object at 0x106ccc8d0> (True, False) <__main__.ClassNoCall object at 0x106cd7690> (False, False) <class '__main__.AsyncClass'> (True, False) <class '__main__.NotAsyncClass'> (True, False) <class '__main__.ClassNoCall'> (True, False) Which is what I wanted.

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
1726236847  
Powered by Datasette · Queries took 1.045ms · About: github-to-sqlite