refurb icon indicating copy to clipboard operation
refurb copied to clipboard

[Enhancement]: functools partial

Open sbrugman opened this issue 1 year ago • 1 comments

Overview

The following pattern I've seen being used for returning a new function based on another function with prefilled variables:

lambda x: _parse_features(
   x, 
   context_manifest, 
   sequence_manifest
)

functools.partial exactly does this, without needing the lambda to pass the input argument again.

from functools import partial

partial(
   _parse_features, 
   context_manifest=context_manifest, 
   sequence_manifest=sequence_manifest,
)

Somewhat related to this rule, although there we can remove the whole statement, and here only the input argument.

Proposal

Could this rule be included in refurb? There is already a functools section.

sbrugman avatar Sep 22 '23 07:09 sbrugman

The rule you mentioned is similar to FURB111 as it detects lambdas where the arguments are passed verbatim, making the lambda redundant.

Adding detection for partial would be good, and there is already an issue open for it (see #173). I haven't had any concrete examples of code that Refurb should replace with partial though, so it's been hard to create a rule for it since I don't know what Refurb should be looking for. Having this code snippet helps.

In general, I think we can replace the following examples:

lambda x: f(1, x)

lambda x: f(x, y=y)

lambda x, *y, **z: f(1, x, *y, **z)

With this:

partial(f, 1)

partial(f, y=y)

partial(f, 1)

My only concern is that lambdas restrict the amount and types of arguments you can pass it, while partial will allow any extra args/kwargs, which might not be desirable. I think this would be good to add regardless, and people can decide to turn it off if they desire.

dosisod avatar Sep 22 '23 19:09 dosisod