On Wednesday, April 25, 2018, Łukasz Langa <luk...@langa.pl> wrote: > > On 25 Apr, 2018, at 5:20 PM, Chris Angelico <ros...@gmail.com> wrote: > > On Thu, Apr 26, 2018 at 10:11 AM, Yury Selivanov > <yselivanov...@gmail.com> wrote: > > Just yesterday this snippet was used on python-dev to show how great the > new syntax is: > > my_func(arg, buffer=(buf := [None]*get_size()), size=len(buf)) > > To my eye this is an anti-pattern. One line of code was saved, but the > other line becomes less readable. The fact that 'buf' can be used after > that line means that it will be harder for a reader to trace the origin of > the variable, as a top-level "buf = " statement would be more visible. > > > Making 'buf' more visible is ONLY a virtue if it's going to be used > elsewhere. Otherwise, the name 'buf' is an implementation detail of > the fact that this function wants both a buffer and a size. > > > You're claiming that `:=` is nicer in this situation because it's less > prominent than regular assignment and thus doesn't suggest that the name > stays visible later. > > But as others said, `:=` *does* make the name visible later until the > enclosing scope ends. In fact, a large part of its appeal is that you > can use the result later (as in the `re.search()` example). Will it be > visible enough to the reaser in those cases then? > > There seems to be a conflict there. > > The question of assignment visibility also makes me think about > unintentional name shadowing:: > > buf = some_value > > ... # 20 lines > > my_func(arg, buffer=(buf := [None]*get_size()), size=len(buf)) > > ... # 20 lines > > buf # <-- What value does this have? > > > Even if we're not using the call pattern, there can be plenty of logic > tests which aren't very obvious:: > > buf = some_value > > ... # 20 lines > > if node.parent is not None and (buf := node.parent.buffer): > ... # 10 lines > > ... # 20 lines > > buf # <-- What value does this have? > > > This is even more interesting because now `buf` isn't rebound > *always*. > > So if I'm confused about an unexpected change in value of `buf`, I'll > skim the code, fail to find the assignment, and then grep for `buf =` > and also fail to find the assignment. Yes, I could have searched for > just `buf` instead but that will give me too many false positives, > especially if I'm using a primitive text editor search or don't know > about \b in regular expressions. > > Debugging this can be confusing. I know it can since a similar > annoyance can be observed with the magic pseudo-scope of `except`:: > > err = some_value > try: > ... > except Error as err: > ... > > err # <-- now sometimes it's not defined > > > Just like Barry, I debugged a few cases of this in the past and within > larger functions this can be hard to find. >
Would this make it easier to put too much code on one line? Is there a good way to get *branch coverage* stats instead of just *line coverage*? Someone can probably explain with some tested pretty code for me why this would be necessary or helpful; why it wouldn't make line coverage stats more misleading for the sake of lazy? > > -- Ł > >
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com