Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #101497 > unrolled thread

I'm missing something here...

Started bySkip Montanaro <skip.montanaro@gmail.com>
First post2016-01-11 17:26 -0600
Last post2016-01-12 11:46 -0600
Articles 5 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  I'm missing something here... Skip Montanaro <skip.montanaro@gmail.com> - 2016-01-11 17:26 -0600
    Re: I'm missing something here... sohcahtoa82@gmail.com - 2016-01-11 16:31 -0800
      Re: I'm missing something here... Skip Montanaro <skip.montanaro@gmail.com> - 2016-01-11 19:04 -0600
      Re: I'm missing something here... Ian Kelly <ian.g.kelly@gmail.com> - 2016-01-12 09:03 -0700
      Re: I'm missing something here... Skip Montanaro <skip.montanaro@gmail.com> - 2016-01-12 11:46 -0600

#101497 — I'm missing something here...

FromSkip Montanaro <skip.montanaro@gmail.com>
Date2016-01-11 17:26 -0600
SubjectI'm missing something here...
Message-ID<mailman.26.1452554821.13488.python-list@python.org>
Here's a dumb little bit of code, adapted from a slightly larger script:

#!/usr/bin/env python

"dummy"

import glob
import os

def compare_prices(*_args):
    "dummy"
    return set()

def find_problems(cx1, cx2, cx3, prob_dates):
    "dummy"
    for fff in sorted(glob.glob("/path/to/*.nrm")):
        sym = os.path.splitext(os.path.basename(fff))[0]
        prob_dates |= compare_prices("E:%s"%sym, cx1, cx2, cx3)

When I run pylint against it, it complains:

junk.py:10: [W0613(unused-argument), find_problems] Unused argument 'prob_dates'

I must be misunderstanding something about the |= operator as applied
to sets. If I read the docs correctly, s1 |= s2 is equivalent to
s1.update(s2). A dumb "test" at the prompt suggests that's true:

>>> s1 = set("abc")
>>> s2 = set("cde")
>>> s1 | s2
set(['a', 'c', 'b', 'e', 'd'])
>>> s1 |= s2
>>> s1
set(['a', 'c', 'b', 'e', 'd'])
>>> s1 = set("abc")
>>> s1.update(s2)
>>> s1
set(['a', 'c', 'b', 'e', 'd'])

If I change the last line of find_problems to call
prob_dates.update(), the message disappears. Why is pylint (1.4.2 BTW)
complaining that the prob_dates argument of find_problems is unused
when I use the |= operator?

Thx,

Skip

[toc] | [next] | [standalone]


#101502

Fromsohcahtoa82@gmail.com
Date2016-01-11 16:31 -0800
Message-ID<e18786b7-c28a-45a8-8d8d-ad82cbd29ae3@googlegroups.com>
In reply to#101497
On Monday, January 11, 2016 at 3:27:21 PM UTC-8, Skip Montanaro wrote:
> Here's a dumb little bit of code, adapted from a slightly larger script:
> 
> #!/usr/bin/env python
> 
> "dummy"
> 
> import glob
> import os
> 
> def compare_prices(*_args):
>     "dummy"
>     return set()
> 
> def find_problems(cx1, cx2, cx3, prob_dates):
>     "dummy"
>     for fff in sorted(glob.glob("/path/to/*.nrm")):
>         sym = os.path.splitext(os.path.basename(fff))[0]
>         prob_dates |= compare_prices("E:%s"%sym, cx1, cx2, cx3)
> 
> When I run pylint against it, it complains:
> 
> junk.py:10: [W0613(unused-argument), find_problems] Unused argument 'prob_dates'
> 
> I must be misunderstanding something about the |= operator as applied
> to sets. If I read the docs correctly, s1 |= s2 is equivalent to
> s1.update(s2). A dumb "test" at the prompt suggests that's true:
> 
> >>> s1 = set("abc")
> >>> s2 = set("cde")
> >>> s1 | s2
> set(['a', 'c', 'b', 'e', 'd'])
> >>> s1 |= s2
> >>> s1
> set(['a', 'c', 'b', 'e', 'd'])
> >>> s1 = set("abc")
> >>> s1.update(s2)
> >>> s1
> set(['a', 'c', 'b', 'e', 'd'])
> 
> If I change the last line of find_problems to call
> prob_dates.update(), the message disappears. Why is pylint (1.4.2 BTW)
> complaining that the prob_dates argument of find_problems is unused
> when I use the |= operator?
> 
> Thx,
> 
> Skip

The pipe character on its own also functions as the binary OR operator, with x |= y being a shortcut for x = x | y.

If prob_dates is an integer, then it is immutable and the your prob_dates |= compare_prices(...) line won't do anything (The variable is being set, but never again read outside the function and it doesn't change the function's return value), which is probably what pylint is complaining about.  Pylint doesn't know that your function is expecting a mutable iterable for the prob_dates argument.

If you change it to prob_dates.update(...), does pylint complain?

[toc] | [prev] | [next] | [standalone]


#101507

FromSkip Montanaro <skip.montanaro@gmail.com>
Date2016-01-11 19:04 -0600
Message-ID<mailman.35.1452560646.13488.python-list@python.org>
In reply to#101502
Sorry, I should have been explicit. prob_dates (the actual argument of the
call) is a set. As far as I know pylint does no type inference, so pylint
can't tell if the LHS and RHS of the |= operator are appropriate, nor can
it tell if it has an update() method.

Before writing, I had more-or-less concluded I had hit a bug, but in my
experience when I hit something I think is a bug, it's not. It's me.
Terry's reply convinced me that I had hit something.

Something else just occurred to me. I should have tried disassembling the
two versions of the function. Here's the output near prob_dates.update()
call:

 14
​  ​
   62 LOAD_FAST                3 (prob_dates)
             65 LOAD_ATTR                6 (update)
             68 LOAD_GLOBAL              7 (compare_prices)
             71 LOAD_CONST               3 ('E:%s')
             74 LOAD_FAST                5 (sym)
             77 BINARY_MODULO
             78 LOAD_FAST                0 (cx1)
             81 LOAD_FAST                1 (cx2)
             84 LOAD_FAST                2 (cx3)
             87 CALL_FUNCTION            4
             90 CALL_FUNCTION            1

Here's how the |= version disassembles in that region:

 20
​  ​
     62 LOAD_FAST                3 (prob_dates)
             65 LOAD_GLOBAL              6 (compare_prices)
             68 LOAD_CONST               3 ('E:%s')
             71 LOAD_FAST                5 (sym)
             74 BINARY_MODULO
             75 LOAD_FAST                0 (cx1)
             78 LOAD_FAST                1 (cx2)
             81 LOAD_FAST                2 (cx3)
             84 CALL_FUNCTION            4
             87 INPLACE_OR
             88 STORE_FAST               3 (prob_dates)

I think what's throwing pylint is that last
​STORE_FAST. That tells pylint the argument is ignored.

I'll at least bring up the issue on the code-quality list.

Thanks,

Skip
​

[toc] | [prev] | [next] | [standalone]


#101548

FromIan Kelly <ian.g.kelly@gmail.com>
Date2016-01-12 09:03 -0700
Message-ID<mailman.67.1452614646.13488.python-list@python.org>
In reply to#101502
On Mon, Jan 11, 2016 at 6:04 PM, Skip Montanaro
<skip.montanaro@gmail.com> wrote:
> Sorry, I should have been explicit. prob_dates (the actual argument of the
> call) is a set. As far as I know pylint does no type inference, so pylint
> can't tell if the LHS and RHS of the |= operator are appropriate, nor can
> it tell if it has an update() method.
>
> Before writing, I had more-or-less concluded I had hit a bug, but in my
> experience when I hit something I think is a bug, it's not. It's me.
> Terry's reply convinced me that I had hit something.
>
> Something else just occurred to me. I should have tried disassembling the
> two versions of the function. Here's the output near prob_dates.update()
> call:
>
>  14
>
>    62 LOAD_FAST                3 (prob_dates)
>              65 LOAD_ATTR                6 (update)
>              68 LOAD_GLOBAL              7 (compare_prices)
>              71 LOAD_CONST               3 ('E:%s')
>              74 LOAD_FAST                5 (sym)
>              77 BINARY_MODULO
>              78 LOAD_FAST                0 (cx1)
>              81 LOAD_FAST                1 (cx2)
>              84 LOAD_FAST                2 (cx3)
>              87 CALL_FUNCTION            4
>              90 CALL_FUNCTION            1
>
> Here's how the |= version disassembles in that region:
>
>  20
>
>      62 LOAD_FAST                3 (prob_dates)
>              65 LOAD_GLOBAL              6 (compare_prices)
>              68 LOAD_CONST               3 ('E:%s')
>              71 LOAD_FAST                5 (sym)
>              74 BINARY_MODULO
>              75 LOAD_FAST                0 (cx1)
>              78 LOAD_FAST                1 (cx2)
>              81 LOAD_FAST                2 (cx3)
>              84 CALL_FUNCTION            4
>              87 INPLACE_OR
>              88 STORE_FAST               3 (prob_dates)
>
> I think what's throwing pylint is that last
> STORE_FAST. That tells pylint the argument is ignored.

I may be wrong, but I believe pylint just looks at the AST, not the opcodes.

[toc] | [prev] | [next] | [standalone]


#101562

FromSkip Montanaro <skip.montanaro@gmail.com>
Date2016-01-12 11:46 -0600
Message-ID<mailman.78.1452620812.13488.python-list@python.org>
In reply to#101502
I created an issue for the pylint folks:
https://github.com/PyCQA/pylint/issues/774

Skip

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web