Black: Strange formatting of fluent interface

Created on 17 Oct 2018  路  4Comments  路  Source: psf/black

Operating system: Mac
Python version: 3.7
Black version: 18.9b0
Does also happen on master:

Following on https://twitter.com/llanga/status/1052631100290420736

I have a code which uses yarl.URL

a = str(
    my_very_very_very_long_url_name
    .with_user(and_very_long_username)
    .with_password(and_very_long_password)
)

Black formats it like this

a = str(
    my_very_very_very_long_url_name.with_user(and_very_long_username).with_password(
        and_very_long_password
    )
)

I understand that first call is not on a new line because of reasons, but the rest still looks quite odd, especially considering that when there are three calls in the chain, Black produces

a = str(
    my_very_very_very_long_url_name.with_user(and_very_long_username)
    .with_user(and_very_long_username)
    .with_password(and_very_long_password)
)
design

Most helpful comment

Forgive me for using this as the fluent questions thread, but another case:

With a single call

def x():
    base_ds["security_score_filtered"] = base_ds["security_score_risk_adj"].where(
        base_ds["is_share_price_valid"]
        & base_ds["is_market_cap_valid"]
        & base_ds["is_liquid"]
    )

With two calls

def x():
    base_ds["security_score_filtered"] = (
        base_ds["security_score_risk_adj"]
        .where(
            base_ds["is_share_price_valid"]
            & base_ds["is_market_cap_valid"]
            & base_ds["is_liquid"]
        )
        .sum()  # <- new line here (only change)
    )

Why the switch of the first line between the two?

I would generally prefer the second format even without the second call (though the question stands independent of my opinion)

All 4 comments

Forgive me for using this as the fluent questions thread, but another case:

With a single call

def x():
    base_ds["security_score_filtered"] = base_ds["security_score_risk_adj"].where(
        base_ds["is_share_price_valid"]
        & base_ds["is_market_cap_valid"]
        & base_ds["is_liquid"]
    )

With two calls

def x():
    base_ds["security_score_filtered"] = (
        base_ds["security_score_risk_adj"]
        .where(
            base_ds["is_share_price_valid"]
            & base_ds["is_market_cap_valid"]
            & base_ds["is_liquid"]
        )
        .sum()  # <- new line here (only change)
    )

Why the switch of the first line between the two?

I would generally prefer the second format even without the second call (though the question stands independent of my opinion)

Adding another here, as a (hopefully) helpful additional case:

From:

    df = (
        gbq
        .read_gbq(query, project="sixty-capital-prod")
        .sort_values("factset_entity_id")
    )

To:

    df = gbq.read_gbq(query, project="sixty-capital-prod").sort_values(
        "factset_entity_id"
    )

And another:

Looks good:

                completion_time = (
                    a.read_namespaced_job(job.metadata.name, namespace="default")
                    .status()
                    .completion_time()
                )

Now without the () on the last two lines after status & completion_time :

                completion_time = a.read_namespaced_job(
                    job.metadata.name, namespace="default"
                ).status.completion_time

I would prefer that black applies the fluent style across more cases of chained calls and attribute accesses, such as those examples provided above, even if it does use a few more lines. Consistency between these similar multi-line expressions is more valuable to me than removing a few extra lines.

Was this page helpful?
0 / 5 - 0 ratings