Re: Use of statement 'global' in scripts.

2024-05-08 Thread Popov, Dmitry Yu via Python-list
Thank you!

From: Python-list  on behalf of 
Greg Ewing via Python-list 
Sent: Wednesday, May 8, 2024 3:56 AM
To: python-list@python.org 
Subject: Re: Use of statement 'global' in scripts.

On 8/05/24 1: 32 pm, Popov, Dmitry Yu wrote: > The statement 'global', 
indicating variables living in the global scope, is very suitable to be used in 
modules. I'm wondering whether in scripts, running at the top-level invocation 
of the interpreter,
ZjQcmQRYFpfptBannerStart
This Message Is From an External Sender
This message came from outside your organization.

ZjQcmQRYFpfptBannerEnd

On 8/05/24 1:32 pm, Popov, Dmitry Yu wrote:
> The statement 'global', indicating variables living in the global scope, is 
> very suitable to be used in modules. I'm wondering whether in scripts, 
> running at the top-level invocation of the interpreter, statement 'global' is 
> used exactly the same way as in modules?

The 'global' statement declares a name to be module-level, so there's no
reason to use it at the top level of either a script or a module, since
everything there is module-level anyway.

You only need it if you want to assign to a module-level name from
within a function, e.g.

spam = 17

def f():
   global spam
   spam = 42

f()
# spam is now 42

A script is a module, so everything that applies to modules also
applies to scripts.

--
Greg
--
https://urldefense.us/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!G_uCfscf7eWS!airWCCS1QeLAhk0AfN3VxhuV9MZkx8YBhs5Vjf89K2WZPjhCUkXt9culFzwlX1_ON0G17lukcR79-kWAsA$

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


Re: Use of statement 'global' in scripts.

2024-05-08 Thread Greg Ewing via Python-list

On 8/05/24 1:32 pm, Popov, Dmitry Yu wrote:

The statement 'global', indicating variables living in the global scope, is 
very suitable to be used in modules. I'm wondering whether in scripts, running 
at the top-level invocation of the interpreter, statement 'global' is used 
exactly the same way as in modules?


The 'global' statement declares a name to be module-level, so there's no
reason to use it at the top level of either a script or a module, since
everything there is module-level anyway.

You only need it if you want to assign to a module-level name from
within a function, e.g.

spam = 17

def f():
  global spam
  spam = 42

f()
# spam is now 42

A script is a module, so everything that applies to modules also
applies to scripts.

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


Use of statement 'global' in scripts.

2024-05-07 Thread Popov, Dmitry Yu via Python-list
Dear Sirs.

The statement 'global', indicating variables living in the global scope, is 
very suitable to be used in modules. I'm wondering whether in scripts, running 
at the top-level invocation of the interpreter, statement 'global' is used 
exactly the same way as in modules? If there are any differences, I would 
really appreciate any comments on this.

Regards,
Dmitry Popov

Lemont, IL
USA

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-08 Thread Chris Angelico via Python-list
On Sat, 9 Mar 2024 at 03:42, Grant Edwards via Python-list
 wrote:
>
> On 2024-03-08, Chris Angelico via Python-list  wrote:
> > On Sat, 9 Mar 2024 at 00:51, Grant Edwards via Python-list
> > wrote:
> >
> >> One might argue that "global" isn't a good choice for what to call the
> >> scope in question, since it's not global. It's limited to that source
> >> file. It doesn't make sense to me to call a binding "global", when
> >> there can be multile different "global" bindings of the same name.
> >
> > Most "globals" aren't global either, since you can have different
> > globals in different running applications.
>
> To me, "global" has always been limited to within a single
> process/address space, but that's probably just bias left over from
> C/Pascal/FORTRAN/assembly/etc. It never occurred to me that a global
> called "X" in one program on one computer would be the same as a
> global called "X" in a different program on a different computer
> somewhere else on the "globe".
>

Yeah. My point is, though, the name "global" is a bit of a hack
anyway, so it's not THAT big a deal if it has other caveats too. For
example, let's say you always "import globals" at the top of every
script, and then assign "globals.x = 123" etc. Now you have a concept
of globals that spans the entire application, right? Well, no, not if
you use multiprocessing.

So, go ahead and call them globals, but people will always have to
learn about exactly what that means.

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-08 Thread Grant Edwards via Python-list
On 2024-03-08, Chris Angelico via Python-list  wrote:
> On Sat, 9 Mar 2024 at 00:51, Grant Edwards via Python-list
> wrote:
>
>> One might argue that "global" isn't a good choice for what to call the
>> scope in question, since it's not global. It's limited to that source
>> file. It doesn't make sense to me to call a binding "global", when
>> there can be multile different "global" bindings of the same name.
>
> Most "globals" aren't global either, since you can have different
> globals in different running applications.

To me, "global" has always been limited to within a single
process/address space, but that's probably just bias left over from
C/Pascal/FORTRAN/assembly/etc. It never occurred to me that a global
called "X" in one program on one computer would be the same as a
global called "X" in a different program on a different computer
somewhere else on the "globe".


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-08 Thread Chris Angelico via Python-list
On Sat, 9 Mar 2024 at 00:51, Grant Edwards via Python-list
 wrote:
> One might argue that "global" isn't a good choice for what to call the
> scope in question, since it's not global. It's limited to that source
> file. It doesn't make sense to me to call a binding "global", when
> there can be multile different "global" bindings of the same name.
>

Most "globals" aren't global either, since you can have different
globals in different running applications.

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-08 Thread Grant Edwards via Python-list
On 2024-03-07, Cameron Simpson via Python-list  wrote:

> Yes. Note that the "global" namespace is the module in which the 
> function is defined.

One might argue that "global" isn't a good choice for what to call the
scope in question, since it's not global. It's limited to that source
file. It doesn't make sense to me to call a binding "global", when
there can be multile different "global" bindings of the same name.

--
Grant




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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-07 Thread Cameron Simpson via Python-list

On 06Mar2024 15:12, Jacob Kruger  wrote:
So, this does not make sense to me in terms of the following snippet 
from the official python docs page:

https://docs.python.org/3/faq/programming.html

"In Python, variables that are only referenced inside a function are 
implicitly global. If a variable is assigned a value anywhere within 
the function’s body, it’s assumed to be a local unless explicitly 
declared as global."


So, I would then assume that if I explicitly include a variable name 
inside the global statement, then even just assigning it a new value 
should update the variable in the global context, outside the 
function?


Yes. Note that the "global" namespace is the module in which the 
function is defined.


x = 1

def f(n):
global x
x += n

This updates the `x` global variable in the module where `f` was 
defined.


If you import `f` and use it in another module it will _still_ update 
`x` in the original module namespace.

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-07 Thread Jacob Kruger via Python-list

Thanks again, all.


I think the python -i scoping2.py would have given me a good beginning 
as well - will archive that one for use.



And, to maybe explain how I work - not an excuse at all - but, I am 
actually 100% blind, so a lot of the IDE's, or their common 
means/methods of interaction don't suit me all the time, which is why I 
generally work via programmer's text editor interfaces, or treat 
something like VS code as such, but then still prefer to run my code via 
command line, using pdb to then play around with forms of debugging, etc.



And, yes, also generally prefer to work via classes, modules, etc. at 
runtime, but this was more or less mostly testing, which then caused 
confusion/interference on my side...LOL!



Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/07 03:55, Grant Edwards via Python-list wrote:

On 2024-03-07, dn via Python-list  wrote:


The idea of importing a module into the REPL and then (repeatedly)
manually entering the code to set-up and execute is unusual (surely type
such into a script (once), and run that (repeatedly). As you say, most
of us would be working from an IDE and hitting 'Run'. Am wondering why
you weren't - but it's not important.

Unless the code is intended to be used as a module, 'import'ing it into
the REPL doesn't make sense.

A simple example:

---testit.py--
x = 'x'
y = 'y'
def foo():
 global y
 print("hi")
 x = 'X'
 y = 'Y'
 print(x)
 print(y)
--

The usual method to play with that interactively is

 $ python -i testit.py
 >>> x
 'x'
 >>> y
 'y'
 >>> foo()
 hi
 X
 Y
 >>> x
 'x'
 >>> y
 'Y'
 >>>

As we've seen, doing a 'from testit.py import *' doesn't let you test
what the OP was trying to test. Doing 'import testit.py' gets you
closer, but it's a hassle to test code that way. The right thing to do
is 'python -i ' (or the equivalent button/option in an IDE).

   https://docs.python.org/3/tutorial/interpreter.html

If you intended to use testit.py as a module, and wanted to experiment
with its behavior as a module, then go ahead and import it. But, don't
do 'from testit.py import *' until

  1. you know how that differs from 'import testit.py'

and

  2. you want to use that difference



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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Grant Edwards via Python-list
On 2024-03-07, dn via Python-list  wrote:

> The idea of importing a module into the REPL and then (repeatedly) 
> manually entering the code to set-up and execute is unusual (surely type 
> such into a script (once), and run that (repeatedly). As you say, most 
> of us would be working from an IDE and hitting 'Run'. Am wondering why 
> you weren't - but it's not important.

Unless the code is intended to be used as a module, 'import'ing it into
the REPL doesn't make sense.

A simple example:

---testit.py--
x = 'x'
y = 'y'
def foo():
global y
print("hi")
x = 'X'
y = 'Y'
print(x)
print(y)
--

The usual method to play with that interactively is

$ python -i testit.py
>>> x
'x'
>>> y
'y'
>>> foo()
hi
X
Y
>>> x
'x'
>>> y
'Y'
>>>

As we've seen, doing a 'from testit.py import *' doesn't let you test
what the OP was trying to test. Doing 'import testit.py' gets you
closer, but it's a hassle to test code that way. The right thing to do
is 'python -i ' (or the equivalent button/option in an IDE).

  https://docs.python.org/3/tutorial/interpreter.html

If you intended to use testit.py as a module, and wanted to experiment
with its behavior as a module, then go ahead and import it. But, don't
do 'from testit.py import *' until

 1. you know how that differs from 'import testit.py'

and

 2. you want to use that difference


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread dn via Python-list

On 7/03/24 05:28, Jacob Kruger via Python-list wrote:
...
So, yes, know this comes across like some form of a scam/joke, or 
list-garbage, since it doesn't make any sense to me at all, but still 
just wondering if missing something, or should I shift over to 3.12 to 
see if if works differently, or just try reinstalling 3.11 from scratch, 
or should I retry the above in something like the VS code console, or a 
different python console, etc.?
Some of the facts, such as HOW the code was being executed were missing 
(see earlier request for a cut-down scenario, AND reports from others 
saying 'but it works for me').


The idea of importing a module into the REPL and then (repeatedly) 
manually entering the code to set-up and execute is unusual (surely type 
such into a script (once), and run that (repeatedly). As you say, most 
of us would be working from an IDE and hitting 'Run'. Am wondering why 
you weren't - but it's not important.


That said, the REPL is the perfect place to learn, experiment, and 
prototype - particularly when compared with the facilities of other 
language's eco-systems. The entirety of the on-line Tutorial cannot be 
wrong! (although, after a quick review, I've failed to see where the 
Tutorial mentions the usual development mode, apart from two very brief 
asides (the most useful is almost at the very end(?)) - but then (as 
they say) the objective is to show the language!


The lesson-learned is that there are different 'environments' and 
different ways of building the environment in which the code will run. 
That's a valuable lesson, and full of subtlety!


Glad to see that comparing id()s was useful - for diagnosis but not 
solution. Other tools might include the locals() and globals() 
functions. You may also have detected that many of us try to avoid 
globals and the implicit assumptions about the behavior of mutable 
collections (eg lists) when treated as 'global'. Then there are 
"closures", the "LEGB" rule, namespaces, scope, and ...


--
--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list




Grant Edwards via Python-list schreef op 6/03/2024 om 18:59:
On 2024-03-06, Roel Schroeven via Python-list  
wrote:

> Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list:
>> >>> from scoping2 import *
>
> [...]
>
> I would advice not to use 'import *', if at all possible, for 
multiple > reasons, one of which is to prevent problems like this.


Unfortunately, many (most?) tutorials for particular modules (and even
example code in the Python documentation itself) are all written
assuming that you do "from  import *". It saves the tutorial
write a few keystrokes, but causes untold trouble for people who learn
incorrectly that "from  import *" is the proper way to do
things.


I know ... it's really irritating.

--
"There is a theory which states that if ever anyone discovers exactly what the
Universe is for and why it is here, it will instantly disappear and be
replaced by something even more bizarre and inexplicable.
There is another theory which states that this has already happened."
-- Douglas Adams, The Restaurant at the End of the Universe

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Grant Edwards via Python-list
On 2024-03-06, Roel Schroeven via Python-list  wrote:
> Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list:
>> >>> from scoping2 import *
>
> [...]
>
> I would advice not to use 'import *', if at all possible, for multiple 
> reasons, one of which is to prevent problems like this.

Unfortunately, many (most?) tutorials for particular modules (and even
example code in the Python documentation itself) are all written
assuming that you do "from  import *".  It saves the tutorial
write a few keystrokes, but causes untold trouble for people who learn
incorrectly that "from  import *" is the proper way to do
things.

> I would also advice not to use global variables from other modules
> directly, and in fact would advice to minimize the use of globals in
> general as much as possible. If you need to keep state between
> methods, it might be better to use a class.


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list:

>>> from scoping2 import *
Ah yes, that explains what's happening. After that statement, the name 
dt_expiry in the current namespace is bound to the same object that the 
name dt_expiry in the namespace of module scoping2 is bound to. Function 
do_it re-binds that last one to a new one, with the new value; name 
dt_expiry in the current namespace is still bound to the old object. (If 
all of that sounds like gibberish, have a look at "Facts and myths about 
Python names and values" (text: 
https://nedbatchelder.com/text/names.html; slides and video: 
https://nedbatchelder.com/text/names1.html)


I would advice not to use 'import *', if at all possible, for multiple 
reasons, one of which is to prevent problems like this.


I would also advice not to use global variables from other modules 
directly, and in fact would advice to minimize the use of globals in 
general as much as possible. If you need to keep state between methods, 
it might be better to use a class.


--
"There is a theory which states that if ever anyone discovers exactly what the
Universe is for and why it is here, it will instantly disappear and be
replaced by something even more bizarre and inexplicable.
There is another theory which states that this has already happened."
-- Douglas Adams, The Restaurant at the End of the Universe

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
Ok, Ethan, that makes sense - I generally work with modules in folders, 
etc., but, this was just test code, but, 'see' if I instead import 
scoping2 as sc2, and then refer to sc2.dt_expiry and sc2.do_it, then it 
does operate as it should - thanks, again.



Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/06 18:57, Ethan Furman via Python-list wrote:

On 3/6/24 08:28, Jacob Kruger via Python-list wrote:

> C:\temp\py_try>python
> Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC 
v.1937 64 bit (AMD64)] on win32

> Type "help", "copyright", "credits" or "license" for more information.
>  >>> from scoping2 import *

And it becomes clear:  only do `from ... import *` when the module has 
been specifically designed to support that.


If you were to also do `import scoping2` and, after calling `do_it()`, 
`print(scoping2.dt_expiry)`, you would see that it had changed.


I know there are good explanations for how variables and names work in 
Python, but I couldn't find any at the moment. Sorry.


--
~Ethan~

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Ethan Furman via Python-list

On 3/6/24 08:28, Jacob Kruger via Python-list wrote:

> C:\temp\py_try>python
> Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC v.1937 64 
bit (AMD64)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> from scoping2 import *

And it becomes clear:  only do `from ... import *` when the module has been 
specifically designed to support that.

If you were to also do `import scoping2` and, after calling `do_it()`, `print(scoping2.dt_expiry)`, you would see that 
it had changed.


I know there are good explanations for how variables and names work in Python, but I couldn't find any at the moment. 
Sorry.


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
You'll see more details in other mail, but, here I am firing up standard 
python interpreter from within windows terminal, and then executing 
following line:


from scoping2 import *


And, this is under windows 11 windows terminal, which is where I 
generally interact with my python code, via command line - generally 
working with flask, and/or other forms of command line interaction, most 
of the time.



Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/06 17:39, Roel Schroeven via Python-list wrote:

Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list:
If you import the contents of that file into the python interpreter, 
[...]


What exactly to you mean by "import the contents of that file into the 
python interpreter"? Other people have put your code in a script, 
executed it, and saw it working as expected. I pasted in IPython, and 
likewise saw it working as expected, and the same with IDLE. It seems 
to me you must be doing something different from us; maybe the way you 
execute that code might be the key to this whole confusion.



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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
Matt, other mail is more relevant - seems to maybe have more to do with 
different behavour if import code, or not - no, does not make sense to 
me - but, here's the command line contents including printing out id() 
results, but, only working via importing code:


#---start session---

C:\temp\py_try>type scoping2.py
from datetime import datetime, timezone, timedelta

dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d 
%H:%M").replace(tzinfo=timezone.utc)


def do_it():
    global dt_expiry
    dt_expiry = datetime.now()+timedelta(minutes=5)
    print("date value", dt_expiry.strftime("%Y-%m-%d %H:%M"))
    print("ID", id(dt_expiry))
# end of do_it function


C:\temp\py_try>python
Python 3.11.7 (tags/v3.11.7:fa7a6f2, Dec  4 2023, 19:24:49) [MSC v.1937 
64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.
>>> from scoping2 import *
>>> print(dt_expiry)
1970-01-01 00:00:00+00:00
>>> print(id(dt_expiry))
1808577867152
>>> do_it()
date value 2024-03-06 18:39
ID 1808572660736
>>> print(dt_expiry)
1970-01-01 00:00:00+00:00
>>> print(id(dt_expiry))
1808577867152
>>>
---end session---

As in, the two different ID values are being returned outside and inside 
the function, whereas, if I included that bit inside the interpreter 
while typing code manually, chances are the same ID would be retained 
both inside and outside function.


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/06 15:57, Mats Wichmann via Python-list wrote:

On 3/6/24 05:55, Jacob Kruger via Python-list wrote:
Ok, simpler version - all the code in a simpler test file, and 
working with two separate variables to explain exactly what am 
talking about:


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check 
the value of the dt_expiry variable afterwards, it's reverted to the 
1970... value?



If I take out the line that removes values from l_test # 
l_test.clear() # before appending new value to it, then it will also 
not retain it's new/additional child items after the function exits, 
and will just revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling 
purely content retrieval functions against said objects, or assigning 
them new values from scratch seems to then ignore the global scope 
specified in the first line inside the function?



Hope this makes more sense


No, it doesn't. Your code is working as one would expect. For example, 
adding prints for the l_test variable, and removing the .clear() which 
you claim makes it not work, shows me:


before: l_test=[1, 2, 3], id(l_test)=140153285385856
leaving do_it: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856
after: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856

It's the same list object, as you can see by the id values. And the 
list is updating as expected.


And... you don't need the global statement for l_test. As it's 
mutable, you can mutate it in the function; the global only acts on 
assignment. Using "global" for that may make your intent more clear to 
readers though, although static checkers will grumble at you.


You must be doing something additional that you're not telling us about.



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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
int statements):


List before: [1, 2, 3]
start: 1970-01-01 00:00
inside after reassignment: 2024-03-06 08:57
outside after: 2024-03-06 08:57
List after: [1, 2, 3, 99]

As an aside, you have gone to some trouble to copy, clear, and 
reconstruct l_test.  It would be simpler like this (and you wouldn't 
have to import the "copy" library):


    l_temp = l_test[:]
    l_test = []

Instead of those lines and then this:

    for i in l_temp: l_test.append(i)

you could achieve the same thing with this single statement:

    l_test = l_test[:]


If I take out the line that removes values from l_test # 
l_test.clear() # before appending new value to it, then it will also 
not retain it's new/additional child items after the function exits, 
and will just revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling 
purely content retrieval functions against said objects, or assigning 
them new values from scratch seems to then ignore the global scope 
specified in the first line inside the function?



Hope this makes more sense


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/05 20:23, dn via Python-list wrote:

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At 
the very least, we can experiment without having to expend amounts 
of time in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am 
completely confused, or missing something - was that, for example, 
when having pre-defined a variable, and then included it in the 
global statement inside a function, that function was still 
referring to a completely local instance, without manipulating 
outside variable object at all unless I first executed a form of 
referral to it, before then possibly assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I 
just run bare-bones test code inside the python interpreter, but 
consistently occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first 
line

inside the functions includes the following:
# code snippet
 global l_servers
# end code snippet

That should, in theory, mean that if I assign a value to that variable
inside one of the functions, it should reflect globally?

However, it seems like that, while inside those functions, it can be
assigned a new list of values, but if I then return to the scope 
outside


the functions, it has reverted back to being an empty list = []?


The issue seems to specifically (or not) occur when I make a call 
to one function, and, in the steps it's executing in one context, 
while it's not doing anything to the list directly, it's then 
making a call to the second function, which is then meant to 
repopulate the list with a brand new set of values.



Now, what almost seems to be occurring, is that while just 
manipulating the contents of a referenced variable is fine in this 
context, the moment I try to reassign it, that's where the issue is 
occurring .



Here are relevant excerpts from the file:-


# start code

# original assignation in main part of file

l_servers = []


# function wich is initially being executed

def interact():
 global l_servers
 # extra code inbetween choosing what to carry out

 # ...

 # end of other code

 bl_response, o_out = list_servers()

 if bl_response: # just make sure other function call was 
successful


 l_servers.clear() # first make reference to global variable

 for srv in o_out: l_servers.append(srv) # now re-populate 
items


 # end code snippet from inside interact function

# end of interact function

# end of code snippet


That other function being called from within, list_servers() was 
initially just trying to populate the values inside the global list 
variable itself, but was ending up in a similar fashion - reverting 
to initial empty val

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 16:39 schreef Roel Schroeven via Python-list:

Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list:
If you import the contents of that file into the python interpreter, 
[...]


What exactly to you mean by "import the contents of that file into the 
python interpreter"? Other people have put your code in a script, 
executed it, and saw it working as expected. I pasted in IPython, and 
likewise saw it working as expected, and the same with IDLE. It seems 
to me you must be doing something different from us; maybe the way you 
execute that code might be the key to this whole confusion.
(As an aside, I made a type; "What exactly _do_ you mean" is what I 
meant to type)


If you want, you can play with the code online here:
https://tio.run/##pVPbitswEH3XVwwJITaNQ9KllATy0EKhL/2AUsqiWKNkWlkykrzZ7NJvT0e@JWT7VmPsEZozc87RqD7Ho7MPl8sUQpQ@QukUCqG9q0DJiJEqBKpqx1vDegHp@@JsHyk0UfaY0tXnIT/FQogpkKVI0lBAcJ4OZKWBJ2kaDEKo@IjPNfkz7MYGyxB9nYJsst58XBWrNb@wWm1Xq8kCJrPvxawqZgpmX7ezb5N86bE2ssQsvpDVbjewWzaxzIUwjxFD5PI/1gt4v4CHn0xKoQblHilm@VYAPwfj9kxrpLOAHjcFGX6jgrp1CqIDjxp9CnrMk/Qk9wYDaOdh7@JRtCUTMtDBgsVTp5edYbuIZZpzl/NP@dadsvzdaG1WkW2Yy@5D3mJqTzZmIzK5pTu37p3JmcOvhkUw2XB0pxsmRxlgj2h7jqh6ygcv990pOg18ZLEV5bFo0ulpoIhVaHOTP1XNvFN21rmV91W0M8adyB64hEWoUNowGHoiY8CwVg/sp8coyQ722MHTwEWRCZYy9SVGMd9KWqqbBFWcGkgh6MaWkbgOryNKlSi2igdZV8kj6RCXpUHps4FtPz/X4QwYU6F@RlNSMoESv071digk6xqtymgoJVXXMdl027DP22xyvg8cpfLt/I0KRL@RLiDwhHanPP@M3Brn@bAu2mdc6/k4B7vXMfxzs98R2L12/@tOPrb48owlz1fH575TMTbsr8sb@CfNR3kH@x9@l8tf

(sorry for the long URL; that's where tio.run puts the code)

Again it works as expected, but with or without the l_test.clear() line.

--
"Il semble que la perfection soit atteinte non quand il n'y a plus rien à
ajouter, mais quand il n'y a plus rien à retrancher."
"Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er
niets meer weg te nemen is."
-- Antoine de Saint-Exupéry

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list:

If you import the contents of that file into the python interpreter, [...]


What exactly to you mean by "import the contents of that file into the 
python interpreter"? Other people have put your code in a script, 
executed it, and saw it working as expected. I pasted in IPython, and 
likewise saw it working as expected, and the same with IDLE. It seems to 
me you must be doing something different from us; maybe the way you 
execute that code might be the key to this whole confusion.


--
"Il semble que la perfection soit atteinte non quand il n'y a plus rien à
ajouter, mais quand il n'y a plus rien à retrancher."
"Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er
niets meer weg te nemen is."
-- Antoine de Saint-Exupéry

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Thomas Passin via Python-list

On 3/6/2024 7:55 AM, Jacob Kruger via Python-list wrote:
Ok, simpler version - all the code in a simpler test file, and working 
with two separate variables to explain exactly what am talking about:


# start code

from datetime import datetime, timezone, timedelta

from copy import copy


# initialise original values

dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d 
%H:%M").replace(tzinfo=timezone.utc)


l_test = [1, 2, 3]


def do_it():
     global dt_expiry, l_test # asked python to refer to global 
variables for both


     # assign new value immediately

     dt_expiry = datetime.now()+timedelta(minutes=5)
     print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new 
value has been assigned

     # grab copy of list for re-use of items
     l_temp = copy(l_test)
     # following line means l_test will later on retain value in global 
scope because it was manipulated inside function instead of just 
assigned new value

     l_test.clear()
     # replace original set of values
     for i in l_temp: l_test.append(i)
     # add new item
     l_test.append(99)
# end of do_it function

# end code


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check the 
value of the dt_expiry variable afterwards, it's reverted to the 1970... 
value?


Not when I run your code. With a little annotation added to the print 
statements I get (I added the import statements to make it run, and I 
used the same date-time formatting for all three print statements):


List before: [1, 2, 3]
start: 1970-01-01 00:00
inside after reassignment: 2024-03-06 08:57
outside after: 2024-03-06 08:57
List after: [1, 2, 3, 99]

As an aside, you have gone to some trouble to copy, clear, and 
reconstruct l_test.  It would be simpler like this (and you wouldn't 
have to import the "copy" library):


l_temp = l_test[:]
l_test = []

Instead of those lines and then this:

for i in l_temp: l_test.append(i)

you could achieve the same thing with this single statement:

l_test = l_test[:]


If I take out the line that removes values from l_test # l_test.clear() 
# before appending new value to it, then it will also not retain it's 
new/additional child items after the function exits, and will just 
revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling purely 
content retrieval functions against said objects, or assigning them new 
values from scratch seems to then ignore the global scope specified in 
the first line inside the function?



Hope this makes more sense


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/05 20:23, dn via Python-list wrote:

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At 
the very least, we can experiment without having to expend amounts of 
time in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am completely 
confused, or missing something - was that, for example, when having 
pre-defined a variable, and then included it in the global statement 
inside a function, that function was still referring to a completely 
local instance, without manipulating outside variable object at all 
unless I first executed a form of referral to it, before then 
possibly assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I just 
run bare-bones test code inside the python interpreter, but 
consistently occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first line
inside the functions includes the following:
# code snippet
 global l_servers
# end code snippet

That should, in theor

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Thomas Passin via Python-list

On 3/6/2024 5:59 AM, Alan Gauld via Python-list wrote:

On 05/03/2024 22:46, Grant Edwards via Python-list wrote:

Unfortunately (presumably thanks to SEO) the enshittification of
Google has reached the point where searching for info on things like
Python name scope, the first page of links are to worthless sites like
geeksforgeeks.

And not just Google, I just tried bing, yahoo and duckduckgo
and they are all the same. Not a one listed anything from
python.org on the first page... In fact it didn't even appear
in the first 100 listings, although wikipedia did manage an
entry, eventually.


I don't know ... I just searched for "python local vs global variables" 
and a python.org page on it was the second hit. I usually use StartPage 
- who knows where they aggregate from - but the same search on Google 
and Bing also popped up the python.org link as the second hit.  As usual 
Bing was a nasty experience, though.


Still, if your search phrase isn't as well focused as that or you are 
less lucky, for sure you'll get all sorts of junk.


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Mats Wichmann via Python-list

On 3/6/24 05:55, Jacob Kruger via Python-list wrote:
Ok, simpler version - all the code in a simpler test file, and working 
with two separate variables to explain exactly what am talking about:


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check the 
value of the dt_expiry variable afterwards, it's reverted to the 1970... 
value?



If I take out the line that removes values from l_test # l_test.clear() 
# before appending new value to it, then it will also not retain it's 
new/additional child items after the function exits, and will just 
revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling purely 
content retrieval functions against said objects, or assigning them new 
values from scratch seems to then ignore the global scope specified in 
the first line inside the function?



Hope this makes more sense


No, it doesn't. Your code is working as one would expect. For example, 
adding prints for the l_test variable, and removing the .clear() which 
you claim makes it not work, shows me:


before: l_test=[1, 2, 3], id(l_test)=140153285385856
leaving do_it: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856
after: l_test=[1, 2, 3, 1, 2, 3, 99], id(l_test)=140153285385856

It's the same list object, as you can see by the id values. And the list 
is updating as expected.


And... you don't need the global statement for l_test. As it's mutable, 
you can mutate it in the function; the global only acts on assignment. 
Using "global" for that may make your intent more clear to readers 
though, although static checkers will grumble at you.


You must be doing something additional that you're not telling us about.


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
So, this does not make sense to me in terms of the following snippet 
from the official python docs page:


https://docs.python.org/3/faq/programming.html


"In Python, variables that are only referenced inside a function are 
implicitly global. If a variable is assigned a value anywhere within the 
function’s body, it’s assumed to be a local unless explicitly declared 
as global."



So, I would then assume that if I explicitly include a variable name 
inside the global statement, then even just assigning it a new value 
should update the variable in the global context, outside the function?



Unless this is something that changed from 3.11 to 3.12 - since that 
snippet is more or less referring to 3.12, but, don't think it was 
changed in any way?



Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/06 14:55, Jacob Kruger wrote:
Ok, simpler version - all the code in a simpler test file, and working 
with two separate variables to explain exactly what am talking about:


# start code

from datetime import datetime, timezone, timedelta

from copy import copy


# initialise original values

dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d 
%H:%M").replace(tzinfo=timezone.utc)


l_test = [1, 2, 3]


def do_it():
    global dt_expiry, l_test # asked python to refer to global 
variables for both


    # assign new value immediately

    dt_expiry = datetime.now()+timedelta(minutes=5)
    print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new 
value has been assigned

    # grab copy of list for re-use of items
    l_temp = copy(l_test)
    # following line means l_test will later on retain value in global 
scope because it was manipulated inside function instead of just 
assigned new value

    l_test.clear()
    # replace original set of values
    for i in l_temp: l_test.append(i)
    # add new item
    l_test.append(99)
# end of do_it function

# end code


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check 
the value of the dt_expiry variable afterwards, it's reverted to the 
1970... value?



If I take out the line that removes values from l_test # 
l_test.clear() # before appending new value to it, then it will also 
not retain it's new/additional child items after the function exits, 
and will just revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling purely 
content retrieval functions against said objects, or assigning them 
new values from scratch seems to then ignore the global scope 
specified in the first line inside the function?



Hope this makes more sense


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/05 20:23, dn via Python-list wrote:

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At 
the very least, we can experiment without having to expend amounts of 
time in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am 
completely confused, or missing something - was that, for example, 
when having pre-defined a variable, and then included it in the 
global statement inside a function, that function was still 
referring to a completely local instance, without manipulating 
outside variable object at all unless I first executed a form of 
referral to it, before then possibly assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I 
just run bare-bones test code inside the python interpreter, but 
consistently occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first 
line

inside the functions includes 

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Jacob Kruger via Python-list
Ok, simpler version - all the code in a simpler test file, and working 
with two separate variables to explain exactly what am talking about:


# start code

from datetime import datetime, timezone, timedelta

from copy import copy


# initialise original values

dt_expiry = datetime.strptime("1970-01-01 00:00", "%Y-%m-%d 
%H:%M").replace(tzinfo=timezone.utc)


l_test = [1, 2, 3]


def do_it():
    global dt_expiry, l_test # asked python to refer to global 
variables for both


    # assign new value immediately

    dt_expiry = datetime.now()+timedelta(minutes=5)
    print(dt_expiry.strftime("%Y-%m-%d %H:%M")) # just to show new 
value has been assigned

    # grab copy of list for re-use of items
    l_temp = copy(l_test)
    # following line means l_test will later on retain value in global 
scope because it was manipulated inside function instead of just 
assigned new value

    l_test.clear()
    # replace original set of values
    for i in l_temp: l_test.append(i)
    # add new item
    l_test.append(99)
# end of do_it function

# end code


If you import the contents of that file into the python interpreter, 
dt_expiry will start off as "1970-01-01 00:00", and, if you execute 
do_it function, it will print out the new value assigned to the 
dt_expiry variable inside that function, but if you then again check the 
value of the dt_expiry variable afterwards, it's reverted to the 1970... 
value?



If I take out the line that removes values from l_test # l_test.clear() 
# before appending new value to it, then it will also not retain it's 
new/additional child items after the function exits, and will just 
revert back to [1, 2, 3] each and every time.



In other words, with some of the variable/object types, if you use a 
function that manipulates the contents of a variable, before then 
re-assigning it a new value, it seems like it might then actually 
update/manipulate the global variable, but, either just calling purely 
content retrieval functions against said objects, or assigning them new 
values from scratch seems to then ignore the global scope specified in 
the first line inside the function?



Hope this makes more sense


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


On 2024/03/05 20:23, dn via Python-list wrote:

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At 
the very least, we can experiment without having to expend amounts of 
time in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am completely 
confused, or missing something - was that, for example, when having 
pre-defined a variable, and then included it in the global statement 
inside a function, that function was still referring to a completely 
local instance, without manipulating outside variable object at all 
unless I first executed a form of referral to it, before then 
possibly assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I just 
run bare-bones test code inside the python interpreter, but 
consistently occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first line
inside the functions includes the following:
# code snippet
 global l_servers
# end code snippet

That should, in theory, mean that if I assign a value to that variable
inside one of the functions, it should reflect globally?

However, it seems like that, while inside those functions, it can be
assigned a new list of values, but if I then return to the scope outside

the functions, it has reverted back to being an empty list = []?


The issue seems to specifically (or not) occur when I make a call to 
one function, and, in the steps it's executing in one context, while 
it's not doing anything to the list directly, it's then making a call 
to the second function, which is then meant to repopulate the list 
with a brand new set of values.



Now, what almost seems to be occurring, is that while just 
manipulating the contents of a referenced variable is fine in this 
context, the moment I try to reassign it, that's where the i

Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Alan Gauld via Python-list
On 05/03/2024 22:46, Grant Edwards via Python-list wrote:
> Unfortunately (presumably thanks to SEO) the enshittification of
> Google has reached the point where searching for info on things like
> Python name scope, the first page of links are to worthless sites like
> geeksforgeeks.
And not just Google, I just tried bing, yahoo and duckduckgo
and they are all the same. Not a one listed anything from
python.org on the first page... In fact it didn't even appear
in the first 100 listings, although wikipedia did manage an
entry, eventually.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-05 Thread Grant Edwards via Python-list
On 2024-03-05, Cameron Simpson via Python-list  wrote:

> Because there are no variable definitions in Python, when you write
> a function Python does a static analysis of it to decide which
> variables are local and which are not. If there's an assignment to a
> variable, it is a local variable.  _Regardless_ of whether that
> assignment has been executed, or gets executed at all (eg in an
> if-statement branch which doesn't fire).

Unfortunately, crap "information" sites like geeksforgeeks often
describe this either incorrectly or so vaguely as to be worthless.
>From the page https://www.geeksforgeeks.org/global-local-variables-python/

 Python Global variables are those which are not defined inside
 any function and have a global scope whereas Python local
 variables are those which are defined inside a function and their
 scope is limited to that function only.

Since "define" (in this context) isn't a term of art in Python, and
it's never defined on the page in question, the quoted paragraph is
not meaningful: it simply says that "global variables are global and
local variables are local".

That page goes on to say:

 In other words, we can say that local variables are accessible
 only inside the function in which it was initialized

This is equally crap. It doesn't matter whether the variable is
initialized or not. As Cameron correctly stated, if a function
contains an assignment to a variable, and that variable is not
declared global, then that variable is local.  For example:

def foo():
print(s)
if 0:
s = "there"
print(s)

In the function above s _is_not_ initialized in the function foo().
However, foo() does contain an assignment to s, therefore s is local
unless declared global/nonlocal.  [And the first print() will throw an
exception even if there is a value bound to the global name 's'.]

Unfortunately (presumably thanks to SEO) the enshittification of
Google has reached the point where searching for info on things like
Python name scope, the first page of links are to worthless sites like
geeksforgeeks.

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-05 Thread Cameron Simpson via Python-list

On 05Mar2024 20:13, Jacob Kruger  wrote:
Now, what almost seems to be occurring, is that while just manipulating 
the contents of a referenced variable is fine in this context, the 
moment I try to reassign it, that's where the issue is occurring .


Because there are no variable definitions in Python, when you write a 
function Python does a static analysis of it to decide which variables 
are local and which are not. If there's an assignment to a variable, it 
is a local variable.  _Regardless_ of whether that assignment has been 
executed, or gets executed at all (eg in an if-statement branch which 
doesn't fire).


You can use `global` or `nonlocal` to change where Python looks for a 
particular name.


In the code below, `f1` has no local variables and `f2` has an `x` and 
`l1` local variable.


x = 1
l1 = [1, 2, 3]

def f1():
print("f1 ...")
l1[1] = 5   # _not_ an assignment to "l1"
print("in f1, x =", x, "l1 =", l1)

def f2():
print("f2 ...")
x = 3
l1 = [6, 7, 9]  # assignment to "l1"
print("in f2, x =", x, "l1 =", l1)

print("outside, x =", x, "l1 =", l1)
f1()
print("outside after f1, x =", x, "l1 =", l1)
f2()
print("outside after f2, x =", x, "l1 =", l1)

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-05 Thread dn via Python-list

Jacob,

Please reduce the problem to a small code-set which reproduces the 
problem. If we can reproduce same, then that tells us something. At the 
very least, we can experiment without having to expend amounts of time 
in a (likely faulty) bid to reproduce the same environment.


Also, code is the ultimate description!


Perhaps start with a small experiment:

- after l_servers is created, print its id()
- after the global statement, print its id()
- after the clear/reassignment, print its id()

Is Python always working with the same list?
Please advise...


On 6/03/24 07:13, Jacob Kruger via Python-list wrote:

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am completely 
confused, or missing something - was that, for example, when having 
pre-defined a variable, and then included it in the global statement 
inside a function, that function was still referring to a completely 
local instance, without manipulating outside variable object at all 
unless I first executed a form of referral to it, before then possibly 
assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I just 
run bare-bones test code inside the python interpreter, but consistently 
occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first line
inside the functions includes the following:
# code snippet
     global l_servers
# end code snippet

That should, in theory, mean that if I assign a value to that variable
inside one of the functions, it should reflect globally?

However, it seems like that, while inside those functions, it can be
assigned a new list of values, but if I then return to the scope outside

the functions, it has reverted back to being an empty list = []?


The issue seems to specifically (or not) occur when I make a call to one 
function, and, in the steps it's executing in one context, while it's 
not doing anything to the list directly, it's then making a call to the 
second function, which is then meant to repopulate the list with a brand 
new set of values.



Now, what almost seems to be occurring, is that while just manipulating 
the contents of a referenced variable is fine in this context, the 
moment I try to reassign it, that's where the issue is occurring .



Here are relevant excerpts from the file:-


# start code

# original assignation in main part of file

l_servers = []


# function wich is initially being executed

def interact():
     global l_servers
     # extra code inbetween choosing what to carry out

     # ...

     # end of other code

     bl_response, o_out = list_servers()

     if bl_response: # just make sure other function call was successful

     l_servers.clear() # first make reference to global variable

     for srv in o_out: l_servers.append(srv) # now re-populate items

     # end code snippet from inside interact function

# end of interact function

# end of code snippet


That other function being called from within, list_servers() was 
initially just trying to populate the values inside the global list 
variable itself, but was ending up in a similar fashion - reverting to 
initial empty value, but, the above now seems to work, as long as I 
first make reference to/manipulate/work with global variable instead of 
just trying to reassign it a brand new value/set of items?



So, am I missing something obvious, have I forgotten about something 
else - yes, know that if was working from within an embedded function, I 
might need/want to then use the nonlocal statement against that variable 
name, but, honestly, just not sure how this can be occurring, and, it's 
not just with this one list variable, etc.?



If I try simple test code from within the python interpreter, using 
different types of variables, this does also not seem to be the same all 
the time, but, don't think it can relate to an iterable like a list, or 
else, just in case, here is the code snippet with all the import 
statements from the top of that file, in case something could be 
overriding standard behaviour - not likely in this context, but, really 
not sure what's occurring:


# import code snippet

import requests, time
from requests.auth import HTTPBasicAuth
import psutil as psu
import pytz
import bcrypt
from copy import copy
from datetime import datetime, timedelta, timezone
from dateutil.parser import parse

# end of import snippet


Thanks if you have any ideas/thoughts on the matter


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."




--
Regards,
=dn
--
https://mail.python.org/mailman/listi

Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-05 Thread Jacob Kruger via Python-list

Hi there


Working with python 3.11, and, issue that confused me for a little 
while, trying to figure out what was occurring - unless am completely 
confused, or missing something - was that, for example, when having 
pre-defined a variable, and then included it in the global statement 
inside a function, that function was still referring to a completely 
local instance, without manipulating outside variable object at all 
unless I first executed a form of referral to it, before then possibly 
assigning a new value to it.



Now, this does not seem to occur consistently if, for example, I just 
run bare-bones test code inside the python interpreter, but consistently 
occurs inside my actual testing script.



Basically, in a file with python code in that am using for a form of
testing at the moment, at the top of the file, under all the import
statements, I initiate the existence of a list variable to make use of

later:


# code snippet

l_servers = []

# end of first code snippet


Then, lower down, inside a couple of different functions, the first line
inside the functions includes the following:
# code snippet
    global l_servers
# end code snippet

That should, in theory, mean that if I assign a value to that variable
inside one of the functions, it should reflect globally?

However, it seems like that, while inside those functions, it can be
assigned a new list of values, but if I then return to the scope outside

the functions, it has reverted back to being an empty list = []?


The issue seems to specifically (or not) occur when I make a call to one 
function, and, in the steps it's executing in one context, while it's 
not doing anything to the list directly, it's then making a call to the 
second function, which is then meant to repopulate the list with a brand 
new set of values.



Now, what almost seems to be occurring, is that while just manipulating 
the contents of a referenced variable is fine in this context, the 
moment I try to reassign it, that's where the issue is occurring .



Here are relevant excerpts from the file:-


# start code

# original assignation in main part of file

l_servers = []


# function wich is initially being executed

def interact():
    global l_servers
    # extra code inbetween choosing what to carry out

    # ...

    # end of other code

    bl_response, o_out = list_servers()

    if bl_response: # just make sure other function call was successful

    l_servers.clear() # first make reference to global variable

    for srv in o_out: l_servers.append(srv) # now re-populate items

    # end code snippet from inside interact function

# end of interact function

# end of code snippet


That other function being called from within, list_servers() was 
initially just trying to populate the values inside the global list 
variable itself, but was ending up in a similar fashion - reverting to 
initial empty value, but, the above now seems to work, as long as I 
first make reference to/manipulate/work with global variable instead of 
just trying to reassign it a brand new value/set of items?



So, am I missing something obvious, have I forgotten about something 
else - yes, know that if was working from within an embedded function, I 
might need/want to then use the nonlocal statement against that variable 
name, but, honestly, just not sure how this can be occurring, and, it's 
not just with this one list variable, etc.?



If I try simple test code from within the python interpreter, using 
different types of variables, this does also not seem to be the same all 
the time, but, don't think it can relate to an iterable like a list, or 
else, just in case, here is the code snippet with all the import 
statements from the top of that file, in case something could be 
overriding standard behaviour - not likely in this context, but, really 
not sure what's occurring:


# import code snippet

import requests, time
from requests.auth import HTTPBasicAuth
import psutil as psu
import pytz
import bcrypt
from copy import copy
from datetime import datetime, timedelta, timezone
from dateutil.parser import parse

# end of import snippet


Thanks if you have any ideas/thoughts on the matter


Jacob Kruger
+2782 413 4791
"Resistance is futile!...Acceptance is versatile..."


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


Re: Match statement with literal strings

2023-06-07 Thread Jason Friedman via Python-list
>
> The bytecode compiler doesn't know that you intend RANGE
> to be a constant -- it thinks it's a variable to bind a
> value to.
>
> To make this work you need to find a way to refer to the
> value that isn't just a bare name. One way would be to
> define your constants using an enum:
>
> class Options(Enum):
> RANGE = "RANGE"
> MANDATORY = "MANDATORY"
>
> match stuff:
> case Options.RANGE:
>...
> case Options.MANDATORY:
>...
>

Got it, thank you.

On Wed, Jun 7, 2023 at 6:01 PM Greg Ewing via Python-list <
python-list@python.org> wrote:

> On 8/06/23 10:18 am, Jason Friedman wrote:
> > SyntaxError: name capture 'RANGE' makes remaining patterns unreachable
>
> The bytecode compiler doesn't know that you intend RANGE
> to be a constant -- it thinks it's a variable to bind a
> value to.
>
> To make this work you need to find a way to refer to the
> value that isn't just a bare name. One way would be to
> define your constants using an enum:
>
> class Options(Enum):
> RANGE = "RANGE"
> MANDATORY = "MANDATORY"
>
> match stuff:
> case Options.RANGE:
>...
> case Options.MANDATORY:
>...
>
> --
> Greg
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Match statement with literal strings

2023-06-07 Thread Chris Angelico via Python-list
On Thu, 8 Jun 2023 at 08:19, Jason Friedman via Python-list
 wrote:
>
> This gives the expected results:
>
> with open(data_file, newline="") as reader:
> csvreader = csv.DictReader(reader)
> for row in csvreader:
> #print(row)
> match row[RULE_TYPE]:
> case "RANGE":
> print("range")
> case "MANDATORY":
> print("mandatory")
> case _:
> print("nothing to do")
>
> This:
>
> RANGE = "RANGE"
> MANDATORY = "MANDATORY"
> with open(data_file, newline="") as reader:
> csvreader = csv.DictReader(reader)
> for row in csvreader:
> #print(row)
> match row[RULE_TYPE]:
> case RANGE:
> print("range")
> case MANDATORY:
> print("mandatory")
> case _:
> print("nothing to do")
>
> Gives (and I don't understand why):
>
> SyntaxError: name capture 'RANGE' makes remaining patterns unreachable

It's being as clear as it can. When you say "case RANGE:", that is not
a literal, that is a name capture. Check the docs and examples for
case statements for more details.

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


Re: Match statement with literal strings

2023-06-07 Thread Greg Ewing via Python-list

On 8/06/23 10:18 am, Jason Friedman wrote:

SyntaxError: name capture 'RANGE' makes remaining patterns unreachable


The bytecode compiler doesn't know that you intend RANGE
to be a constant -- it thinks it's a variable to bind a
value to.

To make this work you need to find a way to refer to the
value that isn't just a bare name. One way would be to
define your constants using an enum:

class Options(Enum):
   RANGE = "RANGE"
   MANDATORY = "MANDATORY"

match stuff:
   case Options.RANGE:
  ...
   case Options.MANDATORY:
  ...

--
Greg


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


Match statement with literal strings

2023-06-07 Thread Jason Friedman via Python-list
This gives the expected results:

with open(data_file, newline="") as reader:
csvreader = csv.DictReader(reader)
for row in csvreader:
#print(row)
match row[RULE_TYPE]:
case "RANGE":
print("range")
case "MANDATORY":
print("mandatory")
case _:
print("nothing to do")

This:

RANGE = "RANGE"
MANDATORY = "MANDATORY"
with open(data_file, newline="") as reader:
csvreader = csv.DictReader(reader)
for row in csvreader:
#print(row)
match row[RULE_TYPE]:
case RANGE:
print("range")
case MANDATORY:
print("mandatory")
case _:
print("nothing to do")

Gives (and I don't understand why):

SyntaxError: name capture 'RANGE' makes remaining patterns unreachable
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-19 Thread Peter J. Holzer
On 2022-12-18 16:49:27 +, Stefan Ram wrote:
> Dennis Lee Bieber  writes:
> >>for idx, thing in enumerate(things):
> >>if idx == 103: 
> >>continue
> >>do_something_with(thing)
> >>
> > For this example, I'd probably reverse the condition.
> > if idx != 103:
> > do_something_with(thing)
> 
>   The first four lines of the quotation above cannot be a
>   complete program as "do_something_with" is not defined
>   therein, so they must be part of a larger program.
>   If, in this larger program, something still follows
>   "do_something_with(thing)" in the loop, the new program
>   after the transformation might not show the same behavior.

“do_something_with(thing)” is obviously not intended to be a single
function call but as a shorthand for “one or more lines of code which do
something with `thing`”. So there is nothing after it because it is
included in it.

That said, the "fail and bail" technique is often more readable than
putting the main incode inside of an if - especially if that code is
long and/or it is guarded by multiple conditions.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-18 Thread Tony Oliver
On Saturday, 17 December 2022 at 23:58:11 UTC, avi.e...@gmail.com wrote:
> Is something sort of taboo when using something like a computer language to 
> write a program?

With what else would you write a program?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-18 Thread Dennis Lee Bieber
On Wed, 14 Dec 2022 10:53:10 -0800 (PST), Aaron P
 declaimed the following:

Late response here, and the concept may have been covered in
skimmed-over posts..

>I occasionally run across something like:
>
>for idx, thing in enumerate(things):
>if idx == 103: 
>continue
>do_something_with(thing)
>

For this example, I'd probably reverse the condition.

if idx != 103:
do_something_with(thing)

and hence completely drop the "continue" -- after all, if idx is 103, the
if statement falls through, and the end of the loop acts as an implicit
"continue"

OTOH: if the "if/continue" is buried in four or five layers of
conditionals, it could be cleaner than trying to configure the conditionals
to have a chained exit.


-- 
Wulfraed Dennis Lee Bieber AF6VN
wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-17 Thread Chris Angelico
On Sun, 18 Dec 2022 at 10:59,  wrote:
>
> If a compiler or interpreter HAPPILY (as happy as machines/code get) compiles 
> or interprets your code without errors every time you use it a certain way, 
> then it is not wrong to use it. Of course if it subject to change or already 
> deprecated, ...
>

Source code is, first and foremost, for programmers to read. You're
confusing it with binary executables.

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


Re: Single line if statement with a continue

2022-12-17 Thread Thomas Passin

>if 5 > 3: a = a * 3
>  b = b * 3

That would be a fairly weird construction, neither one thing nor 
another.  But still, if you really want it that way, this is legal Python:


a = 2; b = 10
if 5 > 3: a = a * 3;\
  b = b * 3
print(a, b)  # 6 30

On 12/17/2022 6:57 PM, avi.e.gr...@gmail.com wrote:

I happen to be of two schools here.

Is something sort of taboo when using something like a computer language to 
write a program? What if another language tells you to do it a different way or 
sort of the opposite? Is it based on the details of the language and 
implementation or the prejudices of the one trying to make rules?

If a compiler or interpreter HAPPILY (as happy as machines/code get) compiles 
or interprets your code without errors every time you use it a certain way, 
then it is not wrong to use it. Of course if it subject to change or already 
deprecated, ...


That's not the point of using some consistent style. IMO, source code 
should be clear, compact, and easy for someone else to understand.  That 
someone might be you six months from now.


These objectives do not always align.  Consistency helps reduce mental 
effort by using constructions and formatting in a familiar way - 
basically, using a familiar programming idiom.  Compactness can help 
clarity, unless the code is too terse which can become a hindrance.  But 
too much verbosity can get in the way of grasping the essential processing.


Personal taste and familiarity also factor into assessing clarity and 
compactness.


It's always a balancing act.  Style guides can help by providing good 
basic idioms. There's no law** that says you *have* to follow them 
exactly all the time.  But it's helpful when you can.  If your own style 
guide i is similar to one used widely, so much the better.


**Except at some organizations


If people around you complain they do not like it, then the word "taboo" does 
apply but you can feel free to re-educate them or move on.

This reminds me too much of people who are taught some grammar such as some part of a sentence requiring a 
"noun-phrase" and later it explains that a non-phrase can be EITHER a noun accompanied by an assortment of 
other words that together form a phrase, or just a "noun" or just a "pronoun" or just a 
"nothing but an implied pronoun".

So which is it? The answer is all of them are legal, at least within bounds. A sentence like "Come over 
here" is an implied "You come over here" and works best if earlier sentences have laid some 
context on what is being talked about so the "you" is obvious or will be explained later but 
perhaps should be discouraged in other circumstances.

So back to computer languages. Many languages using grouping with something like 
"{...}" often do not care where you break your lines albeit some get touchy 
about an else statement placed improperly. It is perfectly legal to write:

If (condition) { first; second; third }

The grammar basically states that a "statement" or similar name can be a simple 
statement or a compound statement and anywhere one can go, within reason, so can the 
other.

Python has a twist here in that they discourage or outlaw some such things as 
they use mainly indentation rather than braces. This makes it hard to use 
multiple lines when the first line is way at the end as the others do not line 
up. It becomes all or ONE. I mean it allows a simple expression on the same 
line after the colon and then terminates the construct so a future indented 
line is seen as an indentation error. An experiment shows the following attempt 
to line up a second line way over below the first also fails:

if 5 > 3: a = a * 3
   b = b * 3

In a constant width font my second line is indented so "b is just below "a" and it fails because 
the interpreter does not measure the beginning column of the first line as being where the " a = a * 3" 
starts but at the "if" and that makes reasonable sense. I could imagine another design but since it is 
not what is done, the multi-line version MUST be done only on subsequent lines indented properly and identically.

So it is not really right or wrong to do one-liners. It is legal and often more 
readable. But if you ever want to extend your lines to be multi-line, it 
probably is best to use the multi-line approach regularly.

Still, using many editors, you will rapidly notice something is wrong when adding a line 
of code and seeing it is indented under the "if".

Is anyone really thrilled to read code in other languages that span so many 
lines:

If (condition)
   {
   var1 = 0
   }
else
   {
   var1 = 1
   }

It is a great way to get your line-of-code count up but the many briefer 
versions can be easier to read in one glance up to and including a bit murkier 
ones like

var1 =  (condition) ? 0 : 1

My view is that simp

RE: Single line if statement with a continue

2022-12-17 Thread avi.e.gross
I happen to be of two schools here.

Is something sort of taboo when using something like a computer language to 
write a program? What if another language tells you to do it a different way or 
sort of the opposite? Is it based on the details of the language and 
implementation or the prejudices of the one trying to make rules?

If a compiler or interpreter HAPPILY (as happy as machines/code get) compiles 
or interprets your code without errors every time you use it a certain way, 
then it is not wrong to use it. Of course if it subject to change or already 
deprecated, ...

If people around you complain they do not like it, then the word "taboo" does 
apply but you can feel free to re-educate them or move on.

This reminds me too much of people who are taught some grammar such as some 
part of a sentence requiring a "noun-phrase" and later it explains that a 
non-phrase can be EITHER a noun accompanied by an assortment of other words 
that together form a phrase, or just a "noun" or just a "pronoun" or just a 
"nothing but an implied pronoun".

So which is it? The answer is all of them are legal, at least within bounds. A 
sentence like "Come over here" is an implied "You come over here" and works 
best if earlier sentences have laid some context on what is being talked about 
so the "you" is obvious or will be explained later but perhaps should be 
discouraged in other circumstances.

So back to computer languages. Many languages using grouping with something 
like "{...}" often do not care where you break your lines albeit some get 
touchy about an else statement placed improperly. It is perfectly legal to 
write:

If (condition) { first; second; third }

The grammar basically states that a "statement" or similar name can be a simple 
statement or a compound statement and anywhere one can go, within reason, so 
can the other.

Python has a twist here in that they discourage or outlaw some such things as 
they use mainly indentation rather than braces. This makes it hard to use 
multiple lines when the first line is way at the end as the others do not line 
up. It becomes all or ONE. I mean it allows a simple expression on the same 
line after the colon and then terminates the construct so a future indented 
line is seen as an indentation error. An experiment shows the following attempt 
to line up a second line way over below the first also fails:

if 5 > 3: a = a * 3
  b = b * 3

In a constant width font my second line is indented so "b is just below "a" and 
it fails because the interpreter does not measure the beginning column of the 
first line as being where the " a = a * 3" starts but at the "if" and that 
makes reasonable sense. I could imagine another design but since it is not what 
is done, the multi-line version MUST be done only on subsequent lines indented 
properly and identically.

So it is not really right or wrong to do one-liners. It is legal and often more 
readable. But if you ever want to extend your lines to be multi-line, it 
probably is best to use the multi-line approach regularly.

Still, using many editors, you will rapidly notice something is wrong when 
adding a line of code and seeing it is indented under the "if".

Is anyone really thrilled to read code in other languages that span so many 
lines:

If (condition)
  {
  var1 = 0
  }
else
  {
  var1 = 1
  }

It is a great way to get your line-of-code count up but the many briefer 
versions can be easier to read in one glance up to and including a bit murkier 
ones like

var1 =  (condition) ? 0 : 1

My view is that simple things that fit easily on a screen, and also held all at 
once in my mind, should be written fairly concisely. I do admit how much I can 
hold at once varies based on how well I can concentrate at that moment and have 
met people whose short-term memory for many things is larger or smaller than 
mine. But generally people can handle simple constructs like we are discussing.

Complicated things and ones that might need changes later should be written 
very cautiously and in detail including judicious use of comments around and 
within the code OR consider re-planning it into a less complicated form that 
calls on other fairly simple functions that can each  be decently understood 
based on naming and usage.

If you have a complicated calculation that eventually assigns values to a1, a2, 
a3, a4 then a language like Python makes a
One liner easy as in:

If (condition): 
  a1, a2, a3, a4 = func(args)

But now that four or more lines have been collapsed into one, maybe something 
like this works too and maybe is a tad more readable with parentheses:

If (condition): (a1, a2, a3, a4) = func(args)


I am not suggesting using something silly like this though:

if(1): (a, b, c, d) = (min(1,2), (1+2)/2, (1*2*2*3)/4, max(1,2))

That is so way beyo

Re: Single line if statement with a continue

2022-12-17 Thread dn

On 16/12/2022 02.30, Rob Cliffe via Python-list wrote:

On 15/12/2022 04:35, Chris Angelico wrote:
On Thu, 15 Dec 2022 at 14:41, Aaron P  
wrote:

I occasionally run across something like:

for idx, thing in enumerate(things):
 if idx == 103:
 continue
 do_something_with(thing)

It seems more succinct and cleaner to use:

if idx == 103: continue.


Nothing at all wrong with writing that on a single line. If you have
issues with Flake8 not accepting your choices, reconfigure Flake8 :)

ChrisA
I'm so glad that Chris and others say this.  It (i.e. if plus 
break/continue/return on a single line) is something I have quite often 
done in my own code, albeit with a feeling of guilt that I was breaking 
a Python taboo.  Now I will do it with a clear conscience. 


Anxiety doesn't help anyone - least of all you.

Remember another Python mantra: "we're all adults here"!

(also (compulsory interjection) PEP-008 is not a set of rules for all 
Python code - see PEP-008)


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-17 Thread Abdullah Nafees
Just wanted to say that a silent reader like me learnt more about PEP-8
solely from this thread than my mentor at work or any other course I have
taken earlier this year. Thank you so much.

On Sun, 18 Dec 2022, 00:16 Rob Cliffe via Python-list, <
python-list@python.org> wrote:

>
>
> On 15/12/2022 04:35, Chris Angelico wrote:
> > On Thu, 15 Dec 2022 at 14:41, Aaron P 
> wrote:
> >> I occasionally run across something like:
> >>
> >> for idx, thing in enumerate(things):
> >>  if idx == 103:
> >>  continue
> >>  do_something_with(thing)
> >>
> >> It seems more succinct and cleaner to use:
> >>
> >> if idx == 103: continue.
> >>
> >>
> >> Nothing at all wrong with writing that on a single line. If you have
> >> issues with Flake8 not accepting your choices, reconfigure Flake8 :)
> >>
> >> ChrisA
> I'm so glad that Chris and others say this.  It (i.e. if plus
> break/continue/return on a single line) is something I have quite often
> done in my own code, albeit with a feeling of guilt that I was breaking
> a Python taboo.  Now I will do it with a clear conscience. 
> Best wishes
> Rob Cliffe
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-17 Thread Rob Cliffe via Python-list



On 15/12/2022 04:35, Chris Angelico wrote:

On Thu, 15 Dec 2022 at 14:41, Aaron P  wrote:

I occasionally run across something like:

for idx, thing in enumerate(things):
 if idx == 103:
 continue
 do_something_with(thing)

It seems more succinct and cleaner to use:

if idx == 103: continue.


Nothing at all wrong with writing that on a single line. If you have
issues with Flake8 not accepting your choices, reconfigure Flake8 :)

ChrisA
I'm so glad that Chris and others say this.  It (i.e. if plus 
break/continue/return on a single line) is something I have quite often 
done in my own code, albeit with a feeling of guilt that I was breaking 
a Python taboo.  Now I will do it with a clear conscience. 

Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-15 Thread Grant Edwards
On 2022-12-15, MRAB  wrote:

> A problem with having a single return is that it can lead to excessive 
> indentation:
>
>  if test_1:
>  ...
>
>  if test_2:
>  ...
>
>  if test_3:
>  ...
>
>  return

I sometimes have to work on code like that with bocks nested 8-10
levels deep spread out over hundreds of lines. The first thing I do is
convert it to something like the code below. Check for error
conditions up front and exit accordingly.

When working in C, a "goto error" or "goto done" instead of "return"
can provide a "single return" if that's deemed important.

>
> With multiple returns, however:
>
>  if not test_1:
>  return
>
>  ...
>
>  if not test_2:
>  return
>
>  ...
>
>  if not test_3:
>  return
>
>  ...
>
>  return

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


Re: Single line if statement with a continue

2022-12-15 Thread Thomas Passin

On 12/15/2022 3:58 AM, Chris Green wrote:

Thomas Passin  wrote:

I personally tend to use

if test: return

even inside larger blocks.


I always try to avoid multiple returns from functions/methods, as soon
as things get complex it's all to easy to miss clean-up etc.

"No multiple returns" is often found in programming guidelines.


Yes, or alternatively, "If any branch uses a return, they all should."


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


Re: Single line if statement with a continue

2022-12-15 Thread MRAB

On 2022-12-15 19:05, avi.e.gr...@gmail.com wrote:

Multiple returns is not always a problem as it depends on the nature of a
task whether it has complex enough cases.

I have seen code that instead sets Boolean variables when it is ready to
return and everything else keeps checking the variables to skip further
processing so the program then slides down to a single return statement. If
done properly, it boils down to the same result if VERY carefully done but
with lots of sometimes complex IF statements that may be not be updated well
if the logic changes a bit.

In such cases, I vastly prefer clean and unambiguous returns  from the
function right at the point where the decision is made, UNLESS the exit is
not always clean as there may be cleanup or finalization of some kind
required that is best done at a single point.

A problem with having a single return is that it can lead to excessive 
indentation:


if test_1:
...

if test_2:
...

if test_3:
...

return

With multiple returns, however:

if not test_1:
return

...

if not test_2:
return

...

if not test_3:
return

...

return


If efficiency is an issue, then clearly a rapid exit may beat one where
processing continues for a while and also often beats a method that involves
creating and calling multiple smaller functions with lots of overhead.

Having said all that, of course, if you can find a fairly simple algorithm
that only returns from one place, use it instead of a convoluted one. The
issue is not necessarily that multiple return points are bad, but that they
are often a symptom of sloppy planning. But for some problems, they fit well
and simplify things.

-Original Message-
From: Python-list  On
Behalf Of Stefan Ram
Sent: Thursday, December 15, 2022 7:42 AM
To: python-list@python.org
Subject: Re: Single line if statement with a continue

Chris Green  writes:
I always try to avoid multiple returns from functions/methods, as soon 
as things get complex it's all to easy to miss clean-up etc.


   This "complexity" could also mean that the function has
   become too large. In such a case, one could say that the
   /size/ of the function is the actual cause of problems
   and not multiple returns.

|Fools ignore complexity. Pragmatists suffer it. Some can avoid it.
|Geniuses remove it.
Alan Perlis (1922/1990)

   Within a small function, multiple returns are rarely
   a problem.

   When a function is large, one can apply well-known
   refactors. For an example, look at the code in the
   first post of the thread

Python script not letting go of files
Date: Tue, 29 Nov 2022 12:52:15 +

   and then at my reply of

29 Nov 2022 14:44:39 GMT.


"No multiple returns" is often found in programming guidelines.


   I religiously followed that when I did more C programming
   than today. Then, I read an article about how the result
   pattern makes functions measurably slower. (It should not
   with an optimizing compiler, but it did due to those
   measurements. Can't find that article now, though.)

   "Result pattern" I call writing,

if a:
 result = 123
else:
 result = 456
return result

   , instead of,

if a:
 return 123
else
 return 456

   .


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



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


Re: Single line if statement with a continue

2022-12-15 Thread Weatherby,Gerard
I once saw a C function full of GOTOs which jumped to the return state at the 
bottom of the functions because the programmer had learned that “multiple 
returns are a bad idea.”

I totally agree multiple returns causing confusion is a symptom of poor design, 
not a cause.

Required cleanup is easily handled by the try / finally construct.

From: Python-list  on 
behalf of avi.e.gr...@gmail.com 
Date: Thursday, December 15, 2022 at 2:07 PM
To: python-list@python.org 
Subject: RE: Single line if statement with a continue
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

Multiple returns is not always a problem as it depends on the nature of a
task whether it has complex enough cases.

I have seen code that instead sets Boolean variables when it is ready to
return and everything else keeps checking the variables to skip further
processing so the program then slides down to a single return statement. If
done properly, it boils down to the same result if VERY carefully done but
with lots of sometimes complex IF statements that may be not be updated well
if the logic changes a bit.

In such cases, I vastly prefer clean and unambiguous returns  from the
function right at the point where the decision is made, UNLESS the exit is
not always clean as there may be cleanup or finalization of some kind
required that is best done at a single point.

If efficiency is an issue, then clearly a rapid exit may beat one where
processing continues for a while and also often beats a method that involves
creating and calling multiple smaller functions with lots of overhead.

Having said all that, of course, if you can find a fairly simple algorithm
that only returns from one place, use it instead of a convoluted one. The
issue is not necessarily that multiple return points are bad, but that they
are often a symptom of sloppy planning. But for some problems, they fit well
and simplify things.

-Original Message-
From: Python-list  On
Behalf Of Stefan Ram
Sent: Thursday, December 15, 2022 7:42 AM
To: python-list@python.org
Subject: Re: Single line if statement with a continue

Chris Green  writes:
>I always try to avoid multiple returns from functions/methods, as soon
>as things get complex it's all to easy to miss clean-up etc.

  This "complexity" could also mean that the function has
  become too large. In such a case, one could say that the
  /size/ of the function is the actual cause of problems
  and not multiple returns.

|Fools ignore complexity. Pragmatists suffer it. Some can avoid it.
|Geniuses remove it.
Alan Perlis (1922/1990)

  Within a small function, multiple returns are rarely
  a problem.

  When a function is large, one can apply well-known
  refactors. For an example, look at the code in the
  first post of the thread

Python script not letting go of files
Date: Tue, 29 Nov 2022 12:52:15 +

  and then at my reply of

29 Nov 2022 14:44:39 GMT.

>"No multiple returns" is often found in programming guidelines.

  I religiously followed that when I did more C programming
  than today. Then, I read an article about how the result
  pattern makes functions measurably slower. (It should not
  with an optimizing compiler, but it did due to those
  measurements. Can't find that article now, though.)

  "Result pattern" I call writing,

if a:
result = 123
else:
result = 456
return result

  , instead of,

if a:
return 123
else
return 456

  .


--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!lVeLOl91qPUjowC1ch_u353upn8X-V4rsReaNberWpIXBlBP6CYcDgr_aaMb0ZHoYX4YWO8id1biCn6sW7V6vJM$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!lVeLOl91qPUjowC1ch_u353upn8X-V4rsReaNberWpIXBlBP6CYcDgr_aaMb0ZHoYX4YWO8id1biCn6sW7V6vJM$>

--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!lVeLOl91qPUjowC1ch_u353upn8X-V4rsReaNberWpIXBlBP6CYcDgr_aaMb0ZHoYX4YWO8id1biCn6sW7V6vJM$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!lVeLOl91qPUjowC1ch_u353upn8X-V4rsReaNberWpIXBlBP6CYcDgr_aaMb0ZHoYX4YWO8id1biCn6sW7V6vJM$>
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Single line if statement with a continue

2022-12-15 Thread avi.e.gross
Multiple returns is not always a problem as it depends on the nature of a
task whether it has complex enough cases. 

I have seen code that instead sets Boolean variables when it is ready to
return and everything else keeps checking the variables to skip further
processing so the program then slides down to a single return statement. If
done properly, it boils down to the same result if VERY carefully done but
with lots of sometimes complex IF statements that may be not be updated well
if the logic changes a bit.

In such cases, I vastly prefer clean and unambiguous returns  from the
function right at the point where the decision is made, UNLESS the exit is
not always clean as there may be cleanup or finalization of some kind
required that is best done at a single point.

If efficiency is an issue, then clearly a rapid exit may beat one where
processing continues for a while and also often beats a method that involves
creating and calling multiple smaller functions with lots of overhead.

Having said all that, of course, if you can find a fairly simple algorithm
that only returns from one place, use it instead of a convoluted one. The
issue is not necessarily that multiple return points are bad, but that they
are often a symptom of sloppy planning. But for some problems, they fit well
and simplify things.

-Original Message-
From: Python-list  On
Behalf Of Stefan Ram
Sent: Thursday, December 15, 2022 7:42 AM
To: python-list@python.org
Subject: Re: Single line if statement with a continue

Chris Green  writes:
>I always try to avoid multiple returns from functions/methods, as soon 
>as things get complex it's all to easy to miss clean-up etc.

  This "complexity" could also mean that the function has
  become too large. In such a case, one could say that the
  /size/ of the function is the actual cause of problems
  and not multiple returns.

|Fools ignore complexity. Pragmatists suffer it. Some can avoid it. 
|Geniuses remove it.
Alan Perlis (1922/1990)

  Within a small function, multiple returns are rarely
  a problem.

  When a function is large, one can apply well-known
  refactors. For an example, look at the code in the
  first post of the thread

Python script not letting go of files
Date: Tue, 29 Nov 2022 12:52:15 +

  and then at my reply of

29 Nov 2022 14:44:39 GMT.

>"No multiple returns" is often found in programming guidelines.

  I religiously followed that when I did more C programming
  than today. Then, I read an article about how the result
  pattern makes functions measurably slower. (It should not
  with an optimizing compiler, but it did due to those
  measurements. Can't find that article now, though.)

  "Result pattern" I call writing,

if a:
result = 123
else:
result = 456
return result

  , instead of,

if a:
return 123
else
return 456 

  .


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

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


Re: Single line if statement with a continue

2022-12-15 Thread Cecil Westerhof via Python-list
r...@zedat.fu-berlin.de (Stefan Ram) writes:

>>"No multiple returns" is often found in programming guidelines.
>
>   I religiously followed that when I did more C programming
>   than today. Then, I read an article about how the result
>   pattern makes functions measurably slower. (It should not
>   with an optimizing compiler, but it did due to those
>   measurements. Can't find that article now, though.)

That makes me think about the quote from Edsger W. Dijkstra about the
go to statement:
Please do not fall into the trap of believing that I am terribly
dogmatic about the go to statement. I have the uncomfortable
feeling that others are making a religion out of it, as if the
conceptual problems of programming could be solved by a simple
trick, by a simple form of coding discipline! 

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-15 Thread Chris Green
Thomas Passin  wrote:
>I personally tend to use
> 
> if test: return
> 
> even inside larger blocks.

I always try to avoid multiple returns from functions/methods, as soon
as things get complex it's all to easy to miss clean-up etc.

"No multiple returns" is often found in programming guidelines.

-- 
Chris Green
·
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Single line if statement with a continue

2022-12-14 Thread avi.e.gross
Unless someone is counting lines of code for some purpose, like number of
error found per thousand lines of code, many short one-liners strike me as
more readable and especially if followed by a blank line so it is a bit
obvious.

Consider a similar issue in many languages that use curly braces and where
they can be skipped in a one liner like "if (condition) statement" rather
than the style some use on multiple lines like:

If (condition) {
  Statement
}

Or even:

If (condition)
  {
  Statement
  }


Of course, once you have additional parts following like an "else" that
contains multiple statements, it seems more symmetric to do both parts the
same style.

And in commented code, a one-liner may get long and harder to read as in 

If (condition) statement # long comment

Note the above are not python and the absence of a colon is intentional. No
one language is being discussed and some have their own vagaries and
variants such as not knowing if your code is done if you change lines in
ambiguous situations.  And note some languages support methods like the ?:
operator or the inline if/else python allows as in this:

min = 5
low = 12
x = low if low >= 12 else min
x
12
low = 3
x = low if low >= 12 else min
result
12

Clearly that is a one-liner that almost has to be a one liner as there is no
obvious easy way to wrap it into multiple lines.

I mean the following works, albeit darned if I know if any of it should be
indented or who wants to read it this way:

x = low \
if \
  low >= 12 \
else \
  min

x
5

As many have discussed, it is a matter of taste and people should be
flexible enough to program in whatever style others want to see when that
applies such as working in a group project or fixing someone else's code.


-Original Message-
From: Python-list  On
Behalf Of dn
Sent: Thursday, December 15, 2022 12:24 AM
To: python-list@python.org
Subject: Re: Single line if statement with a continue

On 15/12/2022 07.53, Aaron P wrote:
> I occasionally run across something like:
> 
> for idx, thing in enumerate(things):
>  if idx == 103:
>  continue
>  do_something_with(thing)
> 
> It seems more succinct and cleaner to use:
> 
> if idx == 103: continue.
> 
> Of course this would be considered an anti-pattern, and Flake8 will
complain.
> 
> Any opinions, or feedback on the matter.


These aged-eyes prefer the second line and indentation.


However, another alternative (given simplicity of example):

for ...
 if idx != 103:
 do_something ...


Which could, in-turn, be boiled-down to a 'one-liner'.

-- 
Regards,
=dn
-- 
https://mail.python.org/mailman/listinfo/python-list

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


Re: Single line if statement with a continue

2022-12-14 Thread Chris Angelico
On Thu, 15 Dec 2022 at 16:29, Thomas Passin  wrote:
>
> PEP-8, which is Guido's style guide and generally good to follow, does
> not completely discourage single-line usage like the example.  It's not
> clear to me how Chris's example fits into the guidelines.
>
> PEP-8:
> "While sometimes it’s okay to put an if/for/while with a small body on
> the same line, never do this for multi-clause statements.
> ...
> # Wrong:
> if foo == 'blah': do_blah_thing()
> for x in lst: total += x
> while t < 10: t = delay()
> "
>
> If the one-liner were not in a multi-statement block, it would be all
> right with PEP-8.

Not sure what your point is about it being "in" a multi-statement
block - PEP 8 has nothing to say about that. What it's saying is that
you shouldn't do this:

if foo == 'blah': one(); two(); three()

And I agree; if you're putting more than one statement after your
'if', it's generally clearest to have it on multiple lines. But a
simple "continue" or "break" statement works just fine on the same
line as the if.

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


Re: Single line if statement with a continue

2022-12-14 Thread Thomas Passin
PEP-8, which is Guido's style guide and generally good to follow, does 
not completely discourage single-line usage like the example.  It's not 
clear to me how Chris's example fits into the guidelines.


PEP-8:
"While sometimes it’s okay to put an if/for/while with a small body on 
the same line, never do this for multi-clause statements.

...
# Wrong:
if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()
"

If the one-liner were not in a multi-statement block, it would be all 
right with PEP-8.  OTOH, there is nothing that says one has to fully 
comply with PEP-8. I personally tend to use


if test: return

even inside larger blocks.  If one is working with other someone else's 
project and there is a style guide, it's important to follow that guide 
because the other people involved will find it easier to read and 
understand your code.


If you are working on your own project, PEP-8 is always a good starting 
point, and flake8 and pylint will be happier.  That's worth something.


On 12/14/2022 11:35 PM, Chris Angelico wrote:

On Thu, 15 Dec 2022 at 14:41, Aaron P  wrote:


I occasionally run across something like:

for idx, thing in enumerate(things):
 if idx == 103:
 continue
 do_something_with(thing)

It seems more succinct and cleaner to use:

if idx == 103: continue.

Of course this would be considered an anti-pattern, and Flake8 will complain.

Any opinions, or feedback on the matter.


Nothing at all wrong with writing that on a single line. If you have
issues with Flake8 not accepting your choices, reconfigure Flake8 :)

ChrisA


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


Re: Single line if statement with a continue

2022-12-14 Thread dn

On 15/12/2022 07.53, Aaron P wrote:

I occasionally run across something like:

for idx, thing in enumerate(things):
 if idx == 103:
 continue
 do_something_with(thing)

It seems more succinct and cleaner to use:

if idx == 103: continue.

Of course this would be considered an anti-pattern, and Flake8 will complain.

Any opinions, or feedback on the matter.



These aged-eyes prefer the second line and indentation.


However, another alternative (given simplicity of example):

for ...
if idx != 103:
do_something ...


Which could, in-turn, be boiled-down to a 'one-liner'.

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Single line if statement with a continue

2022-12-14 Thread Chris Angelico
On Thu, 15 Dec 2022 at 14:41, Aaron P  wrote:
>
> I occasionally run across something like:
>
> for idx, thing in enumerate(things):
> if idx == 103:
> continue
> do_something_with(thing)
>
> It seems more succinct and cleaner to use:
>
> if idx == 103: continue.
>
> Of course this would be considered an anti-pattern, and Flake8 will complain.
>
> Any opinions, or feedback on the matter.

Nothing at all wrong with writing that on a single line. If you have
issues with Flake8 not accepting your choices, reconfigure Flake8 :)

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


Single line if statement with a continue

2022-12-14 Thread Aaron P
I occasionally run across something like:

for idx, thing in enumerate(things):
if idx == 103: 
continue
do_something_with(thing)

It seems more succinct and cleaner to use:

if idx == 103: continue.

Of course this would be considered an anti-pattern, and Flake8 will complain.

Any opinions, or feedback on the matter.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: SyntaxError: multiple statements found while compiling a single statement

2022-08-07 Thread Joe Pfeiffer
Sohail Ahmad  writes:

> kindly please help me about issues
>  SyntaxError: multiple statements found while compiling a single statement 
> how to solve this issues

Please post the code that got the error.  Preferably several lines
before the actual error, and the line with the error itself.
-- 
https://mail.python.org/mailman/listinfo/python-list


on a statement followed by an expression

2022-06-04 Thread Meredith Montgomery
(*) Question

How can I, in a single line, write a statement followed by an
expression?  For example, if /d/ is a dicionary, how can I write

   d["key"] = value # and somehow making this line end up with d

(*) Where does the question come from?

>From the following experiment-exercise.

(*) Introduction

Here's a gentle way to consome records /rs/, each of which represents a
robbery, say, and produce a dictionary containing a count of each zip
code.

--8<---cut here---start->8---
def zip(r):
  return r[0]

def roberry_per_zip(rs):
  d = {}
  for r in rs:
d[zip(r)] = dict.get(d, zip(r), 0) + 1
  return d
--8<---cut here---end--->8---

Now I'd like to compare the code with a version that uses reduce.  Let
me please write my own reduce function for completeness and clarity ---
I suppose.  The code is still pretty clear.

--8<---cut here---start->8---
def my_reduce(it, f, init):
  r = init
  for e in it:
r = f(r, e)
  return r

def count_in(d, r):
  d[zip(r)] = dict.get(d, zip(r), 0) + 1
  return d

def roberry_via_reduce(rs):
  return my_reduce(rs, count_in, {})
--8<---cut here---end--->8---

It's not clear, though, how to write such a procedure using a lambda
expression in place of count_in.  That's because we must return a
dicionary and statements are not expressions.

How can I execute a statement followed by a value in a single line?

def roberry_via_reduce(rs):
  return my_reduce(rs, lambda d, r: ``increment and return d'', {})

I don't know how to write

  ``increment and return d''

I'm just curious.  Thank you.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: on a statement followed by an expression

2022-06-04 Thread Alan Bawden
Meredith Montgomery  writes:

   How can I execute a statement followed by a value in a single line?

   def roberry_via_reduce(rs):
 return my_reduce(rs, lambda d, r: ``increment and return d'', {})

The grammar or Python is deliberately designed so that the body of a
lambda expression cannot contain any statements.  So your original code,
where you defined a separate `count_in' procedure, is probably what you
want.

Although using `reduce' is kind of silly in this case because you aren't
computing a new dictionary every time, but instead you are mutating the
_same_ dictionary every time.  Your original code that used a `for' loop
is actually much clearer.

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


[issue532467] 6.9 The raise statement is confusing

2022-04-10 Thread admin


Change by admin :


--
github: None -> 36289

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue512497] multi-line print statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 36025

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue217377] API docs, 7.2.1, too restrictive statement

2022-04-10 Thread admin


Change by admin :


___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue518989] Import statement Index ref. broken

2022-04-10 Thread admin


Change by admin :


--
github: None -> 36118

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue491246] problem with imports in an if-statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35711

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue481118] 'switch'/'case'/'else' statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35514

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue467381] print statement and exception

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35269

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue401071] whichdb.py: add missing "try:" statement

2022-04-10 Thread admin


Change by admin :


___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue400970] extended print statement

2022-04-10 Thread admin


Change by admin :


___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue217377] API docs, 7.2.1, too restrictive statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 33378

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue401071] whichdb.py: add missing "try:" statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 32882

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue400970] extended print statement

2022-04-10 Thread admin


Change by admin :


--
github: None -> 32648

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46033] Duplicated sentence in for statement documentation

2022-04-02 Thread Terry J. Reedy


Change by Terry J. Reedy :


--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed
type:  -> enhancement

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46033] Duplicated sentence in for statement documentation

2022-04-02 Thread Terry J. Reedy

Terry J. Reedy  added the comment:


New changeset 281f980d354d1709018a2dc77f79388faf3e56c0 by Michał D in branch 
'main':
bpo-46033: Clarify for-statement execution (GH-30025)
https://github.com/python/cpython/commit/281f980d354d1709018a2dc77f79388faf3e56c0


--
nosy: +terry.reedy

___
Python tracker 
<https://bugs.python.org/issue46033>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



Do you support The #Python Software Foundation making a statement in support of peace?

2022-03-13 Thread René Dudfield
hey hey,

Do you support The Python Software Foundation making a statement in support
of peace?

Vote here:
https://twitter.com/pygame_org/status/1502989885296238593


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


[issue41879] Outdated description of async iterables in documentation of async for statement

2022-03-12 Thread Andrew Svetlov


Change by Andrew Svetlov :


--
resolution:  -> fixed
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46980] ast.FunctionDef cannot find functions under if statement

2022-03-10 Thread Ruishi


Ruishi  added the comment:

I see. It's my misunderstanding. Thank you for your help!

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46980] ast.FunctionDef cannot find functions under if statement

2022-03-10 Thread Jelle Zijlstra


Jelle Zijlstra  added the comment:

This is the right place to file an issue.

Your code is incorrect; it will find only top-level functions. Functions within 
an `if` statement will be nested inside an `ast.If` node. To find all functions 
in a file, you'll need to recurse into nested nodes. For example, you could use 
`ast.walk`, an `ast.NodeVisitor`, or manually check for nodes like `ast.If`. 
Which one is best depends on your needs. For example, the first two will also 
find methods in classes. The ast module documentation has more information.

--
nosy: +Jelle Zijlstra
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

___
Python tracker 
<https://bugs.python.org/issue46980>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46980] ast.FunctionDef cannot find functions under if statement

2022-03-10 Thread Ruishi


Ruishi  added the comment:

I'm not sure whether I should file this issue here or on Github and I'm not an 
expert on this so I think I cannot contribute to this but only report to you.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46980] ast.FunctionDef cannot find functions under if statement

2022-03-10 Thread Ruishi


New submission from Ruishi :

When I use the Python ast package to get the functions of Python files, I find 
the functions defined in the body of `if` statement cannot be recognized.

Here is my code:
with open(py_file, 'r') as f:
data = f.read()
module = ast.parse(data)
func_def = [node for node in module.body if isinstance(node, 
ast.FunctionDef)]

Here is an example of Python file:
if supports_bytes_environ:
def _check_bytes(value):
if not isinstance(value, bytes):
raise TypeError("bytes expected, not %s" % type(value).__name__)
return value

The function `_check_bytes` is not in `func_def`. I also tested 
`ast.iter_child_nodes(module)` and it also has this issue.

--
components: Parser
messages: 414886
nosy: Ruishi, lys.nikolaou, pablogsal
priority: normal
severity: normal
status: open
title: ast.FunctionDef cannot find functions under if statement
type: enhancement
versions: Python 3.7

___
Python tracker 
<https://bugs.python.org/issue46980>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2022-01-09 Thread Pablo Galindo Salgado


Pablo Galindo Salgado  added the comment:

I created a PEP to formally propose the change:

https://www.python.org/dev/peps/pep-0679/

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46274] backslash creating statement out of nothing

2022-01-06 Thread Pablo Galindo Salgado


Change by Pablo Galindo Salgado :


--
nosy:  -pablogsal

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46274] backslash creating statement out of nothing

2022-01-05 Thread Jeremy


New submission from Jeremy :

A source of one or more backslash-escaped newlines, and one final newline, is 
not tokenized the same as a source where those lines are "manually joined".

The source
```
\
\
\

```
produces the tokens NEWLINE, ENDMARKER when piped to the tokenize module.

Whereas the source
```

```
produces the tokens NL, ENDMARKER.

What I expect is to receive only one NL token from both sources. As per the 
documentation "Two or more physical lines may be joined into logical lines 
using backslash characters" ... "A logical line that contains only spaces, 
tabs, formfeeds and possibly a comment, is ignored (i.e., no NEWLINE token is 
generated)"

And, because these logical lines are not being ignored, if there are 
spaces/tabs, INDENT and DEDENT tokens are also being unexpectedly produced.

The source
```
\

```
produces the tokens INDENT, NEWLINE, DEDENT, ENDMARKER.

Whereas the source (with spaces)
```

```
produces the tokens NL, ENDMARKER.

--
components: Parser
messages: 409811
nosy: lys.nikolaou, pablogsal, ucodery
priority: normal
severity: normal
status: open
title: backslash creating statement out of nothing
versions: Python 3.10, Python 3.11, Python 3.6, Python 3.7, Python 3.8, Python 
3.9

___
Python tracker 
<https://bugs.python.org/issue46274>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46033] Duplicated sentence in for statement documentation

2022-01-03 Thread Vedran Čačić

Vedran Čačić  added the comment:

Yes, it's ok. The only slight problem is that is suggests that first item is 
somehow special, but later it is explained that in fact it is not. :-) I would 
say "_Each_ item ..." (instead of "First") and without the "this is repeated 
for every item..." at the end, but as I said, this is also fine.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46033] Duplicated sentence in for statement documentation

2022-01-03 Thread Michał D

Michał D  added the comment:

Please see the changes I suggested in my PR.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-24 Thread Guido van Rossum

Guido van Rossum  added the comment:

You don’t have to use the new feature. But people expect it to work.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-24 Thread Serhiy Storchaka


Serhiy Storchaka  added the comment:

For very long expression or very long message you can add parentheses around 
the expression or message. Black will format it as:

assert (
very very long
expression
), (
"very very long "
"message"
)

With the proposed feature it will be:

assert (
very very long
expression,
"very very long "
"message",
)

It saves one line, but the border between an expression and a message is blur. 
Since they are separated by a comma at the end of line and all lines have the 
same indentation it looks less readable to me.

Note also that Black adds a comma after message.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Pablo Galindo Salgado


Change by Pablo Galindo Salgado :


--
keywords: +patch
pull_requests: +28465
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/30247

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Guido van Rossum


Guido van Rossum  added the comment:

I like the lookahead. We could also make the comma and the message mandatory 
when inside parentheses:

| 'assert' '(' a=expression ',' b=expression [','] ')' &(NEWLINE | ';')
| 'assert' a=expression b=[',' z=expression { z }]

(And probably add an "invalid" rule to cover tuples with 0, 1, 3 or more 
elements.)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Pablo Galindo Salgado


Pablo Galindo Salgado  added the comment:

Another possibility is actually handled this in the compiler:

if we see an assert with a tuple of two elements, we can assume is basically in 
the form that we want and proceed as if is in the form
assert A, B

This also feels a bit hacky because the AST is somehow wrong as the assert node 
is already prepared to differentiate these two cases.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Pablo Galindo Salgado


Pablo Galindo Salgado  added the comment:

We could do this, but feels a bit hacky:

| 'assert' '(' a=expression b=[',' z=expression { z }] ')' &(NEWLINE | ';')
| 'assert' a=expression b=[',' z=expression { z }]

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Pablo Galindo Salgado


Pablo Galindo Salgado  added the comment:

> We managed to do this for 'with' so it should be possible here too, I'd 
> think. The "committing" token would be the newline following the close 
> parenthesis.


I am not so sure is that inmediate. Changing the assert statement from:

 'assert' a=expression b=[',' z=expression { z }]

to

| 'assert' '(' a=expression b=[',' z=expression { z }] ')'
| 'assert' a=expression b=[',' z=expression { z }] 

will render this invalid:

assert (a, b) <= c, "something"

The reason is that it will parse the (a, b) as the assert statement eagerly and 
then it will fail to parse the rest.

--

___
Python tracker 
<https://bugs.python.org/issue46167>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Guido van Rossum


Guido van Rossum  added the comment:

We managed to do this for 'with' so it should be possible here too, I'd think. 
The "committing" token would be the newline following the close parenthesis.

Serhiy: the benefit is when you want to split it across two lines, e.g.

assert (a_very_long_condition(),
"A Very Long Message")

I know you can do this using backslash, e..

assert a_very_long_condition(), \
"A Very Long Message"

but there's a strong cultural rejection of backslash for line splitting (it's 
in PEP 8 and engrained in many people's brains) and it's just so natural to use 
parentheses -- they work for 'import', 'with', function calls, 'if', etc.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

> can we finally get rid of this language wart

Yes, please.  This is a pretty bad pitfall.

I've seen this happen to people who've been conditioned by other languages to 
think of assert() as a macro or function:

assert(sometest, somemessage)

--
nosy: +rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Karthikeyan Singaravelan


Change by Karthikeyan Singaravelan :


--
nosy: +gvanrossum, serhiy.storchaka

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Gregory P. Smith


Gregory P. Smith  added the comment:

It's not about an advantage, it's about removing the problem of what edit to 
make when working on


assert 
thing_that_has_a_meaningful_name.methods_have_good_names(value_from_somewhere) 
== other_thing_that_is_meaningful, "Description of what the issue is if this 
fails for humans, as if the names weren't enough"

and making that fit within whatever line length limit your codebase has.

put () in the wrong place and it triggers the long standing Python wart or 
parsing as a tuple.

rather than warn about the syntax wart, we should just do the thing code 
authors want in the first place.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Pablo Galindo Salgado


Pablo Galindo Salgado  added the comment:

I can try to prototype something in the parser to see how it looks and work on 
the pep if everything looks ok.

Parentheses are a bit tricky in general as backtracking ends causing all sorts 
of tricky situations with custom syntax errors as the parser needs to 
distinguish between function calls, tuple construction and grouping so that's 
the only dangerous situation I can think of

--
nosy:  -gvanrossum, serhiy.storchaka

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Serhiy Storchaka


Serhiy Storchaka  added the comment:

It does not need any change in parser, it can be done in the code generator 
which currently explicitly warns about such ambiguity.

Although it needs changes in formal grammar which will be more complex.

But what is a benefit? What is an advantage of writing

   assert (thing, description)

instead of

   assert thing, description

?

--
nosy: +gvanrossum, serhiy.storchaka

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Sergei Lebedev


Change by Sergei Lebedev :


--
nosy: +slebedev

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46167] Parse assert (x == y, "Descriptive text") as statement params instead of a tuple

2021-12-23 Thread Gregory P. Smith


New submission from Gregory P. Smith :

Now that we have a shiny new parser, can we finally get rid of this language 
wart:

assert thing, description  # works as intended

assert (thing, description)  # always True as non-empty tuples are Truthy

This most often happens when extending thing or description beyond a single 
line on assert statements as () are the natural way to do that and as it is 
with assert being a statement, knowing specifically where to place the ()s to 
not fall into the pit of snakes of unintentionally nerfing your assertion to be 
an always true tuple is hard for human authors.

This would obsolete the pylint error about tuple assertion and enable more 
natural assert use.

py.test framework users would presumably rejoice as well.


This parsing change would need a PEP.  I fail to see any obvious downsides 
though.

--
components: Parser
messages: 409101
nosy: gregory.p.smith, lys.nikolaou, pablogsal
priority: normal
severity: normal
status: open
title: Parse assert (x == y, "Descriptive text") as statement params instead of 
a tuple
versions: Python 3.11

___
Python tracker 
<https://bugs.python.org/issue46167>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



  1   2   3   4   5   6   7   8   9   10   >