-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inherit type signature from another method #2003
Comments
That'd be a useful thing to be able to do! I don't think there's a good way to do it right now, or in the existing PEP 484 type system. But this has a lot in common with the discussion of keyword arguments in python/typing#239 , in the context of higher-order functions. Do you think you'd be able to use the proposal there to do what you want? |
None of the proposed approaches seem to quite do the right thing. I've thought about this previously, and if we had types for "dicts as structs" we could perhaps use those for
|
@sixolet's proposal seems reasonable, but I think this is slightly different. In this case, we actually need to do some merging of arguments. For example, it'd also be totally valid for me to do this: def request(method: str, url: str, data: Optional[Dict[str, Any]]=None, headers: Optional[Dict[str, str]]=None) -> Response:
pass
def post(data: Optional[Dict[str, Any]]=None, *args, **kwargs) -> Response:
return request('post', data=data, *args,**kwargs) My ideal would be to have an annotation, something akin to the existing def request(method: str, url: str, data: Optional[Dict[str, str]]=None, headers: Optional[Dict[str, str]]=None) -> Response:
pass
@inherit_signature(request)
def post(data: Optional[Dict[str, Any]]=None, *args, **kwargs) -> Response:
new_data = {k: str(v) for k, v in data.items()}
return request('post', data=new_data, *args,**kwargs)
post() # Missing required parameter `url`
post('foo', headers={'abc': 123'}) # Wrong type for headers
post('foo') # OK
post('foo', data={'abc': 123}) # OK
post('foo', bad_param=roflcopter) # Unexpected parameter `bad_param` And in this case |
@JukkaL For "Dict as struct" types take a look at Shapes from Hack - https://docs.hhvm.com/hack/shapes/introduction |
With my proposal you can do something like this: T = TypeVar('T')
R = TypeVar('R')
def curry(fix: T, f: Callable[[T, OtherArgs], R]) -> Callable[[OtherArgs], R]:
def inner(*args, **kwargs):
return f(fix, *args, **kwargs)
return inner
def request(...): ... # Like you defined it
post = curry('post', request) I still have no good answer about typechecking the body of I understand that this isn't what you asked for -- you asked for a way to make an explicit definition of |
Oh, I think I did not understand your concept of "merging" -- |
@rowillia Thanks for the link. I was aware that Hack has something like that but didn't remember the details. |
@sixolet Currying would be a good start, but not sufficient. For example - https://github.com/kennethreitz/requests/blob/master/requests/api.py#L55-L56 |
Is there a way to inherit a type signature from another method? The most common use case for this is when we've got some convenience method like
requests.post
Below is a super simple version of https://github.com/kennethreitz/requests/blob/master/requests/api.py#L99 which eventually calls down into https://github.com/kennethreitz/requests/blob/master/requests/sessions.py#L397
Ideally I wouldn't have to copy and paste the type signature of
request
intopost
.The text was updated successfully, but these errors were encountered: