Re: evaluation question
On 2023-01-31, Greg Ewing wrote: > That's only one of the syntactic oddities of the old print > statement, thogh. There was also the >> thing, special treatment > of trailing commas, etc. In "old" Python I used to use the trailing comma extensively, but I could never get myself to use the >> thing. I don't know why, but it just felt wrong. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 1/02/23 1:17 pm, dn wrote: 1 nothing "ceased to execute" and Python 2 was maintained and developed for quite some time and in-parallel to many Python 3 releases. And a lot of effort was put into making the transition as easy as possible, e.g. 2to3, and the features added to 2.7 to make it easier to write code that would work in both versions. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 01/02/2023 11.59, Greg Ewing wrote: On 31/01/23 10:24 pm, mutt...@dastardlyhq.com wrote: All languages have their ugly corners due to initial design mistakes and/or constraints. Eg: java with the special behaviour of its string class, C++ with "=0" pure virtual declaration. But they don't dump them and make all old code suddenly cease to execute. No, but it was decided that Python 3 would have to be backwards incompatible, mainly to sort out the Unicode mess. Given that, the opportunity was taken to clean up some other mistakes as well. +1 and the move to Unicode has opened-up the Python community beyond the US, to embrace 'the world' - a proposition (still) not well-recognised by (only) English-speakers/writers/readers. Even though the proposition has a troll-bait smell to it:- 1 nothing "ceased to execute" and Python 2 was maintained and developed for quite some time and in-parallel to many Python 3 releases. 2 the only constant in this business is 'change'. I'd rather cope with an evolution in this language (which we know and love), than one day realise that it has become dated or inflexible, and have to learn a new, replacement, language! -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 1/31/2023 6:18 PM, Greg Ewing wrote: On 1/02/23 7:33 am, Stefan Ram wrote: Thomas Passin writes: Some people say it is a function now so that you can redefine it. Hmm, I didn't write these quotes. Maybe someone got confused by the depth of the nested replies in this thread. Easy enough to do. Well, that's one benefit, but I wouldn't say it's the main one. The point is really that you can do *anything* with it now that you can do with a regular function -- pass it as an argument, wrap it with another function, define your own function with a similar signature for duck-typing purposes, etc. It would still be possible to have a special syntax for the outermost expression of an expression statement that would allow one to omit the parentheses, That's only one of the syntactic oddities of the old print statement, thogh. There was also the >> thing, special treatment of trailing commas, etc. Also, introducing a paren-less call syntax would be a very big and controversial change that would be way out of proportion to the problem. -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On Wed, 1 Feb 2023 at 10:47, Greg Ewing wrote: > That's only one of the syntactic oddities of the old print > statement, thogh. There was also the >> thing, special treatment > of trailing commas, etc. "Soft space" (the trailing comma behaviour) was an incredibly complex wart. Glad it's gone. > Also, introducing a paren-less call syntax would be a very big > and controversial change that would be way out of proportion to > the problem. Oddly enough, that WAS actually proposed recently - by Guido himself - as a demonstration of the power of the new PEG parser: https://mail.python.org/archives/list/python-id...@python.org/thread/NCQX6ZIBREUTLS52VVG3DSZ43OEXJFTT/ (The mailing list archive messes up formatting a bit with REPL transcripts, thinking they're quoted text.) The general consensus was "allowing function calls without parens causes more issues than it solves", with plenty of examples from other programming languages to prove this - Ruby, while generally a decent language, shows a rather nasty wart with this particular feature (see "Ruby allows parens-less function calls" from Steven D'Aprano in that thread). I don't think it'll ever happen in Python, but it's nice to know that the parser is flexible enough. It means that other weird cases, where the intuitive expectation is different, can be better handled (see eg "with (x as y, a as b):" syntax). Having print as a function is WAY better than having it as a special case with lots of warts. And it's so much easier to add extra features to it; for instance, how would you add a "flush after printing" flag to Py2's print statement? With a function, it's easy - just print(..., flush=True). ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 1/02/23 7:33 am, Stefan Ram wrote: Thomas Passin writes: Some people say it is a function now so that you can redefine it. Well, that's one benefit, but I wouldn't say it's the main one. The point is really that you can do *anything* with it now that you can do with a regular function -- pass it as an argument, wrap it with another function, define your own function with a similar signature for duck-typing purposes, etc. It would still be possible to have a special syntax for the outermost expression of an expression statement that would allow one to omit the parentheses, That's only one of the syntactic oddities of the old print statement, thogh. There was also the >> thing, special treatment of trailing commas, etc. Also, introducing a paren-less call syntax would be a very big and controversial change that would be way out of proportion to the problem. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 31/01/23 10:24 pm, mutt...@dastardlyhq.com wrote: All languages have their ugly corners due to initial design mistakes and/or constraints. Eg: java with the special behaviour of its string class, C++ with "=0" pure virtual declaration. But they don't dump them and make all old code suddenly cease to execute. No, but it was decided that Python 3 would have to be backwards incompatible, mainly to sort out the Unicode mess. Given that, the opportunity was taken to clean up some other mistakes as well. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Evaluation of variable as f-string
On Wed, 1 Feb 2023 at 09:14, Rob Cliffe via Python-list wrote: > With great respect, Chris, isn't it for the OP (or anyone else) to > decide - having been warned of the various drawbacks and limitations - > to decide if it's a terrible idea *for him*? He's entitled to decide > that it's just what *he* needs, and that the drawbacks don't matter *for > him". Just as you're entitled to disagree. It's an objectively bad idea. If the OP wants to do it, well, it's a free world, but that doesn't mean I'm going to sugarcoat it and say "oh yes, yes, you are totally right to do that". > Thanks for clarifying. > Hm. So 'x' is neither in locals() nor in globals(). Which starts me > wondering (to go off on a tangent): Should there be a nonlocals() > dictionary? I don't think so, but there might be some value in a dictionary containing all available variables. It would have the same "don't depend on writing" caveats that locals() has (or would be specifically defined as a copy and thus disconnected), so its value would be limited. And it would probably STILL be imperfect, because perfection would require that it be a compiler construct, due to the way that nonlocals are implemented. >>> class Destructible: ... def __init__(self, name): self.name = name ... def __del__(self): print("Deleting", self.name) ... >>> def func(): ... x = Destructible("x") ... y = Destructible("y") ... return lambda: x ... >>> func() Deleting y . at 0x7ff8c9897ce0> The compiler is free to dispose of y as soon as func ends, but x has to be retained for the inner function. So if there were any function that could return every readable variable, it would have to force both x and y to be retained; as such, it would have to be a compiler construct. And given what happened with star imports in functions as of Python 3, I am highly dubious that such a pessimisation would ever be implemented. > > 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 > Now that, I have to admit, IS a challenge! Exactly. This sort of thing is why the OP's idea as written is so bad: it will cause many unnecessary corner cases, where the much simpler idea of working it around format_map will actually behave sanely. So I do not apologize for calling it a bad idea. It is a bad idea. Lying about it won't change anything and won't help anyone. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Evaluation of variable as f-string
On 27/01/2023 23:41, Chris Angelico wrote: 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.) This is hypothetical, but I might want to work on a platform where the REPL was not available. 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. With great respect, Chris, isn't it for the OP (or anyone else) to decide - having been warned of the various drawbacks and limitations - to decide if it's a terrible idea *for him*? He's entitled to decide that it's just what *he* needs, and that the drawbacks don't matter *for him". Just as you're entitled to disagree. 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. I remember it well. As far as I can see (and I may well be wrong; thinking about this example made my head hurt 😁) this could be solved if PEP 701 were implemented (so that f-string expressions can contain backslashes) but not otherwise. 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} Thanks for clarifying. Hm. So 'x' is neither in locals() nor in globals(). Which starts me wondering (to go off on a tangent): Should there be a nonlocals() dictionary? 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 Now that, I have to admit, IS a challenge! 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? What this underlines to me is what a good thing f-strings are. And with PEP 701 they will be IMO even better. Just as when you were working on PEP 463 (Exception-catching expressions) - which I still think would be a Good Thing - some research I did made me realise how good the existing try/except/else/finally mechanism actually is. There's lots of Good Stuff in Python. 😁 Best wishes Rob -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
import io def countprint(*args, **kwargs): capturekw = {k:v for k,v in kwargs.items() if k != 'file'} buffer = io.StringIO() capturekw['file'] = buffer print(*args,**kwargs) print(*args,**capturekw) return len(buffer.getvalue()) def boolprint(*args,active:bool, **kwargs): if active: print(*args,**kwargs) with open("text.txt",'w') as f: y = countprint(1, 3, 3, sep=',', end='\n\n',file=f) print(y) boolprint(3,4,5,sep='/',active=True) boolprint(7,11,active=False) From: Python-list on behalf of avi.e.gr...@gmail.com Date: Tuesday, January 31, 2023 at 3:01 PM To: 'Thomas Passin' , python-list@python.org Subject: RE: evaluation question *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. *** I think its has been discussed here that many functions are DELIBERATELY designed to return without returning anything. Earlier languages like Pascal had explicit ideas that a function that did not return a value was declared as a "procedure" but many other languages like python make no real differentiation. Some functions are designed for a sort of side-effect and often there is nothing much that needs to be returned or even can be. If a function prints a dozen items one at a time, should it return nothing, or a copy of the last item or somehow of all items? Generally nothing looks right. If you want to return something, fine. Do it explicitly. Similar arguments have been made about methods that do things like sort the contents of an object internally and then return nothing. Some would like the return to be the (now altered) object itself. You can emulate that by not sorting internally but instead sorted(object) returns a new object that has been sorted from the old one. So should or could print return anything? Other languages exist, like R, that do return (and often ignore) whatever print displayed elsewhere. This can be of use in many ways such as making it easier to print or store additional copies without recalculating. My preference might be to simply allow a local option at the end of a print statement such as print(..., return=True) or even a way to set a global option so all print statements can be turned on when you want. But is this pythonic? In particular, people who want to give type hints now can safely claim it returns None and would have to modify that so it can optionally return something like str or None. And, of course, once you change print() this way, someone else will want the number of characters (or perhaps bytes) returned instead. Much of this can be worked around by simply making your own customized print function which evaluates the arguments to make a string and then calls print, perhaps with the results pre-calculated, and returns what you wanted. That is not as easy as it sounds, though as print supports various arguments like sep= and end= and file= and flush= so a weird but doable idea is simply to substitute a temporary file for any file= argument and write the results to a temporary file or something in memory that emulates a file. You can then read that back in and return what you want after handling the original print statement with the original arguments, or perhaps just use your result to any actually specified file or the default. You can thus create something like what you want and leave the original print() command alone to do what it was designed to do. And, in general, people who want a copy of what they print, often use other python functionality to craft some or all parts of the text they want printed and only then call print() and thus already may have the ability to use the text afterwards. For many purposes, including efficiency, returning nothing makes good sense. But it is not really the only choice or the right choice and yet, if you want to use THIS language, it has to be accepted as the documented choice. -Original Message- From: Python-list On Behalf Of Thomas Passin Sent: Tuesday, January 31, 2023 1:16 PM To: python-list@python.org Subject: Re: evaluation question On 1/31/2023 4:24 AM, mutt...@dastardlyhq.com wrote: > On Tue, 31 Jan 2023 12:57:33 +1300 > Greg Ewing wrote: >> On 30/01/23 10:41 pm, mutt...@dastardlyhq.com wrote: >>> What was the point of the upheaval of converting the print command >>> in python 2 into a function in python 3 if as a function >>> print() doesn't return anything useful? >> >> It was made a function because there's no good reason for it to have >> special syntax in the language. > > All languages have their ugly corners due to initial design mistakes > and/or constraints. Eg: java with the special behaviour of its string > class, C++ with "=0" pure virtual declaration. But they don't dump > them and make all old code suddenly cease to execute. > > Pragmatism should always come before language purity. > It was more fundamental than that, and not mainly about print(): https://urldefense.com/v3/__https://snarky.ca
Re: evaluation question
Greg Ewing wrote: On 30/01/23 10:41 pm, mutt...@dastardlyhq.com wrote: What was the point of the upheaval of converting the print command in python 2 into a function in python 3 if as a function print() doesn't return anything useful? It was made a function because there's no good reason for it to have special syntax in the language. I think I saw somewhere that making print a function also had something to do with being able to add extra keyword arguments like sep and end. The syntax for printing to a specific file already seemed a bit odd with the print statement, and adding extra arguments would have made it even more clunky (yeah, I know ">>" is similar to C++ streams, but it looks out of place in Python). They couldn't fully make the change from print statement to print function without breaking backward compatibility for existing code. But there were other breaking changes being made in Python 3 anyway, so may as well sort print out while at it and have all the breaking changes at once. Functions don't need to return things to justify their existence, and in fact the usual convention is that functions whose purpose is to have an effect just return None. -- Mark. -- https://mail.python.org/mailman/listinfo/python-list
RE: evaluation question
I think its has been discussed here that many functions are DELIBERATELY designed to return without returning anything. Earlier languages like Pascal had explicit ideas that a function that did not return a value was declared as a "procedure" but many other languages like python make no real differentiation. Some functions are designed for a sort of side-effect and often there is nothing much that needs to be returned or even can be. If a function prints a dozen items one at a time, should it return nothing, or a copy of the last item or somehow of all items? Generally nothing looks right. If you want to return something, fine. Do it explicitly. Similar arguments have been made about methods that do things like sort the contents of an object internally and then return nothing. Some would like the return to be the (now altered) object itself. You can emulate that by not sorting internally but instead sorted(object) returns a new object that has been sorted from the old one. So should or could print return anything? Other languages exist, like R, that do return (and often ignore) whatever print displayed elsewhere. This can be of use in many ways such as making it easier to print or store additional copies without recalculating. My preference might be to simply allow a local option at the end of a print statement such as print(..., return=True) or even a way to set a global option so all print statements can be turned on when you want. But is this pythonic? In particular, people who want to give type hints now can safely claim it returns None and would have to modify that so it can optionally return something like str or None. And, of course, once you change print() this way, someone else will want the number of characters (or perhaps bytes) returned instead. Much of this can be worked around by simply making your own customized print function which evaluates the arguments to make a string and then calls print, perhaps with the results pre-calculated, and returns what you wanted. That is not as easy as it sounds, though as print supports various arguments like sep= and end= and file= and flush= so a weird but doable idea is simply to substitute a temporary file for any file= argument and write the results to a temporary file or something in memory that emulates a file. You can then read that back in and return what you want after handling the original print statement with the original arguments, or perhaps just use your result to any actually specified file or the default. You can thus create something like what you want and leave the original print() command alone to do what it was designed to do. And, in general, people who want a copy of what they print, often use other python functionality to craft some or all parts of the text they want printed and only then call print() and thus already may have the ability to use the text afterwards. For many purposes, including efficiency, returning nothing makes good sense. But it is not really the only choice or the right choice and yet, if you want to use THIS language, it has to be accepted as the documented choice. -Original Message- From: Python-list On Behalf Of Thomas Passin Sent: Tuesday, January 31, 2023 1:16 PM To: python-list@python.org Subject: Re: evaluation question On 1/31/2023 4:24 AM, mutt...@dastardlyhq.com wrote: > On Tue, 31 Jan 2023 12:57:33 +1300 > Greg Ewing wrote: >> On 30/01/23 10:41 pm, mutt...@dastardlyhq.com wrote: >>> What was the point of the upheaval of converting the print command >>> in python 2 into a function in python 3 if as a function >>> print() doesn't return anything useful? >> >> It was made a function because there's no good reason for it to have >> special syntax in the language. > > All languages have their ugly corners due to initial design mistakes > and/or constraints. Eg: java with the special behaviour of its string > class, C++ with "=0" pure virtual declaration. But they don't dump > them and make all old code suddenly cease to execute. > > Pragmatism should always come before language purity. > It was more fundamental than that, and not mainly about print(): https://snarky.ca/why-python-3-exists/ -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list (was: evaluation question)
On 2023-01-31, Alan Gauld wrote: > On 28/01/2023 21:36, Dennis Lee Bieber wrote: > >> Now -- last time I checked the gmane server says posting is prohibited. >> I used to use gmane as it retrieved directly from the mailing list > > I still use gmane but its no posting thing is a pain because responding > (or posting new stuff) is a now more complicated than before. So > I have to be very highly motivated to jump through the hoops. If your newsreader can post via an external inews utility, you can use this Python implementation of inews to post to specified groups via e-mail instead of NNTP: https://github.com/GrantEdwards/hybrid-inews -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On 1/31/2023 4:24 AM, mutt...@dastardlyhq.com wrote: On Tue, 31 Jan 2023 12:57:33 +1300 Greg Ewing wrote: On 30/01/23 10:41 pm, mutt...@dastardlyhq.com wrote: What was the point of the upheaval of converting the print command in python 2 into a function in python 3 if as a function print() doesn't return anything useful? It was made a function because there's no good reason for it to have special syntax in the language. All languages have their ugly corners due to initial design mistakes and/or constraints. Eg: java with the special behaviour of its string class, C++ with "=0" pure virtual declaration. But they don't dump them and make all old code suddenly cease to execute. Pragmatism should always come before language purity. It was more fundamental than that, and not mainly about print(): https://snarky.ca/why-python-3-exists/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list (was: evaluation question)
On 28/01/2023 21:36, Dennis Lee Bieber wrote: > Now -- last time I checked the gmane server says posting is prohibited. > I used to use gmane as it retrieved directly from the mailing list I still use gmane but its no posting thing is a pain because responding (or posting new stuff) is a now more complicated than before. So I have to be very highly motivated to jump through the hoops. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list
Re: evaluation question
On Tue, 31 Jan 2023 12:57:33 +1300 Greg Ewing wrote: >On 30/01/23 10:41 pm, mutt...@dastardlyhq.com wrote: >> What was the point of the upheaval of converting >> the print command in python 2 into a function in python 3 if as a function >> print() doesn't return anything useful? > >It was made a function because there's no good reason for it >to have special syntax in the language. All languages have their ugly corners due to initial design mistakes and/or constraints. Eg: java with the special behaviour of its string class, C++ with "=0" pure virtual declaration. But they don't dump them and make all old code suddenly cease to execute. Pragmatism should always come before language purity. -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list
On 2023-01-31, Anssi Saari wrote: > Grant Edwards writes: > >> No. FWIW, it's the mailing list that's blocking them, not Gmane. >> >> That's why I wrote this: >> >> https://github.com/GrantEdwards/hybrid-inews >> >> It's an inews work-alike that submits most posts via gmanes NNTP >> server, but will deal with particular groups >> (e.g. gmane.comp.python.general) that want posts submitted via email. >> >> It allows me to continue to read (and post to) the Python mailling >> list via slrn pointed at gmane. > > Interesting. In Gnus it was just a couple of settings to make it > understand that in this group (i.e. gmane group > gmane.comp.python.general) posts and follow-ups should be sent via mail > to the mailing list address. Ah, slrn is missing that feature. It will let you e-mail a response instead of posting a followup (IIRC, you hit 'r' instead of 'f'), but when you do that it sends the e-mail to the poster rather than to the list. You can edit the To: header to fix that, but that's too much to remember. :) I looked into adding such a feature to slrn, but it was far easier to switch the slrn setting so that it posted via an external inews utility instead of the built-in NNTP client. Then all I needed was a smarter 'inews'. Thanks the the NNTP and SMTP libraries in Python, it took only 50 lines of Python to implement an external inews utility that routed postings to either gname via NNTP or list-servers via SMTP depending on the group. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: Usenet vs. Mailing-list
Grant Edwards writes: > No. FWIW, it's the mailing list that's blocking them, not Gmane. > > That's why I wrote this: > > https://github.com/GrantEdwards/hybrid-inews > > It's an inews work-alike that submits most posts via gmanes NNTP > server, but will deal with particular groups > (e.g. gmane.comp.python.general) that want posts submitted via email. > > It allows me to continue to read (and post to) the Python mailling > list via slrn pointed at gmane. Interesting. In Gnus it was just a couple of settings to make it understand that in this group (i.e. gmane group gmane.comp.python.general) posts and follow-ups should be sent via mail to the mailing list address. -- https://mail.python.org/mailman/listinfo/python-list