Re: bool and int

2023-01-27 Thread Grant Edwards
On 2023-01-27, Mark Bourne  wrote:

> So Python is even flexible enough to be made to deal with insane 
> situations where False is 2!

IIRC, in VMS DCL even numbers were false and odd numbers were true.

In Unix shells, a return code of 0 is true and non-0 is false.

Though that's not really the same environment that Python lives in...


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


RE: Evaluation of variable as f-string

2023-01-27 Thread avi.e.gross
May I point out that some dynamic situations can in a sense be normalized?

The example below posits a dynamically allocated dictionary during run time.
But why can't you have a placeholder variable name in place and make your
placeholder a link to the dictionary (or other item) before invoking the
existing f-string with the placeholder built-in, rather than trying to
evaluate an F♯ ???

Of course many situations may not have as much of a possible work-around.
But as so many have noted, we never got a really good explanation of what
the OP really wants to do. There have been replies that may be suitable
solutions and some clearly have potential to be security holes if you let
the users dynamically create strings to be evaluated. 

In some languages, many of the facets of the language can be passed along as
a function with some name to be used in functional programming techniques
and this can be very useful. The "operator" module can be used for quite a
few things like operator.add or operator.__add__ or operator.concat and many
more. If the logic used to evaluate an f-string (and for that matter the
other string variants like b'..' and r'...') could be encapsulated in a
function like that, it would be potentially usable as in passing something
like dangerous_operator.f_string and a list of strings and having that
return a list of evaluated strings. 

The fact that something like  this is not known to the people here may hint
that it is not something considered safe to use by amateurs. But then again,
anyone who wants to can use eval() as Chris points out. 

Of course, there may be other reasons too. An f-string is evaluated in a
context that may be different if a string is passed along and then looked at
in another context.

-Original Message-
From: Python-list  On
Behalf Of Stefan Ram
Sent: Friday, January 27, 2023 4:31 PM
To: python-list@python.org
Subject: Re: Evaluation of variable as f-string

Johannes Bauer  writes:
>>Johannes Bauer  writes:
>>>x = { "y": "z" }
>>>s = "-> {x['y']}"
>>>print(s.format(x = x))
>>x = { "y": "z" }
>>def s( x ): return '-> ' + x[ 'y' ]
>>print( s( x = x ))
>Except this is not at all what I asked for. The string "s" in my 
>example is just that, an example. I want to render *arbitrary* strings "s"
>together with arbitrary dictionaries "x".

  I take this to mean that you want to process a dictionary
  name, a string and a dictionary that is only specified as
  late as at run time.

import string

name = input( 'name of the dictionary? ' ) string_ = input( 'string? ' ) #
"-> {x['y']}"
dictionary = eval( input( 'dictionary? ' )) print( eval( 'f"""' + string_ +
'"""', {name:dictionary} ))

name of the dictionary? x
string? -> {x['y']}
dictionary? { 'y': 'z' }
-> z


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

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Thomas Passin

On 1/27/2023 5:10 PM, Christian Gollwitzer wrote:

Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example I 
gave in my original post and angrily claim that you solution works 
when it does not:


x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
   File "", line 1, in 
KeyError: "'y'"

This. Does. Not. Work.


It's because "you're holding it wrong!". Notice the error message; it 
says that the key 'y' does not exist.



(base) Apfelkiste:Abschlussmeeting chris$ ipython
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: x = { "y": "z" }

In [2]: s = "-> {x[y]}"

In [3]: print(s.format(x = x))
-> z

In [4]:

 Christian


Oops, that's not quite what he wrote.

You: s = "-> {x[y]}"# Works
Him: s = "-> {x['y']}"  # Fails

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Thomas Passin

On 1/27/2023 3:33 PM, Johannes Bauer wrote:

Am 25.01.23 um 20:38 schrieb Thomas Passin:


x = { "y": "z" }
s = "-> {target}"
print(s.format(target = x['y']))


Stack overflow to the rescue:


No.


Search phrase:  "python evaluate string as fstring"

https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string

def effify(non_f_str: str):
 return eval(f'f"""{non_f_str}"""')

print(effify(s))  # prints as expected: "-> z"


Great.

s = '"""'

 > def effify(non_f_str: str):
 >  return eval(f'f"""{non_f_str}"""')
 >
 > print(effify(s))  # prints as expected: "-> z"

 >>> print(effify(s))
Traceback (most recent call last):
   File "", line 1, in 
   File "", line 2, in effify
   File "", line 1
     f"
    ^
SyntaxError: unterminated triple-quoted string literal (detected at line 1)

This is literally the version I described myself, except using triple 
quotes. It only modifies the underlying problem, but doesn't solve it.


Ok, so now we are in the territory of "Tell us what you are trying to 
accomplish". And part of that is why you cannot put some constraints on 
what your string fragments are.  The example I gave, copied out of your 
earlier message, worked and now you are springing triple quotes on us.


Stop with the rock management already and explain (briefly if possible) 
what you are up to.


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


Re: evaluation question

2023-01-27 Thread dn via Python-list

On 28/01/2023 05.37, mutt...@dastardlyhq.com wrote:

This is probably a dumb newbie question but I've just started to learn
python3 and eval() isn't behaving as I'd expect in that it works for
some things and not others. eg:


eval("1+1")

2

eval("print(123)")

123

eval("for i in range(1,10): i")

Traceback (most recent call last):
   File "", line 1, in 
   File "", line 1
 for i in range(1,10): i
   ^
SyntaxError: invalid syntax

Why did the 3rd one fail? Does it not handle complex expressions?


eval() is very powerful, and therefore rather dangerous in the risks it 
presents.


Thus, seems a strange/advanced question for a "newbie" to be asking. YMMV!

Do you know about the Python REPL?

If you open python within a terminal, each of the three 
expressions/compound-statements listed will work, as desired, without 
eval().


dn $ ... python
Python 3.11.1 (main, Jan  6 2023, 00:00:00) [GCC 12.2.1 20221121 (Red 
Hat 12.2.1-4)] on linux

Type "help", "copyright", "credits" or "license" for more information.
>>> 1+1
2
>>> print( 123 )
123
>>> for i in range( 1, 10 ): i
...
1
2
3
4
5
6
7
8
9
>>> exit()

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


Re: bool and int

2023-01-27 Thread Chris Angelico
On Sat, 28 Jan 2023 at 11:45, Greg Ewing  wrote:
>
> On 26/01/23 6:10 am, Chris Angelico wrote:
> > And that's a consequence of a system wherein there is only one concept
> > of "success", but many concepts of "failure". Whoever devised that
> > system was clearly a pessimist :)
>
> Murphy's Law for Unix: If something can go wrong, it will go
> wrong 255 times out of 256.
>

Murphy's Law for people working with small integers: "255 out of 256"
will, just when you least expect it, change into "255 out of 0".

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


Re: evaluation question

2023-01-27 Thread Chris Angelico
On Sat, 28 Jan 2023 at 11:45,  wrote:
>
> Hi
>
> This is probably a dumb newbie question but I've just started to learn
> python3 and eval() isn't behaving as I'd expect in that it works for
> some things and not others. eg:
>
> >>> eval("1+1")
> 2
> >>> eval("print(123)")
> 123
> >>> eval("for i in range(1,10): i")
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 1
> for i in range(1,10): i
>   ^
> SyntaxError: invalid syntax
>
> Why did the 3rd one fail? Does it not handle complex expressions?
>

There's a difference between *expressions* (which have values) and
*statements* (which do stuff, including control flow like loops). You
may want the exec function instead.

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


Re: bool and int

2023-01-27 Thread Mark Bourne

avi.e.gr...@gmail.com wrote:
...

Interestingly, I wonder if anyone has
designed an alternate object type that can be used mostly in place of
Booleans but which imposes changes and restrictions so trying to add a
Boolean to an integer, or vice versa, results in an error. Python is
flexible enough to do that and perhaps there already is a module out there


Not exactly what you describe, but I did once write a subclass of int 
for use in an SNMP interface, where true is represented as 1 and false 
as 2.  I don't recall the exact details offhand, but it involved 
overriding __bool__ so that a value of 1 returned True and anything else 
False.  The way it was used should have ensured that it only ever had 
the value 1 or 2, but doing it this way round (rather than e.g. 2 being 
False and anything else True) meant that if it somehow got the value 0, 
that would also be treated as False.  I think it also overrode __init__ 
(or perhaps __new__) to covert a bool True or False to 1 or 2 (rather 
than 1 or 0) for its own value, so it could be initialised from either 
an int or a bool and correctly converted in either direction via int() 
or bool().


So Python is even flexible enough to be made to deal with insane 
situations where False is 2!


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


Re: Evaluation of variable as f-string

2023-01-27 Thread Christian Gollwitzer

Am 27.01.23 um 21:43 schrieb Johannes Bauer:
I don't understand why you fully ignore literally the FIRST example I 
gave in my original post and angrily claim that you solution works when 
it does not:


x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
   File "", line 1, in 
KeyError: "'y'"

This. Does. Not. Work.


It's because "you're holding it wrong!". Notice the error message; it 
says that the key 'y' does not exist.



(base) Apfelkiste:Abschlussmeeting chris$ ipython
Python 3.8.8 (default, Apr 13 2021, 12:59:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.22.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: x = { "y": "z" }

In [2]: s = "-> {x[y]}"

In [3]: print(s.format(x = x))
-> z

In [4]:

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


Re: evaluation question

2023-01-27 Thread Ben Bacarisse
mutt...@dastardlyhq.com writes:

> Hi

It looks like you posted this question via Usenet.  comp.lang.python is
essentially dead as a Usenet group.  It exists, and gets NNTP versions
of mail sent to the mailing list, but nothing posted to the group via
NNTP get send on the mailing list.  I prefer Usenet and dislike mailing
lists but that just means I can't really contribute to this "group"

The "python-list" an an excellent resource (if you like the email
interface) and you can subscribe here:

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

> This is probably a dumb newbie question but I've just started to learn
> python3 and eval() isn't behaving as I'd expect in that it works for
> some things and not others. eg:
>
 eval("1+1")
> 2
 eval("print(123)")
> 123
 eval("for i in range(1,10): i")
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 1
> for i in range(1,10): i
>   ^
> SyntaxError: invalid syntax
>
> Why did the 3rd one fail? Does it not handle complex expressions?

It handles only expressions, and "for i in range(1,10): i" is not an
expression.  You can use

>>> exec("for i in range(1,10): i")

or, to confirm that something is happening:

>>> exec("for i in range(1,10): print(i)")
1
2
3
4
5
6
7
8
9

See: https://docs.python.org/3/library/functions.html?highlight=eval#eval
and the immediately following entry.

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Johannes Bauer

Am 27.01.23 um 20:18 schrieb Chris Angelico:


All you tell us is
what you're attempting to do, which there is *no good way to achieve*.


Fair enough, that is the answer. It's not possible.


Perhaps someone will be inspired to write a function to do it. 


See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen. Using eval() to construct
an f-string and then parse it is TERRIBLE because:

1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"


Exactly my observation as well, which is why I was thinking there's 
something else I missed.



2) You would have to pass it a dictionary of variables, which also
can't be done with full generality


Nonsense. I only am passing a SINGLE variable to eval, called "x". That 
is fully general.



3) These are the exact same problems, but backwards, that led to
f-strings in the first place


I don't know what you mean by that.


4) eval is extremely slow and horrifically inefficient.


Let me worry about it.


For some reason, str.format() isn't suitable,


I don't understand why you fully ignore literally the FIRST example I 
gave in my original post and angrily claim that you solution works when 
it does not:


x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
  File "", line 1, in 
KeyError: "'y'"

This. Does. Not. Work.

I want to pass a single variable as a dictionary and access its members 
inside the expression.



 but *you haven't said
why*,


Yes I have, see above.


Well, yes. If you asked "how can I do X", hoping the answer would be
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".


"You can't" would have been sufficient. Pity. Your judgement is 
unnecessary and, frankly, uncalled for as well. Multiple instances you 
claim that you have no idea what I am doing so how would you even begin 
to judge a solution as fit or unfit?



Don't ask how to use X to do Y. Ask how to do Y.


You don't have to be angry that my question does not have a solution. I 
will manage and so might you.


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


Re: Evaluation of variable as f-string

2023-01-27 Thread Johannes Bauer

Am 23.01.23 um 17:43 schrieb Stefan Ram:

Johannes Bauer  writes:

x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))


x = { "y": "z" }
def s( x ): return '-> ' + x[ 'y' ]
print( s( x = x ))


Except this is not at all what I asked for. The string "s" in my example 
is just that, an example. I want to render *arbitrary* strings "s" 
together with arbitrary dictionaries "x".


Cheers,
Johannes

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Johannes Bauer

Am 25.01.23 um 20:38 schrieb Thomas Passin:


x = { "y": "z" }
s = "-> {target}"
print(s.format(target = x['y']))


Stack overflow to the rescue:


No.


Search phrase:  "python evaluate string as fstring"

https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string

def effify(non_f_str: str):
     return eval(f'f"""{non_f_str}"""')

print(effify(s))  # prints as expected: "-> z"


Great.

s = '"""'

> def effify(non_f_str: str):
>  return eval(f'f"""{non_f_str}"""')
>
> print(effify(s))  # prints as expected: "-> z"

>>> print(effify(s))
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in effify
  File "", line 1
f"
   ^
SyntaxError: unterminated triple-quoted string literal (detected at line 1)

This is literally the version I described myself, except using triple 
quotes. It only modifies the underlying problem, but doesn't solve it.


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


Re: Evaluation of variable as f-string

2023-01-27 Thread Johannes Bauer

Am 23.01.23 um 19:02 schrieb Chris Angelico:


This is supposedly for security reasons. However, when trying to emulate
this behavior that I wanted (and know the security implications of), my
solutions will tend to be less secure. Here is what I have been thinking
about:


If you really want the full power of an f-string, then you're asking
for the full power of eval(),


Exactly.


and that means all the security
implications thereof,


Precisely, as I had stated myself.


not to mention the difficulties of namespacing.


Not an issue in my case.


Have you considered using the vanilla format() method instead?


Yes. It does not provide the functionality I want. Not even the utterly 
trivial example that I gave. To quote myself again, let's say I have an 
arbitrary dictionary x (with many nested data structures), I want an 
expression to be evaluated that can access any members in there.


x = { "y": "z" }
s = "-> {x['y']}"
print(s.format(x = x))
Traceback (most recent call last):
  File "", line 1, in 
KeyError: "'y'"

I also want to be able to say things like {'x' * 100}, which .format() 
also does not do.


In other words: I want the evaluation of a variable as an f-string.



But if you really REALLY know what you're doing, just use eval()
directly.


I do, actually, but I hate it. Not because of the security issue, not 
because of namespaces, but because it does not reliably work:


>>> s = "{\"x\" * 4}"
>>> eval("f'" + s + "'")
''

As I mentioned, it depends on the exact quoting. Triple quotes only 
shift the problem. Actually replacing/escaping the relevant quotation 
marks is also not trivial.


I don't really see what you'd gain from an f-string. 


The full power of eval.


At very
least, work with a well-defined namespace and eval whatever you need
in that context.


That's what I'm doing.


Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?


I want to render data from a template using an easily understandable 
syntax (like an f-string), ideally using native Python. I want the 
template to make use of Python code constructs AND formatting (e.g. 
{x['time']['runtime']['seconds'] // 60:02d}).


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


evaluation question

2023-01-27 Thread Muttley
Hi

This is probably a dumb newbie question but I've just started to learn
python3 and eval() isn't behaving as I'd expect in that it works for
some things and not others. eg:

>>> eval("1+1")
2
>>> eval("print(123)")
123
>>> eval("for i in range(1,10): i")
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1
for i in range(1,10): i
  ^
SyntaxError: invalid syntax

Why did the 3rd one fail? Does it not handle complex expressions?

Thanks for any help



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


Re: bool and int

2023-01-27 Thread Greg Ewing

On 26/01/23 6:10 am, Chris Angelico wrote:

And that's a consequence of a system wherein there is only one concept
of "success", but many concepts of "failure". Whoever devised that
system was clearly a pessimist :)


Murphy's Law for Unix: If something can go wrong, it will go
wrong 255 times out of 256.

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


Re: How to make argparse accept "-4^2+5.3*abs(-2-1)/2" string argument?

2023-01-27 Thread Michael Torrie
On 1/25/23 19:50, Jach Feng wrote:
> To me, argparse has been just a tool which I can use in a CLI app. 

argparse is just a tool for dealing with command-line *flags*, which are
common in command-line tools.  argparse interprets the command line as a
bunch of flags because that's what it's designed to do.  I find it
baffling that you expect some other behavior from argparse.

You don't need or want argparse in this situation. sys.argv has
everything you need in it. Use it directly!

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Thomas Passin

On 1/27/2023 5:54 PM, Rob Cliffe via Python-list wrote:

Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken 
aback by such forceful language.


I generally agree with asking for what the intent is.  In this case it 
seems pretty clear that the OP wants to use these string fragments as 
templates, and he needs to be able to insert variables into them at 
runtime, not compile time.


So I think a good response would have been roughly

"It looks like you want to use these strings as templates, is that 
right?  If not, please tell us what you are trying to do, because it's 
hard to help without knowing that.  If it's right, here's a way you 
could go about it."


Short and amiable.


On 27/01/2023 19:18, Chris Angelico wrote:

On Sat, 28 Jan 2023 at 05:31, Rob Cliffe via Python-list
 wrote:

On 23/01/2023 18:02, Chris Angelico wrote:

Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?

ChrisA

Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
for a different use-case) whether there is a way of evaluating a string
at runtime as if it were an f-string.  We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.

No, it's not, because that's the "how do I use X to do Y" problem.
Instead, just ask how to do *what you actually need*. If the best way
to do that is to eval an f-string, then someone will suggest that.
But, much much much more likely, the best way to do it would be
something completely different. What, exactly? That's hard to say,
because *we don't know what you actually need*. All you tell us is
what you're attempting to do, which there is *no good way to achieve*.

If the above is addressed to the OP, I can't answer for him.
If it's addressed to me:  How about if I wanted a program (a learning 
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it 
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one 
right now.



I appreciate that the answer may be "No, because it would be a lot of
work - and increase the maintenance burden - to support a relatively
rare requirement".

What about: "No, because it's a terrible TERRIBLE idea, requires that
you do things horribly backwards, and we still don't even know what
you're trying to do"?


Perhaps someone will be inspired to write a function to do it. 

See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen.

Again, if this is addressed to the OP: I'm not his keeper. 
If it's addressed to me: "it" means a function that will take a string 
and evaluate it at runtime as if it were an f-string.  Sure, with 
caveats and limitations.  And indeed Thomas Passim found this partial 
solution on Stack Overflow:

def effify(non_f_str: str):
     return eval(f'f"""{non_f_str}"""')

  Using eval() to construct
an f-string and then parse it is TERRIBLE because:

1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.
I understand these limitations.  Nonetheless I can conceive that there 
may be scenarios where it is an acceptable solution (perhaps the 
learning tool program I suggested above).

Addressing your points specifically:
     1) I believe the quote character limitation could be overcome. It 
would need a fair amount of work, for which I haven't (yet) the time or 
inclination.
     2) Yes in general you would have to pass it one dictionary, maybe 
two.  I don't see this as an insuperable obstacle.  I am not sure what 
you mean by "can't be done with full generality" and perhaps that's not 
important.

     3) Not sure I understand this.
     4) On the fairly rare occasions that I have used eval(), I can't 
remember speed ever being a consideration.


For some reason, str.format() isn't suitable, but *you haven't said
why*, so we have to avoid that in our solutions. So, to come back to
your concern:


We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.

Well, yes. If you asked "how can I do X", hoping the answer would be
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".

I hope that I have shown that this is a somewhat dogmatic response.


Don't ask how to use X to do Y. Ask how to do Y.

Good advice.
Best wishes
Rob Cliffe


ChrisA




--

Re: Evaluation of variable as f-string

2023-01-27 Thread Chris Angelico
On Sat, 28 Jan 2023 at 10:08, Rob Cliffe via Python-list
 wrote:
>
> Whoa! Whoa! Whoa!
> I appreciate the points you are making, Chris, but I am a bit taken
> aback by such forceful language.

The exact same points have already been made, but not listened to.
Sometimes, forceful language is required in order to get people to
listen.

> If it's addressed to me:  How about if I wanted a program (a learning
> tool) to allow the user to play with f-strings?
> I.e. to type in a string, and then see what the result would be if it
> had been an f-string?
> I suspect there are other use cases, but I confess I can't think of one
> right now.

Use the REPL, which will happily evaluate f-strings in their original
context, just like any other code would. You're already eval'ing, so
it's exactly what you'd expect. This is not the same thing as "typing
in a string", though - it's typing in code and seeing what the result
would be. (Except to the extent that source code can be considered a
string.)

> If it's addressed to me: "it" means a function that will take a string
> and evaluate it at runtime as if it were an f-string.  Sure, with
> caveats and limitations.

And that's what I am saying is a terrible terrible idea. It will
evaluate things in the wrong context, it has all the normal problems
of eval, and then it introduces its own unique problems with quote
characters.

>  And indeed Thomas Passim found this partial
> solution on Stack Overflow:
> def effify(non_f_str: str):
>  return eval(f'f"""{non_f_str}"""')

You can find anything on Stack Overflow. Just because you found it
there doesn't mean it's any good - even if it's been massively
upvoted.

> Addressing your points specifically:
>  1) I believe the quote character limitation could be overcome. It
> would need a fair amount of work, for which I haven't (yet) the time or
> inclination.

No problem. Here, solve it for this string:

eval_me = ' f"""{f\'\'\'{f"{f\'{1+2}\'}"}\'\'\'}""" '

F-strings can be nested, remember.

>  2) Yes in general you would have to pass it one dictionary, maybe
> two.  I don't see this as an insuperable obstacle.  I am not sure what
> you mean by "can't be done with full generality" and perhaps that's not
> important.

>>> def func():
... x = 1
... class cls:
... y = 2
... print(f"{x=} {y=}")
... print(locals())
...
>>> func()
x=1 y=2
{'__module__': '__main__', '__qualname__': 'func..cls', 'y': 2}

Maybe you don't care. Maybe you do. But locals() is not the same as
"all names currently available in this scope". And, this example is
definitely not something I would recommend, but good luck making this
work with eval:

>>> def func():
... x = 1
... print(f"{(x:=2)}")
... print(x)
...
>>> func()
2
2
... x = 1
... print(eval("(x:=2)", globals(), locals()))
... print(x)
...
>>> func()
2
1

>  3) Not sure I understand this.

Before f-strings existed, one of the big problems with "just use
str.format_map" was that you can't just pass it locals() to get all
the available names. You also can't eval arbitrary code and expect to
get the same results, even if you pass it globals and locals. And
various other considerations here - the exact issues seen here, but
flipped on their heads. So the obvious question is: why not just use
str.format_map?

> > Well, yes. If you asked "how can I do X", hoping the answer would be
> > "with a runtime-evaluated f-string", then you're quite right - the
> > answer might not be what you were hoping for. But since you asked "how
> > can I evaluate a variable as if it were an f-string", the only
> > possible answer is "you can't, and that's a horrible idea".
> I hope that I have shown that this is a somewhat dogmatic response.

And I hope that I have shown that it is fully justified.

> > Don't ask how to use X to do Y. Ask how to do Y.
> Good advice.

Exactly. As I have shown, asking how to use f-strings to achieve this
is simply not suitable, and there's no useful way to discuss other
than to argue semantics. If we had a GOAL to discuss, we could find
much better options.

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


Re: Custom help format for a choice argparse argument

2023-01-27 Thread Thomas Passin

On 1/27/2023 4:53 PM, Ivan "Rambius" Ivanov wrote:

Hello Cameron,

On Fri, Jan 27, 2023 at 4:45 PM Cameron Simpson  wrote:


On 27Jan2023 15:31, Ivan "Rambius" Ivanov  wrote:

I am developing a script that accepts a time zone as an option. The
time zone can be any from pytz.all_timezones. I have

def main():
parser = argparse.ArgumentParser()
parser.add_argument("-z", "--zone", choices=pytz.all_timezones)

[...]


It works, but when I run it with the -h option it dumps all entries in
pytz.all_timezones.


What happens if you just presupply a `help=` parameter in
`add_argument`?


I tried with def main():
 parser = argparse.ArgumentParser()
 parser.add_argument("-z", "--zone", choices=pytz.all_timezones,
help="a timezone from pytz.all_timezones")
 args = parser.parse_args()
 print(args)

-h still shows all the contents of pytz.all_timezones.



Adding a few arguments makes it work (with the help of the argparse doc 
page and Stack Overflow:


https://stackoverflow.com/questions/14950964/overriding-default-argparse-h-behaviour):

import argparse
import pytz

HELP ="""\nThis is the help message.
This is the second line of the help message."""

def main():
parser = argparse.ArgumentParser(add_help=False, usage = HELP)
parser.add_argument("-z", "--zone", choices=pytz.all_timezones,
help = argparse.SUPPRESS)
parser.add_argument('-h', '--h', action = 'help',
help = argparse.SUPPRESS)
args = parser.parse_args()
print(args)
print(f"Specified timezone: {args.zone}")


main()

Your help message will display after "usage", like this -

usage:
This is the help message.
This is the second line of the help message.

You would give up have argparse automatically list all the options, but 
you can add add them manually to the HELP string.



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


Re: Evaluation of variable as f-string

2023-01-27 Thread Rob Cliffe via Python-list

Whoa! Whoa! Whoa!
I appreciate the points you are making, Chris, but I am a bit taken 
aback by such forceful language.


On 27/01/2023 19:18, Chris Angelico wrote:

On Sat, 28 Jan 2023 at 05:31, Rob Cliffe via Python-list
 wrote:

On 23/01/2023 18:02, Chris Angelico wrote:

Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?

ChrisA

Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
for a different use-case) whether there is a way of evaluating a string
at runtime as if it were an f-string.  We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.

No, it's not, because that's the "how do I use X to do Y" problem.
Instead, just ask how to do *what you actually need*. If the best way
to do that is to eval an f-string, then someone will suggest that.
But, much much much more likely, the best way to do it would be
something completely different. What, exactly? That's hard to say,
because *we don't know what you actually need*. All you tell us is
what you're attempting to do, which there is *no good way to achieve*.

If the above is addressed to the OP, I can't answer for him.
If it's addressed to me:  How about if I wanted a program (a learning 
tool) to allow the user to play with f-strings?
I.e. to type in a string, and then see what the result would be if it 
had been an f-string?
I suspect there are other use cases, but I confess I can't think of one 
right now.



I appreciate that the answer may be "No, because it would be a lot of
work - and increase the maintenance burden - to support a relatively
rare requirement".

What about: "No, because it's a terrible TERRIBLE idea, requires that
you do things horribly backwards, and we still don't even know what
you're trying to do"?


Perhaps someone will be inspired to write a function to do it. 

See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen.

Again, if this is addressed to the OP: I'm not his keeper. 
If it's addressed to me: "it" means a function that will take a string 
and evaluate it at runtime as if it were an f-string.  Sure, with 
caveats and limitations.  And indeed Thomas Passim found this partial 
solution on Stack Overflow:

def effify(non_f_str: str):
    return eval(f'f"""{non_f_str}"""')

  Using eval() to construct
an f-string and then parse it is TERRIBLE because:

1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.
I understand these limitations.  Nonetheless I can conceive that there 
may be scenarios where it is an acceptable solution (perhaps the 
learning tool program I suggested above).

Addressing your points specifically:
    1) I believe the quote character limitation could be overcome. It 
would need a fair amount of work, for which I haven't (yet) the time or 
inclination.
    2) Yes in general you would have to pass it one dictionary, maybe 
two.  I don't see this as an insuperable obstacle.  I am not sure what 
you mean by "can't be done with full generality" and perhaps that's not 
important.

    3) Not sure I understand this.
    4) On the fairly rare occasions that I have used eval(), I can't 
remember speed ever being a consideration.


For some reason, str.format() isn't suitable, but *you haven't said
why*, so we have to avoid that in our solutions. So, to come back to
your concern:


We encourage people to ask
questions on this list, even though the answer will not always be what
they're hoping for.

Well, yes. If you asked "how can I do X", hoping the answer would be
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".

I hope that I have shown that this is a somewhat dogmatic response.


Don't ask how to use X to do Y. Ask how to do Y.

Good advice.
Best wishes
Rob Cliffe


ChrisA


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


Re: Custom help format for a choice argparse argument

2023-01-27 Thread Ivan "Rambius" Ivanov
Hello Cameron,

On Fri, Jan 27, 2023 at 4:45 PM Cameron Simpson  wrote:
>
> On 27Jan2023 15:31, Ivan "Rambius" Ivanov  
> wrote:
> >I am developing a script that accepts a time zone as an option. The
> >time zone can be any from pytz.all_timezones. I have
> >
> >def main():
> >parser = argparse.ArgumentParser()
> >parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
> [...]
> >
> >It works, but when I run it with the -h option it dumps all entries in
> >pytz.all_timezones.
>
> What happens if you just presupply a `help=` parameter in
> `add_argument`?

I tried with def main():
parser = argparse.ArgumentParser()
parser.add_argument("-z", "--zone", choices=pytz.all_timezones,
help="a timezone from pytz.all_timezones")
args = parser.parse_args()
print(args)

-h still shows all the contents of pytz.all_timezones.

Regards
rambius

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



-- 
Tangra Mega Rock: http://www.radiotangra.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Custom help format for a choice argparse argument

2023-01-27 Thread Cameron Simpson

On 27Jan2023 15:31, Ivan "Rambius" Ivanov  wrote:

I am developing a script that accepts a time zone as an option. The
time zone can be any from pytz.all_timezones. I have

def main():
   parser = argparse.ArgumentParser()
   parser.add_argument("-z", "--zone", choices=pytz.all_timezones)

[...]


It works, but when I run it with the -h option it dumps all entries in
pytz.all_timezones.


What happens if you just presupply a `help=` parameter in 
`add_argument`?


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


Re: Custom help format for a choice argparse argument

2023-01-27 Thread Ivan "Rambius" Ivanov
Hello,

On Fri, Jan 27, 2023 at 4:22 PM Weatherby,Gerard  wrote:
>
> Why not something like:
>
>
> parser.add_argument("-z", "--zone")
>
>args = parser.parse_args()
>if args.zone and args.zone not in ptyz.all_timezones:
>
> print(“Invalid timezone”,file=sys.stderr)
>
This is what I use now. I still wonder if I can mold HelpFormatter to
do what I want it to do.

> …
>
>
>
>
> From: Python-list  on 
> behalf of Ivan "Rambius" Ivanov 
> Date: Friday, January 27, 2023 at 3:33 PM
> To: Python 
> Subject: Custom help format for a choice argparse argument
>
> *** Attention: This is an external email. Use caution responding, opening 
> attachments or clicking on links. ***
>
> Hello,
>
> I am developing a script that accepts a time zone as an option. The
> time zone can be any from pytz.all_timezones. I have
>
> def main():
> parser = argparse.ArgumentParser()
> parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
> args = parser.parse_args()
> print(args)
> print(f"Specified timezone: {args.zone}")
>
> It works, but when I run it with the -h option it dumps all entries in
> pytz.all_timezones. I would like to modify the help format for just
> -z|--zone option. I read the docs about HelpFormatter and argparse.py
> and I ended up with
>
> class CustomHelpFormatter(argparse.HelpFormatter):
> def _metavar_formatter(self, action, default_metavar):
> if action.dest == 'zone':
> result = 'zone from pytz.all_timezones'
> def format(tuple_size):
> if isinstance(result, tuple):
> return result
> else:
> return (result, ) * tuple_size
> return format
> else:
> return super(CustomHelpFormatter,
> self)._metavar_formatter(action, default_metavar)
>
>
> def main():
> parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter)
> parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
> args = parser.parse_args()
> print(args)
> print(f"Specified timezone: {args.zone}")
>
> This works, but is there a more elegant way to achieve it?
>
> Regards
> rambius
>
> --
> Tangra Mega Rock: 
> https://urldefense.com/v3/__http://www.radiotangra.com__;!!Cn_UX_p3!kiJusdm5pCptP3sOBX85KXqUJkqr2jSa4C_-WAqND7WkL-aw3BYbW50td_AcuzJ1XUPYIVO3JiLMc4gRWS885vTKFsFvaQ$
> --
> https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!kiJusdm5pCptP3sOBX85KXqUJkqr2jSa4C_-WAqND7WkL-aw3BYbW50td_AcuzJ1XUPYIVO3JiLMc4gRWS885vRXq-JKLg$



-- 
Tangra Mega Rock: http://www.radiotangra.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Custom help format for a choice argparse argument

2023-01-27 Thread Weatherby,Gerard
Why not something like:

parser.add_argument("-z", "--zone")
   args = parser.parse_args()
   if args.zone and args.zone not in ptyz.all_timezones:
print(“Invalid timezone”,file=sys.stderr)
…



From: Python-list  on 
behalf of Ivan "Rambius" Ivanov 
Date: Friday, January 27, 2023 at 3:33 PM
To: Python 
Subject: Custom help format for a choice argparse argument
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

Hello,

I am developing a script that accepts a time zone as an option. The
time zone can be any from pytz.all_timezones. I have

def main():
parser = argparse.ArgumentParser()
parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
args = parser.parse_args()
print(args)
print(f"Specified timezone: {args.zone}")

It works, but when I run it with the -h option it dumps all entries in
pytz.all_timezones. I would like to modify the help format for just
-z|--zone option. I read the docs about HelpFormatter and argparse.py
and I ended up with

class CustomHelpFormatter(argparse.HelpFormatter):
def _metavar_formatter(self, action, default_metavar):
if action.dest == 'zone':
result = 'zone from pytz.all_timezones'
def format(tuple_size):
if isinstance(result, tuple):
return result
else:
return (result, ) * tuple_size
return format
else:
return super(CustomHelpFormatter,
self)._metavar_formatter(action, default_metavar)


def main():
parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter)
parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
args = parser.parse_args()
print(args)
print(f"Specified timezone: {args.zone}")

This works, but is there a more elegant way to achieve it?

Regards
rambius

--
Tangra Mega Rock: 
https://urldefense.com/v3/__http://www.radiotangra.com__;!!Cn_UX_p3!kiJusdm5pCptP3sOBX85KXqUJkqr2jSa4C_-WAqND7WkL-aw3BYbW50td_AcuzJ1XUPYIVO3JiLMc4gRWS885vTKFsFvaQ$
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!kiJusdm5pCptP3sOBX85KXqUJkqr2jSa4C_-WAqND7WkL-aw3BYbW50td_AcuzJ1XUPYIVO3JiLMc4gRWS885vRXq-JKLg$
-- 
https://mail.python.org/mailman/listinfo/python-list


Custom help format for a choice argparse argument

2023-01-27 Thread Ivan "Rambius" Ivanov
Hello,

I am developing a script that accepts a time zone as an option. The
time zone can be any from pytz.all_timezones. I have

def main():
parser = argparse.ArgumentParser()
parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
args = parser.parse_args()
print(args)
print(f"Specified timezone: {args.zone}")

It works, but when I run it with the -h option it dumps all entries in
pytz.all_timezones. I would like to modify the help format for just
-z|--zone option. I read the docs about HelpFormatter and argparse.py
and I ended up with

class CustomHelpFormatter(argparse.HelpFormatter):
def _metavar_formatter(self, action, default_metavar):
if action.dest == 'zone':
result = 'zone from pytz.all_timezones'
def format(tuple_size):
if isinstance(result, tuple):
return result
else:
return (result, ) * tuple_size
return format
else:
return super(CustomHelpFormatter,
self)._metavar_formatter(action, default_metavar)


def main():
parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter)
parser.add_argument("-z", "--zone", choices=pytz.all_timezones)
args = parser.parse_args()
print(args)
print(f"Specified timezone: {args.zone}")

This works, but is there a more elegant way to achieve it?

Regards
rambius

-- 
Tangra Mega Rock: http://www.radiotangra.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Evaluation of variable as f-string

2023-01-27 Thread Chris Angelico
On Sat, 28 Jan 2023 at 05:31, Rob Cliffe via Python-list
 wrote:
> On 23/01/2023 18:02, Chris Angelico wrote:
> > Maybe, rather than asking for a way to treat a string as code, ask for
> > what you ACTUALLY need, and we can help?
> >
> > ChrisA
> Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps
> for a different use-case) whether there is a way of evaluating a string
> at runtime as if it were an f-string.  We encourage people to ask
> questions on this list, even though the answer will not always be what
> they're hoping for.

No, it's not, because that's the "how do I use X to do Y" problem.
Instead, just ask how to do *what you actually need*. If the best way
to do that is to eval an f-string, then someone will suggest that.
But, much much much more likely, the best way to do it would be
something completely different. What, exactly? That's hard to say,
because *we don't know what you actually need*. All you tell us is
what you're attempting to do, which there is *no good way to achieve*.

> I appreciate that the answer may be "No, because it would be a lot of
> work - and increase the maintenance burden - to support a relatively
> rare requirement".

What about: "No, because it's a terrible TERRIBLE idea, requires that
you do things horribly backwards, and we still don't even know what
you're trying to do"?

> Perhaps someone will be inspired to write a function to do it. 

See, we don't know what "it" is, so it's hard to write a function
that's any better than the ones we've seen. Using eval() to construct
an f-string and then parse it is TERRIBLE because:

1) It still doesn't work in general, and thus has caveats like "you
can't use this type of quote character"
2) You would have to pass it a dictionary of variables, which also
can't be done with full generality
3) These are the exact same problems, but backwards, that led to
f-strings in the first place
4) eval is extremely slow and horrifically inefficient.

For some reason, str.format() isn't suitable, but *you haven't said
why*, so we have to avoid that in our solutions. So, to come back to
your concern:

> We encourage people to ask
> questions on this list, even though the answer will not always be what
> they're hoping for.

Well, yes. If you asked "how can I do X", hoping the answer would be
"with a runtime-evaluated f-string", then you're quite right - the
answer might not be what you were hoping for. But since you asked "how
can I evaluate a variable as if it were an f-string", the only
possible answer is "you can't, and that's a horrible idea".

Don't ask how to use X to do Y. Ask how to do Y.

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


Re: Evaluation of variable as f-string

2023-01-27 Thread Rob Cliffe via Python-list



On 23/01/2023 18:02, Chris Angelico wrote:

On Tue, 24 Jan 2023 at 04:56, Johannes Bauer  wrote:

Hi there,

is there an easy way to evaluate a string stored in a variable as if it
were an f-string at runtime?

...

This is supposedly for security reasons. However, when trying to emulate
this behavior that I wanted (and know the security implications of), my
solutions will tend to be less secure. Here is what I have been thinking
about:

If you really want the full power of an f-string, then you're asking
for the full power of eval(), and that means all the security
implications thereof, not to mention the difficulties of namespacing.
Have you considered using the vanilla format() method instead?

But if you really REALLY know what you're doing, just use eval()
directly. I don't really see what you'd gain from an f-string. At very
least, work with a well-defined namespace and eval whatever you need
in that context.

Maybe, rather than asking for a way to treat a string as code, ask for
what you ACTUALLY need, and we can help?

ChrisA
Fair enough, Chris, but still ISTM that it is reasonable to ask (perhaps 
for a different use-case) whether there is a way of evaluating a string 
at runtime as if it were an f-string.  We encourage people to ask 
questions on this list, even though the answer will not always be what 
they're hoping for.
I appreciate that the answer may be "No, because it would be a lot of 
work - and increase the maintenance burden - to support a relatively 
rare requirement".

Perhaps someone will be inspired to write a function to do it. 
Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: bool and int

2023-01-27 Thread Rob Cliffe via Python-list



On 24/01/2023 04:22, Dino wrote:


$ python
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> b = True
>>> isinstance(b,bool)
True
>>> isinstance(b,int)
True
>>>


That immediately tells you that either
    bool is a subclass of int
    int is a subclass of bool
    bool and int are both subclasses of some other class
In fact the first one is true.
This is not a logical necessity, but the way Python happens to be designed.
Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Evaluation of variable as f-string

2023-01-27 Thread Rob Cliffe via Python-list



On 25/01/2023 19:38, Thomas Passin wrote:


Stack overflow to the rescue:

Search phrase:  "python evaluate string as fstring"

https://stackoverflow.com/questions/47339121/how-do-i-convert-a-string-into-an-f-string 



def effify(non_f_str: str):
    return eval(f'f"""{non_f_str}"""')

print(effify(s))  # prints as expected: "-> z"

Duh!  Am I the only one who feels stupid not thinking of this?
Although of course it won't work if the string already contains triple 
double quotes.
I believe this could be got round with some ingenuity (having the effify 
function parse the string and replace genuine (not embedded in 
single-quotes) triple double quotes with triple single quotes, though 
there are some complications).
And the effify function can't be put in its own module unless it can be 
passed the globals and/or locals dictionaries as needed for eval to 
use.  Something like this:


def effify(non_f_str, glob=None, loc=None):
    return eval(f'f"""{non_f_str}"""',
    glob if glob is not None else globals(),
    loc if loc is not None else locals())

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


Re: Python not found

2023-01-27 Thread Eryk Sun
On 1/27/23, Bela Gesztesi  wrote:
>
> I'm not that familiar with the steps to be taken.
>
> How do I find the app version of Python for my desktop?
> or
> I don't know how to disable the "python.exe" and "python3.exe" app aliases

To install the app version, run "python3" from the command line. This
will open the Microsoft Store to install the Python app. (If it
doesn't, simply open the store from the start menu.) It may not open
to the latest version of Python, which currently is 3.11.1. Search for
"python" to find the latest version. Make sure the package is from
"Python Software Foundation". Click the "Get" button.

OR

To disable the aliases for the default installer app, begin by
right-clicking the start button and select "settings". Click on "Apps"
in the sidebar. Then click on "Apps & Features" in the window. Click
the drop-down arrow on "More settings". Click on "App execution
aliases". Disable the aliases for "App Installer / python.exe" and
"App Installer / python3.exe".

Some of the above names will be localized to your preferred user
interface language. Hopefully the translations are obvious.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: asyncio questions

2023-01-27 Thread Frank Millman

On 2023-01-27 2:14 PM, Frank Millman wrote:


I have changed it to async, which I call with 'asyncio.run'. It now 
looks like this -


     server = await asyncio.start_server(handle_client, host, port)
     await setup_companies()
     session_check = asyncio.create_task(
     check_sessions())  # start background task

     print('Press Ctrl+C to stop')

     try:
     await server.serve_forever()
     except asyncio.CancelledError:
     pass
     finally:
     session_check.cancel()  # tell session_check to stop running
     await asyncio.wait([session_check])
     server.close()



I don't think I need the 'finally' clause - the cleanup can all happen 
in the 'except' block.


Frank

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


Re: asyncio questions

2023-01-27 Thread Frank Millman

On 2023-01-26 7:16 PM, Dieter Maurer wrote:

Frank Millman wrote at 2023-1-26 12:12 +0200:

I have written a simple HTTP server using asyncio. It works, but I don't
always understand how it works, so I was pleased that Python 3.11
introduced some new high-level concepts that hide the gory details. I
want to refactor my code to use these concepts, but I am not finding it
easy.

In simple terms my main loop looked like this -

     loop = asyncio.get_event_loop()
     server = loop.run_until_complete(
     asyncio.start_server(handle_client, host, port))
     loop.run_until_complete(setup_companies())
     session_check = asyncio.ensure_future(
     check_sessions())  # start background task
     print('Press Ctrl+C to stop')
     try:
     loop.run_forever()
     except KeyboardInterrupt:
     print()
     finally:
     session_check.cancel()  # tell session_check to stop running
     loop.run_until_complete(asyncio.wait([session_check]))
     server.close()
     loop.stop()


Why does your code uses several `loop.run*` calls?

In fact, I would define a single coroutine and run that
with `asyncio.run`.
This way, the coroutine can use all `asyncio` features,
including `loop.create_task`.


You are right, Dieter. The function that I showed above is a normal 
function, not an async one. There was no particular reason for this - I 
must have got it working like that at some point in the past, and 'if it 
ain't broke ...'


I have changed it to async, which I call with 'asyncio.run'. It now 
looks like this -


server = await asyncio.start_server(handle_client, host, port)
await setup_companies()
session_check = asyncio.create_task(
check_sessions())  # start background task

print('Press Ctrl+C to stop')

try:
await server.serve_forever()
except asyncio.CancelledError:
pass
finally:
session_check.cancel()  # tell session_check to stop running
await asyncio.wait([session_check])
server.close()

It works exactly the same as before, and it is now much neater.

Thanks for the input.

Frank

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