Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

In code, list.clear doesn't throw error - it's just ignored

45 views
Skip to first unread message

DFS

unread,
Nov 13, 2022, 4:28:59 PM11/13/22
to
In code, list.clear is just ignored.
At the terminal, list.clear shows
<built-in method clear of list object at 0x000001C9CFEC4240>


in code:
x = [1,2,3]
x.clear
print(len(x))
3

at terminal:
x = [1,2,3]
x.clear
<built-in method clear of list object at 0x000001C9CFEC4240>
print(len(x))
3


Caused me an hour of frustration before I noticed list.clear() was what
I needed.

x = [1,2,3]
x.clear()
print(len(x))
0

Jon Ribbens

unread,
Nov 13, 2022, 5:20:42 PM11/13/22
to
If you want to catch this sort of mistake automatically then you need
a linter such as pylint:

$ cat test.py
"""Create an array and print its length"""

array = [1, 2, 3]
array.clear
print(len(array))
$ pylint -s n test.py
************* Module test
test.py:4:0: W0104: Statement seems to have no effect (pointless-statement)

DFS

unread,
Nov 13, 2022, 6:12:50 PM11/13/22
to
Thanks, I should use linters more often.

But why is it allowed in the first place?

I stared at list.clear and surrounding code a dozen times and said
"Looks right! Why isn't it clearing the list?!?!"

2 parens later and I'm golden!






Jon Ribbens

unread,
Nov 13, 2022, 7:31:59 PM11/13/22
to
Because it's an expression, and you're allowed to execute expressions.

Greg Ewing

unread,
Nov 13, 2022, 7:55:52 PM11/13/22
to
To put it a bit more clearly, you're allowed to evaluate
an expression and ignore the result.

--
Greg

Jon Ribbens

unread,
Nov 13, 2022, 8:22:15 PM11/13/22
to
... because it may have side effects, and it's not possible to determine
whether it will or not in advance.

Chris Angelico

unread,
Nov 13, 2022, 9:11:44 PM11/13/22
to
No part of it is invalid, so nothing causes a problem. For instance,
you can write this:

>>> 1

And you can write this:

>>> 1 + 2

And you can write this:

>>> print(1 + 2)

But only one of those is useful in a script. Should the other two be
errors? No. But linters WILL usually catch them, so if you have a good
linter (especially built into your editor), you can notice these
things.

ChrisA

MRAB

unread,
Nov 13, 2022, 9:17:04 PM11/13/22
to
But if it's an expression where it's expecting a statement and it's not
a call, then it's probably a bug.

Chris Angelico

unread,
Nov 13, 2022, 9:23:05 PM11/13/22
to
On Mon, 14 Nov 2022 at 13:18, MRAB <pyt...@mrabarnett.plus.com> wrote:
>
> On 2022-11-14 00:55, Greg Ewing wrote:
> But if it's an expression where it's expecting a statement and it's not
> a call, then it's probably a bug.

Maybe, but I'd be dubious of making it that simplistic. For instance,
which of these is more likely to be useless?

spam or ham()
spam() or ham

Syntactically, both of them are 'or' expressions, but one of them is
almost certainly unnecessary, while the other is just an oddly-written
conditional statement and most definitely useful.

In any case, this is the job of linters, NOT the language itself.

ChrisA

DFS

unread,
Nov 13, 2022, 10:23:29 PM11/13/22
to
If it wastes time like that it's invalid.

This is an easy check for the interpreter to make.

If I submit a suggestion to pytho...@python.org will it just show up
here? Or do the actual Python devs intercept it?






>>>> 1
>
> And you can write this:
>
>>>> 1 + 2
>
> And you can write this:
>
>>>> print(1 + 2)
>
> But only one of those is useful in a script. Should the other two be
> errors? No. But linters WILL usually catch them, so if you have a good
> linter (especially built into your editor), you can notice these
> things.


ran pylint against it and got 0.0/10.


--disable=
invalid-name
multiple-statements
bad-indentation
line-too-long
trailing-whitespace
missing-module-docstring
missing-function-docstring
too-many-lines
fixme


and got 8.9/10.

Michael Speer

unread,
Nov 13, 2022, 11:53:44 PM11/13/22
to
Python doesn't care what an expression returns.

You've written an expression that returns the value of the 'clear' function
that is bound to that particular list.

The interpreter doesn't know or care if accessing that 'clear' attribute on
the class returns a function or for some reason triggers a bunch of side
effects that the author decided they wanted to use __getattr__ to trigger.

'list.clear' might be a perfectly reasonable expression in some library.
I'd rather it not be, but hey, there are millions of python programmers
making all kinds of code out there

arbitrary expressions can have arbitrary effects. just because a value
isn't assigned, returned or used as an argument to a function doesn't mean
it isn't doing anything.

you might then want python to inspect the result of the function, but how
can python know if the author isn't purposely ignoring the return value of
the expression?

people can call functions that return values for only their side effects.

if you can't tell by the form of the expression or the value it returns,
what is the linter supposed to look for?

what is the interpreter supposed to look for?

if you want to avoid accidentally failing to clear a list during a
function, you should write tests that check that various inputs to the
function produce the expected outputs.

'unit tests' are a good place to make sure that code is acting as you want
it to

for one-off scripts, you should always make the thing dry-run or convert
from an input to an output (rather than in-place) so you can rerun them a
few times and make sure they're doing what you want.

sometimes making sure things are right is just on you.

there will always be the occasional silly error in a script that is hard to
see until you step away for a moment.

stepping away and coming back is a pretty good thing to do if you're stuck
on something that feels impossible.
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Greg Ewing

unread,
Nov 14, 2022, 12:12:46 AM11/14/22
to
On 14/11/22 3:13 pm, MRAB wrote:
> But if it's an expression where it's expecting a statement and it's not
> a call, then it's probably a bug.

The key word there is "probably". If there's any chance it
could be not a bug, it can't be an error. At most it should
be a warning, and that's what linters are for. I wouldn't
like the core interpreter to be producing a bunch of warnings
for things like this.

--
Greg

Chris Angelico

unread,
Nov 14, 2022, 2:09:13 AM11/14/22
to
Notably, linters can be taught about more complex idioms, like:

try:
raw_input
except NameError:
raw_input = input

which is an easy way to make polyglot Py2/Py3 code that handles the
presence/absence of a particular name. Or, similarly:

try:
os.sendfile
except AttributeError:
... # cope with sendfile not being available

When os.sendfile exists, it's a completely useless expression. When it
doesn't, it's an error. But the difference between those two is
crucial.

ChrisA

dn

unread,
Nov 14, 2022, 2:26:03 AM11/14/22
to
It looks 'right' because it is 'right'!
However, compared with what was intended, it was 'wrong'!

«
I really hate this d***umb machine,
I wish that they would sell it.
It never does quite what I want,
but only what I tell it!
»



Lifting some text from a recent PUG-meeting:

«Distinguishing functions and their names:

Please remind yourself that is_odd is the name of a function, whereas
is_odd() calls the function and could thus be considered a 'label' for
the returned-value – either approach could be used in different situations.
»


In this case, the subject is a method, and accordingly has a slightly
different flavor. Rather than a return-value, the impact is an effect
within the scope and/or to the state of the object. However, not
materially-different from the OP's question.


It is assumed that there is no difficulty related to calling the
function, eg len( x ).


So, why would we use the function/method by name instead of its asking
for its return-value?
(please remember that a Python function is a "first class" object)

The (above) Challenge to PUG-members was to use code which produces the
Fibonacci Sequence, and out of the first 16 values, return the number of
Fibonacci-values which are also odd-numbers.

We started with straight-line code which mixed-up these various steps in
the process. As the challenge continued, such tangling made it very
difficult to enable any variations. To illustrate the SRP and DIP
(Single Responsibility and Dependency Inversion Principles of SOLID
Architecture), we refactored and refactored, ending-up with:

values_counted = sm.sequence_select_and_project(
fg.fibonacci_generator,
is_odd,
limit,
)

sequence_select_and_project is a for-loop spanning two if-statements
which count or break
fibonacci_generator is self-explanatory (hopefully)
is_odd returns boolean advice
limit is 16

Note how the first two arguments are [generator-]function names, cf
function-calls!


Now for 'the magic' of a dependency-inverted plug-in architecture:-

If the 16 is changed to 32, we'll be comfortable with the idea that
twice as many values will be generated and considered.

So, think about changing the generator to produce (say) prime numbers.

Alternately, alter the program to count only values divisible by two
(perhaps using "is_even" as function-name).

By 'plugging-in' a different function-name, the above control-routine
can be used with any suitably-lengthy sequence as its data-source,
and/or selection-criteria function!


Accordingly, using the name of a function can be as useful as using the
result of a function-call - even if the latter is far more common.

--
--
Regards,
=dn

Roel Schroeven

unread,
Nov 14, 2022, 4:10:11 AM11/14/22
to
Op 14/11/2022 om 4:23 schreef DFS:
> On 11/13/2022 9:11 PM, Chris Angelico wrote:
>> On Mon, 14 Nov 2022 at 11:53, DFS <nos...@dfs.com> wrote:
>>>
>>> On 11/13/2022 5:20 PM, Jon Ribbens wrote:
>>>> On 2022-11-13, DFS <nos...@dfs.com> wrote:
>>>>> In code, list.clear is just ignored.
>>>>> At the terminal, list.clear shows
>>>>> <built-in method clear of list object at 0x000001C9CFEC4240>
>>>>>
>>>>>
>>>>> in code:
>>>>> x = [1,2,3]
>>>>> x.clear
>>>>> print(len(x))
>>>>> 3
>>>>>
>>> But why is it allowed in the first place?
>>>
>>> I stared at list.clear and surrounding code a dozen times and said
>>> "Looks right!  Why isn't it clearing the list?!?!"
>>>
>>> 2 parens later and I'm golden!
>>>
>>
>> No part of it is invalid, so nothing causes a problem. For instance,
>> you can write this:
>
>
> If it wastes time like that it's invalid.

It's not invalid. In the REPL for example, it does something useful:

>>> x = [1, 2, 3]
>>> x.clear
<built-in method clear of list object at 0x000002947DBBF680>

Others have shown instances where writing a method or function without
calling it are useful in a script too.

There are languages that handle this differently. Ruby, for example,
calls the function/method even when you don't write the parens, if I'm
not mistaken. Personally I don't like that; I much prefer Python's
explicitness in making the difference between the value of a function
and calling that function. Still, there's something to be said for
warnings. I agree with others that such warnings are more the job for a
linter than for the language.

FWIW I've been bitten by this in C++ once. I wanted to write something like

if (some_condition())
    foo();

But I forgot the parens after some_condition, so C++ evaluated the
function pointer (which was non-NULL so evaluated is true in a boolean
context) instead of the return value, and therefore foo() got called
unconditionally.

--

"Don't Panic."
-- Douglas Adams, The Hitchhiker's Guide to the Galaxy

Karsten Hilbert

unread,
Nov 14, 2022, 5:46:38 AM11/14/22
to
Am Mon, Nov 14, 2022 at 02:13:34AM +0000 schrieb MRAB:

> But if it's an expression where it's expecting a statement and it's not a call, then
> it's probably a bug.

That "probably" makes it suitable for a linter, as was pointed out.

Karsten
--
GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B

Weatherby,Gerard

unread,
Nov 14, 2022, 6:35:59 AM11/14/22
to
The terminal told you what x.clear was.

The Python documentation tells you how to call it: https://docs.python.org/3/tutorial/datastructures.html

list.clear()
Remove all items from the list. Equivalent to del a[:].

An IDE (e.g. PyCharm) will try to autocomplete the parentheses and warn you if you don’t:

“Statement seems to have no effect and can be replaced with a function call to have effect”
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jRrjG0fRo46VyY0jLfD1Z5C6tXDiphZy8zi2AqN_N5BB1_OwBe_wxmsBWmIVOFQDdZnvbRq1JNeGnPg$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jRrjG0fRo46VyY0jLfD1Z5C6tXDiphZy8zi2AqN_N5BB1_OwBe_wxmsBWmIVOFQDdZnvbRq1JNeGnPg$>

Jon Ribbens

unread,
Nov 14, 2022, 9:18:44 AM11/14/22
to
On 2022-11-14, Stefan Ram <r...@zedat.fu-berlin.de> wrote:
> Jon Ribbens <jon+u...@unequivocal.eu> writes:
>>"""Create an array and print its length"""
>>array = [1, 2, 3]
>>array.clear
>
> BTW: Above, there are /two/ expression statements
> with no effect; the other one is
>
> """Create an array and print its length"""
>
> . Apparently, linters know this and will not create
> a warning for such string literals.

Not only do they know this, pylint will complain if you *don't* include
that line, which is why I included it ;-)

Chris Angelico

unread,
Nov 14, 2022, 2:14:34 PM11/14/22
to
On Tue, 15 Nov 2022 at 05:57, Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>
> Michael Speer <knom...@gmail.com> writes:
> >Python doesn't care what an expression returns.
>
> In my English, functions return values,
> expression are being evaluated to a value.
> The evaluation of a function yields or
> produces a value. Expressions do not return,
> because they are not functions.
>

Well, you can dispute the terminology all you like, but there's no
real difference between function calls and other types of expression.
They're all just expressions and they can be combined arbitrarily.

ChrisA

Cameron Simpson

unread,
Nov 14, 2022, 5:11:41 PM11/14/22
to
On 13Nov2022 22:23, DFS <nos...@dfs.com> wrote:
>On 11/13/2022 9:11 PM, Chris Angelico wrote:
>> [ ... `x.clear` ... ]
>>No part of it is invalid, so nothing causes a problem. For instance,
>>you can write this:
>
>If it wastes time like that it's invalid.

It's a valid expression.

It looks to your eye like a no-op, but at actually Python _looks up the
name `clear`_ on an object (which happens to be a `list`). That is a
real thing to do, and can have side effects.

While most of the examples here have been in the REPL where running an
expression with no side effects is itself useful, because the REPL can
print the result, I've personally got some real world code with a bare
`some_object.attribute` line. I'm not sure where, or I'd show it, but I
_think_ it was probably prepriming a cached object property. There might
have been a more expressive way to do that, but it was a bare attribute
lookup with side effects, _used for those side effects_.

>This is an easy check for the interpreter to make.

It really isn't, given that (a) this isn't known by the interpreter to
be a `list` until runtime and (b) that would need embedding special
knowledge that looking up an attribute on a `list` has no side effects
(versus some other things, where it is not the case).

Linters are the best place for this: they warn about probably-mistakes
idioms like this, and can have slightly deep knowledge of the code's
semantics sometimes.

>If I submit a suggestion to pytho...@python.org will it just show
>up here? Or do the actual Python devs intercept it?

Nah, it'll go through.

Cheers,
Cameron Simpson <c...@cskk.id.au>

Dennis Lee Bieber

unread,
Nov 14, 2022, 7:15:45 PM11/14/22
to
On Tue, 15 Nov 2022 09:11:10 +1100, Cameron Simpson <c...@cskk.id.au>
declaimed the following:

>On 13Nov2022 22:23, DFS <nos...@dfs.com> wrote:
>>This is an easy check for the interpreter to make.
>
>It really isn't, given that (a) this isn't known by the interpreter to
>be a `list` until runtime and (b) that would need embedding special
>knowledge that looking up an attribute on a `list` has no side effects
>(versus some other things, where it is not the case).
>

There is also the minor facet that "x.clear" can be bound to a
different name...

>>> x = [1, 2, 3.145926536, "Pie"]
>>> clearx = x.clear
>>> x
[1, 2, 3.145926536, 'Pie']
>>> clearx()
>>> x
[]
>>>



--
Wulfraed Dennis Lee Bieber AF6VN
wlf...@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/

Cameron Simpson

unread,
Nov 14, 2022, 9:34:09 PM11/14/22
to
On 14Nov2022 19:15, Dennis Lee Bieber <wlf...@ix.netcom.com> wrote:
> There is also the minor facet that "x.clear" can be bound to a
>different name...
>
>>>> x = [1, 2, 3.145926536, "Pie"]
>>>> clearx = x.clear
>>>> x
>[1, 2, 3.145926536, 'Pie']
>>>> clearx()
>>>> x
>[]
>>>>

I think the OP would take the stance that this:

clearx = x.clear

is more valid than:

x.clear

which discards the return value of the expression.

Cheers,
Cameron Simpson <c...@cskk.id.au>

avi.e...@gmail.com

unread,
Nov 15, 2022, 12:45:43 AM11/15/22
to
Cameron,

What would be the meaning of an ordering relation determining what is MORE
VALID?

As has been pointed out, not only are some uses that look odd sometimes
valid, but perhaps even can be used in ways you simply may not see, such as
side effects. Some examples ranging from poor to horrible are mentioned
below.

In some languages, trying to access a variable that is not properly existing
or initialized, can generate an error, as an example, which may cause the
current function to terminate if not caught and jump up the call chain till
an error handler is found. Code like:

1/0

May seem meaningless as the result is not saved, but may trigger a divide by
zero error.

Is it an error to write code like:

If x.clear:
pass

I suspect it is possible to write quite weird code that might pass most
linters but that does nothing useful and also to write code that is useful
but might be disparaged by many interpreters or linters.

My example above is a fairly common code pattern while code is being written
as a sort of reminder to perhaps come back later and flesh it out properly,
or remove it if it is no longer applicable. If so, it would be reasonable
for it to be challenged and also to ignore such warnings until later when
either it is gone, or the code hint should be gone.

There are many cases where short-circuit evaluation means code is not run
such as "True || x" that is less obvious but equally bypassed if you set a
variable to True and do not change it and use it instead of True above. But
is it an error? What if again, my later goal is to add code that may change
the Truth value. As it is, the statement is not evaluated. But it may be set
up as a placeholder to enhance later, perhaps long after, or retain some
flexibility. Insisting it be removed might be too harsh while a warning
might be reasonable. Yet again, it is not always an error to not use
something like declaring a variable you might need or importing a module you
never use.

Code is chock full of such things in mid-stream. And you can deliberately
ignore some things without it being a mistake as in:

( _, mean, _) = minMeanMax(args)

Sure, it may be overkill to call a function that returns three things then
ignore two of them. So what? What if instead of "_" I used real variable
names like min and max? Should I get error messages that two variable are
set up with values but never again used?

Or consider what I sometimes do when I write code that someone else will use
and to test it I must use something like a different filename/path on my
machine than they do on theirs. I might write code like

# Comment out one or more of the below so only one exists:
Place = "whatever"
Place = "Some other place"

Clearly if I am using the second one, I can comment the first out OR I can
leave it alone and at minor expenses let the variable be unconditionally
reset to the second value. Is it a bug or a feature?

I could go on with other examples including some more subtle ones like
declaring a variable name just to mask another variable from being
accessible from a higher level and perhaps prevent the interpreter or
compiler optimizing it away by using it in the meaningless way this
discussion began with as it has been accessed once.

One person's bug can be another person's feature. And clearly, as has been
mentioned, there MAY be subtle side effects like invoking your custom setter
or dunder method which also does logging or increments a count.

There is a spectrum between being overly permissive and overly strict. This
case almost amuses me because of the way that many a REPL works so something
run directly in a console will take an expression like "varname" and PRINT
the current value to the screen. If the same code is run from a file, or
from inside some function, it does nothing useful and you need something
like "print(varname)" instead. People often cut and paste such snippets of
code and in one context they did something and in another, it seems
meaningless and possibly an error.

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmai...@python.org> On
Behalf Of Cameron Simpson
Sent: Monday, November 14, 2022 9:34 PM
To: pytho...@python.org
Subject: Re: In code, list.clear doesn't throw error - it's just ignored

On 14Nov2022 19:15, Dennis Lee Bieber <wlf...@ix.netcom.com> wrote:
> There is also the minor facet that "x.clear" can be bound to a
>different name...
>
>>>> x = [1, 2, 3.145926536, "Pie"]
>>>> clearx = x.clear
>>>> x
>[1, 2, 3.145926536, 'Pie']
>>>> clearx()
>>>> x
>[]
>>>>

I think the OP would take the stance that this:

clearx = x.clear

is more valid than:

x.clear

which discards the return value of the expression.

Cheers,
Cameron Simpson <c...@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list

Cameron Simpson

unread,
Nov 15, 2022, 4:13:30 AM11/15/22
to
On 15Nov2022 00:45, avi.e...@gmail.com <avi.e...@gmail.com> wrote:
>What would be the meaning of an ordering relation determining what is
>MORE VALID?

Are you asking what criterion would rate:

clearx = x.clear

as "more" valid than:

x.clear

on its own?

I don't want to speak for the OP, but I'd think the OP's issue is that
the bare `x.clear` is evaluated but not stored in a variable. As a
metric, we might gather various descriptive statements we could make
about these statements. They'd perhaps include "is legal Python code",
"is pretty simple". The former line could include "saves the expression
value in a variable for later use" and the latter could not. That's a
comparison test you could use for ordering.

My own opinion is that a bare:

x.clear

is legal and valid for all the example use cases already mentioned, but
an entirely valid target for complaint by a linter, whose task is to
point out dodgy looking stuff for review by the author.

Cheers,
Cameron Simpson <c...@cskk.id.au>

avi.e...@gmail.com

unread,
Nov 15, 2022, 6:10:53 PM11/15/22
to
That is clear, Cameron, but on my python interpreter values evaluated on the
command line ARE saved:

>>> numb = 5
>>> 5 + numb
10
>>> numb
5
>>> _ + _ + 1
11
>>> _ * 2
22
>>>

The point is that a dummy variable of _ is assigned and re-assigned at each
step and there can be a valid, if not very useful, reason to evaluating it
and storing a result. If the darn thing is a very long name like
alpha.beta.gamma.delta.epsilon then code that uses it repeatedly in the very
next line can be much simpler by using _ repeatedly and perhaps more
efficient. Consider:

negsq = _ * -_

versus

negsq = alpha.beta.gamma.delta.epsilon * - alpha.beta.gamma.delta.epsilon

So does your linter now need to look ahead and see if "_" is used properly
in the next line? Note it can also be used on the LHS where it means
something else.

Still, I grant generally a naked evaluation is generally an error. LOL!

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmai...@python.org> On
Behalf Of Cameron Simpson
Sent: Tuesday, November 15, 2022 4:13 AM
To: pytho...@python.org
Subject: Re: In code, list.clear doesn't throw error - it's just ignored

--
https://mail.python.org/mailman/listinfo/python-list

Chris Angelico

unread,
Nov 15, 2022, 6:16:05 PM11/15/22
to
On Wed, 16 Nov 2022 at 10:11, <avi.e...@gmail.com> wrote:
>
> That is clear, Cameron, but on my python interpreter values evaluated on the
> command line ARE saved:
>
> >>> numb = 5
> >>> 5 + numb
> 10
> >>> numb
> 5
> >>> _ + _ + 1
> 11

That's a REPL feature.

ChrisA

avi.e...@gmail.com

unread,
Nov 15, 2022, 7:10:49 PM11/15/22
to
Yes, Chris, that is a REPL feature and one that people may use
interactively.

As you note, it does not work inside something like a function which the
REPL is not trying to evaluate and print. So clearly my supposed use would
not make much sense in such code.


-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmai...@python.org> On
Behalf Of Chris Angelico
Sent: Tuesday, November 15, 2022 6:16 PM
To: pytho...@python.org
Subject: Re: In code, list.clear doesn't throw error - it's just ignored

--
https://mail.python.org/mailman/listinfo/python-list

Chris Angelico

unread,
Nov 23, 2022, 2:29:20 PM11/23/22
to
On Thu, 24 Nov 2022 at 06:26, Stefan Ram <r...@zedat.fu-berlin.de> wrote:
>
> Jon Ribbens <jon+u...@unequivocal.eu> writes:
> >If you want to catch this sort of mistake automatically then you need
> >a linter such as pylint:
>
> output
>
> <string>, line 1
> list.clear
> Warning: Attribute used as statement.
>
> <string>, line 5
> list.clear
> Warning: Attribute used as statement.
>
> source code
>
> import ast, sys
>
> def check( point, source ):
> if isinstance( point, ast.Expr ) and\
> type( point.value )== ast.Attribute:
> print( "<string>, line", point.lineno, file=sys.stderr )
> print( source.split( '\n' )[ point.lineno-1 ], file=sys.stderr )
> print\
> ( "Warning:", "Attribute used as statement.", file=sys.stderr )
> print()
>
> def mylinter( source ):
> for point in ast.walk( ast.parse( example )):
> check( point, source )
>
> example = """\
> list.clear
> list.clear()
> x = list.clear
> print( list.clear )
> list.clear
> """
>
> mylinter( example )
>

Uhh, yes? You just created an extremely simplistic linter. Your point?

ChrisA

Dan Stromberg

unread,
Nov 25, 2022, 10:57:00 AM11/25/22
to
On Sun, Nov 13, 2022 at 4:45 PM DFS <nos...@dfs.com> wrote:

> In code, list.clear is just ignored.
> At the terminal, list.clear shows
> <built-in method clear of list object at 0x000001C9CFEC4240>
>
>
> in code:
> x = [1,2,3]
> x.clear
> print(len(x))
> 3
>
> at terminal:
> x = [1,2,3]
> x.clear
> <built-in method clear of list object at 0x000001C9CFEC4240>
> print(len(x))
> 3
>
>
> Caused me an hour of frustration before I noticed list.clear() was what
> I needed.
>
> x = [1,2,3]
> x.clear()
> print(len(x))
> 0
>
> --
> https://mail.python.org/mailman/listinfo/python-list



I'm not 100% sanguine about properties, but the fact is they are part of
the language:

$ cat p
below cmd output started 2022 Fri Nov 25 07:54:42 AM PST
#!/usr/bin/env python3

class P:
def __init__(self):
self.count = 0

@property
def increment(self):
self.count += 1

def result(self):
return self.count


p = P()
p.increment
p.increment
print(p.result())
above cmd output done 2022 Fri Nov 25 07:54:42 AM PST
dstromberg@tp-mini-c:~/src/experiments/property x86_64-pc-linux-gnu 2670

$ ./p
below cmd output started 2022 Fri Nov 25 07:54:44 AM PST
2

As you can see, if the interpreter refused to do something with p.increment
because it has no parens, the meaning of this code would change
significantly.
0 new messages