Use of paratheses symbols in django-viewflow flow

106 Views Asked by At

I have been at a loss understanding the use of parentheses in django-viewflow flow code. For example in the code below

start = (
    flow.Start(views.StartView)
    .Permission('shipment.can_start_request')
    .Next(this.split_clerk_warehouse)
)

# clerk
split_clerk_warehouse = (
    flow.Split()
    .Next(this.shipment_type)
    .Next(this.package_goods)
)

from here

It seems as though, a tuple containing functions is assigned to start and to split_clerk_warehouse e.t.c. What does it mean. From my best guess it would seem that the .Next functions accept a tuple as input.

NOTE I do understand the method chaining used here. I am just at a loss to understand the use of braces.

Thanks.

1

There are 1 best solutions below

0
On BEST ANSWER

If I understand correctly, you wonder what the use is of the outer brackets.

Let us first write the (first, but applicable to the second) statement without outer brackets:

start = flow.Start(views.StartView).Permission('shipment.can_start_request').Next(this.split_clerk_warehouse)

This is exactly equivalent to code in your sample. But you probably agree that this is quite unreadable. It requires a user to scroll over the code, and furthermore it is a long chain of characters, without any structure. A programmer would have a hard time understanding it, especially if - later - we would also use brackets inside the parameters of calls.

So perhaps it would make sense to write it like:

start = flow.Start(views.StartView).
             Permission('shipment.can_start_request').
             Next(this.split_clerk_warehouse)

But this will not work: Python is a language that uses spacing as a way to attach semantics on code. As a result it will break: Python will try to parse the separate linkes as separate statements. But then what to do with the tailing dot? As a result the parser would error.

Now Python has some ways to write statements in a multi-line fashion. For example with backslashes:

start = flow.Start(views.StartView). \
             Permission('shipment.can_start_request'). \
             Next(this.split_clerk_warehouse)

with the backslash we specify that the next line actually belongs to the current one, and thus it is parsed like we wrote this all on a single line.

The disadvantage is that we easily can forget a backslash here, and this would again let the parser error. Furthermore this requires linear work: for every line we have to add one element.

But programming languages actually typically have a feature that programmers constantly use to group (sub)expressions together: brackets. We use it to give precedence (for example 3 * (2 + 5)), but we can use it to simply group one expression over multiple lines as well, like:

start = (
    flow.Start(views.StartView)
    .Permission('shipment.can_start_request')
    .Next(this.split_clerk_warehouse)
)

Everything that is within the brackets belongs to the same expression, so Python will ignore the new lines.

Note that tuple literals also use brackets. For example:

()              # empty tuple
(1, )           # singleton tuple (one element)
(1, 'a', 2, 5)  # 4-tuple

But here we need to write a comma at the end for a singleton tuple, or multiple elements separated by comma's , (except for the empty tuple).