This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add a new functools.cast() function
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, daniel.ugra, rhettinger
Priority: normal Keywords:

Created on 2019-11-29 11:30 by daniel.ugra, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg357640 - (view) Author: Ugra Dániel (daniel.ugra) Date: 2019-11-29 11:30
In some cases it would be really helpful to have a decorator which automagically casts returned value to a different type.

Particularly, instead of writing something like this:

def example():
    result = []

    for ...:
        result.append(item)

    return result

...this would do the magic:

@functools.cast(list)
def example():
    for ...:
        yield item

On the positive side (apart from its compactness) when an implementation changes from list to set, .append() does not need to be changed to .add().

Of course on the caller side one can always write list(example()) but sometimes this transformation needs to be done on implementation side for architectural reasons.

Pseudocode for proposed functools.cast():

def cast(type):
    def wrapper(func):
        @wraps(func)
        def newfunc(*args, **keywords):
            return type(func(*args, **keywords))

        return newfunc

    return wrapper
msg357641 - (view) Author: Ugra Dániel (daniel.ugra) Date: 2019-11-29 11:31
Currently, the closest functionality I can think of (using standard library functions only):

@functools.partial(lambda func: functools.wraps(func)(lambda *args, **keywords: list(func(*args, **keywords))))

Or without proper wrapping:

@functools.partial(lambda func: lambda *args, **keywords: list(func(*args, **keywords)))
msg357648 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2019-11-29 18:02
First off, thanks for the suggestion!

But there are two things to say about this. One, that isn't actually casting as Python doesn't have the concept of casting like in statically typed languages since everything is dynamically typed.

Two, the solution is so short and simple but not widely needed enough that I don't think this warrants addition in the stdlib. And since you're changing what the function returns you probably need a new docstring anyway, which means having to do a normal wrapping of the function.

So thanks for the idea but I don't think we will be adding this to the stdlib (obviously feel free to put this up on PyPI or as a gist somewhere and share it in a blog post or something.
History
Date User Action Args
2022-04-11 14:59:23adminsetgithub: 83121
2019-11-29 18:02:32brett.cannonsetstatus: open -> closed

nosy: + brett.cannon
messages: + msg357648

resolution: rejected
stage: resolved
2019-11-29 15:41:32pablogsalsetnosy: + rhettinger
2019-11-29 11:31:20daniel.ugrasetmessages: + msg357641
2019-11-29 11:30:18daniel.ugracreate