Re: Quirk difference between classes and functions

2019-02-26 Thread jfong
ast於 2019年2月26日星期二 UTC+8上午12時25分40秒寫道:
> Hello
> 
> I noticed a quirk difference between classes and functions
> 
>  >>> x=0
>  >>>
>  >>> class Test:
>  x = x+1
>  print(x)
>  x = x+1
>  print(x)
> 
> 1
> 2
>  >>> print(x)
> 0
> 
> Previous code doesn't generate any errors.
> x at the right of = in first "x = x+1" line is
> the global one (x=0), then x becomes local
> 
> within a function, this is not allowed
> 
>  >>> x = 0
>  >>>
>  >>> def f():
>  x = x+1
> 
>  >>> f()
> UnboundLocalError: local variable 'x' referenced before assignment
> 
> Since x is written inside the function, it is considered as a local
> variable and x in x+1 is undefined so this throw an exception
> 
> Any comment ?

May I say that the LEGB rule apply to run time, not compile time?

>>> x = 1
>>> def f():
... print(x)
... print(locals())
...
>>> f()
1
{}
>>> def g():
... print(x)
... x = 2
... print(locals())
...
>>> g()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in g
UnboundLocalError: local variable 'x' referenced before assignment
>>> class X:
... print(x)
... x = 2
...
1
>>>
The print(x) difference between class and function was caused by that one was 
executed and the other was compiled. The LEGB rule must apply to run time to 
make the language dynamic.

Any comment:-)?

--Jach

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


Re: Quirk difference between classes and functions

2019-02-26 Thread Thomas Jollans
On 25/02/2019 21.15, Chris Angelico wrote:
> On Tue, Feb 26, 2019 at 6:58 AM DL Neil  
> wrote:
>>
>> On 26/02/19 5:25 AM, ast wrote:
>>> I noticed a quirk difference between classes and functions
>>>  >>> x=0
>>>  >>> class Test:
>>>  x = x+1
>>>  print(x)
>>>  x = x+1
>>>  print(x)
>> ...
>>
>>> Previous code doesn't generate any errors.
>>> x at the right of = in first "x = x+1" line is
>>> the global one (x=0), then x becomes local
>>> within a function, this is not allowed
>>>  >>> x = 0
>>>  >>> def f():
>>>  x = x+1
>>>  >>> f()
>>> UnboundLocalError: local variable 'x' referenced before assignment
>>> Since x is written inside the function, it is considered as a local
>>> variable and x in x+1 is undefined so this throw an exception
>>> Any comment ?
>>
>>
>> At first I misunderstood the question, and even now I'm slightly mystified:-
>>
>> Is the observation to do with the principles of "closure" (being applied
>> to the function) compared with the differences between class and
>> instance variables?
> 
> Classes and functions behave differently. Inside a function, a name is
> local if it's ever assigned to; but in a class, this is not the case.
> (Honestly, I'm not sure why this is, but it's hardly ever significant;
> metaprogramming seldom runs into this kind of thing.)

I imagine there's a justification for the difference in behaviour to do
with the fact that the body of a class is only ever executed once, while
the body of a function is executed multiple times. But I don't quite see it.




> 
>> A question from me: (I'm not an O-O 'native' having taken to it long
>> after first learning 'programming') I've used class attributes to hold
>> 'constants', eg
>>
>> MAXIMUM_WEIGHT = 100
>>
>> Thus only an assignment to which reference/assertions will be made 'later'.
>>
>> I have initialised a counter to zero and then incremented within the
>> instantiated object's __init__(), ie keeping track of how many of 'these
>> objects' have been instantiated.
> 
> Once you're inside a method, you would reference it with a dot -
> either "self.MAXIMUM_WEIGHT" or "cls.MAXIMUM_WEIGHT". So it's now an
> attribute, not a local name.
> 
>> So, I can imagine taking a value from outside the class' namespace,
>> modifying it in some way (per the first "x = x+1") and then retaining
>> the result as a class attribute (a calculation performed once - when the
>> class code is compiled).
> 
> Yes, this is perfectly legitimate. Not common but legit.
> 
>> However, (after that first calculation/definition of the class
>> attribute) why would one (normally) want to redefine the same class
>> attribute (the second x = x+1), at the 'class level'?
>> (perhaps just done for its amusement value?)
> 
> That would not be common either. If you're redefining a variable
> multiple times within a class block, you probably don't also have it
> at top level. (For instance, you can put a "for" loop inside a class
> statement to create attributes/methods, but the loop variable is
> unlikely to also be a global.)
> 
> But hey! It's fun! :)
> 
> ChrisA
> 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to format a datetime MySQL database field to local using strftime()

2019-02-26 Thread vergos . nikolas
Can  you help me rewrite this function, which when iam using 'pymysql' 
conncector works normally, it does not when iam using 'bottle_pymysql'

def coalesce( data ):
newdata = []
seen = {}
for host, ref, location, useros, browser, visits, hits, downloads, 
authuser in data:
# Here i have to decide how to group the rows together
# I want an html row for every unique combination of (host) and 
that hits should be summed together
key = host
if key not in seen:
newdata.append( [ [host], [ref], location, useros, 
browser, [visits], hits, [downloads], authuser ] )
seen[key] = len( newdata ) - 1  # Save index (for 
'newdata') of this row
else:   # This row is a duplicate row with a different 
referrer & visit datetime & torrent download
rowindex = seen[key]
newdata[rowindex][0].append( host )
newdata[rowindex][1].append( ref )
newdata[rowindex][5].append( visits )
newdata[rowindex][6] += hits
newdata[rowindex][7].append( downloads )
return newdata
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to format a datetime MySQL database field to local using strftime()

2019-02-26 Thread vergos . nikolas
Τη Τρίτη, 26 Φεβρουαρίου 2019 - 3:26:29 μ.μ. UTC+2, ο χρήστης 
vergos@gmail.com έγραψε:
> Can  you help me rewrite this function, which when iam using 'pymysql' 
> conncector works normally, it does not when iam using 'bottle_pymysql'
> 
> def coalesce( data ):
>   newdata = []
>   seen = {}
>   for host, ref, location, useros, browser, visits, hits, downloads, 
> authuser in data:
>   # Here i have to decide how to group the rows together
>   # I want an html row for every unique combination of (host) and 
> that hits should be summed together
>   key = host
>   if key not in seen:
>   newdata.append( [ [host], [ref], location, useros, 
> browser, [visits], hits, [downloads], authuser ] )
>   seen[key] = len( newdata ) - 1  # Save index (for 
> 'newdata') of this row
>   else:   # This row is a duplicate row with a different 
> referrer & visit datetime & torrent download
>   rowindex = seen[key]
>   newdata[rowindex][0].append( host )
>   newdata[rowindex][1].append( ref )
>   newdata[rowindex][5].append( visits )
>   newdata[rowindex][6] += hits
>   newdata[rowindex][7].append( downloads )
>   return newdata



For some reason in 'bottle-pymysql'

pagehit = cur.fetchone()[0] does not work

while reffering by name of the field 

pagehit = cur.fetchone()['hits'] does work.

Please help me write the baove function in a similar way.
-- 
https://mail.python.org/mailman/listinfo/python-list


missing 1 required positional argument error

2019-02-26 Thread vergos . nikolas
I'm receiving the following error:

Traceback (most recent call last):
  File "/usr/lib64/python3.6/site-packages/bottle.py", line 862, in _handle
return route.call(**args)
  File "/usr/lib64/python3.6/site-packages/bottle.py", line 1740, in wrapper
rv = callback(*a, **ka)
  File "/usr/lib64/python3.6/site-packages/bottle.py", line 2690, in wrapper
return func(*a, **ka)
TypeError: listall() missing 1 required positional argument: 'pymydb'

and this is my route definition:

@app.route( '/' )
@auth_basic(counters.is_authenticated_user)
def listall( pymydb ):

The way i understand this error is that i'am trying to call 'listall()' without 
giving it an argument while in its definition i do have 'pymydb' as a parameter.

BUT from inside my script i do NOT call listall at all, so how can it miss an 
argument?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: missing 1 required positional argument error

2019-02-26 Thread Calvin Spealman
you call it by visiting the route you've mapped to it, so when you run this
app and navigate to the root / URL it gets called. What do you expect this
parameter to be and where did you expect it to come from when you wrote the
listall() function?

On Tue, Feb 26, 2019 at 10:15 AM  wrote:

> I'm receiving the following error:
>
> Traceback (most recent call last):
>   File "/usr/lib64/python3.6/site-packages/bottle.py", line 862, in _handle
> return route.call(**args)
>   File "/usr/lib64/python3.6/site-packages/bottle.py", line 1740, in
> wrapper
> rv = callback(*a, **ka)
>   File "/usr/lib64/python3.6/site-packages/bottle.py", line 2690, in
> wrapper
> return func(*a, **ka)
> TypeError: listall() missing 1 required positional argument: 'pymydb'
>
> and this is my route definition:
>
> @app.route( '/' )
> @auth_basic(counters.is_authenticated_user)
> def listall( pymydb ):
>
> The way i understand this error is that i'am trying to call 'listall()'
> without giving it an argument while in its definition i do have 'pymydb' as
> a parameter.
>
> BUT from inside my script i do NOT call listall at all, so how can it miss
> an argument?
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 

CALVIN SPEALMAN

SENIOR QUALITY ENGINEER

cspea...@redhat.com  M: +1.336.210.5107

TRIED. TESTED. TRUSTED. 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: missing 1 required positional argument error

2019-02-26 Thread vergos . nikolas
Τη Τρίτη, 26 Φεβρουαρίου 2019 - 5:21:14 μ.μ. UTC+2, ο χρήστης Calvin Spealman 
έγραψε:
> you call it by visiting the route you've mapped to it, so when you run this
> app and navigate to the root / URL it gets called. What do you expect this
> parameter to be and where did you expect it to come from when you wrote the
> listall() function?
> 
> On Tue, Feb 26, 2019 at 10:15 AM  wrote:
> 
> > I'm receiving the following error:
> >
> > Traceback (most recent call last):
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 862, in _handle
> > return route.call(**args)
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 1740, in
> > wrapper
> > rv = callback(*a, **ka)
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 2690, in
> > wrapper
> > return func(*a, **ka)
> > TypeError: listall() missing 1 required positional argument: 'pymydb'
> >
> > and this is my route definition:
> >
> > @app.route( '/' )
> > @auth_basic(counters.is_authenticated_user)
> > def listall( pymydb ):
> >
> > The way i understand this error is that i'am trying to call 'listall()'
> > without giving it an argument while in its definition i do have 'pymydb' as
> > a parameter.
> >
> > BUT from inside my script i do NOT call listall at all, so how can it miss
> > an argument?

Yes, '/' route is being called when i visir it with my browser. Ok, but that 
function needs to work with the 'pymydb' 'bottle-pymysql' keyword so it must 
have it as a parameter.

In another script of mine i have mapped '/' to def index( pymydb ) and its 
working without error. How come it works there and not work here?

They are both '/' routes.
-- 
https://mail.python.org/mailman/listinfo/python-list


Trying to read in data for a file to a python application

2019-02-26 Thread Paul Sutton
Hi

I have been trying to write a small application that is essentially user
information application.

https://raw.githubusercontent.com/zleap/AboutMe/master/Aboutme.py

So far I have managed to write the data generated to a file, what I want
to do now, is read this data back in when the user opens the program.

Trying to use

https://stackoverflow.com/questions/3277503/how-to-read-a-file-line-by-line-into-a-list


with open(fname) as f:
content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end
of each line
content = [x.strip() for x in content]

Trying to use this as a guide (hence my code is a little different).
But am really stuck

So far the GUI window appears but no widgets. So something is clearly
getting stalled.

To begin with If I can read the text in, and just display in the console
this is a start, I can then see if I can figure out how to take that and
insert the data in to the right places.

Can anyone help please.

Thanks

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


Re: missing 1 required positional argument error

2019-02-26 Thread vergos . nikolas
Τη Τρίτη, 26 Φεβρουαρίου 2019 - 5:21:14 μ.μ. UTC+2, ο χρήστης Calvin Spealman 
έγραψε:
> you call it by visiting the route you've mapped to it, so when you run this
> app and navigate to the root / URL it gets called. What do you expect this
> parameter to be and where did you expect it to come from when you wrote the
> listall() function?
> 
> On Tue, Feb 26, 2019 at 10:15 AM  wrote:
> 
> > I'm receiving the following error:
> >
> > Traceback (most recent call last):
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 862, in _handle
> > return route.call(**args)
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 1740, in
> > wrapper
> > rv = callback(*a, **ka)
> >   File "/usr/lib64/python3.6/site-packages/bottle.py", line 2690, in
> > wrapper
> > return func(*a, **ka)
> > TypeError: listall() missing 1 required positional argument: 'pymydb'
> >
> > and this is my route definition:
> >
> > @app.route( '/' )
> > @auth_basic(counters.is_authenticated_user)
> > def listall( pymydb ):
> >
> > The way i understand this error is that i'am trying to call 'listall()'
> > without giving it an argument while in its definition i do have 'pymydb' as
> > a parameter.
> >
> > BUT from inside my script i do NOT call listall at all, so how can it miss
> > an argument?

I expect the parameter to be pass from the top of my script where i have this 
line:

# dbhost is optional, default is localhost
plugin = bottle_pymysql.Plugin( dbuser='nikos', dbpass='*', 
dbname='clientele', dictrows=False )
app.install(plugin)

It works as with another script of mine does.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to format a datetime MySQL database field to local using strftime()

2019-02-26 Thread vergos . nikolas
Actually i just found it has a directive:

dictrows: Whether or not to support dict-like access to row objects (default: 
True).

so i just did:

plugin = bottle_pymysql.Plugin( dbuser='nikos', dbpass='*', 
dbname='counters', dictrows=False )

and now it works with indexes as integers not as strings.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Trying to read in data for a file to a python application

2019-02-26 Thread Peter Pearson
On Tue, 26 Feb 2019 15:51:38 +, Paul Sutton  wrote:
> Hi
>
> I have been trying to write a small application that is essentially user
> information application.
>
> https://raw.githubusercontent.com/zleap/AboutMe/master/Aboutme.py
>
> So far I have managed to write the data generated to a file, what I want
> to do now, is read this data back in when the user opens the program.
>
[snip]
>
> So far the GUI window appears but no widgets. So something is clearly
> getting stalled.
>
> To begin with If I can read the text in, and just display in the console
> this is a start, I can then see if I can figure out how to take that and
> insert the data in to the right places.

I'd suggest writing a terminal-based, non-GUI program to read
your data file and do something simple with it like displaying
it on the terminal.  The strategy is to tackle your problem (reading
back the data) in the simplest context possible.

-- 
To email me, substitute nowhere->runbox, invalid->com.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Trying to read in data for a file to a python application

2019-02-26 Thread Paul Sutton
On 26/02/2019 15:51, Paul Sutton wrote:
> Hi
> 
> I have been trying to write a small application that is essentially user
> information application.
> 
> https://raw.githubusercontent.com/zleap/AboutMe/master/Aboutme.py
> 
> So far I have managed to write the data generated to a file, what I want
> to do now, is read this data back in when the user opens the program.
> 
> Trying to use
> 
> https://stackoverflow.com/questions/3277503/how-to-read-a-file-line-by-line-into-a-list
> 
> 
> with open(fname) as f:
> content = f.readlines()
> # you may also want to remove whitespace characters like `\n` at the end
> of each line
> content = [x.strip() for x in content]
> 
> Trying to use this as a guide (hence my code is a little different).
> But am really stuck
> 
> So far the GUI window appears but no widgets. So something is clearly
> getting stalled.
> 
> To begin with If I can read the text in, and just display in the console
> this is a start, I can then see if I can figure out how to take that and
> insert the data in to the right places.
> 
> Can anyone help please.
> 
> Thanks
> 
> Paul
> 



Hi All

Thank you for the comments and adding some 'sanity' to my problem
solving.  I will do as suggested and create a Python program to read /
write then move on to integrating that in to the main program.


Thanks again

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


Re: Quirk difference between classes and functions

2019-02-26 Thread Gregory Ewing

Thomas Jollans wrote:

I imagine there's a justification for the difference in behaviour to do
with the fact that the body of a class is only ever executed once, while
the body of a function is executed multiple times.


I suspect there isn't any deep reason for it, rather it's just
something that fell out of the implementation, in particular
the decision to optimise local variable access in functions
but not other scopes.

When compiling a function, the compiler needs to know which
variables are local so that it can allocate slots for them in
the stack frame. But when executing a class body, the locals
are kept in a dict and are looked up dynamically.

The compiler *could* be made to treat class bodies the same
way as functions in this regard, but it would be extra work
for little or no benefit. Most code in class bodies just
defines new names without referring to anything else in the
same scope.

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


RE: Quirk difference between classes and functions

2019-02-26 Thread Steve
I have been a silent reader on this and am interested in understanding more
about the scope of variables in Python.  They do not seem to behave as I
have experienced in other programming languages.

I have used functions in python but was not aware of class.
It would benefit me very well if someone could post a simple example of each
on which I might experiment.
Steve




Footnote:
There's 99 bugs in the code, in the code.
99 bugs in the code.
Take one down and patch it all around.
Now there's 117 bugs in the code.

-Original Message-
From: Python-list  On
Behalf Of Gregory Ewing
Sent: Tuesday, February 26, 2019 4:27 PM
To: python-list@python.org
Subject: Re: Quirk difference between classes and functions

Thomas Jollans wrote:
> I imagine there's a justification for the difference in behaviour to 
> do with the fact that the body of a class is only ever executed once, 
> while the body of a function is executed multiple times.

I suspect there isn't any deep reason for it, rather it's just something
that fell out of the implementation, in particular the decision to optimise
local variable access in functions but not other scopes.

When compiling a function, the compiler needs to know which variables are
local so that it can allocate slots for them in the stack frame. But when
executing a class body, the locals are kept in a dict and are looked up
dynamically.

The compiler *could* be made to treat class bodies the same way as functions
in this regard, but it would be extra work for little or no benefit. Most
code in class bodies just defines new names without referring to anything
else in the same scope.

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

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


Lifetime of a local reference

2019-02-26 Thread Marko Rauhamaa


Consider this function:

def fun():
f = open("lock")
flock.flock(f, fcntl.LOCK_EX)
do_stuff()
sys.exit(0)

Question: can a compliant Python implementation close f (and,
consequently, release the file lock) before/while do_stuff() is
executed?

I couldn't find an immediate answer in the documentation.


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


Re: Lifetime of a local reference

2019-02-26 Thread Chris Angelico
On Wed, Feb 27, 2019 at 9:00 AM Marko Rauhamaa  wrote:
> Consider this function:
>
> def fun():
> f = open("lock")
> flock.flock(f, fcntl.LOCK_EX)
> do_stuff()
> sys.exit(0)
>
> Question: can a compliant Python implementation close f (and,
> consequently, release the file lock) before/while do_stuff() is
> executed?
>
> I couldn't find an immediate answer in the documentation.

The variable is alive, so the object is alive. Common sense should
make this clear, but there's probably some details in the
documentation if you actually need a citation. The name "f" is part of
the function's locals until that function returns or the name is
explicitly unbound.

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


Re: Lifetime of a local reference

2019-02-26 Thread Tim Daneliuk
On 2/26/19 3:54 PM, Marko Rauhamaa wrote:
> Consider this function:
> 
> def fun():
> f = open("lock")
> flock.flock(f, fcntl.LOCK_EX)
> do_stuff()
> sys.exit(0)
> 
> Question: can a compliant Python implementation close f (and,
> consequently, release the file lock) before/while do_stuff() is
> executed?
> 
> I couldn't find an immediate answer in the documentation.


Not quite sure what you are asking.  Are you asking if the file handle
can be closed before (or concurrently if do_stuff() is a thread) and
do_stuff() can continue to make use of the handle?

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


Re: missing 1 required positional argument error

2019-02-26 Thread Terry Reedy

On 2/26/2019 10:10 AM, vergos.niko...@gmail.com wrote:

I'm receiving the following error:

Traceback (most recent call last):
   File "/usr/lib64/python3.6/site-packages/bottle.py", line 862, in _handle
 return route.call(**args)
   File "/usr/lib64/python3.6/site-packages/bottle.py", line 1740, in wrapper
 rv = callback(*a, **ka)
   File "/usr/lib64/python3.6/site-packages/bottle.py", line 2690, in wrapper
 return func(*a, **ka)
TypeError: listall() missing 1 required positional argument: 'pymydb'

and this is my route definition:

@app.route( '/' )
@auth_basic(counters.is_authenticated_user)
def listall( pymydb ):

The way i understand this error is that i'am trying to call 'listall()' without 
giving it an argument while in its definition i do have 'pymydb' as a parameter.

BUT from inside my script i do NOT call listall at all, so how can it miss an 
argument?


Follow the traceback.  The error occurred when executing "func(*a, *ka)" 
 in bottle.py.  Clearly, at that time, func = listall, a = [], and ka = 
{}.  To see why this is so, work back up the stack.



--
Terry Jan Reedy

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


Re: Quirk difference between classes and functions

2019-02-26 Thread jfong
Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> Thomas Jollans wrote:
> > I imagine there's a justification for the difference in behaviour to do
> > with the fact that the body of a class is only ever executed once, while
> > the body of a function is executed multiple times.
> 
> I suspect there isn't any deep reason for it, rather it's just
> something that fell out of the implementation, in particular
> the decision to optimise local variable access in functions
> but not other scopes.
> 
> When compiling a function, the compiler needs to know which
> variables are local so that it can allocate slots for them in
> the stack frame. But when executing a class body, the locals
> are kept in a dict and are looked up dynamically.

If the compiler can do any decision on the variable's name, when it goes to 
line of print, how it handle it?

x = 0
def f():
print(x)

def g():
print(x)
x = 1
print(y)

--Jach

> The compiler *could* be made to treat class bodies the same
> way as functions in this regard, but it would be extra work
> for little or no benefit. Most code in class bodies just
> defines new names without referring to anything else in the
> same scope.
> 
> -- 
> Greg

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


Re: Quirk difference between classes and functions

2019-02-26 Thread eryk sun
On 2/26/19, Gregory Ewing  wrote:
> Thomas Jollans wrote:
>> I imagine there's a justification for the difference in behaviour to do
>> with the fact that the body of a class is only ever executed once, while
>> the body of a function is executed multiple times.
>
> I suspect there isn't any deep reason for it, rather it's just
> something that fell out of the implementation, in particular
> the decision to optimise local variable access in functions
> but not other scopes.

At the module level, this goes unnoticed since globals and locals are
the same dict, but we can observe it in an exec() call if we use
separate globals and locals . For example:

>>> x = 0
>>> locals = {}
>>> exec('x = x + 1', globals(), locals)
>>> x
0
>>> locals
{'x': 1}

In terms of implementation, the LOAD_NAME instruction that's used in
unoptimized code looks in the locals, globals, and builtins scopes, in
that order. The intent is to allow locals to shadow globals and
builtins, and globals to shadow builtins. It also allows for temporary
shadowing. Optimized code supports the former (via LOAD_GLOBAL), but
not the latter. For example:

unoptimized:

>>> exec(r'''
... len = lambda x: 42
... print(len('spam'))
... del len
... print(len('spam'))
... ''')
42
4

optimized:

>>> def f():
... len = lambda x: 42
... print(len('spam'))
... del len
... print(len('spam'))
...
>>> f()
42
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in f
UnboundLocalError: local variable 'len' referenced before assignment
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Quirk difference between classes and functions

2019-02-26 Thread Chris Angelico
On Wed, Feb 27, 2019 at 12:21 PM  wrote:
>
> Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> > Thomas Jollans wrote:
> > > I imagine there's a justification for the difference in behaviour to do
> > > with the fact that the body of a class is only ever executed once, while
> > > the body of a function is executed multiple times.
> >
> > I suspect there isn't any deep reason for it, rather it's just
> > something that fell out of the implementation, in particular
> > the decision to optimise local variable access in functions
> > but not other scopes.
> >
> > When compiling a function, the compiler needs to know which
> > variables are local so that it can allocate slots for them in
> > the stack frame. But when executing a class body, the locals
> > are kept in a dict and are looked up dynamically.
>
> If the compiler can do any decision on the variable's name, when it goes to 
> line of print, how it handle it?
>
> x = 0
> def f():
> print(x)
>
> def g():
> print(x)
> x = 1
> print(y)
>

Not sure what you mean by "decision", but the definition is that since
x is assigned to in g(), it is local to g(). It's not local to f(), so
the global is visible.

(Incidentally, "print" is handled exactly the same way. Since neither
function assigns to print, it's not local, so the built-in is found.)

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


Re: Lifetime of a local reference

2019-02-26 Thread Alan Bawden
Marko Rauhamaa  writes:
> def fun():
> f = open("lock")
> flock.flock(f, fcntl.LOCK_EX)
> do_stuff()
> sys.exit(0)
> 
> Question: can a compliant Python implementation close f (and,
> consequently, release the file lock) before/while do_stuff() is
> executed?

A correct-but-fails-to-answer-your-real-question answer would be: "If you
_care_ about when f gets closed, then just call f.close() yourself."  So
if you want to be _sure_ the lock stays locked while you "do stuff", you
should write:

   def fun():
   f = open("lock")
   flock.flock(f, fcntl.LOCK_EX)
   do_stuff()
   f.close()
   sys.exit(0)

And now you don't have to worry about the details of variable lifetimes.

But I appreciate that that isn't the true question that you wanted to ask!
You are wondering if a Python implementation is _permitted_ to treat the
code you wrote _as if_ you had written:

   def fun():
   f = open("lock")
   flock.flock(f, fcntl.LOCK_EX)
   del f
   do_stuff()
   sys.exit(0)

which deletes the variable f from the local environment at a point where it
will never be used again.  (Which could cause the lock to be released
before do_stuff is even called.)

This is an interesting question, and one that any garbage collected
language should probably address somehow.  For example, the Java Language
Specification contains the following language:

   Optimizing transformations of a program can be designed that reduce the
   number of objects that are reachable to be less than those which would
   naively be considered reachable.  For example, a Java compiler or code
   generator may choose to set a variable or parameter that will no longer be
   used to null to cause the storage for such an object to be potentially
   reclaimable sooner.

(This is from section 12.6.1 of the Java 8 version, which is what I had
handy.)

So you're not crazy to ask such a question.

> I couldn't find an immediate answer in the documentation.

I suspect that given the history of Python, pretty much everybody has
always assumed that a Python implementation will not delete local variables
early.  But I agree with you that the Python Language Reference does not
appear to address this question anywhere!

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


Re: Quirk difference between classes and functions

2019-02-26 Thread jfong
Chris Angelico於 2019年2月27日星期三 UTC+8上午9時25分11秒寫道:
> On Wed, Feb 27, 2019 at 12:21 PM  wrote:
> >
> > Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> > > Thomas Jollans wrote:
> > > > I imagine there's a justification for the difference in behaviour to do
> > > > with the fact that the body of a class is only ever executed once, while
> > > > the body of a function is executed multiple times.
> > >
> > > I suspect there isn't any deep reason for it, rather it's just
> > > something that fell out of the implementation, in particular
> > > the decision to optimise local variable access in functions
> > > but not other scopes.
> > >
> > > When compiling a function, the compiler needs to know which
> > > variables are local so that it can allocate slots for them in
> > > the stack frame. But when executing a class body, the locals
> > > are kept in a dict and are looked up dynamically.
> >
> > If the compiler can do any decision on the variable's name, when it goes to 
> > line of print, how it handle it?
> >
> > x = 0
> > def f():
> > print(x)
> >
> > def g():
> > print(x)
> > x = 1
> > print(y)
> >
> 
> Not sure what you mean by "decision", but the definition is that since
> x is assigned to in g(), it is local to g(). It's not local to f(), so
> the global is visible.

So, may I say that the Python compiler is a multi-pass one?

--Jach
> 
> (Incidentally, "print" is handled exactly the same way. Since neither
> function assigns to print, it's not local, so the built-in is found.)
> 
> ChrisA

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


Re: Quirk difference between classes and functions

2019-02-26 Thread Chris Angelico
On Wed, Feb 27, 2019 at 2:21 PM  wrote:
>
> Chris Angelico於 2019年2月27日星期三 UTC+8上午9時25分11秒寫道:
> > On Wed, Feb 27, 2019 at 12:21 PM  wrote:
> > >
> > > Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> > > > Thomas Jollans wrote:
> > > > > I imagine there's a justification for the difference in behaviour to 
> > > > > do
> > > > > with the fact that the body of a class is only ever executed once, 
> > > > > while
> > > > > the body of a function is executed multiple times.
> > > >
> > > > I suspect there isn't any deep reason for it, rather it's just
> > > > something that fell out of the implementation, in particular
> > > > the decision to optimise local variable access in functions
> > > > but not other scopes.
> > > >
> > > > When compiling a function, the compiler needs to know which
> > > > variables are local so that it can allocate slots for them in
> > > > the stack frame. But when executing a class body, the locals
> > > > are kept in a dict and are looked up dynamically.
> > >
> > > If the compiler can do any decision on the variable's name, when it goes 
> > > to line of print, how it handle it?
> > >
> > > x = 0
> > > def f():
> > > print(x)
> > >
> > > def g():
> > > print(x)
> > > x = 1
> > > print(y)
> > >
> >
> > Not sure what you mean by "decision", but the definition is that since
> > x is assigned to in g(), it is local to g(). It's not local to f(), so
> > the global is visible.
>
> So, may I say that the Python compiler is a multi-pass one?
>

At this point, you're veering away from "Python-the-language" and
towards "CPython-the-implementation" (or whichever other
implementation you want to explore). But I would say that, yes, most
or all Python implementations will use multi-pass compilation. It's
the easiest way to guarantee correct behaviour. For instance, when you
reach a "try" statement, you don't know whether there'll be an
"except" block after it (there might just be a "finally"); the
bytecode that CPython produces is different for setting up a
finally-only block than for setting up a try/except. Easiest to find
out that sort of thing by running multiple passes.

Plus, depending on how you define "pass", there are additional steps
such as constant folding and peephole optimization that can be done
after everything else. So, yeah, it's highly unlikely that there are
any performant implementations of Python that run a single compilation
pass.

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


Re: Quirk difference between classes and functions

2019-02-26 Thread jfong
Chris Angelico於 2019年2月27日星期三 UTC+8上午11時29分04秒寫道:
> On Wed, Feb 27, 2019 at 2:21 PM  wrote:
> >
> > Chris Angelico於 2019年2月27日星期三 UTC+8上午9時25分11秒寫道:
> > > On Wed, Feb 27, 2019 at 12:21 PM  wrote:
> > > >
> > > > Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> > > > > Thomas Jollans wrote:
> > > > > > I imagine there's a justification for the difference in behaviour 
> > > > > > to do
> > > > > > with the fact that the body of a class is only ever executed once, 
> > > > > > while
> > > > > > the body of a function is executed multiple times.
> > > > >
> > > > > I suspect there isn't any deep reason for it, rather it's just
> > > > > something that fell out of the implementation, in particular
> > > > > the decision to optimise local variable access in functions
> > > > > but not other scopes.
> > > > >
> > > > > When compiling a function, the compiler needs to know which
> > > > > variables are local so that it can allocate slots for them in
> > > > > the stack frame. But when executing a class body, the locals
> > > > > are kept in a dict and are looked up dynamically.
> > > >
> > > > If the compiler can do any decision on the variable's name, when it 
> > > > goes to line of print, how it handle it?
> > > >
> > > > x = 0
> > > > def f():
> > > > print(x)
> > > >
> > > > def g():
> > > > print(x)
> > > > x = 1
> > > > print(y)
> > > >
> > >
> > > Not sure what you mean by "decision", but the definition is that since
> > > x is assigned to in g(), it is local to g(). It's not local to f(), so
> > > the global is visible.
> >
> > So, may I say that the Python compiler is a multi-pass one?
> >
> 
> At this point, you're veering away from "Python-the-language" and
> towards "CPython-the-implementation" (or whichever other
> implementation you want to explore). 

Yes, it's a little away:-) I was curious about how the compiled print(x) can be 
influenced by x = 1 after it. Anyway, thank you for your confirmation.

--Jach

> But I would say that, yes, most
> or all Python implementations will use multi-pass compilation. It's
> the easiest way to guarantee correct behaviour. For instance, when you
> reach a "try" statement, you don't know whether there'll be an
> "except" block after it (there might just be a "finally"); the
> bytecode that CPython produces is different for setting up a
> finally-only block than for setting up a try/except. Easiest to find
> out that sort of thing by running multiple passes.
> 
> Plus, depending on how you define "pass", there are additional steps
> such as constant folding and peephole optimization that can be done
> after everything else. So, yeah, it's highly unlikely that there are
> any performant implementations of Python that run a single compilation
> pass.
> 
> ChrisA

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


Multi meaning of label: Doc bug

2019-02-26 Thread Rustom Mody
Ref: This stackexchange post:
https://unix.stackexchange.com/q/503241/323121

Context: Theres this guy who's really struggling with disk partitioning LVM etc 
concepts.  That point is not directly relevant to this question.

My answer on that post tries to clarify that 'label' can mean 3 things at 
least; 
and that just in the context of disks, partitions etc. Quite confusing!!

My question: In his parted output he has

Error: /dev/mapper/lubuntu--vg-home: unrecognised disk label

In which sense is this 'label' used??

Is it the Open/Free-BSD sense? Or the partition label sense?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Multi meaning of label: Doc bug

2019-02-26 Thread Rustom Mody
On Wednesday, February 27, 2019 at 11:12:28 AM UTC+5:30, Rustom Mody wrote:
> Ref: This stackexchange post:
> https://unix.stackexchange.com/q/503241/323121
> 
> Context: Theres this guy who's really struggling with disk partitioning LVM 
> etc concepts.  That point is not directly relevant to this question.
> 
> My answer on that post tries to clarify that 'label' can mean 3 things at 
> least; 
> and that just in the context of disks, partitions etc. Quite confusing!!
> 
> My question: In his parted output he has
> 
> Error: /dev/mapper/lubuntu--vg-home: unrecognised disk label
> 
> In which sense is this 'label' used??
> 
> Is it the Open/Free-BSD sense? Or the partition label sense?

OOps wrong list! Sorry!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Lifetime of a local reference

2019-02-26 Thread Marko Rauhamaa
Alan Bawden :

> Marko Rauhamaa  writes:
>> def fun():
>> f = open("lock")
>> flock.flock(f, fcntl.LOCK_EX)
>> do_stuff()
>> sys.exit(0)
>> 
>> Question: can a compliant Python implementation close f (and,
>> consequently, release the file lock) before/while do_stuff() is
>> executed?
>
> A correct-but-fails-to-answer-your-real-question answer would be: "If
> you _care_ about when f gets closed, then just call f.close()
> yourself." So if you want to be _sure_ the lock stays locked while you
> "do stuff", you should write:
>
>def fun():
>f = open("lock")
>flock.flock(f, fcntl.LOCK_EX)
>do_stuff()
>f.close()
>sys.exit(0)
>
> And now you don't have to worry about the details of variable
> lifetimes.

Yes, although the operating system closes all files (and releases the
associated file locks) on process exit.

> But I appreciate that that isn't the true question that you wanted to ask!
> You are wondering if a Python implementation is _permitted_ to treat the
> code you wrote _as if_ you had written:
>
>def fun():
>f = open("lock")
>flock.flock(f, fcntl.LOCK_EX)
>del f
>do_stuff()
>sys.exit(0)
>
> which deletes the variable f from the local environment at a point where it
> will never be used again.  (Which could cause the lock to be released
> before do_stuff is even called.)
>
> This is an interesting question, and one that any garbage collected
> language should probably address somehow.  For example, the Java Language
> Specification contains the following language:
>
>Optimizing transformations of a program can be designed that reduce the
>number of objects that are reachable to be less than those which would
>naively be considered reachable.  For example, a Java compiler or code
>generator may choose to set a variable or parameter that will no longer be
>used to null to cause the storage for such an object to be potentially
>reclaimable sooner.
>
> (This is from section 12.6.1 of the Java 8 version, which is what I had
> handy.)

C compilers do similar things, which is why Guile documentation mentions
a special mechanism to prevent premature garbage collection:

   https://www.gnu.org/software/guile/docs/docs-2.0/guile-ref/Rememb
   ering-During-Operations.html>

> I suspect that given the history of Python, pretty much everybody has
> always assumed that a Python implementation will not delete local
> variables early. But I agree with you that the Python Language
> Reference does not appear to address this question anywhere!

Then there's the question of a sufficient way to prevent premature
garbage collection:

 def fun():
 f = open("lock")
 flock.flock(f, fcntl.LOCK_EX)
 do_stuff()
 f.close()
 sys.exit(0)

 def fun():
 f = open("lock")
 flock.flock(f, fcntl.LOCK_EX)
 do_stuff()
 f.close
 sys.exit(0)

 def fun():
 f = open("lock")
 flock.flock(f, fcntl.LOCK_EX)
 do_stuff()
 f
 sys.exit(0)

 def fun():
 f = open("lock")
 flock.flock(f, fcntl.LOCK_EX)
 do_stuff()
 sys.exit(0)


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