From sajadian.ali at gmail.com Mon Feb 1 02:19:31 2021 From: sajadian.ali at gmail.com (Ali Sajadian) Date: Sun, 31 Jan 2021 23:19:31 -0800 (PST) Subject: Converting hex data to image In-Reply-To: References: <7w61ruwv0q.fsf@benfinney.id.au> <7w1u2iwu3l.fsf@benfinney.id.au> <04f92a06-0720-453b-a988-dd4717797466@googlegroups.com> <2f4ef238-11cb-4c4f-aae5-1151046e19c2@googlegroups.com> Message-ID: <3f8ae6b6-e873-4819-97d9-6c688d7b1665n@googlegroups.com> dimplem... at gmail.com ?? ????? ??????? ?? ???? ???? ???? ??:??:?? (UTC+3:30) ????: > On Tuesday, March 12, 2019 at 2:53:49 PM UTC+5:30, Peter Otten wrote: > > dimplem... at gmail.com wrote: > > > > >> Save the image to a file (in binary mode!) and then try to open it with > > >> an image viewer. The data may be corrupted. > > > > > > When i tried doing that it says Invalid Image... > > > > So it looks like the problem occurs somewhere before you are decoding the > > image with the PIL... > This is what i am doing : > for associate in self.conn.response[:-1]: > attributes = associate['attributes'] > obj = { > 'img':attributes['thumbnailPhoto'],} > This img i am calling in my view and writing to the file... Hi could you solve this problem dimplem? I have exactly the same issue when I read thumbnailPhoto from active directory From skip.montanaro at gmail.com Mon Feb 1 19:54:49 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 1 Feb 2021 18:54:49 -0600 Subject: Best practice for handling exceptions raised at lower levels? Message-ID: I'm curious if there are best practices for handling exceptions raised by lower level modules and packages. For example, I wrote an application called polly[1] which constructs a personalized dictionary from email messages using IMAP4. That dictionary is then used as input to a password generator based on the famous XKCD 936 comic[2]. The idea is based on a similar tool Chris Angelico mentioned here several years ago[3], though as not a D&D player, I didn't have player chat available as user-specific input from which to construct a dictionary and chose email instead. So much for background. After a long period of stasis, I decided to update polly to Python 3. While the 2-to-3 process was straightforward, I had problems after the update which looked like IMAP4 issues. I really didn't want to get knee deep in a pond full of IMAP alligators, so rather than bookmarking the IMAP4 RFC[4], I cast about for something higher level than imaplib, eventually settling on IMAPClient[5]. I thus have a collection of modules and packages: imapclient, imaplib, ssl, socket, and many other non-network bits. IMAPClient did what I wanted, for the most part abstracting away IMAP4 details. I still have to craft a couple IMAP4 parameter strings, but the rest of the interface is pretty Pythonic. However... Network applications being what they are, hiccups are going to happen. In the time since I swapped in the imapclient package, I've also had to catch exceptions raised by lower level modules/packages I wasn't using directly, discovering them only as they occurred. (Think of it as lazy exception discovery. I suppose if I was developing the application for others, I'd have been more proactive about uncovering the exceptions.) In addition to a couple imapclient exceptions, I also now need to catch socket.gaierror, ConnectionError and imaplib.IMAP4.error. Here's the crux of the problem. Where does responsibility generally fall for low level exception handling? I don't mean to pick on IMAPClient. It's just a recent example and got me thinking about the problem. Is it (generally) the responsibility of the application author or the package author? This isn't an issue just for network applications with a number of moving parts (socket, ssl, higher level packages, etc). It happens in almost all applications or packages, even if it's just to deal with exceptions raised by internal data structures. Skip [1] https://github.com/smontanaro/polly [2] https://xkcd.com/936/ [3] https://mail.python.org/pipermail/python-list/2014-August/827854.html [4] https://tools.ietf.org/html/rfc3501 [5] https://pypi.org/project/IMAPClient/ From antoon.pardon at vub.be Tue Feb 2 06:07:12 2021 From: antoon.pardon at vub.be (Antoon Pardon) Date: Tue, 2 Feb 2021 12:07:12 +0100 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: <84e12bcc-e532-c812-4a23-fc9c5010bec6@vub.be> Op 2/02/21 om 01:54 schreef Skip Montanaro: > Here's the crux of the problem. Where does responsibility generally > fall for low level exception handling? I don't mean to pick on > IMAPClient. It's just a recent example and got me thinking about the > problem. Is it (generally) the responsibility of the application > author or the package author? This isn't an issue just for network > applications with a number of moving parts (socket, ssl, higher level > packages, etc). It happens in almost all applications or packages, > even if it's just to deal with exceptions raised by internal data > structures. Here is my two cents worth. I think it should be the resposibility of the package. The package should catch the low level exception and raise its own exception. Why? Because in a sense we are talking about implementation details. If in the future the package would choose an implementation that relies on other low-level packages, the appication should still run as before, the application shouldn't have to care about how the package is implemented and thuse shouldn't have to care about what potential low level exception can be raised. Maybe python should introduce a ComponentError as a new exception. If a low level exception is raised in the package, the package should catch it and raise the ComponentErrror instead. -- Antoon. From tjreedy at udel.edu Tue Feb 2 10:20:29 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 2 Feb 2021 10:20:29 -0500 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: On 2/1/2021 7:54 PM, Skip Montanaro wrote: > However... Network applications being what they are, hiccups are going > to happen. In the time since I swapped in the imapclient package, I've > also had to catch exceptions raised by lower level modules/packages I > wasn't using directly, discovering them only as they occurred. (Think > of it as lazy exception discovery. I suppose if I was developing the > application for others, I'd have been more proactive about uncovering > the exceptions.) In addition to a couple imapclient exceptions, I also > now need to catch socket.gaierror, ConnectionError and > imaplib.IMAP4.error. > > Here's the crux of the problem. Where does responsibility generally > fall for low level exception handling? The general advice on this list is 'Only catch exceptions you can usefully do something with'. Some things are clear. Any code calling next(it) should catch possible StopIteration. Library code, like IMAPClient, should not catch BaseException and reraise SystemExit. Other times, 'useful' is not so clear. > I don't mean to pick on IMAPClient. It's pypi page https://pypi.org/project/IMAPClient/ has author and maintainer email links. You can ask them what their intention is in regard to dependency exceptions. Their feature list includes "Exceptions are raised when errors occur." Does this include letting the exceptions you mention, and others, pass through? Do you think their doc should be any clearer than it is? I think responsibility partly depends on whether a particular low level exception is a flow control exception or bug exception, and if the latter, in whose code. > It's just a recent example and got me thinking about the > problem. Is it (generally) the responsibility of the application > author or the package author? This isn't an issue just for network > applications with a number of moving parts (socket, ssl, higher level > packages, etc). It happens in almost all applications or packages, > even if it's just to deal with exceptions raised by internal data > structures. -- Terry Jan Reedy From barry at barrys-emacs.org Tue Feb 2 14:59:33 2021 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 2 Feb 2021 19:59:33 +0000 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: > On 2 Feb 2021, at 00:54, Skip Montanaro wrote: > > I'm curious if there are best practices for handling exceptions raised > by lower level modules and packages. For example, I wrote an > application called polly[1] which constructs a personalized dictionary > from email messages using IMAP4. That dictionary is then used as input > to a password generator based on the famous XKCD 936 comic[2]. The > idea is based on a similar tool Chris Angelico mentioned here several > years ago[3], though as not a D&D player, I didn't have player chat > available as user-specific input from which to construct a dictionary > and chose email instead. > > So much for background. After a long period of stasis, I decided to > update polly to Python 3. While the 2-to-3 process was > straightforward, I had problems after the update which looked like > IMAP4 issues. I really didn't want to get knee deep in a pond full of > IMAP alligators, so rather than bookmarking the IMAP4 RFC[4], I cast > about for something higher level than imaplib, eventually settling on > IMAPClient[5]. I thus have a collection of modules and packages: > imapclient, imaplib, ssl, socket, and many other non-network bits. > IMAPClient did what I wanted, for the most part abstracting away IMAP4 > details. I still have to craft a couple IMAP4 parameter strings, but > the rest of the interface is pretty Pythonic. > > However... Network applications being what they are, hiccups are going > to happen. In the time since I swapped in the imapclient package, I've > also had to catch exceptions raised by lower level modules/packages I > wasn't using directly, discovering them only as they occurred. (Think > of it as lazy exception discovery. I suppose if I was developing the > application for others, I'd have been more proactive about uncovering > the exceptions.) In addition to a couple imapclient exceptions, I also > now need to catch socket.gaierror, ConnectionError and > imaplib.IMAP4.error. > > Here's the crux of the problem. Where does responsibility generally > fall for low level exception handling? I don't mean to pick on > IMAPClient. It's just a recent example and got me thinking about the > problem. Is it (generally) the responsibility of the application > author or the package author? This isn't an issue just for network > applications with a number of moving parts (socket, ssl, higher level > packages, etc). It happens in almost all applications or packages, > even if it's just to deal with exceptions raised by internal data > structures. The principle that I code to is "only catch specific exceptions". And at the top of my app I catch all exceptions and write enough info to the app log or stderr as appropriate. When I write packages I aim to trap the exceptions from the lower levels and convert into a package specific exceptions or document that a low level exception can propagate. With that said how should I deal with exception from packages that do not define the exceptions they raise? First I catch the documented exceptions and handle in an app specific way. For apps that other people will use I'll also do a code inspection to spot sources of exceptions. In your case its a network usage that may need a catch of socket.error. Clearly we cannot impose a requirement to design packages with a specific set of rules implemented. This is open source after all. Barry > > Skip > > [1] https://github.com/smontanaro/polly > [2] https://xkcd.com/936/ > [3] https://mail.python.org/pipermail/python-list/2014-August/827854.html > [4] https://tools.ietf.org/html/rfc3501 > [5] https://pypi.org/project/IMAPClient/ > -- > https://mail.python.org/mailman/listinfo/python-list > From drsalists at gmail.com Tue Feb 2 15:24:32 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Tue, 2 Feb 2021 12:24:32 -0800 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: On Tue, Feb 2, 2021 at 12:00 PM Barry Scott wrote: > When I write packages I aim to trap the exceptions from the lower levels > and convert into a package specific exceptions or document that a low > level exception can propagate. > But how do you know what exceptions could be raised? I love Python in a big way, but this is one thing Java has on Python - knowing what exceptions are relevant. Python's approach is great as long as an uncaught exception should cause termination of the program - and most of my programs fit into this category. But not all of them. From rosuav at gmail.com Tue Feb 2 15:31:35 2021 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 3 Feb 2021 07:31:35 +1100 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: On Wed, Feb 3, 2021 at 7:26 AM Dan Stromberg wrote: > > On Tue, Feb 2, 2021 at 12:00 PM Barry Scott wrote: > > > When I write packages I aim to trap the exceptions from the lower levels > > and convert into a package specific exceptions or document that a low > > level exception can propagate. > > > But how do you know what exceptions could be raised? > > I love Python in a big way, but this is one thing Java has on Python - > knowing what exceptions are relevant. Not really true. Java's declared exceptions still don't tell you anything about what's *relevant*; only you as a programmer can figure that out. > Python's approach is great as long as an uncaught exception should cause > termination of the program - and most of my programs fit into this > category. But not all of them. If there's some boundary where termination shouldn't happen (for instance, a web app, where an uncaught exception should kick a 500 back to the client and then go back for another request, or a REPL where exceptions should be printed to the console and then you continue), it's easy enough to add a generic handler. ChrisA From barry at barrys-emacs.org Tue Feb 2 16:42:40 2021 From: barry at barrys-emacs.org (Barry Scott) Date: Tue, 2 Feb 2021 21:42:40 +0000 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: <532237E7-CF32-4A0B-8BAA-B9557E408AF7@barrys-emacs.org> > On 2 Feb 2021, at 20:24, Dan Stromberg wrote: > > > > On Tue, Feb 2, 2021 at 12:00 PM Barry Scott > wrote: > When I write packages I aim to trap the exceptions from the lower levels > and convert into a package specific exceptions or document that a low > level exception can propagate. > But how do you know what exceptions could be raised? By reading the code of the modules I use. Yes that is tedious and time consuming. I can understand why most users will not want to d this. > I love Python in a big way, but this is one thing Java has on Python - knowing what exceptions are relevant. > > Python's approach is great as long as an uncaught exception should cause termination of the program - and most of my programs fit into this category. But not all of them. > Barry From greg.ewing at canterbury.ac.nz Tue Feb 2 19:16:35 2021 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Wed, 3 Feb 2021 13:16:35 +1300 Subject: Best practice for handling exceptions raised at lower levels? In-Reply-To: References: Message-ID: On 3/02/21 9:24 am, Dan Stromberg wrote: > But how do you know what exceptions could be raised? Mostly I find that it's not really necessary to know precisely which exceptions could be raised. The way I usually deal with exceptions is: 1. If it descends from OSError, I assume it results from some external condition, so I catch it at a level where I know what the user was trying to accomplish and can report it in a meaningful way. E.g. def open_connection(address): try: return some_library.open_thing(address) except OSError as e: tell_user("Couldn't connect to %s: %s" % (address, e)) 2. If it's anything else, I assume it's a bug and let it propagate. -- Greg From random832 at fastmail.com Tue Feb 2 20:26:34 2021 From: random832 at fastmail.com (Random832) Date: Tue, 02 Feb 2021 20:26:34 -0500 Subject: Response for PING in ircbot. In-Reply-To: References: Message-ID: <9921ac0f-d4ae-45fd-b2a5-c4fc06f44273@www.fastmail.com> On Sat, Jan 30, 2021, at 11:50, Bischoop wrote: > > Got problem with responding for Ping, tried so many ways to response > and always end up with time out or other error. This time: 1. It looks like you're forgetting to send \n\r 2. i'm not sure if the server ping is guaranteed to have : character 3. if it does have : character you need to send everything after it even if it includes spaces 4. what happens if the data in recv includes more than one line of data, or partial line at the end? this isn't a proper way to handle irc protocol in general, let alone the ping command > ERROR :(Ping timeout: 264 seconds) > Traceback (most recent call last): > s.send(bytes('PONG ' + data.split()[1], 'UTF-8')) > BrokenPipeError: [Errno 32] Broken pipe > > while True: > time.sleep(2) > data=s.recv(2040).decode('utf8') > data = data.strip("\n\r") > print(data) > if data.find ("PING :"): > s.send(bytes('PONG ' + data.split()[1], 'UTF-8')) From pablogsal at gmail.com Wed Feb 3 05:56:06 2021 From: pablogsal at gmail.com (Pablo Galindo Salgado) Date: Wed, 3 Feb 2021 10:56:06 +0000 Subject: Python 3.10.0a5 is now available Message-ID: Well, this one took a bit more time due to some surprise last time reference leaks and release blockers to fix, but now Python 3.10.0a5 it?s here. Will this be the first release announcement of the 3.10 series without copy-paste typos? Go get it here: https://www.python.org/downloads/release/python-3100a5/ *Major new features of the 3.10 series, compared to 3.9* Python 3.10 is still in development. This release, 3.10.0a5 is the fifth of seven planned alpha releases. Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process. During the alpha phase, features may be added up until the start of the beta phase (2021-05-03) and, if necessary, may be modified or deleted up until the release candidate phase (2021-10-04). Please keep in mind that this is a preview release and its use is not recommended for production environments. Many new features for Python 3.10 are still being planned and written. Among the new major new features and changes so far: - PEP 623 ? Remove wstr from Unicode - PEP 604 ? Allow writing union types as X | Y - PEP 612 ? Parameter Specification Variables - PEP 626 ? Precise line numbers for debugging and other tools. - bpo-38605 : from __future__ import annotations (PEP 563 ) is now the default. - PEP 618 ? Add Optional Length-Checking To zip. - bpo-12782 : Parenthesized context managers are now officially allowed. - (Hey, fellow core developer, if a feature you find important is missing from this list, let Pablo know .) The next pre-release of Python 3.10 will be 3.10.0a6, currently scheduled for 2021-03-01. And now for something completely different The Chandrasekhar limit is the maximum mass of a stable white dwarf star. White dwarfs resist gravitational collapse primarily through electron degeneracy pressure, compared to main sequence stars, which resist collapse through thermal pressure. The Chandrasekhar limit is the mass above which electron degeneracy pressure in the star?s core is insufficient to balance the star?s own gravitational self-attraction. Consequently, a white dwarf with a mass greater than the limit is subject to further gravitational collapse, evolving into a different type of stellar remnant, such as a neutron star or black hole. Those with masses up to the limit remain stable as white dwarfs. The currently accepted value of the Chandrasekhar limit is about 1.4 M? (2.765?1030 kg). So we can be safe knowing that our sun is not going to become a black hole! Regards from cloudy London, Pablo Galindo Salgado From damienjenman at hotmail.com Tue Feb 2 22:40:51 2021 From: damienjenman at hotmail.com (damien jenman) Date: Wed, 3 Feb 2021 03:40:51 +0000 Subject: Fw: Trouble running python 3.6.4 In-Reply-To: References: Message-ID: ________________________________ From: damien jenman Sent: Monday, 1 February 2021 10:29 AM To: python-list at python.org Subject: Trouble running python 3.6.4 Hi After setup being successful, of python 3.6.4 , it comes up online tutorial, documentation and whats new, all being underlined. I click on one of these, and i try to type in search 'Command Prompt'. To get to the Command Prompt Window. Unsuccesfully. I then close the application. I then double click the app in downloads. It comes up with Modify Setup. Modify, Repair or Install. All i wish to do is go to the Command Prompt and start programming. Thanks Damien Jenman From mats at wichmann.us Wed Feb 3 10:37:19 2021 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 3 Feb 2021 08:37:19 -0700 Subject: Fw: Trouble running python 3.6.4 In-Reply-To: References: Message-ID: <4926346c-c02e-f833-3193-ba741a91aca4@wichmann.us> On 2/2/21 8:40 PM, damien jenman wrote: > > > ________________________________ > From: damien jenman > Sent: Monday, 1 February 2021 10:29 AM > To: python-list at python.org > Subject: Trouble running python 3.6.4 > > Hi > > After setup being successful, of python 3.6.4 , it comes up online tutorial, documentation and whats new, all being > > underlined. > > I click on one of these, and i try to type in search 'Command Prompt'. To get to the Command Prompt Window. > > Unsuccesfully. > > I then close the application. > > I then double click the app in downloads. > > It comes up with Modify Setup. Modify, Repair or Install. That's re-running the installer, don't do that (unless you actually need to Modify/Repair/Install). > All i wish to do is go to the Command Prompt and start programming. From a shell window (if on Windows that means cmd or PowerShell), type "py" or "python". The latter requires the path to have been amended, which is something the installer can do. Or, from the start menu, select the Python folder and click the entry for the program, which in your case should be labeled "Python 3.6 (64-bit)" (or 32-bit if you installed the 32-bit version, of course). This is less good, because it will have you starting in Python's installation directory, which is probably not where you want to be working. See https://docs.python.org/3/using/ and if pick the entry for the correct operating system. From freelanceismail001 at gmail.com Wed Feb 3 11:48:17 2021 From: freelanceismail001 at gmail.com (ismail nagi) Date: Wed, 3 Feb 2021 08:48:17 -0800 (PST) Subject: SMS API Message-ID: Hello everyone. I would like to know how an sms api is created. And if this is possible with python, for example, using flask. Thank You From dieter at handshake.de Wed Feb 3 12:54:19 2021 From: dieter at handshake.de (Dieter Maurer) Date: Wed, 3 Feb 2021 18:54:19 +0100 Subject: SMS API In-Reply-To: References: Message-ID: <24602.58187.588668.237843@ixdm.fritz.box> ismail nagi wrote at 2021-2-3 08:48 -0800: >I would like to know how an sms api is created. I assume that "sms api" means that your Python application should be able to send SMS messages. In this case, you need a service which interfaces between your device (mobile phone, computer, tablet, ...) and the telephone network. Such a service will provide some API - and depending on the type of API, you might be able to use it in Python. First thing is to find out about this service. From dieter at handshake.de Wed Feb 3 13:50:32 2021 From: dieter at handshake.de (Dieter Maurer) Date: Wed, 3 Feb 2021 19:50:32 +0100 Subject: SMS API In-Reply-To: References: <24602.58187.588668.237843@ixdm.fritz.box> Message-ID: <24602.61560.650584.672217@ixdm.fritz.box> ismail nagi wrote at 2021-2-3 21:06 +0300: >Yes, its about sending messages. For example, something like >twilio...it's an SMS API, can something like twilio be created using python >and how (just a basic idea)? Thank You. "twilio" provides a web service interface to send messages. You can use Python libraries to access web services (e.g. "suds") - and thereby, control the "twilio" service via Python applications. If your aim is to implement a "twilio" like functionality out of the box, you need a gateway between your device and the telephone network. In particular, this gateway must ensure proper payment for the use of the telephone network; as a consequence, access will be restricted and subject to quite strict policies (to avoid abuse). If your telephone network (access point) does not provide an easy access, then it is likely very difficult to implement access on your own. If you look for an application on a mobile phone, then the phone's operating system likely provides a service to send SMS messages. There are Python components to facilitate the use of Python on mobile phones (but I have no experience in this domain). With Python for mobile phones, it may be possible to access those mobile phone services provided by the phone's operating system. From szhang31415 at gmail.com Wed Feb 3 12:32:34 2021 From: szhang31415 at gmail.com (Simon Zhang) Date: Wed, 3 Feb 2021 12:32:34 -0500 Subject: need help with a ctypes project for PyPI Message-ID: Hi, I have created a ctypes project as in the following link's first answer: https://stackoverflow.com/questions/42585210/extending-setuptools-extension-to-use-cmake-in-setup-py Since my machine's gcc is too high version or something, I used the docker image located here: https://quay.io/repository/pypa/manylinux2014_x86_64 to compile the copied .whl file. I ran auditwheel repair on my whl file then copied it back to my local machine without complaints. I'm not sure I understand the subsequent process I need to do with PyPI. If I copy the manylinux2014 wheel back to my local machine (into the dist folder) and run the command: python3 -m twine upload --repository testpypi dist/* following the instructions from: https://packaging.python.org/tutorials/packaging-projects/ when I pip3 install spamplusplus (this is the name I gave my test project) https://test.pypi.org/project/spamplusplus/ I get that the CMakeLists.txt file is not existent. I used the same setup.py file given in the link: https://stackoverflow.com/questions/42585210/extending-setuptools-extension-to-use-cmake-in-setup-py However I get the error that CMakeLists.txt file is not being uploaded? cmake /tmp/pip-build-6ff9ifuu/spamplusplus -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/tmp/pip-build-6ff9ifuu/spamplusplus/build/lib.linux-x86_64-3.6/spamplusplus -DCMAKE_BUILD_TYPE=Release CMake Error: The source directory "/tmp/pip-build-6ff9ifuu/spamplusplus" does not appear to contain CMakeLists.txt. I think this is something basic involving paths but could be more involved. Can anyone help!! Thanks, Simon Zhang From PythonList at DancesWithMice.info Wed Feb 3 23:30:55 2021 From: PythonList at DancesWithMice.info (dn) Date: Thu, 4 Feb 2021 17:30:55 +1300 Subject: Response for PING in ircbot. In-Reply-To: References: <9921ac0f-d4ae-45fd-b2a5-c4fc06f44273@www.fastmail.com> Message-ID: <781b886e-e000-9e37-2247-a67a9e5f6018@DancesWithMice.info> On 04/02/2021 07.07, Dennis Lee Bieber wrote: > On Tue, 02 Feb 2021 20:26:34 -0500, Random832 > declaimed the following: > > >> 1. It looks like you're forgetting to send \n\r > > Isn't the convention \r\n -- from the days of teletype, when the return > took longer to complete than the line feed, so start return, have it finish > while the line feed activates... Yes, "CRLF" = Carriage Return (chr( 13 )) and Line-Feed (chr( 10 )). > The order didn't matter in the .strip() call as that strips any > leading/trailing characters that match any of the provided set, it is not a > "trim" of the exact sequence (hmm, looks like that would be require using > string.removeprefix("\n\r").removesuffix("\n\r") if the expected sequence > were such). If every line ends with the same (odd) suffix, then why not slice the string [ :-2 ]? Alternately, consider str.translate() where both character codes are removed, regardless of location. -- Regards, =dn From tjol at tjol.eu Thu Feb 4 10:56:02 2021 From: tjol at tjol.eu (Thomas Jollans) Date: Thu, 4 Feb 2021 16:56:02 +0100 Subject: IDE tools to debug in Python? In-Reply-To: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: On 27/01/2021 19:32, flaskee via Python-list wrote: > > While print() is groovy and all, > if anyone runs across a non-pdb python debugger (standalone or IDE-based) > please let me know. > > I too was blessed with IDE-based debugging (in the 90's!) > * where you can set break point(s); > * have the program stop right before a suspected failure point; > * check the contents of ALL variables, and choose whether to restart; > * or skip a few lines before restarting; > * or change a variable (hot, move back a few lines and restart, etc. > * Some, would even let you alter the code a bit before restarting. > > I too, miss this. > > > Hopefully I did not miss someone mentioning > such a python tool in the prior thread. This comes up every now and again. There are a number of visual debugging tools for Python, but a lot of people don't bother with them. I don't, though I've been meaning to have a closer look into the options. https://wiki.python.org/moin/PythonDebuggingTools There are full-fat IDEs like PyCharm, Eclipse PyDev, Komodo, Wing, or Visual Studio. There's Spyder, which is reasonably popular in the scientific Python ecosystem. I think there are VSCode plugins for Python debugging. And there is even an experimental debugger for Jupyter now! Just to give you some pointers as to where to look. -- Thomas From alan.gauld at yahoo.co.uk Fri Feb 5 03:34:21 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 5 Feb 2021 08:34:21 +0000 Subject: IDE tools to debug in Python? In-Reply-To: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: On 27/01/2021 18:32, flaskee via Python-list wrote: > > While print() is groovy and all, > if anyone runs across a non-pdb python debugger (standalone or IDE-based) > please let me know. > There are many. But why must it be non-pdb? That seems rather arbitrary. Or do you really mean you want a non-command-line debugger? One standalone option is winpdb But most Python IDEs have basic debugging tools built in. -- 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 From Joseph.Schachner at Teledyne.com Fri Feb 5 17:03:34 2021 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Fri, 5 Feb 2021 22:03:34 +0000 Subject: IDE tools to debug in Python? In-Reply-To: References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: Indeed there are many. One I have not seen listed here yet, that is quite light, starts quickly, but does have good debugging capability is PyScripter. Completely free, downloadable from SourceForge, 32 or 64 bit versions (must match your Python type). --- Joseph S. Teledyne Confidential; Commercially Sensitive Business Data -----Original Message----- From: Alan Gauld Sent: Friday, February 5, 2021 3:34 AM To: python-list at python.org Subject: Re: IDE tools to debug in Python? On 27/01/2021 18:32, flaskee via Python-list wrote: > > While print() is groovy and all, > if anyone runs across a non-pdb python debugger (standalone or > IDE-based) please let me know. > There are many. But why must it be non-pdb? That seems rather arbitrary. Or do you really mean you want a non-command-line debugger? One standalone option is winpdb But most Python IDEs have basic debugging tools built in. -- 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 From flaskee at protonmail.com Fri Feb 5 20:27:34 2021 From: flaskee at protonmail.com (flaskee) Date: Sat, 06 Feb 2021 01:27:34 +0000 Subject: IDE tools to debug in Python? In-Reply-To: References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: <3Au3OaQmpmIZjoRqcez5VDlr29B2yCzcd6pvDLFv8G2BJVu6cbXQiiqpMq-FoeXdi7RL7yzfXJFkqhA0f4MggyIx3JSFN-wHb-zwAZyBApk=@protonmail.com> ??????? Original Message ??????? On Friday, February 5, 2021 5:03 PM, Schachner, Joseph wrote: > capability is PyScripter. > Completely free, downloadable from SourceForge Thank you. I just wanted to add, that it is here as well: https://github.com/pyscripter https://github.com/pyscripter/pyscripter Sourceforge has had problems in the past with allowing virus-infected downloads. Three of which I have seen myself. --- As regards the Alan pdb note; yes -- I was trying for a full IDE & integrated debugging, along the lines of Visual Studio, pre-sneaky-Telemetry API. It looks like it will be Wing IDE and maybe pyscripter to start. Thanks From robertvstepp at gmail.com Fri Feb 5 23:55:33 2021 From: robertvstepp at gmail.com (boB Stepp) Date: Fri, 5 Feb 2021 22:55:33 -0600 Subject: IDE tools to debug in Python? In-Reply-To: <3Au3OaQmpmIZjoRqcez5VDlr29B2yCzcd6pvDLFv8G2BJVu6cbXQiiqpMq-FoeXdi7RL7yzfXJFkqhA0f4MggyIx3JSFN-wHb-zwAZyBApk=@protonmail.com> References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> <3Au3OaQmpmIZjoRqcez5VDlr29B2yCzcd6pvDLFv8G2BJVu6cbXQiiqpMq-FoeXdi7RL7yzfXJFkqhA0f4MggyIx3JSFN-wHb-zwAZyBApk=@protonmail.com> Message-ID: On Sat, Feb 06, 2021 at 01:27:34AM +0000, flaskee via Python-list wrote: >On Friday, February 5, 2021 5:03 PM, Schachner, Joseph wrote: >As regards the Alan pdb note; yes -- I was trying for >a full IDE & integrated debugging, >along the lines of Visual Studio, pre-sneaky-Telemetry API. You do know that there is a 100% open source version of Microsoft VS Code with absolutely no tracking? It is VSCodium: https://vscodium.com/ Perhaps it is more along the lines of what you are looking for? -- Wishing you only the best, boB Stepp From tjreedy at udel.edu Fri Feb 5 13:35:16 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 5 Feb 2021 13:35:16 -0500 Subject: IDE tools to debug in Python? In-Reply-To: References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: On 2/5/2021 3:34 AM, Alan Gauld via Python-list wrote: > On 27/01/2021 18:32, flaskee via Python-list wrote: >> >> While print() is groovy and all, >> if anyone runs across a non-pdb python debugger (standalone or IDE-based) >> please let me know. >> > > There are many. But why must it be non-pdb? That seems rather arbitrary. > Or do you really mean you want a non-command-line debugger? > > One standalone option is winpdb > But most Python IDEs have basic debugging tools built in. IDLE also has a mostly usable GUI debugger. Polishing it is a current process. -- Terry Jan Reedy From grant.b.edwards at gmail.com Fri Feb 5 17:46:29 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 5 Feb 2021 22:46:29 -0000 (UTC) Subject: IDE tools to debug in Python? References: <88OB0d-SjSbvDOqJJmhHDs3oC4IH82IeBifbF3ppQZesLwSjeociw8RZlTQ-6F0YgWpX7pTp3S0soL28Fn9N326EX_jjw20VO3hhwxTZhQA=@protonmail.com> Message-ID: On 2021-02-05, Schachner, Joseph wrote: > Indeed there are many. One I have not seen listed here yet, that is > quite light, starts quickly, but does have good debugging capability > is PyScripter. Completely free, downloadable from SourceForge, 32 > or 64 bit versions (must match your Python type). Windows only. -- Grant From barry at barrys-emacs.org Sat Feb 6 10:16:46 2021 From: barry at barrys-emacs.org (Barry) Date: Sat, 6 Feb 2021 15:16:46 +0000 Subject: IDE tools to debug in Python? In-Reply-To: References: Message-ID: <3D629B14-200D-4C4C-9BD3-0D23ABB817CB@barrys-emacs.org> > On 6 Feb 2021, at 08:06, Grant Edwards wrote: > > ?On 2021-02-05, Schachner, Joseph wrote: > >> Indeed there are many. One I have not seen listed here yet, that is >> quite light, starts quickly, but does have good debugging capability >> is PyScripter. Completely free, downloadable from SourceForge, 32 >> or 64 bit versions (must match your Python type). > > Windows only. See https://github.com/pyscripter/pyscripter/tree/master/Install It says use the zip file non windows. I have not tested this. Barry > > -- > Grant > > -- > https://mail.python.org/mailman/listinfo/python-list > From pa.daher at icloud.com Sat Feb 6 14:21:36 2021 From: pa.daher at icloud.com (Philipp Daher) Date: Sat, 06 Feb 2021 19:21:36 -0000 Subject: =?utf-8?B?U2VsZW5pdW0gZmluZHMgb2JqZWN0IHRoYXQgaXMgaW50ZXJhY3RpYmxlIGJ1?= =?utf-8?B?dCBzYXlzIG90aGVyd2lzZQ==?= Message-ID: <7e039cbf-2203-44a1-b70d-3780f17f274a@me.com> Hello, I recently programmed some code for a webdriver with selenium. I asked the program to find an input tag, which is interactible, with this: ???searchbar=driver.find_element_by_class_name("ut-player-search-control--input-container") then i ask it to send keys, which has worked before too. But this is the message I get. And yes, i have checked, the input tag is the only tag with that class name, so there isn?t another tag which selenium could?ve interacted with. regards, me. From PythonList at DancesWithMice.info Sat Feb 6 14:55:27 2021 From: PythonList at DancesWithMice.info (dn) Date: Sun, 7 Feb 2021 08:55:27 +1300 Subject: Selenium finds object that is interactible but says otherwise In-Reply-To: <7e039cbf-2203-44a1-b70d-3780f17f274a@me.com> References: <7e039cbf-2203-44a1-b70d-3780f17f274a@me.com> Message-ID: <78ccab33-8257-2059-4bf9-92c9c556026c@DancesWithMice.info> On 07/02/2021 08.21, Philipp Daher via Python-list wrote: > Hello, > > > I recently programmed some code for a webdriver with selenium. > I asked the program to find an input tag, which is interactible, with this: > ???searchbar=driver.find_element_by_class_name("ut-player-search-control--input-container") > > then i ask it to send keys, which has worked before too. But this is the > message I get. > And yes, i have checked, the input tag is the only tag with that class > name, so there isn?t another tag which selenium could?ve interacted with. This mailing list strips many attachments. Please copy-paste. First step is to check the target HTML-page to ensure it does actually have a class of that name. Whilst used by many CSS-tools, is the double-dash/hyphen intended? -- Regards, =dn From skip.montanaro at gmail.com Sat Feb 6 22:01:37 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Sat, 6 Feb 2021 21:01:37 -0600 Subject: Log exception so traceback contains timestamp and level? Message-ID: The logging package can log exceptions and call stacks, but it does (in my opinion) a suboptimal job of it. Consider this simple example: >>> import logging >>> FORMAT = '%(asctime)-15s %(levelname)s %(message)s' >>> logging.basicConfig(format=FORMAT, force=True) >>> log.warning("msg", stack_info=True) 2021-02-06 20:46:52,399 WARNING msg Stack (most recent call last): File "", line 1, in It formats the warning message just fine, but simply dumps the traceback onto the stream with no timestamp or level. For my purposes, this is more important for exceptions. (I'm just using the stack trace feature as it's easier in a small example.) I would like to call something like log.exception("Some message...") and find something like this in the output stream: 2021-02-06 20:46:52,399 ERROR Some message... 2021-02-06 20:46:52,400 ERROR Traceback (most recent call last): 2021-02-06 20:46:52,402 ERROR File "", line 1, in That way I can more easily grep log files for errors and get the entire detail, including the traceback. It seems I have to subclass logging.Formatter to override formatStack or formatException, then construct the individual lines of output, set handler and formatter, blah blah blah. I'm pretty sure I've done this in the past by writing my own little log_exception method which formats the exception and calls log.error for each row of the traceback. That seems easier than the "right" way. That seems harder than it ought to be. Hopefully I'm just missing something simple. Skip From grant.b.edwards at gmail.com Sat Feb 6 13:16:35 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sat, 6 Feb 2021 18:16:35 -0000 (UTC) Subject: IDE tools to debug in Python? References: <3D629B14-200D-4C4C-9BD3-0D23ABB817CB@barrys-emacs.org> Message-ID: On 2021-02-06, Barry wrote: > > >> On 6 Feb 2021, at 08:06, Grant Edwards wrote: >> >> ?On 2021-02-05, Schachner, Joseph wrote: >> >>> Indeed there are many. One I have not seen listed here yet, that is >>> quite light, starts quickly, but does have good debugging capability >>> is PyScripter. Completely free, downloadable from SourceForge, 32 >>> or 64 bit versions (must match your Python type). >> >> Windows only. > > See https://github.com/pyscripter/pyscripter/tree/master/Install > It says use the zip file non windows. It's Windows only. That zip file contains a "portable" version of the Windows app (you unzip it and run it from the unzipped directory, rather than installing it using the setup.exe). Running it on non-windows systems requires a windows emulator (e.g. wine). >From the FAQ: How do I use PyScripter in Ubuntu? This how-to is based on the XFCE 4.8 desktop running on top of Ubuntu 11.04. The easiest way to get this configuration is to install Xubuntu. Or from any Ubuntu distribution one can install the XFCE meta package from Synaptic and choose XFCE from the boot manager at login. First, install Wine. From kr4ckali at gmail.com Sun Feb 7 09:06:17 2021 From: kr4ckali at gmail.com (Kr4ck ALI) Date: Sun, 7 Feb 2021 15:06:17 +0100 Subject: Convert MBOX thunderbird to PST outlook Message-ID: Hello, I have to migrate multiple mailbox (emails, contacts, calendar, tasks) from thunderbird to outlook Office 365. I plan to export all items from thunderbird files (.mbox for email, .sqlite or .sdb for calendar, .mab to contact) to PST files and import each PST files to Office 365. I know it's a tedious task ... But I know that nothing is impossible ! I found this script very helpfull to begin : #!python3 import os, sys import gzip import mailbox import urllib.request import win32com.client dispatch = win32com.client.gencache.EnsureDispatch const = win32com.client.constants PST_FILEPATH = os.path.abspath(os.path.join(os.path.expandvars("%APPDATA%"), "scratch.pst")) if os.path.exists(PST_FILEPATH): os.remove(PST_FILEPATH) ARCHIVE_URL = "https://mail.python.org/pipermail/python-list/2015-November.txt.gz" MBOX_FILEPATH = "archive.mbox" def download_archive(url, local_mbox): with gzip.open(urllib.request.urlopen(url)) as archive: with open(local_mbox, "wb") as f: print("Writing %s to %s" % (url, local_mbox)) f.write(archive.read()) def copy_archive_to_pst(mbox_filepath, pst_folder): archive = mailbox.mbox(mbox_filepath) for message in archive: print(message.get("Subject")) pst_message = pst_folder.Items.Add() pst_message.Subject = message.get("Subject") pst_message.Sender = message.get("From") pst_message.Body = message.get_payload() pst_message.Move(pst_folder) pst_message.Save() def find_pst_folder(namespace, pst_filepath): for store in dispatch(mapi.Stores): if store.IsDataFileStore and store.FilePath == PST_FILEPATH: return store.GetRootFolder() download_archive(ARCHIVE_URL, MBOX_FILEPATH) outlook = dispatch("Outlook.Application") mapi = outlook.GetNamespace("MAPI") pst_folder = find_pst_folder(mapi, PST_FILEPATH) if not pst_folder: mapi.AddStoreEx(PST_FILEPATH, const.olStoreDefault) pst_folder = find_pst_folder(mapi, PST_FILEPATH) if not pst_folder: raise RuntimeError("Can't find PST folder at %s" % PST_FILEPATH) copy_archive_to_pst(MBOX_FILEPATH, pst_folder) My question is : Have you already make a mission like that ? Thanks in advance ! @Kr4ckali From hjp-python at hjp.at Sun Feb 7 10:12:15 2021 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 7 Feb 2021 16:12:15 +0100 Subject: Log exception so traceback contains timestamp and level? In-Reply-To: References: Message-ID: <20210207151215.GA32059@hjp.at> On 2021-02-06 21:01:37 -0600, Skip Montanaro wrote: > The logging package can log exceptions and call stacks, but it does > (in my opinion) a suboptimal job of it. Consider this simple example: > >>> import logging > >>> FORMAT = '%(asctime)-15s %(levelname)s %(message)s' > >>> logging.basicConfig(format=FORMAT, force=True) > >>> log.warning("msg", stack_info=True) > 2021-02-06 20:46:52,399 WARNING msg > Stack (most recent call last): > File "", line 1, in > > It formats the warning message just fine, but simply dumps the > traceback onto the stream with no timestamp or level. For my purposes, > this is more important for exceptions. (I'm just using the stack trace > feature as it's easier in a small example.) I would like to call > something like I suspect that it just adds the stack trace to the message, so that you are left with a multi-line message. I often produce multi-line log messages myself. They are much nicer to read than extremely long lines or groups of messages which should really be read as a unit ... > log.exception("Some message...") > > and find something like this in the output stream: > > 2021-02-06 20:46:52,399 ERROR Some message... > 2021-02-06 20:46:52,400 ERROR Traceback (most recent call last): > 2021-02-06 20:46:52,402 ERROR File "", line 1, in ... like this. > That way I can more easily grep log files for errors and get the > entire detail, including the traceback. Yes, grep is unfortunately very line-oriented. I often write write simple scripts to filter log files where one message can span multiple lines (Python's logging module isn't the only one - Samba and PostgreSQL come to mind). Another possibility would be to write the logs into a database. That also has the advantage that the messages are stored in a structure and you don't have to parse them. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From flaskee at protonmail.com Sun Feb 7 13:47:56 2021 From: flaskee at protonmail.com (flaskee) Date: Sun, 07 Feb 2021 18:47:56 +0000 Subject: Response for PING in ircbot. In-Reply-To: References: Message-ID: ??????? Original Message ??????? On Saturday, January 30, 2021 11:50 AM, Bischoop wrote: > Got problem with responding for Ping, tried so many ways to response > and always end up with time out or other error. This time: > Is it possible to share your final Ping answer? I've had a long term Flask/Python issue where the site just dies. (MY) External ping attempts still report the Flask site is functioning; but accessing the pages returns 500 errors. Apache is still running and other (non-Flask) sites are still running on the Linux server. I see no errors that might be causing this under /var/log/*, or apache's error log; or the site's access/error logs. What I'd like to do is set up my own external monitor, to at least known WHEN the site has died. And I'm wondering if your PING might be better. Thanks! From flaskee at protonmail.com Sun Feb 7 13:47:56 2021 From: flaskee at protonmail.com (flaskee) Date: Sun, 07 Feb 2021 18:47:56 +0000 Subject: Response for PING in ircbot. In-Reply-To: References: Message-ID: ??????? Original Message ??????? On Saturday, January 30, 2021 11:50 AM, Bischoop wrote: > Got problem with responding for Ping, tried so many ways to response > and always end up with time out or other error. This time: > Is it possible to share your final Ping answer? I've had a long term Flask/Python issue where the site just dies. (MY) External ping attempts still report the Flask site is functioning; but accessing the pages returns 500 errors. Apache is still running and other (non-Flask) sites are still running on the Linux server. I see no errors that might be causing this under /var/log/*, or apache's error log; or the site's access/error logs. What I'd like to do is set up my own external monitor, to at least known WHEN the site has died. And I'm wondering if your PING might be better. Thanks! From support at kidspython.com Sun Feb 7 14:30:58 2021 From: support at kidspython.com (Kids Python) Date: Sun, 7 Feb 2021 11:30:58 -0800 (PST) Subject: Kids Python 101 free learning materials Message-ID: <1bcbb134-d21f-499d-b75e-cbee6ee6aeadn@googlegroups.com> Hello there, I have developed free learning materials for young kids (targeting 8+ kids) to learn Python from scratch on https://kidspython.com lately. I put lots of efforts on simplifying the course materials, providing plenty of good examples and sufficient exercises for kids to practice coding. The Web site even provides a Python Playground that supports visualization mode for kids to trace their code execution. I hope the information is helpful. Please give it a try, and subscribe to our YouTube channel - https://www.youtube.com/channel/UC-VGmSaLz-WGwyeWk7kyebA for watching Kids Python 101 videos. From pa.daher at icloud.com Sun Feb 7 14:34:34 2021 From: pa.daher at icloud.com (Philipp Daher) Date: Sun, 7 Feb 2021 20:34:34 +0100 Subject: Python cannot count apparently Message-ID: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Hello, I recently coded this snippet of code: myString=?hello? for i in range(len(myString): print(string[i]) And now for the weird part: SOMETIMES, the output is this: hello And SOMETIMES, the output changes to: ohell WHY??? Why do I get different outputs with the EXACT SAME CODE? Can someone help me please? Thank you From pa.daher at icloud.com Sun Feb 7 14:34:34 2021 From: pa.daher at icloud.com (Philipp Daher) Date: Sun, 7 Feb 2021 20:34:34 +0100 Subject: Python cannot count apparently Message-ID: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Hello, I recently coded this snippet of code: myString=?hello? for i in range(len(myString): print(string[i]) And now for the weird part: SOMETIMES, the output is this: hello And SOMETIMES, the output changes to: ohell WHY??? Why do I get different outputs with the EXACT SAME CODE? Can someone help me please? Thank you From Karsten.Hilbert at gmx.net Sun Feb 7 14:40:13 2021 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 7 Feb 2021 20:40:13 +0100 Subject: Python cannot count apparently In-Reply-To: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: Am Sun, Feb 07, 2021 at 08:34:34PM +0100 schrieb Philipp Daher via Python-list: > I recently coded this snippet of code: > myString=?hello? I doubt you have (coded *this* snippet of code) -- because those quotes wouldn't work. Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From rosuav at gmail.com Sun Feb 7 14:40:21 2021 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 8 Feb 2021 06:40:21 +1100 Subject: Python cannot count apparently In-Reply-To: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: On Mon, Feb 8, 2021 at 6:36 AM Philipp Daher via Python-list wrote: > > Hello, > > I recently coded this snippet of code: > myString=?hello? > for i in range(len(myString): > print(string[i]) This code won't work as is. Please *copy and paste* your code when asking for help. > And now for the weird part: > > SOMETIMES, the output is this: > > hello > > And SOMETIMES, the output changes to: > > ohell Neither of those makes sense based on the code you're showing, so again, please *copy and paste* the code and output. > WHY??? Why do I get different outputs with the EXACT SAME CODE? > > Can someone help me please? Thank you I would recommend that you start by iterating over the string itself, instead of a range. My crystal ball tells me that you're getting tangled with negative indexing, but without seeing the code each time, it's impossible to be sure. ChrisA From joel.goldstick at gmail.com Sun Feb 7 14:46:33 2021 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Sun, 7 Feb 2021 14:46:33 -0500 Subject: Python cannot count apparently In-Reply-To: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: On Sun, Feb 7, 2021 at 2:36 PM Philipp Daher via Python-list wrote: > > Hello, > > I recently coded this snippet of code: > myString=?hello? > for i in range(len(myString): > print(string[i]) > > And now for the weird part: > > SOMETIMES, the output is this: > > hello > > And SOMETIMES, the output changes to: > > ohell > > WHY??? Why do I get different outputs with the EXACT SAME CODE? > > Can someone help me please? Thank you > -- > https://mail.python.org/mailman/listinfo/python-list Did you type the code using idle, or the default python interactive console? If you did, please do that again, and copy and paste your code and the results here. There is something amiss. -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From pbryan at anode.ca Sun Feb 7 14:47:03 2021 From: pbryan at anode.ca (Paul Bryan) Date: Sun, 7 Feb 2021 19:47:03 +0000 Subject: Python cannot count apparently In-Reply-To: References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> That's not the only problem with the code. There's a missing close- paren and a reference to "string" which I presume was meant to be "myString". Suggest OP create a?reproducible?case, and paste the code and output verbatim. On Sun, 2021-02-07 at 20:40 +0100, Karsten Hilbert wrote: > Am Sun, Feb 07, 2021 at 08:34:34PM +0100 schrieb Philipp Daher via > Python-list: > > > I recently coded this snippet of code: > > myString=?hello? > > I doubt you have (coded *this* snippet of code) -- because > those quotes wouldn't work. > > Karsten > -- > GPG? 40BE 5B0E C98E 1713 AFA6? 5BC0 3BEA AC80 7D4F C89B From Karsten.Hilbert at gmx.net Sun Feb 7 14:54:55 2021 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 7 Feb 2021 20:54:55 +0100 Subject: Python cannot count apparently In-Reply-To: <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> Message-ID: Am Sun, Feb 07, 2021 at 07:47:03PM +0000 schrieb Paul Bryan: > That's not the only problem with the code. There's a missing close- > paren and a reference to "string" which I presume was meant to be > "myString". I know. I wasn't going to spoil everything right away. The sort of response we would get from OP would tell us what sort of help might be most suitable :-) Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From kevinmwilson1956 at yahoo.com Sun Feb 7 15:49:52 2021 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Sun, 7 Feb 2021 20:49:52 +0000 (UTC) Subject: Python cannot count apparently In-Reply-To: References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> Message-ID: <1319383271.364125.1612730992907@mail.yahoo.com> Set i = 0 at the begin of the code, that way each entry starts at Logical 0 of the array/container/list... "The only way to have experience is by?having?the experience"! On Sunday, February 7, 2021, 12:56:40 PM MST, Karsten Hilbert wrote: Am Sun, Feb 07, 2021 at 07:47:03PM +0000 schrieb Paul Bryan: > That's not the only problem with the code. There's a missing close- > paren and a reference to "string" which I presume was meant to be > "myString". I know. I wasn't going to spoil everything right away. The sort of response we would get from OP would tell us what sort of help might be most suitable :-) Karsten -- GPG? 40BE 5B0E C98E 1713 AFA6? 5BC0 3BEA AC80 7D4F C89B -- https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Sun Feb 7 16:00:12 2021 From: PythonList at DancesWithMice.info (dn) Date: Mon, 8 Feb 2021 10:00:12 +1300 Subject: Python cannot count apparently In-Reply-To: <1319383271.364125.1612730992907@mail.yahoo.com> References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> <1319383271.364125.1612730992907@mail.yahoo.com> Message-ID: On 08/02/2021 09.49, Kevin M. Wilson via Python-list wrote: > Set i = 0 at the begin of the code, that way each entry starts at Logical 0 of the array/container/list... FYI: https://docs.python.org/3/library/stdtypes.html#typesseq-range See also @Chris' contribution regarding the pythonic idiom for iterating over a container. -- Regards, =dn From pkpearson at nowhere.invalid Sun Feb 7 17:06:25 2021 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 7 Feb 2021 22:06:25 GMT Subject: Python cannot count apparently References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> <010d01777e088518-7b0001c6-a224-445f-923b-b0a275923e37-000000@ca-central-1.amazonses.com> <1319383271.364125.1612730992907@mail.yahoo.com> Message-ID: On Sun, 7 Feb 2021 20:49:52 +0000 (UTC), Kevin M. Wilson wrote: > Set i = 0 at the begin of the code, that way each entry starts at > Logical 0 of the array/container/list... No. The original code, as posted, was >> I recently coded this snippet of code: >> myString=?hello? >> for i in range(len(myString): >> print(string[i]) Setting i=0 before the "for" statement would make no difference. In the first pass through the for loop, i is set to the first value in the range, which is zero. -- To email me, substitute nowhere->runbox, invalid->com. From mats at wichmann.us Sun Feb 7 17:23:40 2021 From: mats at wichmann.us (Mats Wichmann) Date: Sun, 7 Feb 2021 15:23:40 -0700 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: Message-ID: On 2/7/21 7:06 AM, Kr4ck ALI wrote: > Hello, > > I have to migrate multiple mailbox (emails, contacts, calendar, tasks) from > thunderbird to outlook Office 365. So sorry to hear that. > I plan to export all items from thunderbird files (.mbox for email, .sqlite > or .sdb for calendar, .mab to contact) to PST files and import each PST > files to Office 365. > I know it's a tedious task ... But I know that nothing is impossible ! There's nothing wrong with trying to tackle this task, but there are some actual commercial tools available which will probably know more about the quirks of such a conversion than you are likely to find out in the course of one migration, as they'll have experiences from probably hundreds of them. From cs at cskk.id.au Sun Feb 7 18:43:21 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 8 Feb 2021 10:43:21 +1100 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: Message-ID: On 07Feb2021 15:06, Kr4ck ALI wrote: >I have to migrate multiple mailbox (emails, contacts, calendar, tasks) >from thunderbird to outlook Office 365. I am also sorry to hear that. Had you considered getting them to enable IMAP access? Then you can migrate just by moving messages inside Thunderbird. And you can keep using your mail reader of choice. >I plan to export all items from thunderbird files (.mbox for email, .sqlite >or .sdb for calendar, .mab to contact) to PST files and import each PST >files to Office 365. The contacts and calendar stuff I have less idea about, alas. CalDAV for the calendar? I know that's a vague and unspecific suggestion. Cheers, Cameron Simpson From kr4ckali at gmail.com Mon Feb 8 01:00:34 2021 From: kr4ckali at gmail.com (Kr4ck ALI) Date: Mon, 8 Feb 2021 07:00:34 +0100 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: Message-ID: I have about 1000 mailbox to migrate and all are store in local on each computers. I know PST files store contacts, calendar, tasks... So, I think that is possible to build a PST file with python to integrate the differents items (emails, calendar, tasks,...) from thunderbird files. Le lun. 8 f?vr. 2021 ? 00:45, Cameron Simpson a ?crit : > On 07Feb2021 15:06, Kr4ck ALI wrote: > >I have to migrate multiple mailbox (emails, contacts, calendar, tasks) > >from thunderbird to outlook Office 365. > > I am also sorry to hear that. > > Had you considered getting them to enable IMAP access? Then you can > migrate just by moving messages inside Thunderbird. And you can keep > using your mail reader of choice. > > >I plan to export all items from thunderbird files (.mbox for email, > .sqlite > >or .sdb for calendar, .mab to contact) to PST files and import each PST > >files to Office 365. > > The contacts and calendar stuff I have less idea about, alas. CalDAV for > the calendar? I know that's a vague and unspecific suggestion. > > Cheers, > Cameron Simpson > -- > https://mail.python.org/mailman/listinfo/python-list > From __peter__ at web.de Mon Feb 8 05:06:01 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 8 Feb 2021 11:06:01 +0100 Subject: Log exception so traceback contains timestamp and level? In-Reply-To: <20210207151215.GA32059@hjp.at> References: <20210207151215.GA32059@hjp.at> Message-ID: On 07/02/2021 16:12, Peter J. Holzer wrote: > On 2021-02-06 21:01:37 -0600, Skip Montanaro wrote: >> The logging package can log exceptions and call stacks, but it does >> (in my opinion) a suboptimal job of it. Consider this simple example: >>>>> import logging >>>>> FORMAT = '%(asctime)-15s %(levelname)s %(message)s' >>>>> logging.basicConfig(format=FORMAT, force=True) >>>>> log.warning("msg", stack_info=True) >> 2021-02-06 20:46:52,399 WARNING msg >> Stack (most recent call last): >> File "", line 1, in >> >> It formats the warning message just fine, but simply dumps the >> traceback onto the stream with no timestamp or level. For my purposes, >> this is more important for exceptions. (I'm just using the stack trace >> feature as it's easier in a small example.) I would like to call >> something like > > I suspect that it just adds the stack trace to the message, so that you > are left with a multi-line message. If you are willing to process all multiline messages in the same way that simplifies your custom Formatter: def make_formatter_class(prefix, style): class PrefixFormatter(logging.Formatter): prefix_template = logging._STYLES[style][0](prefix) prefix_uses_time = prefix_template.usesTime() def usesTime(self): return self.prefix_uses_time or super().usesTime() def format(self, record): # this is supposed to set asctime attribute implicitly: text = super().format(record) lines = text.splitlines(True) if len(lines) > 1: prefix = self.prefix_template.format(record) return "".join( lines[:1] + [prefix + line for line in lines[1:]] ) return text return PrefixFormatter # optional: monkey-patch to affect basicConfig() logging.Formatter = make_formatter_class( prefix="X... %(asctime)s %(levelname)s ", style="%" ) From __peter__ at web.de Mon Feb 8 05:06:01 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 8 Feb 2021 11:06:01 +0100 Subject: Log exception so traceback contains timestamp and level? In-Reply-To: <20210207151215.GA32059@hjp.at> References: <20210207151215.GA32059@hjp.at> Message-ID: On 07/02/2021 16:12, Peter J. Holzer wrote: > On 2021-02-06 21:01:37 -0600, Skip Montanaro wrote: >> The logging package can log exceptions and call stacks, but it does >> (in my opinion) a suboptimal job of it. Consider this simple example: >>>>> import logging >>>>> FORMAT = '%(asctime)-15s %(levelname)s %(message)s' >>>>> logging.basicConfig(format=FORMAT, force=True) >>>>> log.warning("msg", stack_info=True) >> 2021-02-06 20:46:52,399 WARNING msg >> Stack (most recent call last): >> File "", line 1, in >> >> It formats the warning message just fine, but simply dumps the >> traceback onto the stream with no timestamp or level. For my purposes, >> this is more important for exceptions. (I'm just using the stack trace >> feature as it's easier in a small example.) I would like to call >> something like > > I suspect that it just adds the stack trace to the message, so that you > are left with a multi-line message. If you are willing to process all multiline messages in the same way that simplifies your custom Formatter: def make_formatter_class(prefix, style): class PrefixFormatter(logging.Formatter): prefix_template = logging._STYLES[style][0](prefix) prefix_uses_time = prefix_template.usesTime() def usesTime(self): return self.prefix_uses_time or super().usesTime() def format(self, record): # this is supposed to set asctime attribute implicitly: text = super().format(record) lines = text.splitlines(True) if len(lines) > 1: prefix = self.prefix_template.format(record) return "".join( lines[:1] + [prefix + line for line in lines[1:]] ) return text return PrefixFormatter # optional: monkey-patch to affect basicConfig() logging.Formatter = make_formatter_class( prefix="X... %(asctime)s %(levelname)s ", style="%" ) From user at example.net Mon Feb 8 05:08:39 2021 From: user at example.net (J.O. Aho) Date: Mon, 8 Feb 2021 11:08:39 +0100 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: <87im72ykw7.fsf@nightsong.com> References: <87im72ykw7.fsf@nightsong.com> Message-ID: On 08/02/2021 10.22, Paul Rubin wrote: > "J.O. Aho" writes: >> I think most migrated to use IMAP like 30 years ago > > That handles email but not calendar or the other stuff. I think there > are starting to be standards for that, but no idea whether either > Thunderbird or Outlook follows them. Yes, that is true that the IMAP don't handle the calendar, for those you need caldav/webcal and then maybe carddav for address books too and I do think those are well supported in Thunderbird, the question is more what the web based Outlook handles, the company behind that one has never been keen on open standards but locking in customers. -- //Aho From mstemper at gmail.com Mon Feb 8 09:18:41 2021 From: mstemper at gmail.com (Michael F. Stemper) Date: Mon, 8 Feb 2021 08:18:41 -0600 Subject: Python cannot count apparently In-Reply-To: References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: On 07/02/2021 13.34, Philipp Daher wrote: > Hello, > > I recently coded this snippet of code: > myString=?hello? > for i in range(len(myString): > print(string[i]) > > And now for the weird part: > > SOMETIMES, the output is this: > > hello Strange. When I fix the errors in what you posted: - wrong character to start the string - wrong variable name in the call to print() I get[1]: ... myString="hello" ... for i in range(len(myString)): ... print( myString[i] ) ... h e l l o ... You must have done something to suppress the newlines after each call to print(). So it's quite obvious that the code you posted has very little to do with the code you ran. If you really want us to help, please directly copy and paste the exact code that you ran. We can't really help you with only guesses as to what you did. [1] (leading > replaced with . to fool news clients) -- Michael F. Stemper Galatians 3:28 From Joseph.Schachner at Teledyne.com Mon Feb 8 14:12:13 2021 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Mon, 8 Feb 2021 19:12:13 +0000 Subject: Python cannot count apparently In-Reply-To: References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: This code works: mystr = "hello" for ch in mystr: print(ch, end="") result is: hello Note that the for loop does not use range. Strings are iterable, that is they support Python's iteration protocol. So, for ch in mystr: assigns one character from mystr to ch each time, each iteration gets the next character. To prevent each character from appearing on a separate line (in Python 3) you need end="". That is, don't put in the usual end-of-line ending. --- Joseph S. Teledyne Confidential; Commercially Sensitive Business Data -----Original Message----- From: Michael F. Stemper Sent: Monday, February 8, 2021 9:19 AM To: python-list at python.org Subject: Re: Python cannot count apparently On 07/02/2021 13.34, Philipp Daher wrote: > Hello, > > I recently coded this snippet of code: > myString=?hello? > for i in range(len(myString): > print(string[i]) > > And now for the weird part: > > SOMETIMES, the output is this: > > hello Strange. When I fix the errors in what you posted: - wrong character to start the string - wrong variable name in the call to print() I get[1]: ... myString="hello" ... for i in range(len(myString)): ... print( myString[i] ) ... h e l l o ... You must have done something to suppress the newlines after each call to print(). So it's quite obvious that the code you posted has very little to do with the code you ran. If you really want us to help, please directly copy and paste the exact code that you ran. We can't really help you with only guesses as to what you did. [1] (leading > replaced with . to fool news clients) -- Michael F. Stemper Galatians 3:28 From mstemper at gmail.com Mon Feb 8 16:05:51 2021 From: mstemper at gmail.com (Michael F. Stemper) Date: Mon, 8 Feb 2021 15:05:51 -0600 Subject: Python cannot count apparently In-Reply-To: References: <1E2B574E-FBC6-4C63-953C-8A4C3BC7515A@icloud.com> Message-ID: On 08/02/2021 13.12, Schachner, Joseph wrote: > This code works: > mystr = "hello" > for ch in mystr: > print(ch, end="") > > result is: hello > > Note that the for loop does not use range. Strings are iterable, that is they support Python's iteration protocol. So, for ch in mystr: assigns one character from mystr to ch each time, each iteration gets the next character. > To prevent each character from appearing on a separate line (in Python 3) you need end="". That is, don't put in the usual end-of-line ending. Then you agree that the OP: > You must have done something to suppress the newlines after each call to print(). > > So it's quite obvious that the code you posted has very little to do with the code you ran. If you really want us to help, please directly copy and paste the exact code that you ran. We can't really help you with only guesses as to what you did. -- Michael F. Stemper Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read. From user at example.net Mon Feb 8 01:52:33 2021 From: user at example.net (J.O. Aho) Date: Mon, 8 Feb 2021 07:52:33 +0100 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: Message-ID: On 07/02/2021 15.06, Kr4ck ALI wrote: > Hello, > > I have to migrate multiple mailbox (emails, contacts, calendar, tasks) from > thunderbird to outlook Office 365. I'm sorry to hear that. > I plan to export all items from thunderbird files (.mbox for email, .sqlite > or .sdb for calendar, .mab to contact) to PST files and import each PST > files to Office 365. I think most migrated to use IMAP like 30 years ago, so you tend to do the migration from the IMAP to IMAP server and there are usually help to get from the provider you move to to get all the data migrated. > My question is : Have you already make a mission like that ? I kind of doubt this. Once alternative is that you see to enable IMAP/SMTP or pay for ExQuilla and let each user have their old mail on the computer and the new mail account will store the mail and other stuff remotely. -- //Aho From Knighticarus at gmx.de Mon Feb 8 16:33:07 2021 From: Knighticarus at gmx.de (Stefan Ritter) Date: Mon, 8 Feb 2021 22:33:07 +0100 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: References: Message-ID: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Hi, It would be highly appreciated if you could offer me some advice to solve a problem I'm currently facing: I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. I wrote some code to insert text in a .txt-file. It works perfectly on my laptop. On my desktop it works only if i run it in IDLE, the text appears afterwards in the file . However it does not work if run it in Powershell (or anything else), there are no changes made in the file. I do not understand why this is the case. Python version, installation paths and user are the same on desktop and laptop. I searched a bit and found out that this issue might be caused by my antivirus software comodo, but even after I replaced it with antivir, an reinstalled python this didn't change anything. As mentionned, any help is highly appreciated. If you need any additional information please let me know! Best regards, Stefan From pjfarley3 at earthlink.net Mon Feb 8 19:43:28 2021 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Mon, 8 Feb 2021 19:43:28 -0500 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: Message-ID: <000101d6fe7c$95b95800$c12c0800$@earthlink.net> I can recommend the commercial product Aid4Mail from my personal experience moving from another mbox-based email client (not Thunderbird) to Outlook (though that was a few years back, well before Outlook 365 became available). Very well supported and responsive, very reasonably priced at the time I needed it. HTH Peter > -----Original Message----- > From: Kr4ck ALI > Sent: Monday, February 8, 2021 1:01 AM > To: python-list at python.org > Subject: Re: Convert MBOX thunderbird to PST outlook > > I have about 1000 mailbox to migrate and all are store in local on each > computers. > I know PST files store contacts, calendar, tasks... So, I think that is > possible to build a PST file with python to integrate the differents items > (emails, calendar, tasks,...) from thunderbird files. > > > Le lun. 8 f?vr. 2021 ? 00:45, Cameron Simpson a ?crit : > > > On 07Feb2021 15:06, Kr4ck ALI wrote: > > >I have to migrate multiple mailbox (emails, contacts, calendar, tasks) > > >from thunderbird to outlook Office 365. > > > > I am also sorry to hear that. > > > > Had you considered getting them to enable IMAP access? Then you can > > migrate just by moving messages inside Thunderbird. And you can keep > > using your mail reader of choice. > > > > >I plan to export all items from thunderbird files (.mbox for email, > > .sqlite > > >or .sdb for calendar, .mab to contact) to PST files and import each PST > > >files to Office 365. > > > > The contacts and calendar stuff I have less idea about, alas. CalDAV for > > the calendar? I know that's a vague and unspecific suggestion. > > > > Cheers, > > Cameron Simpson > > -- > > https://mail.python.org/mailman/listinfo/python-list > > From python at mrabarnett.plus.com Mon Feb 8 21:20:25 2021 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 9 Feb 2021 02:20:25 +0000 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: <79cbb280-39b0-4aae-626d-cf093402c7eb@mrabarnett.plus.com> On 2021-02-08 21:33, Stefan Ritter wrote: > > Hi, > > It would be highly appreciated if you could offer me some advice to > solve a problem I'm currently facing: > > I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. > > I wrote some code to insert text in a .txt-file. It works perfectly on > my laptop. > > On my desktop it works only if i run it in IDLE, the text appears > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. > > I do not understand why this is the case. Python version, installation > paths and user are the same on desktop and laptop. I searched a bit and > found out that this issue might be caused by my antivirus software > comodo, but even after I replaced it with antivir, an reinstalled python > this didn't change anything. > > As mentionned, any help is highly appreciated. If you need any > additional information please let me know! > It's difficult to troubleshoot with any code. From auriocus at gmx.de Tue Feb 9 01:53:51 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 9 Feb 2021 07:53:51 +0100 Subject: Convert MBOX thunderbird to PST outlook In-Reply-To: References: <87im72ykw7.fsf@nightsong.com> Message-ID: Am 08.02.21 um 11:08 schrieb J.O. Aho: > > On 08/02/2021 10.22, Paul Rubin wrote: >> "J.O. Aho" writes: >>> I think most migrated to use IMAP like 30 years ago >> >> That handles email but not calendar or the other stuff.? I think there >> are starting to be standards for that, but no idea whether either >> Thunderbird or Outlook follows them. > > Yes, that is true that the IMAP don't handle the calendar, for those you > need caldav/webcal and then maybe carddav for address books too and I do > think those are well supported in Thunderbird, the question is more what > the web based Outlook handles, For thatm you can run radicale: https://radicale.org/3.0.html A Python-based calendar server. Then upload your calendars there from Thunderbird and download them from Outlook. Christian From __peter__ at web.de Tue Feb 9 04:50:02 2021 From: __peter__ at web.de (Peter Otten) Date: Tue, 9 Feb 2021 10:50:02 +0100 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: On 08/02/2021 22:33, Stefan Ritter wrote: > > Hi, > > It would be highly appreciated if you could offer me some advice to > solve a problem I'm currently facing: > > I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. > > I wrote some code to insert text in a .txt-file. It works perfectly on > my laptop. > > On my desktop it works only if i run it in IDLE, the text appears > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. > > I do not understand why this is the case. Python version, installation > paths and user are the same on desktop and laptop. I searched a bit and > found out that this issue might be caused by my antivirus software > comodo, but even after I replaced it with antivir, an reinstalled python > this didn't change anything. > > As mentionned, any help is highly appreciated. If you need any > additional information please let me know! My crystal ball says Idle and the shell use different working directories; you have a relative path, change one file and are looking at the other. If that's not the case -- show us the code. If there is an error message and a traceback provide that, too. Use copy-and-paste for both code and error. From __peter__ at web.de Tue Feb 9 04:50:02 2021 From: __peter__ at web.de (Peter Otten) Date: Tue, 9 Feb 2021 10:50:02 +0100 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: On 08/02/2021 22:33, Stefan Ritter wrote: > > Hi, > > It would be highly appreciated if you could offer me some advice to > solve a problem I'm currently facing: > > I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. > > I wrote some code to insert text in a .txt-file. It works perfectly on > my laptop. > > On my desktop it works only if i run it in IDLE, the text appears > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. > > I do not understand why this is the case. Python version, installation > paths and user are the same on desktop and laptop. I searched a bit and > found out that this issue might be caused by my antivirus software > comodo, but even after I replaced it with antivir, an reinstalled python > this didn't change anything. > > As mentionned, any help is highly appreciated. If you need any > additional information please let me know! My crystal ball says Idle and the shell use different working directories; you have a relative path, change one file and are looking at the other. If that's not the case -- show us the code. If there is an error message and a traceback provide that, too. Use copy-and-paste for both code and error. From tjreedy at udel.edu Mon Feb 8 19:53:49 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 8 Feb 2021 19:53:49 -0500 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: On 2/8/2021 4:33 PM, Stefan Ritter wrote: > > Hi, > > It would be highly appreciated if you could offer me some advice to > solve a problem I'm currently facing: > > I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. > > I wrote some code to insert text in a .txt-file. It works perfectly on > my laptop. > > On my desktop it works only if i run it in IDLE, the text appears > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. Find the minimum code that exhibits a behavior difference. It should be short enough to post here, along with the command you used to run it in PowerShell or CommandPrompt and how you ran it in IDLE. > I do not understand why this is the case. Python version, installation > paths and user are the same on desktop and laptop. I searched a bit and > found out that this issue might be caused by my antivirus software > comodo, but even after I replaced it with antivir, an reinstalled python > this didn't change anything. > > As mentionned, any help is highly appreciated. If you need any > additional information please let me know! > > Best regards, > Stefan > > -- Terry Jan Reedy From 10-10883 at usb.ve Mon Feb 8 21:13:21 2021 From: 10-10883 at usb.ve (Juan Jose Reyna Figuera) Date: Mon, 8 Feb 2021 22:13:21 -0400 Subject: Fwd: Inconveniente In-Reply-To: References: Message-ID: *Buenas tardes, le escribo breve y puntualmente para reportar este el siguiente error al cual no le pude dar soluci?n.* *Instal? Python 3.9.1 (64 bits), todo hab?a funcionado bien hasta que necesit? usar la librer?a seaborn. Al ejecutar mi algoritmo obten?a el siguiente error: * (...\Python\Python39\site-packages\matplotlib\__init__.py) * Desinstal? python, lo reinstal?. * Instale diversas versiones de Matpltlib * Desinstal? seaborn, lo reinstal?. Busque soluciones en la p?gina oficial, foros como:Stack Overflow, reddit, etc y no pud? dar con la soluci?n para esta versi?n de python. Al final instal? python 3.8 de 32 bits, con las librer?as que necesitaba, y logr? realizar el trabaj?. Mi OS es Windows 10, 64 bits. Sin m?s por el momento, me despido cordialmente. From alan.gauld at yahoo.co.uk Tue Feb 9 04:33:24 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 9 Feb 2021 09:33:24 +0000 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: On 08/02/2021 21:33, Stefan Ritter wrote: > I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. So notionally identical. > I wrote some code to insert text in a .txt-file. It works perfectly on > my laptop. > > On my desktop it works only if i run it in IDLE, the text appears > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. You only mention powershell in the context of the desktop. How are you running the code. Can you show us the command line for both laptop and desktop? Or describe exactly what you are doing if using a GUI tool. Showing us the code may help too! -- 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 From skip.montanaro at gmail.com Tue Feb 9 09:53:50 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 9 Feb 2021 08:53:50 -0600 Subject: UTF-16 or something else? Message-ID: I downloaded US hospital ICU capacity data this morning from this page: https://healthdata.gov/dataset/covid-19-reported-patient-impact-and-hospital-capacity-facility (The download link is about halfway down the page.) Trying to read it using my personal CSV tools without specifying an encoding, it failed to understand the first column, hospital_pk. That is apparently because the file isn't simply ASCII or UTF-8. There are a few bytes ahead of the "h". However, if I open the file using "utf-16" as the encoding, Python complains there is no BOM. od(1) suggests there is *something* ahead of the first column name, but it's three bytes, not two: % od -A x -t x1z -v < reported_hospital_capacity_admissions_facility_level_weekly_average_timeseries_20210207.csv | head 000000 *ef bb bf* 68 6f 73 70 69 74 61 6c 5f 70 6b 2c 63 >...hospital_pk,c< 000010 6f 6c 6c 65 63 74 69 6f 6e 5f 77 65 65 6b 2c 73 >ollection_week,s< 000020 74 61 74 65 2c 63 63 6e 2c 68 6f 73 70 69 74 61 >tate,ccn,hospita< ... I'm opening the file like so: inf = open(args[0], "r", encoding=encoding) where encoding is passed on the command line. I know I can simply edit out those bytes and probably be good-to-go, but I'd prefer not to. What should I be passing for the encoding? Skip, who thought everybody had effectively settled on utf-8 at this point, but apparently not... From pa.daher at icloud.com Tue Feb 9 09:55:36 2021 From: pa.daher at icloud.com (Philipp Daher) Date: Tue, 9 Feb 2021 15:55:36 +0100 Subject: Troubles with Python imports Message-ID: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> Hello, I?ve just typed ?pip install selenium? into my command prompt on windows 10. Although my computer told me that the requirement was already satisfied, import selenium did not work. So I tried different methods to install it and typed ?Python? in my command prompt and imported selenium. It worked fine. Then, I typed it into my shell and got an error. Why is it working in the command prompt but not in the actual shell? From stestagg at gmail.com Tue Feb 9 09:59:08 2021 From: stestagg at gmail.com (Stestagg) Date: Tue, 9 Feb 2021 14:59:08 +0000 Subject: UTF-16 or something else? In-Reply-To: References: Message-ID: Try setting encoding to: "utf-8-sig". 'eb bb bf' is the byte order mark for UTF8 (most systems do not include this in UTF-8 encoded files) Python will correctly read UTF8 BOMs if you use the 'utf-8-sig' encoding when reading files Steve On Tue, Feb 9, 2021 at 2:56 PM Skip Montanaro wrote: > I downloaded US hospital ICU capacity data this morning from this page: > > > https://healthdata.gov/dataset/covid-19-reported-patient-impact-and-hospital-capacity-facility > > (The download link is about halfway down the page.) > > Trying to read it using my personal CSV tools without specifying an > encoding, it failed to understand the first column, hospital_pk. That is > apparently because the file isn't simply ASCII or UTF-8. There are a few > bytes ahead of the "h". However, if I open the file using "utf-16" as the > encoding, Python complains there is no BOM. od(1) suggests there is > *something* ahead of the first column name, but it's three bytes, not two: > > % od -A x -t x1z -v < > > reported_hospital_capacity_admissions_facility_level_weekly_average_timeseries_20210207.csv > | head > 000000 *ef bb bf* 68 6f 73 70 69 74 61 6c 5f 70 6b 2c 63 > >...hospital_pk,c< > 000010 6f 6c 6c 65 63 74 69 6f 6e 5f 77 65 65 6b 2c 73 >ollection_week,s< > 000020 74 61 74 65 2c 63 63 6e 2c 68 6f 73 70 69 74 61 >tate,ccn,hospita< > ... > > I'm opening the file like so: > > inf = open(args[0], "r", encoding=encoding) > > where encoding is passed on the command line. I know I can simply edit out > those bytes and probably be good-to-go, but I'd prefer not to. What should > I be passing for the encoding? > > Skip, who thought everybody had effectively settled on utf-8 at this point, > but apparently not... > -- > https://mail.python.org/mailman/listinfo/python-list > From antoon.pardon at vub.be Tue Feb 9 10:17:12 2021 From: antoon.pardon at vub.be (Antoon Pardon) Date: Tue, 9 Feb 2021 16:17:12 +0100 Subject: Mutable defaults Message-ID: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Most of us know of the perils of mutable default values. So I came up with the following proof of concept: from inspect import signature as signature_of, Parameter from itertools import zip_longest from copy import copy def copy_defaults(f): signature = signature_of(f) def wrapper(*args): newargs = [] for argument, parameter_item in zip_longest(args, signature.parameters.items(), fillvalue = Parameter.empty): _, parameter = parameter_item if argument is not Parameter.empty: newargs.append(argument) elif (parameter.default is not Parameter.empty): newargs.append(copy(parameter.default)) else: raise TypeError("Not enough arguments") return f(*newargs) return wrapper @copy_defaults def prepare(value, lst = []): for vl in range(value): lst.append(vl) return lst print(prepare(2)) print(prepare(3)) Running the above will produce: [0, 1] [0, 1, 2] From jon+usenet at unequivocal.eu Tue Feb 9 10:17:24 2021 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 9 Feb 2021 15:17:24 -0000 (UTC) Subject: UTF-16 or something else? References: Message-ID: On 2021-02-09, Skip Montanaro wrote: > I downloaded US hospital ICU capacity data this morning from this page: > > https://healthdata.gov/dataset/covid-19-reported-patient-impact-and-hospital-capacity-facility > > (The download link is about halfway down the page.) > > Trying to read it using my personal CSV tools without specifying an > encoding, it failed to understand the first column, hospital_pk. That is > apparently because the file isn't simply ASCII or UTF-8. There are a few > bytes ahead of the "h". However, if I open the file using "utf-16" as the > encoding, Python complains there is no BOM. od(1) suggests there is > *something* ahead of the first column name, but it's three bytes, not two: > > % od -A x -t x1z -v < > reported_hospital_capacity_admissions_facility_level_weekly_average_timeseries_20210207.csv >| head > 000000 *ef bb bf* 68 6f 73 70 69 74 61 6c 5f 70 6b 2c 63 >...hospital_pk,c< > 000010 6f 6c 6c 65 63 74 69 6f 6e 5f 77 65 65 6b 2c 73 >ollection_week,s< > 000020 74 61 74 65 2c 63 63 6e 2c 68 6f 73 70 69 74 61 >tate,ccn,hospita< > ... It's UTF-8 with a UTF-16 BOM prepended, which is not uncommon when you have a file that's been converted to UTF-8 from UTF-16 or has been produced by shitty Microsoft software. You can tell instantly at a glance that it's not UTF-16 because the ascii dump would l.o.o.k. .l.i.k.e. .t.h.i.s. You can decode it as utf-8 and ignore the BOM character, or as someone else has rightly said, Python can decode it as utf-8-sig, which does that automatically for you. From rosuav at gmail.com Tue Feb 9 10:26:44 2021 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 10 Feb 2021 02:26:44 +1100 Subject: Mutable defaults In-Reply-To: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: On Wed, Feb 10, 2021 at 2:19 AM Antoon Pardon wrote: > > Most of us know of the perils of mutable default values. So I came up with the following proof of concept: > > def copy_defaults(f): > > def wrapper(*args): > return f(*newargs) > return wrapper > > @copy_defaults > def prepare(value, lst = []): > for vl in range(value): > lst.append(vl) > return lst > > print(prepare(2)) > print(prepare(3)) > > Running the above will produce: > > [0, 1] > [0, 1, 2] > Nice idea, but you've limited your functions to positional-only parameters. Extending this to support keyword arguments is a lot harder, and is why it's generally easier to use standard idioms like defaulting to None (or to a unique object) and then "if lst is None: lst = []" at the start of the function. Have you considered inspect.signature and its various methods? It may be useful here. ChrisA From __peter__ at web.de Tue Feb 9 10:47:04 2021 From: __peter__ at web.de (Peter Otten) Date: Tue, 9 Feb 2021 16:47:04 +0100 Subject: Mutable defaults In-Reply-To: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: <9b50f75b-483d-7624-61d5-3bf67d7f9595@web.de> On 09/02/2021 16:17, Antoon Pardon wrote: > Most of us know of the perils of mutable default values. So I came up > with the following proof of concept: [...] def copy_defaults(f): Once you know you need that decorator you won't need it anymore ;) > @copy_defaults > def prepare(value, lst = []): > ??? for vl in range(value): > ??????? lst.append(vl) > ??? return lst > > print(prepare(2)) > print(prepare(3)) > > Running the above will produce: > > [0, 1] > [0, 1, 2] Because of @copy_defaults def prepare(value, lst=[[]]): for vl in range(value): lst[0].append(vl) return lst you may consider changing it to deepcopy_defaults. From __peter__ at web.de Tue Feb 9 10:47:04 2021 From: __peter__ at web.de (Peter Otten) Date: Tue, 9 Feb 2021 16:47:04 +0100 Subject: Mutable defaults In-Reply-To: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: <9b50f75b-483d-7624-61d5-3bf67d7f9595@web.de> On 09/02/2021 16:17, Antoon Pardon wrote: > Most of us know of the perils of mutable default values. So I came up > with the following proof of concept: [...] def copy_defaults(f): Once you know you need that decorator you won't need it anymore ;) > @copy_defaults > def prepare(value, lst = []): > ??? for vl in range(value): > ??????? lst.append(vl) > ??? return lst > > print(prepare(2)) > print(prepare(3)) > > Running the above will produce: > > [0, 1] > [0, 1, 2] Because of @copy_defaults def prepare(value, lst=[[]]): for vl in range(value): lst[0].append(vl) return lst you may consider changing it to deepcopy_defaults. From mats at wichmann.us Tue Feb 9 10:58:17 2021 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 9 Feb 2021 08:58:17 -0700 Subject: Troubles with Python imports In-Reply-To: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> References: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> Message-ID: <627b4785-4eb7-532a-9210-56775017b8b8@wichmann.us> On 2/9/21 7:55 AM, Philipp Daher via Python-list wrote: > Hello, > > I?ve just typed ?pip install selenium? into my command prompt on windows 10. Although my computer told me that the requirement was already satisfied, import selenium did not work. So I tried different methods to install it and typed ?Python? in my command prompt and imported selenium. It worked fine. Then, I typed it into my shell and got an error. Why is it working in the command prompt but not in the actual shell? This isn't really making sense - what do you consider to be the difference between "the command prompt" and "the actual shell"? When you run the python program from a command line (cmd.exe or PowerShell), what you get is the Python interpreter, or shell, or whatever you want to call it. You said things worked there - so the installation is fine. Now what does "Then, I typed it into my shell and got an error" mean? If you mean you typed "import selenium" in cmd.exe, why would you expect that to work? The import is an instruction to Python... Please explain further so we can try to help. From skip.montanaro at gmail.com Tue Feb 9 11:32:11 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 9 Feb 2021 10:32:11 -0600 Subject: UTF-16 or something else? In-Reply-To: References: Message-ID: > > Try setting encoding to: "utf-8-sig". > > 'eb bb bf' is the byte order mark for UTF8 (most systems do not include > this in UTF-8 encoded files) > > Python will correctly read UTF8 BOMs if you use the 'utf-8-sig' encoding > when reading files > Excellent, thanks. That worked like a charm. Knowing what its called also allowed me to look up more info. Skip From skip.montanaro at gmail.com Tue Feb 9 11:34:08 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 9 Feb 2021 10:34:08 -0600 Subject: UTF-16 or something else? In-Reply-To: References: Message-ID: > > It's UTF-8 with a UTF-16 BOM prepended, which is not uncommon when you > have a file that's been converted to UTF-8 from UTF-16 or has been > produced by shitty Microsoft software. You can tell instantly at a > glance that it's not UTF-16 because the ascii dump would l.o.o.k. > .l.i.k.e. .t.h.i.s. > Ah, right. Been a long, long while (well before Unicode was a thing) since I needed to use od(1) and don't remember dealing with UTF-16 before. Skip From drsalists at gmail.com Tue Feb 9 14:11:47 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Tue, 9 Feb 2021 11:11:47 -0800 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: On Mon, Feb 8, 2021 at 4:22 PM Stefan Ritter wrote: > > Hi, > > It would be highly appreciated if you could offer me some advice to > solve a problem I'm currently facing: > > afterwards in the file . However it does not work if run it in > Powershell (or anything else), there are no changes made in the file. > > I do not understand why this is the case. Python version, installation > paths and user are the same on desktop and laptop. I searched a bit and > found out that this issue might be caused by my antivirus software > comodo, but even after I replaced it with antivir, an reinstalled python > this didn't change anything. > > As mentionned, any help is highly appreciated. If you need any > additional information please let me know! > It's probably either two different paths, or an ignored traceback. Please cut and paste the output of your script - one paste for the working output, and one for the nonworking output. You may want to use os.path.abspath(*path*) on your path, and print it to the screen. Then compare that to Resolve-Path pathname in Powershell. HTH References: https://docs.python.org/3/library/os.path.html https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/resolve-path?view=powershell-7.1 From PythonList at DancesWithMice.info Tue Feb 9 15:39:12 2021 From: PythonList at DancesWithMice.info (dn) Date: Wed, 10 Feb 2021 09:39:12 +1300 Subject: Fwd: Inconveniente In-Reply-To: References: Message-ID: On 09/02/2021 15.13, Juan Jose Reyna Figuera wrote: > *Buenas tardes, le escribo breve y puntualmente para reportar este el > siguiente error al cual no le pude dar soluci?n.* > > *Instal? Python 3.9.1 (64 bits), todo hab?a funcionado bien hasta que > necesit? usar la librer?a seaborn. Al ejecutar mi algoritmo obten?a el > siguiente error: * > > (...\Python\Python39\site-packages\matplotlib\__init__.py) > > * Desinstal? python, lo reinstal?. > * Instale diversas versiones de Matpltlib > * Desinstal? seaborn, lo reinstal?. > > Busque soluciones en la p?gina oficial, foros como:Stack Overflow, reddit, > etc y no pud? dar con la soluci?n para esta versi?n de python. > > Al final instal? python 3.8 de 32 bits, con las librer?as que necesitaba, y > logr? realizar el trabaj?. > > Mi OS es Windows 10, 64 bits. > > Sin m?s por el momento, > > me despido cordialmente. Well done for solving the problem! [ Translation: matplotlib (and seaborn) not playing-nicely with Python 3.9 64-bit edition on MS-Win 10. Solved by down-grading to Python 3.8 32-bit. ] Yes, there have been problems with certain libraries that have not (yet) been updated to run on Python 3.9. Your solution is the current advice. However, I'm concerned about mathematical applications on 32-bit platforms. Did you try Python 3.8's 64-bit option (plus libraries)? NB this is an English-language list - for faster response to questions. [Cordialmente] -- Regards, =dn From Knighticarus at gmx.de Tue Feb 9 15:49:21 2021 From: Knighticarus at gmx.de (Stefan Ritter) Date: Tue, 9 Feb 2021 21:49:21 +0100 Subject: Files can only be modified in IDLE, but not via Powershell In-Reply-To: References: <61ca6194-d6b0-8bf9-9121-b22448b1d706@gmx.de> Message-ID: Thanks for your advice! To be honest i'm not quite sure what did the trick, I just played a little bit around with the paths. Anyway, now its working as expected. Bless your crystal ball! Needless to say: Many thanks for all the other responses i did receive! Am 09.02.2021 um 10:50 schrieb Peter Otten: > On 08/02/2021 22:33, Stefan Ritter wrote: >> >> Hi, >> >> It would be highly appreciated if you could offer me some advice to >> solve a problem I'm currently facing: >> >> I have a Windows 10 ADM64 desktop and a Windows 10 AMD64 Laptop. >> >> I wrote some code to insert text in a .txt-file. It works perfectly on >> my laptop. >> >> On my desktop it works only if i run it in IDLE, the text appears >> afterwards in the file . However it does not work if run it in >> Powershell (or anything else), there are no changes made in the file. >> >> I do not understand why this is the case. Python version, installation >> paths and user are the same on desktop and laptop. I searched a bit and >> found out that this issue might be caused by my antivirus software >> comodo, but even after I replaced it with antivir, an reinstalled python >> this didn't change anything. >> >> As mentionned, any help is highly appreciated. If you need any >> additional information please let me know! > > My crystal ball says Idle and the shell use different working > directories; you have a relative path, change one file and are looking > at the other. > > If that's not the case -- show us the code. > If there is an error message and a traceback provide that, too. > > Use copy-and-paste for both code and error. From flaskee at protonmail.com Tue Feb 9 17:07:12 2021 From: flaskee at protonmail.com (flaskee) Date: Tue, 09 Feb 2021 22:07:12 +0000 Subject: Response for PING in ircbot. In-Reply-To: References: Message-ID: ??????? Original Message ??????? On Saturday, January 30, 2021 11:50 AM, Bischoop wrote: > Got problem with responding for Ping, > tried so many ways to response > and always end up with time out or other error. > This time: > Is it possible to share your final Ping answer with the list? I've had a long term Flask/Python issue where the site just dies. (MY) External ping attempts still report the Flask site is functioning; but accessing the pages returns 500 errors. Apache is still running and other (non-Flask) sites are still running on the Linux server. I see no errors that might be causing this under /var/log/*, or apache's error log; or the site's access/error logs. What I'd like to do is set up my own external monitor, to at least known WHEN the site has died. And I'm wondering if your PING might be better. Thanks! From tjreedy at udel.edu Tue Feb 9 12:13:33 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 9 Feb 2021 12:13:33 -0500 Subject: Fwd: Inconveniente In-Reply-To: References: Message-ID: This is an English list. There are Spanish lists, such as Esto es lista engleis. Hai listas espanolas. https://mail.python.org/mailman/listinfo/python-es On 2/8/2021 9:13 PM, Juan Jose Reyna Figuera wrote: > *Buenas tardes, le escribo breve y puntualmente para reportar este el > siguiente error al cual no le pude dar soluci?n.* > *Instal? Python 3.9.1 (64 bits), todo hab?a funcionado bien hasta que > necesit? usar la librer?a seaborn. Al ejecutar mi algoritmo obten?a el > siguiente error: * > > (...\Python\Python39\site-packages\matplotlib\__init__.py) When asking about errors, copy and paste entire traceback. Cuando pidiendo cerca de errores, 'copy and paste' todo 'traceback'. -- Terry Jan Reedy From tjreedy at udel.edu Tue Feb 9 12:17:17 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 9 Feb 2021 12:17:17 -0500 Subject: Mutable defaults In-Reply-To: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: On 2/9/2021 10:17 AM, Antoon Pardon wrote: > Most of us know of the perils of mutable default values. So I came up > with the following proof of concept: Which is intended to do what? > from inspect import signature as signature_of, Parameter > from itertools import zip_longest > from copy import copy > > def copy_defaults(f): Docstring? > ??? signature = signature_of(f) > > ??? def wrapper(*args): > ??????? newargs = [] > ??????? for argument, parameter_item in zip_longest(args, > signature.parameters.items(), fillvalue = Parameter.empty): > ??????????? _, parameter = parameter_item > ??????????? if argument is not Parameter.empty: > ??????????????? newargs.append(argument) > ??????????? elif (parameter.default is not Parameter.empty): > ??????????????? newargs.append(copy(parameter.default)) > ??????????? else: > ??????????????? raise TypeError("Not enough arguments") > ??????? return f(*newargs) > > ??? return wrapper > > @copy_defaults > def prepare(value, lst = []): > ??? for vl in range(value): > ??????? lst.append(vl) > ??? return lst > > print(prepare(2)) > print(prepare(3)) > > Running the above will produce: > > [0, 1] > [0, 1, 2] > > -- Terry Jan Reedy From tjreedy at udel.edu Tue Feb 9 12:23:17 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 9 Feb 2021 12:23:17 -0500 Subject: Troubles with Python imports In-Reply-To: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> References: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> Message-ID: On 2/9/2021 9:55 AM, Philipp Daher via Python-list wrote: > Hello, > > I?ve just typed ?pip install selenium? into my command prompt on windows 10. Although my computer told me that the requirement was already satisfied, import selenium did not work. So I tried different methods to install it and typed ?Python? in my command prompt and imported selenium. It worked fine. Then, I typed it into my shell and got an error. Why is it working in the command prompt but not in the actual shell? One common problem (and answer -- monthy on stackoverflow) is that you have more than one python binary installed; do not have module xyz installed for all of them; and are running different binaries to get the different responses. -- Terry Jan Reedy From tjreedy at udel.edu Tue Feb 9 17:34:33 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 9 Feb 2021 17:34:33 -0500 Subject: Fwd: Inconveniente In-Reply-To: References: Message-ID: On 2/9/2021 3:39 PM, dn via Python-list wrote: > On 09/02/2021 15.13, Juan Jose Reyna Figuera wrote: > [ Translation: > matplotlib (and seaborn) not playing-nicely with Python 3.9 64-bit > edition on MS-Win 10. Solved by down-grading to Python 3.8 32-bit. > ] > > > Yes, there have been problems with certain libraries that have not (yet) > been updated to run on Python 3.9. Your solution is the current advice. I checked that seaborn lists 3.9. To my surprise, matplotlib does not. If real, not good, and indeed, using 3.8 is the only solution. A traceback from matplotlib failing might have revealed the specific problem. -- Terry Jan Reedy From mmllopezmartin at gmail.com Tue Feb 9 18:23:56 2021 From: mmllopezmartin at gmail.com (Martin Lopez) Date: Tue, 9 Feb 2021 15:23:56 -0800 Subject: installation issues Message-ID: Hello, My name is Martin Lopez. I just downloaded Python 3.9.1 (64 bit) Setup. After I install the program then try to run it, with no success. I've uninstalled all previous versions and reinstalled them, but it does not seem to help. Can you please assist? Thank you, From mmllopezmartin at gmail.com Tue Feb 9 19:04:45 2021 From: mmllopezmartin at gmail.com (Martin Lopez) Date: Tue, 9 Feb 2021 16:04:45 -0800 Subject: Python 3.9. 1 not working Message-ID: Where do I inquire about installation support? From PythonList at DancesWithMice.info Tue Feb 9 23:12:13 2021 From: PythonList at DancesWithMice.info (dn) Date: Wed, 10 Feb 2021 17:12:13 +1300 Subject: installation issues In-Reply-To: References: Message-ID: <7b451f0d-02fc-8749-1358-5f435e664afe@DancesWithMice.info> On 10/02/2021 12.23, Martin Lopez wrote: > Hello, > > My name is Martin Lopez. I just downloaded Python 3.9.1 (64 bit) Setup. > > After I install the program then try to run it, with no success. > > I've uninstalled all previous versions and reinstalled them, but it does > not seem to help. > > Can you please assist? Welcome to the mailing list Martin! Please also note that there is a Python-Tutor list expressly for Python-learners. Answers vary according to which Operating System is in-use! Useful Web.Refs: https://wiki.python.org/moin/FrontPage (particularly the Beginner's Guide) https://www.python.org/doc/ (for everything, but start with "Using Python") -- Regards, =dn From roland.em0001 at googlemail.com Wed Feb 10 06:22:00 2021 From: roland.em0001 at googlemail.com (Roland Mueller) Date: Wed, 10 Feb 2021 13:22:00 +0200 Subject: Python 3.9. 1 not working In-Reply-To: References: Message-ID: Hello, Please note that this is not a kind of support service rather than a community where people help each other on voluntary base. In order to get help from here, you should provide enough information about your issue with Python 3.9 that others can figure out what happened. BR, Roland ke 10. helmik. 2021 klo 5.10 Martin Lopez (mmllopezmartin at gmail.com) kirjoitti: > Where do I inquire about installation support? > -- > https://mail.python.org/mailman/listinfo/python-list > From roland.em0001 at googlemail.com Wed Feb 10 06:33:12 2021 From: roland.em0001 at googlemail.com (Roland Mueller) Date: Wed, 10 Feb 2021 13:33:12 +0200 Subject: Troubles with Python imports In-Reply-To: References: <95120F2A-1344-4C23-B19E-E56F15796334@icloud.com> Message-ID: ke 10. helmik. 2021 klo 5.07 Terry Reedy (tjreedy at udel.edu) kirjoitti: > On 2/9/2021 9:55 AM, Philipp Daher via Python-list wrote: > > Hello, > > > > I?ve just typed ?pip install selenium? into my command prompt on windows > 10. Although my computer told me that the requirement was already > satisfied, import selenium did not work. So I tried different methods to > install it and typed ?Python? in my command prompt and imported selenium. > It worked fine. Then, I typed it into my shell and got an error. Why is it > working in the command prompt but not in the actual shell? > > One common problem (and answer -- monthy on stackoverflow) is that you > have more than one python binary installed; do not have module xyz > installed for all of them; and are running different binaries to get the > different responses. > > > May be the first thing is to check whether one is using the right pip. Example output is from Linux box, but in Windows the output should also show the relevant information: $ pip -V pip 19.3.1 from /usr/lib/python3.8/site-packages/pip (python 3.8) $ python -V Python 3.8.7 > From python at mrabarnett.plus.com Wed Feb 10 08:00:07 2021 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 10 Feb 2021 13:00:07 +0000 Subject: Fwd: Inconveniente In-Reply-To: References: Message-ID: <28eddbf3-2313-f603-2ec2-b1918c402cd9@mrabarnett.plus.com> On 2021-02-09 22:34, Terry Reedy wrote: > On 2/9/2021 3:39 PM, dn via Python-list wrote: >> On 09/02/2021 15.13, Juan Jose Reyna Figuera wrote: > >> [ Translation: >> matplotlib (and seaborn) not playing-nicely with Python 3.9 64-bit >> edition on MS-Win 10. Solved by down-grading to Python 3.8 32-bit. >> ] >> >> >> Yes, there have been problems with certain libraries that have not (yet) >> been updated to run on Python 3.9. Your solution is the current advice. > > I checked that seaborn lists 3.9. To my surprise, matplotlib does not. > If real, not good, and indeed, using 3.8 is the only solution. A > traceback from matplotlib failing might have revealed the specific problem. > Christoph Gohlke's site appears to have it: https://www.lfd.uci.edu/~gohlke/pythonlibs/#matplotlib From hfollmann at itcfollmann.com Wed Feb 10 07:20:01 2021 From: hfollmann at itcfollmann.com (Henning Follmann) Date: Wed, 10 Feb 2021 07:20:01 -0500 Subject: Best practices for software architecture in Python References: <602397a3$0$12711$426a74cc@news.free.fr> Message-ID: On 2021-02-10, Python wrote: > Hi, > > If you had to train engineers who are used to write > Python scripts for image processing, data format conversion, > etc. (so they know most the basics of Python types and > programming structures except advanced OOP techniques) > who now are about to develop quite a big application > in the same field (to get rid of some well known proprietary > scientific software monoliths), and would like to study in-depth > an existing open source application in order to study how > to organize classes hierarchy, modules, packages, etc. which > one would you recommend ? > > P. Looks like you (the project leader?) needs training, not the software engineers. "Making Things Happen" by Scott Berkun -H -- Henning Follmann | hfollmann at itcfollmann.com From mats at wichmann.us Wed Feb 10 09:11:55 2021 From: mats at wichmann.us (Mats Wichmann) Date: Wed, 10 Feb 2021 07:11:55 -0700 Subject: installation issues In-Reply-To: References: Message-ID: On 2/9/21 4:23 PM, Martin Lopez wrote: > Hello, > > My name is Martin Lopez. I just downloaded Python 3.9.1 (64 bit) Setup. > > After I install the program then try to run it, with no success. > > I've uninstalled all previous versions and reinstalled them, but it does > not seem to help. > > Can you please assist? This is going to sound rude, but is not intended that way: No, we can't help because you've given no information. Seemingly, you've had previous versions of Python working (it's not necessary to uninstall them to add a new one). What is different? What is the symptom of "no success". From rlleravega at gmail.com Wed Feb 10 09:26:42 2021 From: rlleravega at gmail.com (Rafael Llera) Date: Wed, 10 Feb 2021 10:26:42 -0400 Subject: Running Jupyter Notebook Message-ID: I installed Python and jupyter via pip, but when I run jupyter notebook I keep getting the following error. Requirement already satisfied: pyparsing>=2.0.2 in c:\users\mitzi\appdata\roaming\python\python39\site-packages (from packaging->bleach->nbconvert->jupyter) (2.4.7) Requirement already satisfied: qtpy in c:\users\mitzi\appdata\roaming\python\python39\site-packages (from qtconsole->jupyter) (1.9.0) C:\WINDOWS\system32>jupyter notebook 'jupyter' is not recognized as an internal or external command, operable program or batch file. C:\WINDOWS\system32> From sapna.intell at gmail.com Wed Feb 10 10:34:26 2021 From: sapna.intell at gmail.com (Priya Singh) Date: Wed, 10 Feb 2021 07:34:26 -0800 (PST) Subject: Very starnge problem in python Message-ID: <4384c28d-4193-4746-8524-3f70ddf5d9cdn@googlegroups.com> def closset_match(check, arr, itr): id_min = [] for ii in range(itr): id_min_tmp = np.argmin( abs(arr - check) ) id_min.append(id_min_tmp) arr[id_min_tmp] = float('-inf') id_min = np.array(id_min) return id_min def get_match(arr1, arr2, tol, itr): tt = arr2 for ii in range(5,6): id_com = np.where( abs(arr1[ii] - tt) < tol )[0] if np.size(id_com) >= itr: mm = closset_match(arr1[ii], tt[id_com], itr) id_ttt = np.array(id_com)[mm] #print(id_ttt) print(arr2[id_ttt]) tt[id_ttt] = 0.0 ########-9999.9 ###float('-inf') print(arr2[id_ttt]) This is the two routines I am using to compare the two float arrays and getting the matching in them up to some tolerance. The very strange thing which is happening here is you see variable arr2 at ID id_ttt before changing the variable tt at the same ID (i.e. id_ttt]) is showing some value but once I am printing its value after assigning tt[id_ttt] = 0.0, arr2[id_ttt] is also showing 0 value however, I have not touched arr2 anywhere as far as changing its values are concerned. Can any one please help me. From david at lowryduda.com Wed Feb 10 11:38:07 2021 From: david at lowryduda.com (David Lowry-Duda) Date: Wed, 10 Feb 2021 11:38:07 -0500 Subject: Very starnge problem in python In-Reply-To: <4384c28d-4193-4746-8524-3f70ddf5d9cdn@googlegroups.com> References: <4384c28d-4193-4746-8524-3f70ddf5d9cdn@googlegroups.com> Message-ID: Hello! > The very strange thing which is happening here is you see variable > arr2 at ID id_ttt before changing the variable tt at the same ID (i.e. > id_ttt]) is showing some value but once I am printing its value after > assigning tt[id_ttt] = 0.0, arr2[id_ttt] is also showing 0 value > however, I have not touched arr2 anywhere as far as changing its > values are concerned. The relevant lines are these: > def get_match(arr1, arr2, tol, itr): > tt = arr2 In python, this assignment doesn't make a copy, it makes `tt` and `arr2` refer to the same list. You can examine this with this little code. ``` arr = [1, 2, 3] arr_other = arr arr_other[1] = "different" print(arr_other) # This line prints the same print(arr) # array as this line. ``` Thus when you assign `tt = arr2`, modifying `tt` will modify `arr2`, and vice-versa. Cheers - DLD -- David Lowry-Duda From bluebox03 at gmail.com Wed Feb 10 12:35:28 2021 From: bluebox03 at gmail.com (tommy yama) Date: Thu, 11 Feb 2021 02:35:28 +0900 Subject: Running Jupyter Notebook In-Reply-To: References: Message-ID: Hi, Have you tried this? python -m notebook On Wed, Feb 10, 2021 at 11:28 PM Rafael Llera wrote: > I installed Python and jupyter via pip, but when I run jupyter notebook I > keep getting the following error. > > Requirement already satisfied: pyparsing>=2.0.2 in > c:\users\mitzi\appdata\roaming\python\python39\site-packages (from > packaging->bleach->nbconvert->jupyter) (2.4.7) > Requirement already satisfied: qtpy in > c:\users\mitzi\appdata\roaming\python\python39\site-packages (from > qtconsole->jupyter) (1.9.0) > > C:\WINDOWS\system32>jupyter notebook > 'jupyter' is not recognized as an internal or external command, > operable program or batch file. > > C:\WINDOWS\system32> > -- > https://mail.python.org/mailman/listinfo/python-list > From ming at pgp.cool Tue Feb 9 23:26:39 2021 From: ming at pgp.cool (Ming) Date: Wed, 10 Feb 2021 12:26:39 +0800 Subject: installation issues In-Reply-To: References: Message-ID: <20210210042634.GA15@pgp.cool> On Tue, Feb 09, 2021 at 03:23:56PM -0800, Martin Lopez wrote: > Hello, > > My name is Martin Lopez. I just downloaded Python 3.9.1 (64 bit) Setup. > > After I install the program then try to run it, with no success. > > I've uninstalled all previous versions and reinstalled them, but it does > not seem to help. > > Can you please assist? > > Thank you, How did you run it? Are there any error messages? If there is not enough information, no one can help you solve the issues. Personal guess: Did you not add python.exe to the Path environment variable? (You can check this option during the installation process to let the installer add it for you, or you can add it manually after the installation is complete) -- OpenPGP fingerprint: 3C47 5977 4819 267E DD64 C7E4 6332 5675 A739 C74E -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From tjreedy at udel.edu Wed Feb 10 13:14:49 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 10 Feb 2021 13:14:49 -0500 Subject: Running Jupyter Notebook In-Reply-To: References: Message-ID: On 2/10/2021 9:26 AM, Rafael Llera wrote: > I installed Python and jupyter via pip, but when I run jupyter notebook I > keep getting the following error. > > Requirement already satisfied: pyparsing>=2.0.2 in > c:\users\mitzi\appdata\roaming\python\python39\site-packages (from > packaging->bleach->nbconvert->jupyter) (2.4.7) > Requirement already satisfied: qtpy in > c:\users\mitzi\appdata\roaming\python\python39\site-packages (from > qtconsole->jupyter) (1.9.0) > > C:\WINDOWS\system32>jupyter notebook > 'jupyter' is not recognized as an internal or external command, > operable program or batch file. When you install some software, it is a good idea to read at least a basic introduction as to how to use it, especially when your naive efforts fail. https://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/index.html PS: Running commands in the system32 directory or anything in C:\Windows is a bad idea since you might accidentally change something so something no longer works properly. -- Terry Jan Reedy From jpic at yourlabs.org Wed Feb 10 18:05:54 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 00:05:54 +0100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: > Most of us know of the perils of mutable default values. And those who don't pay the price. I wonder what would be the harm in removing them, or doing copy on call by default. From rosuav at gmail.com Wed Feb 10 18:29:54 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Feb 2021 10:29:54 +1100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: On Thu, Feb 11, 2021 at 10:17 AM J. Pic wrote: > > > Most of us know of the perils of mutable default values. > > And those who don't pay the price. > > I wonder what would be the harm in removing them Define "removing". Most objects in Python are mutable; would that mean you can no longer use any custom class, or any object at all that has a __dict__, as a default? > or doing copy on call by default. I assume you are referring only to argument defaults, because copy-on-call for ALL parameters would be ridiculously costly, not to mention problematic in many ways. The main problem is that mutable defaults are only very rarely an issue (for starters, you have to actually mutate the object - just because it's mutable, that doesn't mean you'll change anything), but any global "solution" to the "problem" is going to have a very high global cost. Not every mutable object is copyable. And it would have to be a deep copy (in case, for instance, the default is a tuple containing a list), which has even more cost. Strongly -1 on any proposal to change the defaults. Now, if you're interested in some kind of proposal for opt-in late-bound defaults, I think there'd be some value in researching that. It would probably require language support, but there'd be a few potential advantages: 1) The function signature would actually say the real default. For instance, "def flurble(stuff=[]):" shows that the default is a list, but "def flurble(stuff=None): if stuff is None: stuff = []" doesn't. 2) This could be more flexible than just copying. The default could simply be an expression that's evaluated at call time, and could even refer to other arguments (eg "def frob(things, start=0, stop=len(things)):"), and, again, the displayed signature would show the real default, instead of some placeholder. 3) It's far cleaner to read a coherent function signature than to have to read a handful of lines at the top of the function. That's why we have defaults in the first place. But this would depend heavily on finding a really good syntax for it. It's been investigated at times, but no proposal has ever been strong enough to push forward. Feel free to try a few things out, see if you can find something that makes sense. ChrisA From pbryan at anode.ca Wed Feb 10 20:43:55 2021 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 11 Feb 2021 01:43:55 +0000 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> Message-ID: <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Also -1 on changing the existing default behavior. +1 to an opt-in late-bound solution. On Thu, 2021-02-11 at 10:29 +1100, Chris Angelico wrote: > On Thu, Feb 11, 2021 at 10:17 AM J. Pic wrote: > > > > > Most of us know of the perils of mutable default values. > > > > And those who don't pay the price. > > > > I wonder what would be the harm in removing them > > Define "removing". Most objects in Python are mutable; would that > mean > you can no longer use any custom class, or any object at all that has > a __dict__, as a default? > > > or doing copy on call by default. > > I assume you are referring only to argument defaults, because > copy-on-call for ALL parameters would be ridiculously costly, not to > mention problematic in many ways. > > The main problem is that mutable defaults are only very rarely an > issue (for starters, you have to actually mutate the object - just > because it's mutable, that doesn't mean you'll change anything), but > any global "solution" to the "problem" is going to have a very high > global cost. Not every mutable object is copyable. And it would have > to be a deep copy (in case, for instance, the default is a tuple > containing a list), which has even more cost. > > Strongly -1 on any proposal to change the defaults. > > Now, if you're interested in some kind of proposal for opt-in > late-bound defaults, I think there'd be some value in researching > that. It would probably require language support, but there'd be a > few > potential advantages: > > 1) The function signature would actually say the real default. For > instance, "def flurble(stuff=[]):" shows that the default is a list, > but "def flurble(stuff=None): if stuff is None: stuff = []" doesn't. > 2) This could be more flexible than just copying. The default could > simply be an expression that's evaluated at call time, and could even > refer to other arguments (eg "def frob(things, start=0, > stop=len(things)):"), and, again, the displayed signature would show > the real default, instead of some placeholder. > 3) It's far cleaner to read a coherent function signature than to > have > to read a handful of lines at the top of the function. That's why we > have defaults in the first place. > > But this would depend heavily on finding a really good syntax for it. > It's been investigated at times, but no proposal has ever been strong > enough to push forward. Feel free to try a few things out, see if you > can find something that makes sense. > > ChrisA From jpic at yourlabs.org Wed Feb 10 20:56:43 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 02:56:43 +0100 Subject: Mutable defaults In-Reply-To: <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: I just meant removing the whole "default value mutating" story, not removing mutable variables. Really, I was wondering if there was a use case where this actually turns to an advantage, in which case it would be a designed feature rather than an undesirable side effect, which it seems to be. Now I'm wondering if you have considered copy on write, to save the overhead from copying every mutable default at every call when it is not necessary. Le jeu. 11 f?vr. 2021 ? 02:46, Paul Bryan a ?crit : > Also -1 on changing the existing default behavior. +1 to an opt-in > late-bound solution. > > On Thu, 2021-02-11 at 10:29 +1100, Chris Angelico wrote: > > On Thu, Feb 11, 2021 at 10:17 AM J. Pic wrote: > > > > > > > Most of us know of the perils of mutable default values. > > > > > > And those who don't pay the price. > > > > > > I wonder what would be the harm in removing them > > > > Define "removing". Most objects in Python are mutable; would that > > mean > > you can no longer use any custom class, or any object at all that has > > a __dict__, as a default? > > > > > or doing copy on call by default. > > > > I assume you are referring only to argument defaults, because > > copy-on-call for ALL parameters would be ridiculously costly, not to > > mention problematic in many ways. > > > > The main problem is that mutable defaults are only very rarely an > > issue (for starters, you have to actually mutate the object - just > > because it's mutable, that doesn't mean you'll change anything), but > > any global "solution" to the "problem" is going to have a very high > > global cost. Not every mutable object is copyable. And it would have > > to be a deep copy (in case, for instance, the default is a tuple > > containing a list), which has even more cost. > > > > Strongly -1 on any proposal to change the defaults. > > > > Now, if you're interested in some kind of proposal for opt-in > > late-bound defaults, I think there'd be some value in researching > > that. It would probably require language support, but there'd be a > > few > > potential advantages: > > > > 1) The function signature would actually say the real default. For > > instance, "def flurble(stuff=[]):" shows that the default is a list, > > but "def flurble(stuff=None): if stuff is None: stuff = []" doesn't. > > 2) This could be more flexible than just copying. The default could > > simply be an expression that's evaluated at call time, and could even > > refer to other arguments (eg "def frob(things, start=0, > > stop=len(things)):"), and, again, the displayed signature would show > > the real default, instead of some placeholder. > > 3) It's far cleaner to read a coherent function signature than to > > have > > to read a handful of lines at the top of the function. That's why we > > have defaults in the first place. > > > > But this would depend heavily on finding a really good syntax for it. > > It's been investigated at times, but no proposal has ever been strong > > enough to push forward. Feel free to try a few things out, see if you > > can find something that makes sense. > > > > ChrisA > > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Wed Feb 10 21:02:53 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Feb 2021 13:02:53 +1100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: On Thu, Feb 11, 2021 at 12:56 PM J. Pic wrote: > > I just meant removing the whole "default value mutating" story, not removing mutable variables. Really, I was wondering if there was a use case where this actually turns to an advantage, in which case it would be a designed feature rather than an undesirable side effect, which it seems to be. > Right, I know you weren't asking about removing mutables altogether. But how would you remove "default value mutating"? Do you disallow any mutable values from being argument defaults? Because that's a huge category of values that are no longer available. Mutable defaults most certainly ARE used deliberately, although often it's more as a sort of "static variable" rather than actually a parameter. But it's common enough as an idiom that it can't be changed without breaking a lot of code. > Now I'm wondering if you have considered copy on write, to save the overhead from copying every mutable default at every call when it is not necessary. > That's its own level of mess. The only way to move forward with this is something backward-compatible, which probably means an explicit request for late binding (or copying, which comes to much the same thing). But it needs an elegant syntax. The proposal lives or dies on that syntax, and so far, it's always died. ChrisA From jamtlu at gmail.com Wed Feb 10 21:51:16 2021 From: jamtlu at gmail.com (James Lu) Date: Wed, 10 Feb 2021 21:51:16 -0500 Subject: Python subinterpreters with separate GILs Message-ID: Directly removing the Global Interpreter Lock (GIL) would break a lot of libraries that implicitly assume it is there. What if Python had "realms" that each had separate GILs? The "realms" (not sure if "subinterpreter" is the correct term here) could share objects. From jpic at yourlabs.org Wed Feb 10 21:54:55 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 03:54:55 +0100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: Adding decorators with some inspect sauce could certainly work with the syntax we already have: @default(x=lambda: copy([]), y=lambda x: len(x)) def foo(x=None, y=None): I think this PoC is doable. But the lambda copy is a boring so, two decorators: @default.copy(x=[]) @default.call(y=lamba x: len(x)) def foo(x=None, y=None): Or with a new syntax: def foo(x:=[], y`=len(x)) Here walrus is used to denote that an assignment of the right side is going to take place at call, and the backtick to denote that execution of the right side is going to take place. Le jeu. 11 f?vr. 2021 ? 03:06, Chris Angelico a ?crit : > On Thu, Feb 11, 2021 at 12:56 PM J. Pic wrote: > > > > I just meant removing the whole "default value mutating" story, not > removing mutable variables. Really, I was wondering if there was a use case > where this actually turns to an advantage, in which case it would be a > designed feature rather than an undesirable side effect, which it seems to > be. > > > > Right, I know you weren't asking about removing mutables altogether. > But how would you remove "default value mutating"? Do you disallow any > mutable values from being argument defaults? Because that's a huge > category of values that are no longer available. > > Mutable defaults most certainly ARE used deliberately, although often > it's more as a sort of "static variable" rather than actually a > parameter. But it's common enough as an idiom that it can't be changed > without breaking a lot of code. > > > Now I'm wondering if you have considered copy on write, to save the > overhead from copying every mutable default at every call when it is not > necessary. > > > > That's its own level of mess. > > The only way to move forward with this is something > backward-compatible, which probably means an explicit request for late > binding (or copying, which comes to much the same thing). But it needs > an elegant syntax. The proposal lives or dies on that syntax, and so > far, it's always died. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From jpic at yourlabs.org Wed Feb 10 21:58:17 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 03:58:17 +0100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: Silly me, we don't even need copy but just execution @lazy(x=lambda: [], y=lamba x: len(x)) def foo(x=None, y=None): So only one operator is needed, the walrus is still fine: def foo(x:=[], y:=len(x)): Not copy, just evaluate. Le jeu. 11 f?vr. 2021 ? 03:54, J. Pic a ?crit : > Adding decorators with some inspect sauce could certainly work with the > syntax we already have: > > @default(x=lambda: copy([]), y=lambda x: len(x)) > def foo(x=None, y=None): > > I think this PoC is doable. But the lambda copy is a boring so, two > decorators: > > @default.copy(x=[]) > @default.call(y=lamba x: len(x)) > def foo(x=None, y=None): > > Or with a new syntax: > > def foo(x:=[], y`=len(x)) > > Here walrus is used to denote that an assignment of the right side is > going to take place at call, and the backtick to denote that execution of > the right side is going to take place. > > Le jeu. 11 f?vr. 2021 ? 03:06, Chris Angelico a ?crit : > >> On Thu, Feb 11, 2021 at 12:56 PM J. Pic wrote: >> > >> > I just meant removing the whole "default value mutating" story, not >> removing mutable variables. Really, I was wondering if there was a use case >> where this actually turns to an advantage, in which case it would be a >> designed feature rather than an undesirable side effect, which it seems to >> be. >> > >> >> Right, I know you weren't asking about removing mutables altogether. >> But how would you remove "default value mutating"? Do you disallow any >> mutable values from being argument defaults? Because that's a huge >> category of values that are no longer available. >> >> Mutable defaults most certainly ARE used deliberately, although often >> it's more as a sort of "static variable" rather than actually a >> parameter. But it's common enough as an idiom that it can't be changed >> without breaking a lot of code. >> >> > Now I'm wondering if you have considered copy on write, to save the >> overhead from copying every mutable default at every call when it is not >> necessary. >> > >> >> That's its own level of mess. >> >> The only way to move forward with this is something >> backward-compatible, which probably means an explicit request for late >> binding (or copying, which comes to much the same thing). But it needs >> an elegant syntax. The proposal lives or dies on that syntax, and so >> far, it's always died. >> >> ChrisA >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From rosuav at gmail.com Wed Feb 10 22:00:35 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Feb 2021 14:00:35 +1100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: On Thu, Feb 11, 2021 at 1:55 PM J. Pic wrote: > > Adding decorators with some inspect sauce could certainly work with the syntax we already have: > > @default(x=lambda: copy([]), y=lambda x: len(x)) > def foo(x=None, y=None): This would work, although the copy is unnecessary here. But you're assuming that it magically figures out whether to pass 'x' or not. Seems awkward. Also, it doesn't solve the problems of signature display, so you're not really much better than: def foo(x=None, y=None): if x is None: x = [] if y is None: y = len(x) > I think this PoC is doable. But the lambda copy is a boring so, two decorators: > > @default.copy(x=[]) > @default.call(y=lamba x: len(x)) > def foo(x=None, y=None): > > Or with a new syntax: > > def foo(x:=[], y`=len(x)) Now this is the sort of thing I was talking about: actual syntactic support. But this syntax looks pretty terrible, and if you propose it like this, I doubt it'll be accepted. Backtick had a very very different meaning in Py2, and := is going to be extremely confusing. This proposal will stand or fall on the syntax. Don't just give placeholder syntax. Put some thought into figuring out what would actually be good, and propose *that*. The semantics aren't really even that hard - it'd be equivalent to an if statement just inside the function. ChrisA From jpic at yourlabs.org Wed Feb 10 22:16:10 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 04:16:10 +0100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: Ok, maybe: def foo(x=:[], y=:len(x)): As a shorthand for: @default(x=lambda: [], y=lambda x: len(x)) def foo(x=None, y=None): =: Is the contraction for =lambda: At the same time, this new syntax avoid breaking def foo(x=lamba: []) which is completely different as we know. Le jeu. 11 f?vr. 2021 ? 04:03, Chris Angelico a ?crit : > On Thu, Feb 11, 2021 at 1:55 PM J. Pic wrote: > > > > Adding decorators with some inspect sauce could certainly work with the > syntax we already have: > > > > @default(x=lambda: copy([]), y=lambda x: len(x)) > > def foo(x=None, y=None): > > This would work, although the copy is unnecessary here. But you're > assuming that it magically figures out whether to pass 'x' or not. > Seems awkward. Also, it doesn't solve the problems of signature > display, so you're not really much better than: > > def foo(x=None, y=None): > if x is None: x = [] > if y is None: y = len(x) > > > I think this PoC is doable. But the lambda copy is a boring so, two > decorators: > > > > @default.copy(x=[]) > > @default.call(y=lamba x: len(x)) > > def foo(x=None, y=None): > > > > Or with a new syntax: > > > > def foo(x:=[], y`=len(x)) > > Now this is the sort of thing I was talking about: actual syntactic > support. But this syntax looks pretty terrible, and if you propose it > like this, I doubt it'll be accepted. Backtick had a very very > different meaning in Py2, and := is going to be extremely confusing. > > This proposal will stand or fall on the syntax. Don't just give > placeholder syntax. Put some thought into figuring out what would > actually be good, and propose *that*. The semantics aren't really even > that hard - it'd be equivalent to an if statement just inside the > function. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From cs at cskk.id.au Wed Feb 10 23:22:35 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 11 Feb 2021 15:22:35 +1100 Subject: Python subinterpreters with separate GILs In-Reply-To: References: Message-ID: On 10Feb2021 21:51, James Lu wrote: >Directly removing the Global Interpreter Lock (GIL) would break a lot >of libraries that implicitly assume it is there. What if Python had >"realms" that each had separate GILs? > >The "realms" (not sure if "subinterpreter" is the correct term here) >could share objects. If realms can shared objects then they'd need the same GIL, because otherwise objects are not protected from concurrency via different realms. CPython code and C code, unless it has itself released the GIL, assumes it is the exclusive user of objects - that's what the GIL means. Separate GILs would mean different realms' GIL-holding threads could run against a shared object at the same time. Cheers, Cameron Simpson From christian at python.org Thu Feb 11 00:21:49 2021 From: christian at python.org (Christian Heimes) Date: Thu, 11 Feb 2021 06:21:49 +0100 Subject: Python subinterpreters with separate GILs In-Reply-To: References: Message-ID: On 11/02/2021 03.51, James Lu wrote: > Directly removing the Global Interpreter Lock (GIL) would break a lot > of libraries that implicitly assume it is there. What if Python had > "realms" that each had separate GILs? > > The "realms" (not sure if "subinterpreter" is the correct term here) > could share objects. Eric Snow and others have been working on that since 2017, https://www.python.org/dev/peps/pep-0554/ From robert.nicholson at gmail.com Wed Feb 10 16:21:34 2021 From: robert.nicholson at gmail.com (Robert Nicholson) Date: Wed, 10 Feb 2021 15:21:34 -0600 Subject: Why am I unable to using rsync to install modules and appear to have to use pip install instead? Message-ID: I?m using Python 3.7.0 so I have multiple environments all on the same architecture with the same python release using anonconda. What I discovered was that if I install the cryptography module in my dev / uat and then tried to synchronize to production server using rsync I ended up with errors relating to dependencies of the cryptography module. Specifically Cannot import name ?_get_backend? these errors appear to have gone away if I actually use pip install cryptography==3.2.1 instead of using rsync from an existing install machine. why is this the case? From robert.nicholson at gmail.com Wed Feb 10 16:40:56 2021 From: robert.nicholson at gmail.com (Robert Nicholson) Date: Wed, 10 Feb 2021 15:40:56 -0600 Subject: Why am I unable to using rsync to install modules and appear to have to use pip install instead? In-Reply-To: References: Message-ID: Just reinstalling cryptography with pip install seems to have fixed my issue. Any pointers on why? > On Feb 10, 2021, at 3:21 PM, Robert Nicholson wrote: > > I?m using Python 3.7.0 > > so I have multiple environments all on the same architecture with the same python release using anonconda. > > What I discovered was that if I install the cryptography module in my dev / uat and then tried to synchronize to production server using rsync I ended up with errors relating to dependencies of the cryptography module. > > Specifically > > Cannot import name ?_get_backend? > > these errors appear to have gone away if I actually use pip install cryptography==3.2.1 instead of using rsync from an existing install machine. > > why is this the case? > > > From robert.nicholson at gmail.com Wed Feb 10 17:38:45 2021 From: robert.nicholson at gmail.com (Robert Nicholson) Date: Wed, 10 Feb 2021 16:38:45 -0600 Subject: Why am I unable to using rsync to install modules and appear to have to use pip install instead? In-Reply-To: References: Message-ID: <85111CBD-A012-4731-B77D-39530CB53F40@gmail.com> Ok this was due to an install of miniconda then choosing to unconditionally install an older version of cryptography. > On Feb 10, 2021, at 3:40 PM, Robert Nicholson wrote: > > Just reinstalling cryptography with pip install seems to have fixed my issue. > > Any pointers on why? > >> On Feb 10, 2021, at 3:21 PM, Robert Nicholson wrote: >> >> I?m using Python 3.7.0 >> >> so I have multiple environments all on the same architecture with the same python release using anonconda. >> >> What I discovered was that if I install the cryptography module in my dev / uat and then tried to synchronize to production server using rsync I ended up with errors relating to dependencies of the cryptography module. >> >> Specifically >> >> Cannot import name ?_get_backend? >> >> these errors appear to have gone away if I actually use pip install cryptography==3.2.1 instead of using rsync from an existing install machine. >> >> why is this the case? >> >> >> > From grant.b.edwards at gmail.com Wed Feb 10 21:22:13 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 11 Feb 2021 02:22:13 -0000 (UTC) Subject: Mutable defaults References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: On 2021-02-11, J. Pic wrote: > I just meant removing the whole "default value mutating" story, not > removing mutable variables. Really, I was wondering if there was a use case > where this actually turns to an advantage, I've seen people show how it can be used to provide function-scope persistent storage -- the equivalent of declaring a static variable in a C function. I don't think I've seen that done in the wild, though. class StaticStorage(): pass def foo(static=StaticStorage()): if not hasattr(static,'x'): static.x = 0 static.x += 1 return static.x print(foo()) print(foo()) print(foo()) print(foo()) print(foo()) Run that, and it prints: 1 2 3 4 5 From rzzzwilson at gmail.com Thu Feb 11 02:02:21 2021 From: rzzzwilson at gmail.com (Ross Wilson) Date: Thu, 11 Feb 2021 14:02:21 +0700 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: On Thu, 11 Feb 2564 BE at 12:52 Grant Edwards wrote: > On 2021-02-11, J. Pic wrote: > > > I just meant removing the whole "default value mutating" story, not > > removing mutable variables. Really, I was wondering if there was a use > case > > where this actually turns to an advantage, > > I've seen people show how it can be used to provide function-scope > persistent storage -- the equivalent of declaring a static variable in > a C function. I don't think I've seen that done in the wild, though. Not sure this qualifies as "use in the wild", but the memoized naive Fibonacci is very nice when written this way: def fib(n, memo={0: 0, 1: 1}): if n not in memo: memo[n] = fib(n-1) + fib(n-2) return memo[n] From rosuav at gmail.com Thu Feb 11 02:34:50 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 11 Feb 2021 18:34:50 +1100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: On Thu, Feb 11, 2021 at 6:03 PM Ross Wilson wrote: > > On Thu, 11 Feb 2564 BE at 12:52 Grant Edwards > wrote: > > > On 2021-02-11, J. Pic wrote: > > > > > I just meant removing the whole "default value mutating" story, not > > > removing mutable variables. Really, I was wondering if there was a use > > case > > > where this actually turns to an advantage, > > > > I've seen people show how it can be used to provide function-scope > > persistent storage -- the equivalent of declaring a static variable in > > a C function. I don't think I've seen that done in the wild, though. > > > Not sure this qualifies as "use in the wild", but the memoized naive > Fibonacci is very nice when written this way: > > def fib(n, memo={0: 0, 1: 1}): > if n not in memo: > memo[n] = fib(n-1) + fib(n-2) > return memo[n] Yep, that's a pretty elegant example of mutable defaults as statics. In theory, you could use this for a Fibonacci-like sequence, just by passing an appropriate memo dictionary; to make that work, the recursive calls would have to pass that down the line. # What comes next in the sequence 1 3 4 7 11? fib(6, {1:1, 2:3}) But otherwise, the memo parameter isn't really being used as a parameter, it's just a way to maintain state. It could just as easily be a global, a closure cell, or anything else. ChrisA From jpic at yourlabs.org Thu Feb 11 05:59:11 2021 From: jpic at yourlabs.org (J. Pic) Date: Thu, 11 Feb 2021 11:59:11 +0100 Subject: Mutable defaults In-Reply-To: References: <290c56f1-6ac8-0c95-0112-432d63256b9f@vub.be> <010d01778ec25042-eda74339-c6ce-40c8-a5c9-fe946a392987-000000@ca-central-1.amazonses.com> Message-ID: Thank you, if anybody finds such an example in the wild where using a mutable default is actually better than a global or closure I would be happy to learn about it! About the proposal, this is a quick PoC of the @default decorator: import inspect def default(**defaults): def decorator(func): def wrapper(*args, **kwargs): signature = inspect.signature(func) bound = signature.bind(*args, **kwargs) for key, value in defaults.items(): if key in bound.arguments: continue defaultsig = inspect.signature(value) defaultargs = { k: v for k, v in bound.arguments.items() if k in defaultsig.parameters } bound.arguments[key] = value(**defaultargs) return func(*bound.args, **bound.kwargs) return wrapper return decorator @default(x=lambda: [], y=lambda x: len(x)) def foo(x=None, y=None): return x, y assert foo() == ([], 0) assert foo([1]) == ([1], 1) assert foo(y=2) == ([], 2) assert foo(y=2, x=[2]) == ([2], 2) It seems pretty obvious to have this shorthand syntax: def foo (x=default: [], y=default: len(x)): =default: defines a lambda returning the default value to use for a keyword argument. We can't use x=lambda: here because that would define a lambda as default argument, so that's why we *need* another keyword. Also, note that it gets the any other bound argument as parameter so far from left to right, which makes y=default: len(x) possible. =: is the contraction, proposing an even simpler syntax: def foo (x=:[], y=:len(x)): Chris, I understand your concerns about having arguments in there, but I'd like to try to defend y=:len(x) for a bit because I really like your idea, I think this is pythonic and will contribute to justify this feature and keep python apart from other languages by offering more powerful and expressive syntax than alternatives. Le jeu. 11 f?vr. 2021 ? 08:38, Chris Angelico a ?crit : > On Thu, Feb 11, 2021 at 6:03 PM Ross Wilson wrote: > > > > On Thu, 11 Feb 2564 BE at 12:52 Grant Edwards > > > wrote: > > > > > On 2021-02-11, J. Pic wrote: > > > > > > > I just meant removing the whole "default value mutating" story, not > > > > removing mutable variables. Really, I was wondering if there was a > use > > > case > > > > where this actually turns to an advantage, > > > > > > I've seen people show how it can be used to provide function-scope > > > persistent storage -- the equivalent of declaring a static variable in > > > a C function. I don't think I've seen that done in the wild, though. > > > > > > Not sure this qualifies as "use in the wild", but the memoized naive > > Fibonacci is very nice when written this way: > > > > def fib(n, memo={0: 0, 1: 1}): > > if n not in memo: > > memo[n] = fib(n-1) + fib(n-2) > > return memo[n] > > Yep, that's a pretty elegant example of mutable defaults as statics. > In theory, you could use this for a Fibonacci-like sequence, just by > passing an appropriate memo dictionary; to make that work, the > recursive calls would have to pass that down the line. > > # What comes next in the sequence 1 3 4 7 11? > fib(6, {1:1, 2:3}) > > But otherwise, the memo parameter isn't really being used as a > parameter, it's just a way to maintain state. It could just as easily > be a global, a closure cell, or anything else. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From jornws200602 at xs4all.nl Thu Feb 11 07:10:21 2021 From: jornws200602 at xs4all.nl (Oscar) Date: 11 Feb 2021 12:10:21 GMT Subject: Best practices for software architecture in Python References: <602397a3$0$12711$426a74cc@news.free.fr> Message-ID: <60251ead$0$27902$e4fe514c@news.xs4all.nl> In article , Henning Follmann wrote: >On 2021-02-10, Python wrote: >> Hi, >> >> If you had to train engineers who are used to write >> Python scripts for image processing, data format conversion, >> etc. (so they know most the basics of Python types and >> programming structures except advanced OOP techniques) >> who now are about to develop quite a big application >> in the same field (to get rid of some well known proprietary >> scientific software monoliths), and would like to study in-depth >> an existing open source application in order to study how >> to organize classes hierarchy, modules, packages, etc. which >> one would you recommend ? >> >> P. > >Looks like you (the project leader?) needs training, not the >software engineers. > >"Making Things Happen" by Scott Berkun This looks like a very interesting book to add to my reading list, but how do you think it will help the OP with his/her quest? Of course your answer might just as well be: read the book! But since you clearly did that already, what knowledge did you gain that triggered this response? -- [J|O|R] <- .signature.gz From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 07:30:37 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 12:30:37 +0000 Subject: New Python implementation Message-ID: Hi! I am starting work on creating a new Python implementation from scratch using "neos" my universal compiler that can compile any programming language. I envision this implementation to be significantly faster than the currently extant Python implementations (which isn't a stretch given how poorly they perform). Sample neos session (parsing a fibonacci program, neoscript rather than Python in this case): neos 1.0.0.0 ED-209 ] help h(elp) s(chema) Load language schema l(oad) Load program list List program c(ompile) Compile program r(un) Run program ![] Evaluate expression (enter interactive mode if expression omitted) : Input (as stdin) q(uit) Quit neos lc List loaded concept libraries t(race) <0|1|2|3|4|5> [] Compiler trace m(etrics) Display metrics for running programs ] lc [neos.core] (file:///D:\code\neos\build\win32\vs2019\x64\Release\core.ncl) [neos.boolean] [neos.language] [neos.logic] [neos.math] [neos.module] [neos.object] [neos.string] [neos.math.universal] (file:///D:\code\neos\build\win32\vs2019\x64\Release\core.math.universal.ncl) ] s neoscript Loading schema 'neoscript'... Language: Default neoGFX scripting language Version: 1.0.0 Copyright (C) 2019 Leigh Johnston neoscript] l examples/neoscript/fibonacci.neo neoscript] list File 'examples/neoscript/fibonacci.neo': -- neoscript example: Fibonacci using neos.string; using neos.stream; import fn to_string(x : i32) -> string; import fn to_integer(s : string) -> i32; import proc input(s : out string); import proc print(s : in string); -- functions are pure def fn add(x, y : i32) -> i32 { return x + y; } def fn fib(x : i32) -> i32 { if (x < 2) return 1; else return add(fib(x-1), fib(x-2)); } -- procedures are impure def proc main() s : string; { print("Enter a positive " "integer: "); input(s); print("Fibonacci(" + s + ") = " + to_string(fib(to_integer(s))) + "\n"); } neoscript] t 1 neoscript] c folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) folding: string.utf8(g) <- string.utf8.character.alpha() folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) folding: string.utf8(gn) <- string.utf8.character.alpha() folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) folding: string.utf8(gni) <- string.utf8.character.alpha() folded: string.utf8(gni) <- string.utf8.character.alpha() = string.utf8(gnir) folding: string.utf8(gnir) <- string.utf8.character.alpha() folded: string.utf8(gnir) <- string.utf8.character.alpha() = string.utf8(gnirt) folding: string.utf8(gnirt) <- string.utf8.character.alpha() folded: string.utf8(gnirt) <- string.utf8.character.alpha() = string.utf8(gnirts) folding: string.utf8(gnirts) <- string.utf8.character.period() folded: string.utf8(gnirts) <- string.utf8.character.period() = string.utf8(gnirts.) folding: string.utf8(gnirts.) <- string.utf8.character.alpha() folded: string.utf8(gnirts.) <- string.utf8.character.alpha() = string.utf8(gnirts.s) folding: string.utf8(gnirts.s) <- string.utf8.character.alpha() folded: string.utf8(gnirts.s) <- string.utf8.character.alpha() = string.utf8(gnirts.so) folding: string.utf8(gnirts.so) <- string.utf8.character.alpha() folded: string.utf8(gnirts.so) <- string.utf8.character.alpha() = string.utf8(gnirts.soe) folding: string.utf8(gnirts.soe) <- string.utf8.character.alpha() folded: string.utf8(gnirts.soe) <- string.utf8.character.alpha() = string.utf8(gnirts.soen) folding: source.package.name() <- string.utf8(gnirts.soen) folded: source.package.name() <- string.utf8(gnirts.soen) = source.package.name(neos.string) folding: source.package.import() <- source.package.name(neos.string) folded: source.package.import() <- source.package.name(neos.string) = source.package.import(neos.string) folding: source.package.import(neos.string) <- source.package.import(neos.string) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) folding: string.utf8(g) <- string.utf8.character.alpha() folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) folding: string.utf8(gn) <- string.utf8.character.alpha() folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) folding: string.utf8(gni) <- string.utf8.character.alpha() folded: string.utf8(gni) <- string.utf8.character.alpha() = string.utf8(gnir) folding: string.utf8(gnir) <- string.utf8.character.alpha() folded: string.utf8(gnir) <- string.utf8.character.alpha() = string.utf8(gnirt) folding: string.utf8(gnirt) <- string.utf8.character.alpha() folded: string.utf8(gnirt) <- string.utf8.character.alpha() = string.utf8(gnirts) folding: string.utf8(gnirts) <- string.utf8.character.underscore() folded: string.utf8(gnirts) <- string.utf8.character.underscore() = string.utf8(gnirts_) folding: string.utf8(gnirts_) <- string.utf8.character.alpha() folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = string.utf8(gnirts_o) folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = string.utf8(gnirts_ot) folding: language.identifier() <- string.utf8(gnirts_ot) folded: language.identifier() <- string.utf8(gnirts_ot) = language.identifier(to_string) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) folding: string.utf8(r) <- string.utf8.character.alpha() folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) folding: string.utf8(re) <- string.utf8.character.alpha() folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) folding: string.utf8(reg) <- string.utf8.character.alpha() folded: string.utf8(reg) <- string.utf8.character.alpha() = string.utf8(rege) folding: string.utf8(rege) <- string.utf8.character.alpha() folded: string.utf8(rege) <- string.utf8.character.alpha() = string.utf8(reget) folding: string.utf8(reget) <- string.utf8.character.alpha() folded: string.utf8(reget) <- string.utf8.character.alpha() = string.utf8(regetn) folding: string.utf8(regetn) <- string.utf8.character.alpha() folded: string.utf8(regetn) <- string.utf8.character.alpha() = string.utf8(regetni) folding: string.utf8(regetni) <- string.utf8.character.underscore() folded: string.utf8(regetni) <- string.utf8.character.underscore() = string.utf8(regetni_) folding: string.utf8(regetni_) <- string.utf8.character.alpha() folded: string.utf8(regetni_) <- string.utf8.character.alpha() = string.utf8(regetni_o) folding: string.utf8(regetni_o) <- string.utf8.character.alpha() folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = string.utf8(regetni_ot) folding: language.identifier() <- string.utf8(regetni_ot) folded: language.identifier() <- string.utf8(regetni_ot) = language.identifier(to_integer) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folded: source.package.import(neos.string) <- source.package.import(neos.string) = () folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(m) folding: string.utf8(m) <- string.utf8.character.alpha() folded: string.utf8(m) <- string.utf8.character.alpha() = string.utf8(ma) folding: string.utf8(ma) <- string.utf8.character.alpha() folded: string.utf8(ma) <- string.utf8.character.alpha() = string.utf8(mae) folding: string.utf8(mae) <- string.utf8.character.alpha() folded: string.utf8(mae) <- string.utf8.character.alpha() = string.utf8(maer) folding: string.utf8(maer) <- string.utf8.character.alpha() folded: string.utf8(maer) <- string.utf8.character.alpha() = string.utf8(maert) folding: string.utf8(maert) <- string.utf8.character.alpha() folded: string.utf8(maert) <- string.utf8.character.alpha() = string.utf8(maerts) folding: string.utf8(maerts) <- string.utf8.character.period() folded: string.utf8(maerts) <- string.utf8.character.period() = string.utf8(maerts.) folding: string.utf8(maerts.) <- string.utf8.character.alpha() folded: string.utf8(maerts.) <- string.utf8.character.alpha() = string.utf8(maerts.s) folding: string.utf8(maerts.s) <- string.utf8.character.alpha() folded: string.utf8(maerts.s) <- string.utf8.character.alpha() = string.utf8(maerts.so) folding: string.utf8(maerts.so) <- string.utf8.character.alpha() folded: string.utf8(maerts.so) <- string.utf8.character.alpha() = string.utf8(maerts.soe) folding: string.utf8(maerts.soe) <- string.utf8.character.alpha() folded: string.utf8(maerts.soe) <- string.utf8.character.alpha() = string.utf8(maerts.soen) folding: source.package.name() <- string.utf8(maerts.soen) folded: source.package.name() <- string.utf8(maerts.soen) = source.package.name(neos.stream) folding: source.package.import() <- source.package.name(neos.stream) folded: source.package.import() <- source.package.name(neos.stream) = source.package.import(neos.stream) folding: source.package.import(neos.stream) <- source.package.import(neos.stream) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) folding: string.utf8(tu) <- string.utf8.character.alpha() folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) folding: string.utf8(tup) <- string.utf8.character.alpha() folded: string.utf8(tup) <- string.utf8.character.alpha() = string.utf8(tupn) folding: string.utf8(tupn) <- string.utf8.character.alpha() folded: string.utf8(tupn) <- string.utf8.character.alpha() = string.utf8(tupni) folding: language.identifier() <- string.utf8(tupni) folded: language.identifier() <- string.utf8(tupni) = language.identifier(input) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) folding: string.utf8(tn) <- string.utf8.character.alpha() folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) folding: string.utf8(tni) <- string.utf8.character.alpha() folded: string.utf8(tni) <- string.utf8.character.alpha() = string.utf8(tnir) folding: string.utf8(tnir) <- string.utf8.character.alpha() folded: string.utf8(tnir) <- string.utf8.character.alpha() = string.utf8(tnirp) folding: language.identifier() <- string.utf8(tnirp) folded: language.identifier() <- string.utf8(tnirp) = language.identifier(print) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folded: source.package.import(neos.stream) <- source.package.import(neos.stream) = () folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) folding: string.utf8(g) <- string.utf8.character.alpha() folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) folding: string.utf8(gn) <- string.utf8.character.alpha() folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) folding: string.utf8(gni) <- string.utf8.character.alpha() folded: string.utf8(gni) <- string.utf8.character.alpha() = string.utf8(gnir) folding: string.utf8(gnir) <- string.utf8.character.alpha() folded: string.utf8(gnir) <- string.utf8.character.alpha() = string.utf8(gnirt) folding: string.utf8(gnirt) <- string.utf8.character.alpha() folded: string.utf8(gnirt) <- string.utf8.character.alpha() = string.utf8(gnirts) folding: string.utf8(gnirts) <- string.utf8.character.underscore() folded: string.utf8(gnirts) <- string.utf8.character.underscore() = string.utf8(gnirts_) folding: string.utf8(gnirts_) <- string.utf8.character.alpha() folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = string.utf8(gnirts_o) folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = string.utf8(gnirts_ot) folding: language.identifier() <- string.utf8(gnirts_ot) folded: language.identifier() <- string.utf8(gnirts_ot) = language.identifier(to_string) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) folding: string.utf8(r) <- string.utf8.character.alpha() folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) folding: string.utf8(re) <- string.utf8.character.alpha() folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) folding: string.utf8(reg) <- string.utf8.character.alpha() folded: string.utf8(reg) <- string.utf8.character.alpha() = string.utf8(rege) folding: string.utf8(rege) <- string.utf8.character.alpha() folded: string.utf8(rege) <- string.utf8.character.alpha() = string.utf8(reget) folding: string.utf8(reget) <- string.utf8.character.alpha() folded: string.utf8(reget) <- string.utf8.character.alpha() = string.utf8(regetn) folding: string.utf8(regetn) <- string.utf8.character.alpha() folded: string.utf8(regetn) <- string.utf8.character.alpha() = string.utf8(regetni) folding: string.utf8(regetni) <- string.utf8.character.underscore() folded: string.utf8(regetni) <- string.utf8.character.underscore() = string.utf8(regetni_) folding: string.utf8(regetni_) <- string.utf8.character.alpha() folded: string.utf8(regetni_) <- string.utf8.character.alpha() = string.utf8(regetni_o) folding: string.utf8(regetni_o) <- string.utf8.character.alpha() folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = string.utf8(regetni_ot) folding: language.identifier() <- string.utf8(regetni_ot) folded: language.identifier() <- string.utf8(regetni_ot) = language.identifier(to_integer) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) folding: string.utf8(tu) <- string.utf8.character.alpha() folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) folding: string.utf8(tup) <- string.utf8.character.alpha() folded: string.utf8(tup) <- string.utf8.character.alpha() = string.utf8(tupn) folding: string.utf8(tupn) <- string.utf8.character.alpha() folded: string.utf8(tupn) <- string.utf8.character.alpha() = string.utf8(tupni) folding: language.identifier() <- string.utf8(tupni) folded: language.identifier() <- string.utf8(tupni) = language.identifier(input) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) folding: string.utf8(tn) <- string.utf8.character.alpha() folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) folding: string.utf8(tni) <- string.utf8.character.alpha() folded: string.utf8(tni) <- string.utf8.character.alpha() = string.utf8(tnir) folding: string.utf8(tnir) <- string.utf8.character.alpha() folded: string.utf8(tnir) <- string.utf8.character.alpha() = string.utf8(tnirp) folding: language.identifier() <- string.utf8(tnirp) folded: language.identifier() <- string.utf8(tnirp) = language.identifier(print) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(d) folding: string.utf8(d) <- string.utf8.character.alpha() folded: string.utf8(d) <- string.utf8.character.alpha() = string.utf8(dd) folding: string.utf8(dd) <- string.utf8.character.alpha() folded: string.utf8(dd) <- string.utf8.character.alpha() = string.utf8(dda) folding: language.identifier() <- string.utf8(dda) folded: language.identifier() <- string.utf8(dda) = language.identifier(add) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(y) folding: language.identifier() <- string.utf8(y) folded: language.identifier() <- string.utf8(y) = language.identifier(y) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(y) folding: language.identifier() <- string.utf8(y) folded: language.identifier() <- string.utf8(y) = language.identifier(y) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) folding: string.utf8(b) <- string.utf8.character.alpha() folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) folding: string.utf8(bi) <- string.utf8.character.alpha() folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) folding: language.identifier() <- string.utf8(bif) folded: language.identifier() <- string.utf8(bif) = language.identifier(fib) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(d) folding: string.utf8(d) <- string.utf8.character.alpha() folded: string.utf8(d) <- string.utf8.character.alpha() = string.utf8(dd) folding: string.utf8(dd) <- string.utf8.character.alpha() folded: string.utf8(dd) <- string.utf8.character.alpha() = string.utf8(dda) folding: language.identifier() <- string.utf8(dda) folded: language.identifier() <- string.utf8(dda) = language.identifier(add) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) folding: string.utf8(b) <- string.utf8.character.alpha() folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) folding: string.utf8(bi) <- string.utf8.character.alpha() folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) folding: language.identifier() <- string.utf8(bif) folded: language.identifier() <- string.utf8(bif) = language.identifier(fib) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) folding: string.utf8(b) <- string.utf8.character.alpha() folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) folding: string.utf8(bi) <- string.utf8.character.alpha() folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) folding: language.identifier() <- string.utf8(bif) folded: language.identifier() <- string.utf8(bif) = language.identifier(fib) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) folding: language.identifier() <- string.utf8(x) folded: language.identifier() <- string.utf8(x) = language.identifier(x) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(n) folding: string.utf8(n) <- string.utf8.character.alpha() folded: string.utf8(n) <- string.utf8.character.alpha() = string.utf8(ni) folding: string.utf8(ni) <- string.utf8.character.alpha() folded: string.utf8(ni) <- string.utf8.character.alpha() = string.utf8(nia) folding: string.utf8(nia) <- string.utf8.character.alpha() folded: string.utf8(nia) <- string.utf8.character.alpha() = string.utf8(niam) folding: language.identifier() <- string.utf8(niam) folded: language.identifier() <- string.utf8(niam) = language.identifier(main) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) folding: string.utf8(tn) <- string.utf8.character.alpha() folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) folding: string.utf8(tni) <- string.utf8.character.alpha() folded: string.utf8(tni) <- string.utf8.character.alpha() = string.utf8(tnir) folding: string.utf8(tnir) <- string.utf8.character.alpha() folded: string.utf8(tnir) <- string.utf8.character.alpha() = string.utf8(tnirp) folding: language.identifier() <- string.utf8(tnirp) folded: language.identifier() <- string.utf8(tnirp) = language.identifier(print) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8( ) folding: string.utf8( ) <- string.utf8.character.alpha() folded: string.utf8( ) <- string.utf8.character.alpha() = string.utf8( folding: string.utf8( <- string.utf8.character.alpha() folded: string.utf8( <- string.utf8.character.alpha() = string.utf8( :r) folding: string.utf8( :r) <- string.utf8.character.alpha() folded: string.utf8( :r) <- string.utf8.character.alpha() = string.utf8( :re) folding: string.utf8( :re) <- string.utf8.character.alpha() folded: string.utf8( :re) <- string.utf8.character.alpha() = string.utf8( :reg) folding: string.utf8( :reg) <- string.utf8.character.alpha() folded: string.utf8( :reg) <- string.utf8.character.alpha() = string.utf8( :rege) folding: string.utf8( :rege) <- string.utf8.character.alpha() folded: string.utf8( :rege) <- string.utf8.character.alpha() = string.utf8( :reget) folding: string.utf8( :reget) <- string.utf8.character.alpha() folded: string.utf8( :reget) <- string.utf8.character.alpha() = string.utf8( :regetn) folding: string.utf8( :regetn) <- string.utf8.character.alpha() folded: string.utf8( :regetn) <- string.utf8.character.alpha() = string.utf8( :regetni) folding: string.utf8( :regetni) <- string.utf8.character.alpha() folded: string.utf8( :regetni) <- string.utf8.character.alpha() = string.utf8( :regetni ) folding: string.utf8( :regetni ) <- string.utf8.character.alpha() folded: string.utf8( :regetni ) <- string.utf8.character.alpha() = string.utf8( :regetni e) folding: string.utf8( :regetni e) <- string.utf8.character.alpha() folded: string.utf8( :regetni e) <- string.utf8.character.alpha() = string.utf8( :regetni ev) folding: string.utf8( :regetni ev) <- string.utf8.character.alpha() folded: string.utf8( :regetni ev) <- string.utf8.character.alpha() = string.utf8( :regetni evi) folding: string.utf8( :regetni evi) <- string.utf8.character.alpha() folded: string.utf8( :regetni evi) <- string.utf8.character.alpha() = string.utf8( :regetni evit) folding: string.utf8( :regetni evit) <- string.utf8.character.alpha() folded: string.utf8( :regetni evit) <- string.utf8.character.alpha() = string.utf8( :regetni eviti) folding: string.utf8( :regetni eviti) <- string.utf8.character.alpha() folded: string.utf8( :regetni eviti) <- string.utf8.character.alpha() = string.utf8( :regetni evitis) folding: string.utf8( :regetni evitis) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitis) <- string.utf8.character.alpha() = string.utf8( :regetni evitiso) folding: string.utf8( :regetni evitiso) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitiso) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop) folding: string.utf8( :regetni evitisop) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop ) folding: string.utf8( :regetni evitisop ) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop ) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a) folding: string.utf8( :regetni evitisop a) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a ) folding: string.utf8( :regetni evitisop a ) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a ) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a r) folding: string.utf8( :regetni evitisop a r) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a r) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a re) folding: string.utf8( :regetni evitisop a re) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a re) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a ret) folding: string.utf8( :regetni evitisop a ret) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a ret) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a retn) folding: string.utf8( :regetni evitisop a retn) <- string.utf8.character.alpha() folded: string.utf8( :regetni evitisop a retn) <- string.utf8.character.alpha() = string.utf8( :regetni evitisop a retnE) folding: string.utf8( :regetni evitisop a retnE) <- string.utf8( :regetni evitisop a retnE) folded: string.utf8( :regetni evitisop a retnE) <- string.utf8( :regetni evitisop a retnE) = string.utf8(Enter a positive integer: ) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) folding: string.utf8(tu) <- string.utf8.character.alpha() folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) folding: string.utf8(tup) <- string.utf8.character.alpha() folded: string.utf8(tup) <- string.utf8.character.alpha() = string.utf8(tupn) folding: string.utf8(tupn) <- string.utf8.character.alpha() folded: string.utf8(tupn) <- string.utf8.character.alpha() = string.utf8(tupni) folding: language.identifier() <- string.utf8(tupni) folded: language.identifier() <- string.utf8(tupni) = language.identifier(input) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) folding: string.utf8(t) <- string.utf8.character.alpha() folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) folding: string.utf8(tn) <- string.utf8.character.alpha() folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) folding: string.utf8(tni) <- string.utf8.character.alpha() folded: string.utf8(tni) <- string.utf8.character.alpha() = string.utf8(tnir) folding: string.utf8(tnir) <- string.utf8.character.alpha() folded: string.utf8(tnir) <- string.utf8.character.alpha() = string.utf8(tnirp) folding: language.identifier() <- string.utf8(tnirp) folded: language.identifier() <- string.utf8(tnirp) = language.identifier(print) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(() folding: string.utf8(() <- string.utf8.character.alpha() folded: string.utf8(() <- string.utf8.character.alpha() = string.utf8((i) folding: string.utf8((i) <- string.utf8.character.alpha() folded: string.utf8((i) <- string.utf8.character.alpha() = string.utf8((ic) folding: string.utf8((ic) <- string.utf8.character.alpha() folded: string.utf8((ic) <- string.utf8.character.alpha() = string.utf8((icc) folding: string.utf8((icc) <- string.utf8.character.alpha() folded: string.utf8((icc) <- string.utf8.character.alpha() = string.utf8((icca) folding: string.utf8((icca) <- string.utf8.character.alpha() folded: string.utf8((icca) <- string.utf8.character.alpha() = string.utf8((iccan) folding: string.utf8((iccan) <- string.utf8.character.alpha() folded: string.utf8((iccan) <- string.utf8.character.alpha() = string.utf8((iccano) folding: string.utf8((iccano) <- string.utf8.character.alpha() folded: string.utf8((iccano) <- string.utf8.character.alpha() = string.utf8((iccanob) folding: string.utf8((iccanob) <- string.utf8.character.alpha() folded: string.utf8((iccanob) <- string.utf8.character.alpha() = string.utf8((iccanobi) folding: string.utf8((iccanobi) <- string.utf8.character.alpha() folded: string.utf8((iccanobi) <- string.utf8.character.alpha() = string.utf8((iccanobiF) folding: string.utf8((iccanobiF) <- string.utf8((iccanobiF) folded: string.utf8((iccanobiF) <- string.utf8((iccanobiF) = string.utf8(Fibonacci() folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8( ) folding: string.utf8( ) <- string.utf8.character.alpha() folded: string.utf8( ) <- string.utf8.character.alpha() = string.utf8( =) folding: string.utf8( =) <- string.utf8.character.alpha() folded: string.utf8( =) <- string.utf8.character.alpha() = string.utf8( = ) folding: string.utf8( = ) <- string.utf8.character.alpha() folded: string.utf8( = ) <- string.utf8.character.alpha() = string.utf8( = )) folding: string.utf8( = )) <- string.utf8( = )) folded: string.utf8( = )) <- string.utf8( = )) = string.utf8() = ) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) folding: string.utf8(g) <- string.utf8.character.alpha() folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) folding: string.utf8(gn) <- string.utf8.character.alpha() folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) folding: string.utf8(gni) <- string.utf8.character.alpha() folded: string.utf8(gni) <- string.utf8.character.alpha() = string.utf8(gnir) folding: string.utf8(gnir) <- string.utf8.character.alpha() folded: string.utf8(gnir) <- string.utf8.character.alpha() = string.utf8(gnirt) folding: string.utf8(gnirt) <- string.utf8.character.alpha() folded: string.utf8(gnirt) <- string.utf8.character.alpha() = string.utf8(gnirts) folding: string.utf8(gnirts) <- string.utf8.character.underscore() folded: string.utf8(gnirts) <- string.utf8.character.underscore() = string.utf8(gnirts_) folding: string.utf8(gnirts_) <- string.utf8.character.alpha() folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = string.utf8(gnirts_o) folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = string.utf8(gnirts_ot) folding: language.identifier() <- string.utf8(gnirts_ot) folded: language.identifier() <- string.utf8(gnirts_ot) = language.identifier(to_string) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) folding: string.utf8(b) <- string.utf8.character.alpha() folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) folding: string.utf8(bi) <- string.utf8.character.alpha() folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) folding: language.identifier() <- string.utf8(bif) folded: language.identifier() <- string.utf8(bif) = language.identifier(fib) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) folding: string.utf8(r) <- string.utf8.character.alpha() folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) folding: string.utf8(re) <- string.utf8.character.alpha() folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) folding: string.utf8(reg) <- string.utf8.character.alpha() folded: string.utf8(reg) <- string.utf8.character.alpha() = string.utf8(rege) folding: string.utf8(rege) <- string.utf8.character.alpha() folded: string.utf8(rege) <- string.utf8.character.alpha() = string.utf8(reget) folding: string.utf8(reget) <- string.utf8.character.alpha() folded: string.utf8(reget) <- string.utf8.character.alpha() = string.utf8(regetn) folding: string.utf8(regetn) <- string.utf8.character.alpha() folded: string.utf8(regetn) <- string.utf8.character.alpha() = string.utf8(regetni) folding: string.utf8(regetni) <- string.utf8.character.underscore() folded: string.utf8(regetni) <- string.utf8.character.underscore() = string.utf8(regetni_) folding: string.utf8(regetni_) <- string.utf8.character.alpha() folded: string.utf8(regetni_) <- string.utf8.character.alpha() = string.utf8(regetni_o) folding: string.utf8(regetni_o) <- string.utf8.character.alpha() folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = string.utf8(regetni_ot) folding: language.identifier() <- string.utf8(regetni_ot) folded: language.identifier() <- string.utf8(regetni_ot) = language.identifier(to_integer) folding: string.utf8() <- string.utf8.character.alpha() folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) folding: language.identifier() <- string.utf8(s) folded: language.identifier() <- string.utf8(s) = language.identifier(s) folding: string.utf8() <- string.utf8.character.LF() folded: string.utf8() <- string.utf8.character.LF() = string.utf8( ) folding: string.utf8( ) <- string.utf8( ) folded: string.utf8( ) <- string.utf8( ) = string.utf8( ) Compilation time: 336.892ms neoscript] Message ends. /Flibble -- ? From hfollmann at itcfollmann.com Thu Feb 11 08:54:11 2021 From: hfollmann at itcfollmann.com (Henning Follmann) Date: Thu, 11 Feb 2021 08:54:11 -0500 Subject: Best practices for software architecture in Python References: <602397a3$0$12711$426a74cc@news.free.fr> <60251ead$0$27902$e4fe514c@news.xs4all.nl> Message-ID: On 2021-02-11, Oscar wrote: > In article , > Henning Follmann wrote: >>On 2021-02-10, Python wrote: >>> Hi, >>> >>> If you had to train engineers who are used to write >>> Python scripts for image processing, data format conversion, >>> etc. (so they know most the basics of Python types and >>> programming structures except advanced OOP techniques) >>> who now are about to develop quite a big application >>> in the same field (to get rid of some well known proprietary >>> scientific software monoliths), and would like to study in-depth >>> an existing open source application in order to study how >>> to organize classes hierarchy, modules, packages, etc. which >>> one would you recommend ? >>> >>> P. >> >>Looks like you (the project leader?) needs training, not the >>software engineers. >> >>"Making Things Happen" by Scott Berkun > > This looks like a very interesting book to add to my reading list, but > how do you think it will help the OP with his/her quest? > Well the question makes it very obvious that it is a leadership issue. Does he really think giving all engineers the Gang of 4 book will magically lead to a well run OOP project. It all but always is about the leader. > Of course your answer might just as well be: read the book! But since > you clearly did that already, what knowledge did you gain that triggered > this response? Well this book exemplifies how to brake down the task of leadership in the context of software development. For me this seems like a match. -H -- Henning Follmann | hfollmann at itcfollmann.com From rosuav at gmail.com Thu Feb 11 10:13:50 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 12 Feb 2021 02:13:50 +1100 Subject: New Python implementation In-Reply-To: References: Message-ID: On Thu, Feb 11, 2021 at 11:36 PM Mr Flibble wrote: > > > Hi! > > I am starting work on creating a new Python implementation from scratch using "neos" my universal compiler that can compile any programming language. Is it your intention to support all of Python's syntax and semantics, or is this an unrelated language with mandatory strict type tags and a severely restricted set of data types? For instance, can your neos compile this code? def power(): return (2**3**4**2) % 1000000000 from time import time start = time() print(power()) time = time() - start print("Took %s seconds" % time) On my system, I get this from CPython 3.10: 176561152 Took 0.1589798927307129 seconds And this from PyPy: 176561152 Took 0.0233387947083 seconds > I envision this implementation to be significantly faster than the currently extant Python implementations (which isn't a stretch given how poorly they perform). Riiiiiight, yep, all existing Python implementations are terribly slow. Go ahead then; run the code above, show me a better time, and of course compare to what a recent off-the-shelf CPython can do on the same hardware. Then see how PyPy performs at the same job. > Sample neos session (parsing a fibonacci program, neoscript rather than Python in this case): Is neoscript an intermediate language like RPython, used only to implement the compiler, or are you actually transforming Python code into neoscript? ChrisA From jornws200602 at xs4all.nl Thu Feb 11 11:21:41 2021 From: jornws200602 at xs4all.nl (Oscar) Date: 11 Feb 2021 16:21:41 GMT Subject: Best practices for software architecture in Python References: <602397a3$0$12711$426a74cc@news.free.fr> <60251ead$0$27902$e4fe514c@news.xs4all.nl> Message-ID: <60255995$0$27901$e4fe514c@news.xs4all.nl> In article , Henning Follmann wrote: >>>Looks like you (the project leader?) needs training, not the >>>software engineers. >>> >>>"Making Things Happen" by Scott Berkun >> >> This looks like a very interesting book to add to my reading list, but >> how do you think it will help the OP with his/her quest? >> >Well the question makes it very obvious that it is a leadership >issue. Does he really think giving all engineers the Gang of 4 >book will magically lead to a well run OOP project. >It all but always is about the leader. >> Of course your answer might just as well be: read the book! But since >> you clearly did that already, what knowledge did you gain that triggered >> this response? >Well this book exemplifies how to brake down the task of >leadership in the context of software development. >For me this seems like a match. But it could be both. You can be a good leader and still look for a good example of how to build a complex piece of software. Granted, it's probably easier to ask for bad examples. ;-) This is why I still don't see how you derived the quality of OP's leadership from this question. -- [J|O|R] <- .signature.gz From drsalists at gmail.com Thu Feb 11 11:31:38 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Thu, 11 Feb 2021 08:31:38 -0800 Subject: New Python implementation In-Reply-To: References: Message-ID: On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble wrote: > > Hi! > > I am starting work on creating a new Python implementation from scratch > using "neos" my universal compiler that can compile any programming > language. I envision this implementation to be significantly faster than > the currently extant Python implementations (which isn't a stretch given > how poorly they perform). > I'd like to encourage you to give this a go. It's a huge task, but it's needed. You may be interested in the approaches of Pypy, Cython, Shedskin and Nuitka. Pypy is a Python written in RPython, where RPython is a restricted subset of Python 2. It can translate RPython to C, or JIT compile pretty full Python code - 2.x or 3.x. It has trouble with C extension modules, as the CPython API for extension modules is pretty leaky. CFFI appears to be the big hope of fixing this problem, but most C extension modules still use the CPython C extension Module API. Cython transpiles a Python-like language to C. It allows you to intermix Python datatypes and C datatypes; the more you use C datatypes, the faster the result is. It can be slower if you aren't careful with your type conversions, but it can be faster if used well. It has a really nice --annotate option that shows how close to C your program is, line by line. Shedskin transpiles an implicitly static subset of Python 2 to C++. It's a great tool, but sadly it is unlikely to make the jump from Python 2 to Python 3, and Python 3 is definitely the future of Python. Nuitka is a Python -> C/C++ transpiler. I know little about it, but it sounds kind of like what you're proposing. It's been focusing on compatibility first, followed by performance. Good luck! From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 12:45:25 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 17:45:25 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 15:13, Chris Angelico wrote: > On Thu, Feb 11, 2021 at 11:36 PM Mr Flibble > wrote: >> >> >> Hi! >> >> I am starting work on creating a new Python implementation from scratch using "neos" my universal compiler that can compile any programming language. > > Is it your intention to support all of Python's syntax and semantics, Yes. > or is this an unrelated language with mandatory strict type tags and a > severely restricted set of data types? For instance, can your neos > compile this code? No. The neos universal compiler itself is language agnostic: a pre-requisite for the requirement to be able to compile any programming language. > > def power(): > return (2**3**4**2) % 1000000000 > > from time import time > start = time() > print(power()) > time = time() - start > print("Took %s seconds" % time) > > On my system, I get this from CPython 3.10: > 176561152 > Took 0.1589798927307129 seconds > > And this from PyPy: > 176561152 > Took 0.0233387947083 seconds > >> I envision this implementation to be significantly faster than the currently extant Python implementations (which isn't a stretch given how poorly they perform). > > Riiiiiight, yep, all existing Python implementations are terribly > slow. Go ahead then; run the code above, show me a better time, and of > course compare to what a recent off-the-shelf CPython can do on the > same hardware. Then see how PyPy performs at the same job. You are timing the arithmetic library rather than the interpreter. > >> Sample neos session (parsing a fibonacci program, neoscript rather than Python in this case): > > Is neoscript an intermediate language like RPython, used only to > implement the compiler, or are you actually transforming Python code > into neoscript? neoscript is the neos reference language (i.e. not an intermediate language) and will be unrelated to the Python implementation. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 12:56:09 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 17:56:09 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 16:31, Dan Stromberg wrote: > On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble > wrote: > >> >> Hi! >> >> I am starting work on creating a new Python implementation from scratch >> using "neos" my universal compiler that can compile any programming >> language. I envision this implementation to be significantly faster than >> the currently extant Python implementations (which isn't a stretch given >> how poorly they perform). >> > > I'd like to encourage you to give this a go. It's a huge task, but it's > needed. Actually it is a relatively small task due to the neos universal compiler's architectural design. If it was a large task I wouldn't be doing it. > > You may be interested in the approaches of Pypy, Cython, Shedskin and > Nuitka. I am not particularly interested in any of the existing implementations as they bear no relation to the design of my language agnostic universal compiler, runtime, VM and JIT; the only use they will have will be to disambiguate certain Python language constructs that I cannot disambiguate from documentation alone: this is a natural consequence of Python not being standardized; those steering the language need to grow a pair and get Python standardized preferably as an ISO Standard. > > Pypy is a Python written in RPython, where RPython is a restricted subset > of Python 2. It can translate RPython to C, or JIT compile pretty full > Python code - 2.x or 3.x. It has trouble with C extension modules, as the > CPython API for extension modules is pretty leaky. CFFI appears to be the > big hope of fixing this problem, but most C extension modules still use the > CPython C extension Module API. RPython doesn't interest me. neos will be using libffi for FFI. > > Cython transpiles a Python-like language to C. It allows you to intermix > Python datatypes and C datatypes; the more you use C datatypes, the faster > the result is. It can be slower if you aren't careful with your type > conversions, but it can be faster if used well. It has a really nice > --annotate option that shows how close to C your program is, line by line. I don't agree with the concept of delivering C compilers to end users. The only compilers I think end users should be running are GPU shader compilers and byecode/JIT compilers such as neos. > > Shedskin transpiles an implicitly static subset of Python 2 to C++. It's a > great tool, but sadly it is unlikely to make the jump from Python 2 to > Python 3, and Python 3 is definitely the future of Python. Not interested in that (see previous answer replacing "C" with "C++"). > > Nuitka is a Python -> C/C++ transpiler. I know little about it, but it > sounds kind of like what you're proposing. It's been focusing on > compatibility first, followed by performance. Bears no relation to neos architecture. > > Good luck! Thanks for the sentiment but I am not relying on luck. /Flibble -- ? From rosuav at gmail.com Thu Feb 11 13:03:27 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 12 Feb 2021 05:03:27 +1100 Subject: New Python implementation In-Reply-To: References: Message-ID: On Fri, Feb 12, 2021 at 4:52 AM Mr Flibble wrote: > > On 11/02/2021 15:13, Chris Angelico wrote: > > On Thu, Feb 11, 2021 at 11:36 PM Mr Flibble > > wrote: > >> > >> > >> Hi! > >> > >> I am starting work on creating a new Python implementation from scratch using "neos" my universal compiler that can compile any programming language. > > > > Is it your intention to support all of Python's syntax and semantics, > > Yes. > > > or is this an unrelated language with mandatory strict type tags and a > > severely restricted set of data types? For instance, can your neos > > compile this code? > > No. The neos universal compiler itself is language agnostic: a pre-requisite for the requirement to be able to compile any programming language. > Okay, cool, then I misunderstood the point of neoscript (I thought you would compile Python to neoscript and then neoscript to binary). As Dan says, go for it, give it a go. I think it'll give you a very good demonstration of how CPython, and especially PyPy, are actually highly performant languages :) > You are timing the arithmetic library rather than the interpreter. Hmm, I didn't call on any library functions. The crucial and time-consuming operations were entirely implemented using operators on constants. (I also deliberately reused the name "time" in multiple ways, just to stress-test anything that tries to restrict data types.) In any case, it's not Python if it can't handle arbitrarily large numbers. Python is an excellent language for mathematics. ChrisA From rosuav at gmail.com Thu Feb 11 13:06:48 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 12 Feb 2021 05:06:48 +1100 Subject: New Python implementation In-Reply-To: References: Message-ID: On Fri, Feb 12, 2021 at 5:01 AM Mr Flibble wrote: > > On 11/02/2021 16:31, Dan Stromberg wrote: > > On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble > > wrote: > > > >> > >> Hi! > >> > >> I am starting work on creating a new Python implementation from scratch > >> using "neos" my universal compiler that can compile any programming > >> language. I envision this implementation to be significantly faster than > >> the currently extant Python implementations (which isn't a stretch given > >> how poorly they perform). > >> > > > > I'd like to encourage you to give this a go. It's a huge task, but it's > > needed. > > Actually it is a relatively small task due to the neos universal compiler's architectural design. If it was a large task I wouldn't be doing it. > > > > > You may be interested in the approaches of Pypy, Cython, Shedskin and > > Nuitka. > > I am not particularly interested in any of the existing implementations as they bear no relation to the design of my language agnostic universal compiler, runtime, VM and JIT; the only use they will have will be to disambiguate certain Python language constructs that I cannot disambiguate from documentation alone: this is a natural consequence of Python not being standardized; those steering the language need to grow a pair and get Python standardized preferably as an ISO Standard. > You keep insulting Python and the Python devs. Put up or shut up - show some actual code before you make too many boasts. Python DOES have a strong language specification. Its semantics are documented. If you find places where the documentation is lacking, point them out specifically, don't FUD your way through. ChrisA From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 13:10:52 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 18:10:52 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 18:03, Chris Angelico wrote: > In any case, it's not Python if it can't handle arbitrarily large > numbers. Python is an excellent language for mathematics. I am also creating Ada and Haskell implementations which have a similar requirement. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 13:14:42 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 18:14:42 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 18:06, Chris Angelico wrote: > On Fri, Feb 12, 2021 at 5:01 AM Mr Flibble > wrote: >> >> On 11/02/2021 16:31, Dan Stromberg wrote: >>> On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble >>> wrote: >>> >>>> >>>> Hi! >>>> >>>> I am starting work on creating a new Python implementation from scratch >>>> using "neos" my universal compiler that can compile any programming >>>> language. I envision this implementation to be significantly faster than >>>> the currently extant Python implementations (which isn't a stretch given >>>> how poorly they perform). >>>> >>> >>> I'd like to encourage you to give this a go. It's a huge task, but it's >>> needed. >> >> Actually it is a relatively small task due to the neos universal compiler's architectural design. If it was a large task I wouldn't be doing it. >> >>> >>> You may be interested in the approaches of Pypy, Cython, Shedskin and >>> Nuitka. >> >> I am not particularly interested in any of the existing implementations as they bear no relation to the design of my language agnostic universal compiler, runtime, VM and JIT; the only use they will have will be to disambiguate certain Python language constructs that I cannot disambiguate from documentation alone: this is a natural consequence of Python not being standardized; those steering the language need to grow a pair and get Python standardized preferably as an ISO Standard. >> > > You keep insulting Python and the Python devs. Put up or shut up - > show some actual code before you make too many boasts. > > Python DOES have a strong language specification. Its semantics are > documented. If you find places where the documentation is lacking, > point them out specifically, don't FUD your way through. For a language to transition from "toy" status it has to be formally standardized. It is unacceptable to define a language in terms of a particular implementation. A git repo of Source code and associated observable dynamic behaviour when that code is compiled and ran is a poor substitute for an official ISO Standard. /Flibble -- ? From pbryan at anode.ca Thu Feb 11 13:24:27 2021 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 11 Feb 2021 18:24:27 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: <010d01779256540d-f7f905b4-2352-4fa5-9862-8fabb32102d2-000000@ca-central-1.amazonses.com> On Thu, 2021-02-11 at 17:56 +0000, Mr Flibble wrote: > Actually it is a relatively small task due to the neos universal > compiler's architectural design.? If it was a large task I wouldn't > be doing it. When do you estimate this task will be completed? > I am not particularly interested in any of the existing > implementations as they bear no relation to the design of my language > agnostic universal compiler, runtime, VM and JIT; the only use they > will have will be to disambiguate certain Python language constructs > that I cannot disambiguate from documentation alone: this is a > natural consequence of Python not being standardized; those steering > the language need to grow a pair and get Python standardized > preferably as an ISO Standard. I take it you don't hope to receive any support from those you're insulting by such a statement? > Thanks for the sentiment but I am not relying on luck. By your conduct so far, I think you will also not be relying on the goodwill of this community. Paul From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 13:29:52 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 18:29:52 +0000 Subject: New Python implementation In-Reply-To: References: <010d01779256540d-f7f905b4-2352-4fa5-9862-8fabb32102d2-000000@ca-central-1.amazonses.com> Message-ID: On 11/02/2021 18:24, Paul Bryan wrote: > On Thu, 2021-02-11 at 17:56 +0000, Mr Flibble wrote: > >> Actually it is a relatively small task due to the neos universal >> compiler's architectural design.? If it was a large task I wouldn't >> be doing it. > > When do you estimate this task will be completed? > >> I am not particularly interested in any of the existing >> implementations as they bear no relation to the design of my language >> agnostic universal compiler, runtime, VM and JIT; the only use they >> will have will be to disambiguate certain Python language constructs >> that I cannot disambiguate from documentation alone: this is a >> natural consequence of Python not being standardized; those steering >> the language need to grow a pair and get Python standardized >> preferably as an ISO Standard. > > I take it you don't hope to receive any support from those you're > insulting by such a statement? > >> Thanks for the sentiment but I am not relying on luck. > > By your conduct so far, I think you will also not be relying on the > goodwill of this community. Personally I prefer telling it like it is (i.e. the truth) rather than walking on eggshells. /Flibble -- ? From python-list at andras.tantosonline.com Thu Feb 11 13:05:12 2021 From: python-list at andras.tantosonline.com (Andras Tantos) Date: Thu, 11 Feb 2021 10:05:12 -0800 Subject: super() in injected methods In-Reply-To: <4e77b37f-0bdb-570b-6052-ebdd0a1ae3cc@tantosonline.com> References: <4e77b37f-0bdb-570b-6052-ebdd0a1ae3cc@tantosonline.com> Message-ID: <21b95123-f9f6-7a8a-2676-0dd3050815cc@andras.tantosonline.com> Esteemed Python Gurus, I think, I actually know the answer to this question, but - maybe beyond reason - I'm hoping there to be some magic. Consider the following code: ?? ?from types import MethodType ?? ?class A(object): ?? ??? ?pass ?? ??? ?def m(self, x): ?? ??? ??? ?print(f"A.m({x})") ?? ?class B(A): ?? ??? ?def m(self, x): ?? ??? ??? ?print(f"B.m({x})") ?? ??? ??? ?ss = super() ?? ??? ??? ?ss.m(x) ?? ?def method(self, s): ?? ??? ?print(f"method({s})") ?? ??? ?try: ?? ??? ??? ?ss = super() # <-- Complains about __class__ cell not being found ?? ??? ?except: ?? ??? ??? ?print("I shouldn't need to do this!") ?? ??? ??? ?ss = super(type(self), self) # <-- Works just fine ?? ??? ?ss.m(s) ?? ?a = B() ?? ?a.m(41) ?? ?a.m = MethodType(method, a) ?? ?a.m(42) In the function 'method', I try to access the super() class. Now, of course that makes no sense as a stand-alone function, but it does, once it gets injected as a method into 'a' below. The two-parameter version of the call of course works without a hitch. I think I actually understand why this is happening (some interpreter magic around super() forcing the insertion of __class__, which that doesn't happen when parsing a stand-alone function). I think I even understand the rationale for it, which is that super() needs to be statically evaluated. Now to the question though: In theory this information (static type of 'self' at the point of method binding to class) is available at the point of method injection, in this example, the next-to-last line of the code. So, is there a way to somehow inject/override/magically-make-it-appear the __class__ cell in 'method' such that super() starts working as expected again? Thanks, Andras Tantos From rosuav at gmail.com Thu Feb 11 14:08:25 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 12 Feb 2021 06:08:25 +1100 Subject: super() in injected methods In-Reply-To: <21b95123-f9f6-7a8a-2676-0dd3050815cc@andras.tantosonline.com> References: <4e77b37f-0bdb-570b-6052-ebdd0a1ae3cc@tantosonline.com> <21b95123-f9f6-7a8a-2676-0dd3050815cc@andras.tantosonline.com> Message-ID: On Fri, Feb 12, 2021 at 5:54 AM Andras Tantos wrote: > > Esteemed Python Gurus, > > I think, I actually know the answer to this question, but - maybe beyond > reason - I'm hoping there to be some magic. Consider the following code: > > from types import MethodType > > class A(object): > pass > def m(self, x): > print(f"A.m({x})") > class B(A): > def m(self, x): > print(f"B.m({x})") > ss = super() > ss.m(x) > > def method(self, s): > print(f"method({s})") > try: > ss = super() # <-- Complains about __class__ cell not being > found > except: > print("I shouldn't need to do this!") > ss = super(type(self), self) # <-- Works just fine > ss.m(s) > > a = B() > a.m(41) > a.m = MethodType(method, a) > a.m(42) > > > In the function 'method', I try to access the super() class. Now, of > course that makes no sense as a stand-alone function, but it does, once > it gets injected as a method into 'a' below. > > The two-parameter version of the call of course works without a hitch. Be careful: the first parameter is supposed to be the class that you're currently implementing, which may well NOT be type(self). Given that you're attaching to an instance, though, it's probably okay to assume you are looking at the leaf class. > I think I actually understand why this is happening (some interpreter > magic around super() forcing the insertion of __class__, which that > doesn't happen when parsing a stand-alone function). I think I even > understand the rationale for it, which is that super() needs to be > statically evaluated. What happens in the normal case is that __class__ is accessed via closure cell from the class block itself. The compiler translates super() into super(__class__, self) where 'self' is actually 'whatever the first parameter is'. > Now to the question though: In theory this information (static type of > 'self' at the point of method binding to class) is available at the > point of method injection, in this example, the next-to-last line of the > code. So, is there a way to somehow > inject/override/magically-make-it-appear the __class__ cell in 'method' > such that super() starts working as expected again? > Hmm. I don't think it'd work for technical reasons, but in theory, the MethodType constructor would be the place to do this. But injecting methods into instances (as opposed to classes) is a sufficiently unusual thing that it's probably safest to just use the two-arg super and have done with it. ChrisA From PythonList at DancesWithMice.info Thu Feb 11 14:45:49 2021 From: PythonList at DancesWithMice.info (dn) Date: Fri, 12 Feb 2021 08:45:49 +1300 Subject: New Python implementation In-Reply-To: References: Message-ID: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> On 12/02/2021 07.14, Mr Flibble wrote: > On 11/02/2021 18:06, Chris Angelico wrote: >> On Fri, Feb 12, 2021 at 5:01 AM Mr Flibble >> wrote: >>> >>> On 11/02/2021 16:31, Dan Stromberg wrote: >>>> On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble >>>> >>>> wrote: >>>> >>>>> I am starting work on creating a new Python implementation from >>>>> scratch ... (which isn't a stretch given how poorly they perform). >>>> I'd like to encourage you to give this a go.? It's a huge task, but >>>> it's needed. >>> >>> Actually it is a relatively small task due to the neos universal >>> compiler's architectural design.? If it was a large task I wouldn't >>> be doing it. >>> >>>> You may be interested in... >>> >>> I am not particularly interested in any of the existing >>> implementations as they bear no relation to the design of my language ...not being standardized; those steering >>> the language need to grow a pair and get Python standardized >>> preferably as an ISO Standard. ... > For a language to transition from "toy" status it has to be formally > standardized.? It is unacceptable to define a language in terms of a > particular implementation. A git repo of Source code and associated > observable dynamic behaviour when that code is compiled and ran is a > poor substitute for an official ISO Standard. > > /Flibble When I first met it, one of the concepts I found difficult to 'wrap my head around' was the idea that "open software" allowed folk to fork the original work and 'do their own thing'. My thinking was (probably) "surely, the original is the authoritative version". Having other versions seemed an invitation to confusion and dilution. However, as soon as (open) software is made available, other people start making it 'better' - whatever their own definition of "better". Yes, it is both a joy and a complication. Such is contrary to the principle of "standards". At its extreme, a standard says there is only one way to do the-whatever. This is why many 'standard programming languages' then offer the 'out' of having various levels of 'standard'. For example, despite being one of the longest standardised languages, many COBOL implementations achieve only part of "the standard" - and one has to dive (deep) into the 'small print' to establish which 'bits' are in their particular 'pick and mix'. Yet, they still (quite legally) refer to their product as 'standard'! The second issue with standards is the time and effort it takes to achieve an agreement and thus reach the point of publishing. A third issue, and possibly the reason why attempting a standard is a "losing battle", is that programming and languages are in a constant state of flux - we call it "ongoing development". Even though Python v3.10 is reaching a state of anticipation, there are organisations and libraries that still work using Python 2. Thus, and HTML/"the browser wars" is an example of this, as fast as a standard is discussed, someone (even those contributing to said standards) is doing his/her best to build 'more advanced features' beyond the standard... "Standards" and 'driving development forward' are at least in tension, at worst, complete-opposites. Standards, like "waterfall" project specifications, cannot be 'cast in stone' because the world keeps changing. Standards are insufficiently agile and Agile! Whereas the likes of COBOL had "owners", if not as a point-of-fact, at least in terms of (commercial) 'might' and 'power', Python has its "Python Software Foundation" (https://www.python.org/psf/). Please feel free to approach that group to talk about 'what is Python' and 'standardisation'. Rather than a process of "imposing" a standard, Python has a more 'grass roots' democratic process which involves PEPs (Python Enhancement Proposal). These are 'great ideas', even intentions-to-build or proofs-of-concept, documented, and presented for the community to consider. The better ones make it through and become part of the language and its eco-system. Has the above proposal started on that 'standards path'? Is it 'documented', or merely an idea? Another aspect of open source is its 'meritocracy' - respect for those who have demonstrated their abilities (and commitment). Certain names 'crop-up' on PEPs, and more tellingly, on "accepted" PEPs. Of the three names appearing in this thread, which two have been seen before, and have contributed to PEPs or to this list, in the past? Is there a choice to 'stand on the shoulders of giants', or to 'walk all over ... in hob-nailed boots'? Has this conversation illustrated respect, or (perhaps unintentionally) torn-down others' sweat-and-tears without offering something (better) for consideration/approval/use? Is there any proof that you/I/someone-else can actually "do" better? An applicable saying is "the proof is in the pudding". So, rather than claims, shouldn't we be dealing with facts, eg system-A does better than system-B under the following conditions? A community comprises people who are prepared to work towards some commonality. Positivity and friendliness, ie 'honey', tend to work better than 'vinegar'. Would you say that anything approaching "troll" behavior is less-likely to achieve cohesion? Few (successful) projects are managed by a single person. This list is a great meeting-place to find others who might share your particular interest - and further, who might be prepared to collaborate - as the saying goes "scratch your own itch". Is this what you seek? Has the choice of language/approach in this conversation been best-calculated to 'gather around' like-minded folk? Is there a difference between speaking with determination and making a case, and being disrespectful of others? Wishing you well. It seems (to (neos-ignorant) me at least) an ambitious project. There are certainly times when 'execution speed' becomes a major criteria. Many of us will look forward to (your development of) a solution. Please let us know when it's ready for use/trials... Personal comments: 1 Am admitting to a sense of wariness towards 'new' people who use a made-up name - despite mine being somewhat obfuscated (NB calling "David?" in any given community is likely to elicit multiple replies, thus the "dn"/inviting colleagues to call me by my initials). 2 Noting a false (non-standard/RFC) email address, and consequently every message's (non-standard) impact on the email-reflector. 3 My mind is whirling in an attempt to understand "show me a better time". Does this perhaps indicate that @Chris' social life leaves something to be desired? Are Python-nerds really the ones to turn-to for dating advice, or is that not what @Chris means by "(having) a good time"? -- Regards, =dn From rosuav at gmail.com Thu Feb 11 14:53:51 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 12 Feb 2021 06:53:51 +1100 Subject: New Python implementation In-Reply-To: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> References: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> Message-ID: On Fri, Feb 12, 2021 at 6:47 AM dn via Python-list wrote: > 3 > My mind is whirling in an attempt to understand "show me a better time". > Does this perhaps indicate that @Chris' social life leaves something to > be desired? Are Python-nerds really the ones to turn-to for dating > advice, or is that not what @Chris means by "(having) a good time"? LOL! I was referring to the fact that my demonstration snippet included a rudimentary timing bracket, and that, if existing Python implementations are indeed abysmally slow, it should be possible to run the same code on a different interpreter and get a lower number - a "better" time being shorter. ChrisA From uri at speedy.net Thu Feb 11 15:25:27 2021 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Thu, 11 Feb 2021 22:25:27 +0200 Subject: @unittest.skip doesn't print anything in Python <= 3.7 Message-ID: Hi, https://stackoverflow.com/questions/66161394/unittest-skip-doesnt-print-anything-in-python-3-7 We are using Django with unittest. Some tests are skipped with the @unittest.skip decorator. But if I run the tests with Python 3.6 or 3.7, I get a number of tests passed (Ran 993 tests / OK), and if I run the same tests with Python 3.8, I get the same number of tests but with some tests skipped (Ran 993 tests / OK (skipped=4)). I would like to know if the same tests were also skipped with Python 3.6 and 3.7, or only with Python 3.8? And why do I get the skipped output only with Python 3.8? And is the number 993 including the skipped tests or not including them? Is one of the outputs incorrect? Because it doesn't make sense that the output is different for different versions of Python and I don't understand the reason for this difference. I didn't find it documented in the documentation. Our code is open source, and you can see for example a skipped test here. *Update:* I added 4 more tests with the decorator @unittest.skip. When I run all the tests with Python 3.8, I get this output: Ran 997 tests / OK (skipped=8) (with an s for every skipped test, like before). But if I run the tests with Python 3.6 or 3.7, I get this output: Ran 997 tests / OK and there are no s in the output, like before (I get 997 dots). Although I have 4 more tests than before. The tests I added raise an exception, so if they would not be skipped they would fail. I think the skipped tests are skipped in all Python versions, but in Python 3.6 and 3.7 there is no output about them being skipped. Is it a bug? ???? uri at speedy.net From duncan at invalid.invalid Thu Feb 11 15:22:11 2021 From: duncan at invalid.invalid (duncan smith) Date: Thu, 11 Feb 2021 20:22:11 +0000 Subject: mutating a deque whilst iterating over it Message-ID: Hello, It seems that I can mutate a deque while iterating over it if I assign to an index, but not if I append to it. Is this the intended behaviour? It seems a bit inconsistent. Cheers. Duncan >>> from collections import deque >>> d = deque(range(8)) >>> it = iter(d) >>> next(it) 0 >>> d[1] = 78 >>> next(it) 78 >>> d.append(8) >>> next(it) Traceback (most recent call last): File "", line 1, in next(it) RuntimeError: deque mutated during iteration >>> From PythonList at DancesWithMice.info Thu Feb 11 15:42:00 2021 From: PythonList at DancesWithMice.info (dn) Date: Fri, 12 Feb 2021 09:42:00 +1300 Subject: New Python implementation In-Reply-To: References: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> Message-ID: <686c3103-5af8-9620-f14e-7ff768c60796@DancesWithMice.info> On 12/02/2021 08.53, Chris Angelico wrote: > On Fri, Feb 12, 2021 at 6:47 AM dn via Python-list > wrote: >> 3 >> My mind is whirling in an attempt to understand "show me a better time". >> Does this perhaps indicate that @Chris' social life leaves something to >> be desired? Are Python-nerds really the ones to turn-to for dating >> advice, or is that not what @Chris means by "(having) a good time"? > > LOL! I was referring to the fact that my demonstration snippet > included a rudimentary timing bracket, and that, if existing Python > implementations are indeed abysmally slow, it should be possible to > run the same code on a different interpreter and get a lower number - > a "better" time being shorter. Agreed. I've been 'bitten' by running 'the same' interpreter on different hardware/configs and finding that one part of the program[me] ran faster on the dev-machine, and another part faster on the prod-box. Felt a bit like a no-win situation! Timing was an important contribution. However, needing to perform same in-situ was a surprise. 'Gotcha'! There are a lot of variables in the efficiency-game. It's not completely cut-and-dried to say this, but as a general rule-of-thumb one does not select Python for applications/components which have significant execution-time constraints/requirements. However, Python is rarely bettered when it comes to developer-time! Horses for courses... As to being outrageously cheeky: even if COVID travel-restrictions have been lifted, knowing the Tasman Sea remains between us, allowed/emboldened me to go for the prize(?) for finding at least some word-play to laugh-about in this whole conversation. PS my version of bravery is that if you come after me carrying a big stick, I shall run in the opposite direction - very quickly! PPS speaking of travel: have you taken advantage of any of the "vouchers" offered by your (Fed?State) government as an economic stimulus/recovery for the hospitality industry? -- Regards, =dn From drsalists at gmail.com Thu Feb 11 16:13:43 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Thu, 11 Feb 2021 13:13:43 -0800 Subject: New Python implementation In-Reply-To: References: Message-ID: On Thu, Feb 11, 2021 at 10:21 AM Mr Flibble wrote: > For a language to transition from "toy" status it has to be formally > standardized. It is unacceptable to define a language in terms of a > particular implementation. A git repo of Source code and associated > observable dynamic behaviour when that code is compiled and ran is a poor > substitute for an official ISO Standard. > I'm inclined to agree, though Python has done surprisingly well at fostering multiple implementations despite having a reference implementation for so long. The thing it'd probably help the most with, is slowly down the rate of change in the language. The Core Devs seem to want to improve CPython rapidly, which is not great for the many other implementations - EG Jython and IronPython. Also, "improvements" in CPython are frequently tending toward featuritis, since the complexity of a language tends to grow with the square of its feature count. Does your project have a name yet? I'd like to follow it through google alerts or an announcement mailing list. From PythonList at DancesWithMice.info Thu Feb 11 16:17:31 2021 From: PythonList at DancesWithMice.info (dn) Date: Fri, 12 Feb 2021 10:17:31 +1300 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On 12/02/2021 09.22, duncan smith wrote: > Hello, > It seems that I can mutate a deque while iterating over it if I > assign to an index, but not if I append to it. Is this the intended > behaviour? It seems a bit inconsistent. Cheers. Yes, and no! Agree and disagree. (see how decisive I can be?) Inconsistent when compared with what? A tuple is immutable, but if it contains mutable objects as elements, they are mutable. Consistent! That said, tuples can't be append-ed/extend-ed, so a deque may seem more like a list than a tuple. A list will allow both element and list mutation. Substituting a list in the sample code, the iterator will adjust to include an appended element. Inconsistent! However... what happens if you have a for-loop which processes a list, and within the loop one element is mutated in value and another appended to the list? Oops! Maybe the deque authors wanted to avoid that, or perhaps such is related to the option to bound the length of a deque (by design or side-effect)? Imagine a bounded-deque (completely 'filled') and the code is (overly-simple example) printing its contents. If the deque-element printing-loop also allows deque-mutation, then the first value(s), previously printed, will no longer exist within the queue. I'm enjoying the question: wither inconsistency? Perhaps someone (wiser) will jump in... -- Regards, =dn From greg.ewing at canterbury.ac.nz Thu Feb 11 16:43:43 2021 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 12 Feb 2021 10:43:43 +1300 Subject: super() in injected methods In-Reply-To: References: <4e77b37f-0bdb-570b-6052-ebdd0a1ae3cc@tantosonline.com> <21b95123-f9f6-7a8a-2676-0dd3050815cc@andras.tantosonline.com> Message-ID: On 12/02/21 7:05 am, Andras Tantos wrote: > ?? ?a = B() > ?? ?a.m(41) > ?? ?a.m = MethodType(method, a) > ?? ?a.m(42) Are you sure you really need to inject methods into instances like this? What problem are you trying to solve by doing so? There's almost certainly a better way to approach it. -- Greg From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 16:58:49 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 21:58:49 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 21:13, Dan Stromberg wrote: > Does your project have a name yet? I'd like to follow it through google > alerts or an announcement mailing list. "neos" - https://neos.dev/ https://github.com/i42output/neos /Flibble -- ? From avigross at verizon.net Thu Feb 11 17:22:35 2021 From: avigross at verizon.net (Avi Gross) Date: Thu, 11 Feb 2021 17:22:35 -0500 Subject: New Python implementation In-Reply-To: References: Message-ID: <07d701d700c4$66592ff0$330b8fd0$@verizon.net> I may be the only one who does not deal well with a condescending attitude. I have to wonder what international standards body ever completes a task in finite time, only to find the real world has moved on. Having standards can be a great idea. When the standard does not properly describe any implementations either because some leave out things and others have partial or enhanced implementations, then it is just a goal. May I ask if the proposed product itself needs standardization? Since it claims to support many (or amusingly ANY) language fully, perhaps they can share their Ada or other version before they do Python, or are they working on all of them at once? Realistically, many languages have chosen various paths and a model that captures them all will have to be fairly complex and perhaps needlessly complex. Does it need multiple ways to deal with issues like scope and perhaps keep track of that if a program crosses several boundaries? Will it be able to handle something like an R program running a package that allows a parallel running of a Python program as they work jointly on the same or copied data structures? I have been writing those lately and in the future may incorporate additional languages to take advantage of the strengths and features of each while avoiding the weaknesses or missing aspects of another. Anyone who considers the task specified to be a small problem is either brilliant or perhaps not well informed. If they can do what they say well, great. But I have seen other such attempts such as finding a way to translate between word processor formats that try to deal with overlapping but different concepts and do imperfect translations. That may of course not be relevant here if what is produced is code that runs and yet follows the expected rules as if it was being interpreted. But a more pleasant attitude may make the same points, not that I am sure what those are and what is being asked. It sounds more like being told. -----Original Message----- From: Python-list On Behalf Of Mr Flibble Sent: Thursday, February 11, 2021 1:15 PM To: python-list at python.org Subject: Re: New Python implementation On 11/02/2021 18:06, Chris Angelico wrote: > On Fri, Feb 12, 2021 at 5:01 AM Mr Flibble > wrote: >> >> On 11/02/2021 16:31, Dan Stromberg wrote: >>> On Thu, Feb 11, 2021 at 4:35 AM Mr Flibble >>> >>> wrote: >>> >>>> >>>> Hi! >>>> >>>> I am starting work on creating a new Python implementation from >>>> scratch using "neos" my universal compiler that can compile any >>>> programming language. I envision this implementation to be >>>> significantly faster than the currently extant Python >>>> implementations (which isn't a stretch given how poorly they perform). >>>> >>> >>> I'd like to encourage you to give this a go. It's a huge task, but >>> it's needed. >> >> Actually it is a relatively small task due to the neos universal compiler's architectural design. If it was a large task I wouldn't be doing it. >> >>> >>> You may be interested in the approaches of Pypy, Cython, Shedskin >>> and Nuitka. >> >> I am not particularly interested in any of the existing implementations as they bear no relation to the design of my language agnostic universal compiler, runtime, VM and JIT; the only use they will have will be to disambiguate certain Python language constructs that I cannot disambiguate from documentation alone: this is a natural consequence of Python not being standardized; those steering the language need to grow a pair and get Python standardized preferably as an ISO Standard. >> > > You keep insulting Python and the Python devs. Put up or shut up - > show some actual code before you make too many boasts. > > Python DOES have a strong language specification. Its semantics are > documented. If you find places where the documentation is lacking, > point them out specifically, don't FUD your way through. For a language to transition from "toy" status it has to be formally standardized. It is unacceptable to define a language in terms of a particular implementation. A git repo of Source code and associated observable dynamic behaviour when that code is compiled and ran is a poor substitute for an official ISO Standard. /Flibble -- ? -- https://mail.python.org/mailman/listinfo/python-list From drsalists at gmail.com Thu Feb 11 17:25:18 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Thu, 11 Feb 2021 14:25:18 -0800 Subject: New Python implementation In-Reply-To: References: Message-ID: On Thu, Feb 11, 2021 at 2:00 PM Mr Flibble wrote: > On 11/02/2021 21:13, Dan Stromberg wrote: > > Does your project have a name yet? I'd like to follow it through google > > alerts or an announcement mailing list. > > "neos" - https://neos.dev/ https://github.com/i42output/neos > Pypi already appears to have another project named neos: https://pypi.org/project/neos/ From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 17:33:52 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Thu, 11 Feb 2021 22:33:52 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 22:25, Dan Stromberg wrote: > On Thu, Feb 11, 2021 at 2:00 PM Mr Flibble > wrote: > >> On 11/02/2021 21:13, Dan Stromberg wrote: >>> Does your project have a name yet? I'd like to follow it through google >>> alerts or an announcement mailing list. >> >> "neos" - https://neos.dev/ https://github.com/i42output/neos >> > > Pypi already appears to have another project named neos: > https://pypi.org/project/neos/ neos isn't a Python package so that isn't a problem. /Flibble -- ? From greg.ewing at canterbury.ac.nz Thu Feb 11 18:12:37 2021 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 12 Feb 2021 12:12:37 +1300 Subject: New Python implementation In-Reply-To: References: Message-ID: On 12/02/21 11:33 am, Mr Flibble wrote: > neos isn't a Python package so that isn't a problem. It might be a bit confusing if it ever becomes part of the wider Python ecosystem, though. -- Greg From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 19:05:53 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Fri, 12 Feb 2021 00:05:53 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 23:12, Greg Ewing wrote: > On 12/02/21 11:33 am, Mr Flibble wrote: >> neos isn't a Python package so that isn't a problem. > > It might be a bit confusing if it ever becomes part of the > wider Python ecosystem, though. Python is but one language that neos will implement. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Thu Feb 11 19:06:55 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Fri, 12 Feb 2021 00:06:55 +0000 Subject: New Python implementation In-Reply-To: <87sg62urww.fsf@nightsong.com> References: <87sg62urww.fsf@nightsong.com> Message-ID: On 11/02/2021 23:05, Paul Rubin wrote: > Mr Flibble writes: >> "neos" - https://neos.dev/ https://github.com/i42output/neos > > Good luck, let us know when it is done. What is there doesn't look like > a credible start so far, but maybe you will surprise us. Have you > actually written any code in the languages you say you are going to > support? E.g. Ada, Haskell, Rust. I'd agree that Python is fairly > simple compared to those. Not credible? On what do you base that analysis? /Flibble -- ? From python-list at andras.tantosonline.com Thu Feb 11 21:40:10 2021 From: python-list at andras.tantosonline.com (Andras Tantos) Date: Thu, 11 Feb 2021 18:40:10 -0800 Subject: super() in injected methods In-Reply-To: <389382e8-b794-30f8-7179-a4b738adbbca@tantosonline.com> References: <389382e8-b794-30f8-7179-a4b738adbbca@tantosonline.com> Message-ID: <2805a092-4f8f-ba79-f964-2fad6bcf27f9@andras.tantosonline.com> Chris, Thanks for the reply! On 2/11/21 11:08 AM, Chris Angelico wrote: > On Fri, Feb 12, 2021 at 5:54 AM Andras Tantos > wrote: >> Esteemed Python Gurus, >> >> I think, I actually know the answer to this question, but - maybe beyond >> reason - I'm hoping there to be some magic. Consider the following code: >> >> from types import MethodType >> >> class A(object): >> pass >> def m(self, x): >> print(f"A.m({x})") >> class B(A): >> def m(self, x): >> print(f"B.m({x})") >> ss = super() >> ss.m(x) >> >> def method(self, s): >> print(f"method({s})") >> try: >> ss = super() # <-- Complains about __class__ cell not being >> found >> except: >> print("I shouldn't need to do this!") >> ss = super(type(self), self) # <-- Works just fine >> ss.m(s) >> >> a = B() >> a.m(41) >> a.m = MethodType(method, a) >> a.m(42) >> >> >> In the function 'method', I try to access the super() class. Now, of >> course that makes no sense as a stand-alone function, but it does, once >> it gets injected as a method into 'a' below. >> >> The two-parameter version of the call of course works without a hitch. > Be careful: the first parameter is supposed to be the class that > you're currently implementing, which may well NOT be type(self). Given > that you're attaching to an instance, though, it's probably okay to > assume you are looking at the leaf class. Good point, thanks for raising it. That is the of course the reason it's not implemented that way by the interpreter. In this particular instance that happens to be the correct answer, but generally no, it's not the same. > >> I think I actually understand why this is happening (some interpreter >> magic around super() forcing the insertion of __class__, which that >> doesn't happen when parsing a stand-alone function). I think I even >> understand the rationale for it, which is that super() needs to be >> statically evaluated. > What happens in the normal case is that __class__ is accessed via > closure cell from the class block itself. The compiler translates > super() into super(__class__, self) where 'self' is actually 'whatever > the first parameter is'. > >> Now to the question though: In theory this information (static type of >> 'self' at the point of method binding to class) is available at the >> point of method injection, in this example, the next-to-last line of the >> code. So, is there a way to somehow >> inject/override/magically-make-it-appear the __class__ cell in 'method' >> such that super() starts working as expected again? >> > Hmm. I don't think it'd work for technical reasons, but in theory, the > MethodType constructor would be the place to do this. But injecting > methods into instances (as opposed to classes) is a sufficiently > unusual thing that it's probably safest to just use the two-arg super > and have done with it. > Yes, MethodType could be a place to deal with this, but - since it doesn't - I'm looking for any way to do it outside of it. The question of packaging it up into a neat API can wait for another day. Andras From python-list at andras.tantosonline.com Thu Feb 11 21:39:41 2021 From: python-list at andras.tantosonline.com (Andras Tantos) Date: Thu, 11 Feb 2021 18:39:41 -0800 Subject: super() in injected methods In-Reply-To: References: Message-ID: <07b74cb4-4b0a-dd2c-b37b-7d93662b9f12@andras.tantosonline.com> On 2/11/21 1:43 PM, Greg Ewing wrote: > On 12/02/21 7:05 am, Andras Tantos wrote: > >> ??? ?a = B() >> ??? ?a.m(41) >> ??? ?a.m = MethodType(method, a) >> ??? ?a.m(42) > > Are you sure you really need to inject methods into instances > like this? What problem are you trying to solve by doing so? > There's almost certainly a better way to approach it. > Greg, This is going to be a long a convoluted story, but since, you've asked... I'm developing a library to describe hardware (RTL) in Python and convert it into Verilog (or potentially other languages). In this project, I have two concepts: 1. Ports, which are the connection points on the various netlist entities. These would be the inputs and outputs of an AND gate for example 2. NetTypes, which describe the type of data that can travel through a net (and thus through a Port). One such type would be an 8-bit signed integer, or a simple logic signal. There are derived types of the Port object (for inputs and outputs etc.) as well as of NetType (for signed integers, structs, etc.) An interesting aspect of the problem is that most ports don't need to have a type initially: it can be deduced from the connectivity (netlist) of the circuit described. So, for example the above mentioned AND gate can handle any input as long as they are of the same NetType and produce an output of the same NetType. This is to say, that Ports have an optional NetType, the association between Port and NetType is dynamic and changes during the lifetime of the Port instance. There are two ways I can think of modelling this in Python: 1. A (derived) Port instance uses multiple-inheritance to also inherit from it's (derived) NetType 2. A (derived) Port instance has a member of a (derived) NetType instance I went with #2 in my current implementation. Now, when a Port gets assigned a NetType, it needs to gain all sorts of new features. It for example should have a 'length' attribute that tells how many bits are needed to represent its possible values. The list of these new features (attributes, methods, properties) are known to the NetType and should be injected into the Port when the NetType is assigned to the Port. With #1, the situation is different, but not any less complicated: now, the features are automatically appear in the Port instance (maybe even too much so) but we dynamically mess with the inheritance tree of the type of the Port instance. The example I've written up deals with the problems when I try to inject these new features into the Port instance (say a new method) and the method implementation intends to call back the base-class behavior for some reason. I believe even #1 could have similar problems in different ways though: since I manipulate the inheritance chain dynamically, I don't think there's a guarantee that the statically determined '__class__' cell will be the same as the dynamically expected one. Andras From cs at cskk.id.au Thu Feb 11 23:05:41 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Fri, 12 Feb 2021 15:05:41 +1100 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On 11Feb2021 20:22, duncan smith wrote: > It seems that I can mutate a deque while iterating over it if I >assign to an index, but not if I append to it. Is this the intended >behaviour? It seems a bit inconsistent. Cheers. I think that just means that the deque didn't _notice_ your change in the former case. Not necessarily that it wouldn't want to. I confess to not being sure that appending to a deque during an iteration should be a bad thing, except that with a bounded deque that might entail discarding the element at your current iteration point. Maybe. Cheers, Cameron Simpson From greg.ewing at canterbury.ac.nz Fri Feb 12 01:35:36 2021 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 12 Feb 2021 19:35:36 +1300 Subject: super() in injected methods In-Reply-To: References: <07b74cb4-4b0a-dd2c-b37b-7d93662b9f12@andras.tantosonline.com> Message-ID: On 12/02/21 3:39 pm, Andras Tantos wrote: > Now, when a Port gets assigned a NetType, it needs to gain all sorts of > new features. It for example should have a 'length' attribute that tells > how many bits are needed to represent its possible values. The way I would probably approach this is to have a single Port type with all the methods that might be required, and forward their implementations to the NetType. e.g. class Port: @property def length(self): return self.net_type.length Another possibility might be to change the __class__ of the port object at run time to a subclass of Port having the required features. That would be a lot easier and more efficient than adding individual methods to every Port instance, and super() should work normally. -- Greg From python-list at andras.tantosonline.com Fri Feb 12 13:15:40 2021 From: python-list at andras.tantosonline.com (Andras Tantos) Date: Fri, 12 Feb 2021 10:15:40 -0800 Subject: super() in injected methods In-Reply-To: References: <07b74cb4-4b0a-dd2c-b37b-7d93662b9f12@andras.tantosonline.com> Message-ID: <86f36524-9efc-43ab-b476-86cdf17f7dd1@andras.tantosonline.com> On 2/11/21 10:35 PM, Greg Ewing wrote: > On 12/02/21 3:39 pm, Andras Tantos wrote: >> Now, when a Port gets assigned a NetType, it needs to gain all sorts >> of new features. It for example should have a 'length' attribute that >> tells how many bits are needed to represent its possible values. > > The way I would probably approach this is to have a single > Port type with all the methods that might be required, and > forward their implementations to the NetType. > > e.g. > > class Port: > > ??? @property > ??? def length(self): > ??????? return self.net_type.length > > Another possibility might be to change the __class__ of the port > object at run time to a subclass of Port having the required > features. That would be a lot easier and more efficient than > adding individual methods to every Port instance, and super() > should work normally. > That's actually a pretty good idea, thanks! Let me turn it around in my head to see how to integrate it into the library. Thanks again, Andras From alan.gauld at yahoo.co.uk Thu Feb 11 19:15:57 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 12 Feb 2021 00:15:57 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 11/02/2021 12:30, Mr Flibble wrote: > I am starting work on creating a new Python implementation > from scratch using "neos" my universal compiler that can > compile any programming language. Can i clarify that? Are you saying that you are going to recompile the existing C code for pyhton using yoour universal compiler and the resulting binary file will be a new implementation of the interpreter that you expect to be faster? That's what it sounds like to me. In which case the question is not whether you can write a better interpreter than CPython but whether you can write a better compiler than GNU/MING/VC etc While a universal compiler is certainly an interesting and challenging project I'm not sure how much it tells us about existing Python implementations. On the other hand, if you are planning on rewriting the existing interpreter in something other than C, what is that something? > Sample neos session (parsing a fibonacci program, > neoscript rather than Python in this case): I'm not sure what relevance this has unless you want to rewrite Python in neoscript? Or are you translating the C into neoscript and then compiling it? But in a later response you seem to say neoscript was not involved? Slightly confused... -- 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 From tjreedy at udel.edu Thu Feb 11 21:45:05 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 11 Feb 2021 21:45:05 -0500 Subject: New Python implementation In-Reply-To: References: Message-ID: On 2/11/2021 5:33 PM, Mr Flibble wrote: > On 11/02/2021 22:25, Dan Stromberg wrote: >> On Thu, Feb 11, 2021 at 2:00 PM Mr Flibble >> >> wrote: >> >>> On 11/02/2021 21:13, Dan Stromberg wrote: >>>> Does your project have a name yet?? I'd like to follow it through >>>> google >>>> alerts or an announcement mailing list. >>> >>> "neos" - https://neos.dev/ https://github.com/i42output/neos >>> >> >> Pypi already appears to have another project named neos: >> https://pypi.org/project/neos/ > > neos isn't a Python package so that isn't a problem. Since it obviously is a Python package, as in importable into a Python program, why do you deny it? -- Terry Jan Reedy From tjreedy at udel.edu Thu Feb 11 21:53:07 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 11 Feb 2021 21:53:07 -0500 Subject: @unittest.skip doesn't print anything in Python <= 3.7 In-Reply-To: References: Message-ID: On 2/11/2021 3:25 PM, ???? wrote: > Hi, > > https://stackoverflow.com/questions/66161394/unittest-skip-doesnt-print-anything-in-python-3-7 > > We are using Django with unittest. Some tests are skipped with the > @unittest.skip decorator. But if I run the tests with Python 3.6 or 3.7, I > get a number of tests passed (Ran 993 tests / OK), and if I run the same > tests with Python 3.8, I get the same number of tests but with some tests > skipped (Ran 993 tests / OK (skipped=4)). ... > I think the skipped tests are skipped in all Python versions, but in Python > 3.6 and 3.7 there is no output about them being skipped. Is it a bug? Perhaps you have discover a bug in 3.7 that was fixed in 3.8. Each new version comes with a few hundred bug fixes, not just the new features, although only the latter are featured in the new version announcement. If you are really concerned, find What's New in 3.8 and look changelog, linked in the first paragraph, for 'unittest' issues. -- Terry Jan Reedy From tjreedy at udel.edu Thu Feb 11 22:04:37 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 11 Feb 2021 22:04:37 -0500 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On 2/11/2021 3:22 PM, duncan smith wrote: > It seems that I can mutate a deque while iterating over it if I > assign to an index, but not if I append to it. Is this the intended > behaviour? Does the deque doc say anything about mutation while iterating? (Knowing the author of deque, I would consider everything about it intentional without *good* reason to think otherwise. >>>> from collections import deque >>>> d = deque(range(8)) >>>> it = iter(d) >>>> next(it) > 0 >>>> d[1] = 78 This does not change the structure of the deque, so next does not notice. It could be considered not be a mutation. It could be detected by changing deque.__setitem__, but why bother and slow down all __setitem__ calls. >>>> next(it) > 78 >>>> d.append(8) This changes the structure, which can apparently mess-up iteration. >>>> next(it) > Traceback (most recent call last): > File "", line 1, in > next(it) > RuntimeError: deque mutated during iteration >>>> -- Terry Jan Reedy From alan.gauld at yahoo.co.uk Fri Feb 12 04:35:39 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 12 Feb 2021 09:35:39 +0000 Subject: super() in injected methods In-Reply-To: <07b74cb4-4b0a-dd2c-b37b-7d93662b9f12@andras.tantosonline.com> References: <07b74cb4-4b0a-dd2c-b37b-7d93662b9f12@andras.tantosonline.com> Message-ID: On 12/02/2021 02:39, Andras Tantos wrote: > 1. Ports, which are the connection points on the various netlist > entities. These would be the inputs and outputs of an AND gate for example > > 2. NetTypes, which describe the type of data that can travel through a > net (and thus through a Port). One such type would be an 8-bit signed > integer, or a simple logic signal. > 2. A (derived) Port instance has a member of a (derived) NetType instance Sounds like the right solution. > Now, when a Port gets assigned a NetType, it needs to gain all sorts of > new features. It for example should have a 'length' attribute that tells > how many bits are needed to represent its possible values. The list of > these new features (attributes, methods, properties) are known to the > NetType and should be injected into the Port when the NetType is > assigned to the Port. So aren't these operations of the type rather than the port. If you expose the type the users can message it directly. n = myport.type.length() Keep the responsibility with the object that owns them. Creating a facade over another object is sometimes useful but a dynamic facade sounds like trouble. Client code is going to have to know which methods exist and when. Can you ever change the type? What happens to the injected methods, do you need to remove them and replace them with others? -- 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 From tony.ogilvie at ogilvie89.plus.com Fri Feb 12 13:29:48 2021 From: tony.ogilvie at ogilvie89.plus.com (Tony Ogilvie) Date: Fri, 12 Feb 2021 18:29:48 -0000 Subject: PSYCOPG2 Message-ID: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> I am trying to write a program to open a PostgesSQL 13 database using psycopg2. All seems to work if I write direct to Python but if I write the script into IDLE it does not work with the IDLE Shell 3.9.1 reporting an error of no attribute 'connect'. I have tried many options to try and get this to work. Regards Tony From flibble at i42.REMOVETHISBIT.co.uk Fri Feb 12 16:42:53 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Fri, 12 Feb 2021 21:42:53 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 12/02/2021 02:45, Terry Reedy wrote: > On 2/11/2021 5:33 PM, Mr Flibble wrote: >> On 11/02/2021 22:25, Dan Stromberg wrote: >>> On Thu, Feb 11, 2021 at 2:00 PM Mr Flibble >>> wrote: >>> >>>> On 11/02/2021 21:13, Dan Stromberg wrote: >>>>> Does your project have a name yet?? I'd like to follow it through google >>>>> alerts or an announcement mailing list. >>>> >>>> "neos" - https://neos.dev/ https://github.com/i42output/neos >>>> >>> >>> Pypi already appears to have another project named neos: >>> https://pypi.org/project/neos/ >> >> neos isn't a Python package so that isn't a problem. > > Since it obviously is a Python package, as in importable into a Python program, why do you deny it? You are mistaken: it isn't a Python package and it isn't importable into a Python program. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Fri Feb 12 16:46:24 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Fri, 12 Feb 2021 21:46:24 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 12/02/2021 00:15, Alan Gauld wrote: > On 11/02/2021 12:30, Mr Flibble wrote: > >> I am starting work on creating a new Python implementation >> from scratch using "neos" my universal compiler that can >> compile any programming language. > > Can i clarify that? > Are you saying that you are going to recompile the existing > C code for pyhton using yoour universal compiler and the > resulting binary file will be a new implementation of > the interpreter that you expect to be faster? Nope. > > That's what it sounds like to me. > In which case the question is not whether you can write a > better interpreter than CPython but whether you can write > a better compiler than GNU/MING/VC etc See previous answer. > > While a universal compiler is certainly an interesting > and challenging project I'm not sure how much it tells us > about existing Python implementations. The two things are unrelated; however it is well known that Python is slow. > > On the other hand, if you are planning on rewriting the > existing interpreter in something other than C, what > is that something? Nope. > >> Sample neos session (parsing a fibonacci program, >> neoscript rather than Python in this case): > > I'm not sure what relevance this has unless you want > to rewrite Python in neoscript? Or are you translating > the C into neoscript and then compiling it? But in a > later response you seem to say neoscript was not involved? > > Slightly confused... > The neos Python implementation will consist of a schema file which describes the language plus any Python-specific semantic concepts that don't generalize to more than one language. /Flibble -- ? From alan.gauld at yahoo.co.uk Fri Feb 12 19:01:33 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 13 Feb 2021 00:01:33 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 12/02/2021 21:46, Mr Flibble wrote: > The neos Python implementation will consist of a schema file > which describes the language plus any Python-specific semantic concepts So the schema file is some kind of formal grammar definition of the language? And you "compile" this directly into machine code? Is that the idea? So when you say you have a universal compiler for any language what you mean is that you can produce a compiler/interpreter for any language from a language definition/schema. Is that it? I'm still not sure I understand what exactly you are proposing to do. What the final output looks like? I'm assuming it's a new executable interpreter that can run any valid python code. Is that correct? -- 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 From mgogala at yahoo.com Sat Feb 13 00:34:48 2021 From: mgogala at yahoo.com (Mladen Gogala) Date: Sat, 13 Feb 2021 05:34:48 +0000 (UTC) Subject: PSYCOPG2 References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> Message-ID: On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > I am trying to write a program to open a PostgesSQL 13 database using > psycopg2. All seems to work if I write direct to Python but if I write > the script into IDLE it does not work with the IDLE Shell 3.9.1 > reporting an error of no attribute 'connect'. > > > > I have tried many options to try and get this to work. > > > > Regards > > > > Tony It looks like your idle is not using the same interpreter that you are using when writing direct code. Anyway, my advice would be to ditch Idle and use VSCode. It's fabulous. -- Mladen Gogala Database Consultant https://dbwhisperer.wordpress.com From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 11:09:50 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sat, 13 Feb 2021 16:09:50 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 13/02/2021 00:01, Alan Gauld wrote: > On 12/02/2021 21:46, Mr Flibble wrote: > >> The neos Python implementation will consist of a schema file >> which describes the language plus any Python-specific semantic concepts > > So the schema file is some kind of formal grammar definition of > the language? > > And you "compile" this directly into machine code? > Is that the idea? > > So when you say you have a universal compiler for any language > what you mean is that you can produce a compiler/interpreter > for any language from a language definition/schema. Is that it? > > I'm still not sure I understand what exactly you are proposing > to do. What the final output looks like? > > I'm assuming it's a new executable interpreter that can run any > valid python code. Is that correct? It is a universal *compiler* so it compiles the python code to byte code and then optionally to machine code via a JIT which is then executed. /Flibble -- ? From tjreedy at udel.edu Sat Feb 13 01:56:44 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 13 Feb 2021 01:56:44 -0500 Subject: New Python implementation In-Reply-To: References: Message-ID: On 2/12/2021 4:42 PM, Mr Flibble wrote: > On 12/02/2021 02:45, Terry Reedy wrote: >> On 2/11/2021 5:33 PM, Mr Flibble wrote: >>> On 11/02/2021 22:25, Dan Stromberg wrote: >>>> On Thu, Feb 11, 2021 at 2:00 PM Mr Flibble >>>> >>>> wrote: >>>> >>>>> On 11/02/2021 21:13, Dan Stromberg wrote: >>>>>> Does your project have a name yet?? I'd like to follow it through >>>>>> google >>>>>> alerts or an announcement mailing list. >>>>> >>>>> "neos" - https://neos.dev/ https://github.com/i42output/neos >>>>> >>>> >>>> Pypi already appears to have another project named neos: >>>> https://pypi.org/project/neos/ >>> >>> neos isn't a Python package so that isn't a problem. >> >> Since it obviously is a Python package, as in importable into a Python >> program, why do you deny it? > > You are mistaken: it isn't a Python package and it isn't importable into > a Python program. https://pypi.org/project/neos/ shows import neos.makers as makers import neos.cls as cls When you wrote 'neos' without qualification right after the neos package url, I though you were referring to the package, not your neos. My mistake and your unclear writing. -- Terry Jan Reedy From duncan at invalid.invalid Sat Feb 13 13:20:22 2021 From: duncan at invalid.invalid (duncan smith) Date: Sat, 13 Feb 2021 18:20:22 +0000 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On 12/02/2021 03:04, Terry Reedy wrote: > On 2/11/2021 3:22 PM, duncan smith wrote: > >> ?????? It seems that I can mutate a deque while iterating over it if I >> assign to an index, but not if I append to it. Is this the intended >> behaviour? > > Does the deque doc say anything about mutation while iterating? (Knowing > the author of deque, I would consider everything about it intentional > without *good* reason to think otherwise. > >>>>> from collections import deque >>>>> d = deque(range(8)) >>>>> it = iter(d) >>>>> next(it) >> 0 >>>>> d[1] = 78 > > This does not change the structure of the deque, so next does not > notice.? It could be considered not be a mutation.? It could be detected > by changing deque.__setitem__, but why bother and slow down all > __setitem__ calls. > >>>>> next(it) >> 78 >>>>> d.append(8) > > This changes the structure, which can apparently mess-up iteration. > >>>>> next(it) >> Traceback (most recent call last): >> ?? File "", line 1, in >> ???? next(it) >> RuntimeError: deque mutated during iteration >>>>> > > What I was really wondering was whether the behaviour is as it is because of the implementation or because it's how deques should ideally behave. i.e. In my implementation do I stick strictly to the same API, or allow it to differ? In some places I'm jumping through hoops to stick to the API, and (when it comes to iteration) I'm jumping through different hoops for different types of container (e.g. lists versus deques). BTW, the reason I am implementing these at all is that my containers are on-disk. Cheers. Duncan From nulla.epistola at web.de Sat Feb 13 13:48:52 2021 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sat, 13 Feb 2021 19:48:52 +0100 Subject: PSYCOPG2 In-Reply-To: References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> Message-ID: <90bfa686-fb54-d052-a67b-11d038bac089@web.de> Am 13.02.2021 um 06:34 schrieb Mladen Gogala via Python-list: > On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > >> I am trying to write a program to open a PostgesSQL 13 database using >> psycopg2. All seems to work if I write direct to Python but if I write >> the script into IDLE it does not work with the IDLE Shell 3.9.1 >> reporting an error of no attribute 'connect'. >> >> I have tried many options to try and get this to work. >> > > It looks like your idle is not using the same interpreter that you are > using when writing direct code. Anyway, my advice would be to ditch Idle > and use VSCode. It's fabulous. > That may or may not circumvent the problem but it won't help in clearing up the cause. Without any code and without the exact error message we can only guess. I'm translating "an error of no attribute 'connect'" into "AttributeError: module 'psycopg2' has no attribute 'connect'". Right? If yes, that would mean a module with this name was imported, but it wasn't the right module. Did you perhaps give that same name to some Python script you wrote yourself? In that case the call to 'connect' would work if and only if you start your program from a directory that doesn't contain this script. But of course you should rename it so it doesn't clash with a module of the standard library. I think problems with different interpreters would rather result in a ModuleNotFoundError, wouldn't they? HTH Sibylle From nulla.epistola at web.de Sat Feb 13 13:48:52 2021 From: nulla.epistola at web.de (Sibylle Koczian) Date: Sat, 13 Feb 2021 19:48:52 +0100 Subject: PSYCOPG2 In-Reply-To: References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> Message-ID: <90bfa686-fb54-d052-a67b-11d038bac089@web.de> Am 13.02.2021 um 06:34 schrieb Mladen Gogala via Python-list: > On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > >> I am trying to write a program to open a PostgesSQL 13 database using >> psycopg2. All seems to work if I write direct to Python but if I write >> the script into IDLE it does not work with the IDLE Shell 3.9.1 >> reporting an error of no attribute 'connect'. >> >> I have tried many options to try and get this to work. >> > > It looks like your idle is not using the same interpreter that you are > using when writing direct code. Anyway, my advice would be to ditch Idle > and use VSCode. It's fabulous. > That may or may not circumvent the problem but it won't help in clearing up the cause. Without any code and without the exact error message we can only guess. I'm translating "an error of no attribute 'connect'" into "AttributeError: module 'psycopg2' has no attribute 'connect'". Right? If yes, that would mean a module with this name was imported, but it wasn't the right module. Did you perhaps give that same name to some Python script you wrote yourself? In that case the call to 'connect' would work if and only if you start your program from a directory that doesn't contain this script. But of course you should rename it so it doesn't clash with a module of the standard library. I think problems with different interpreters would rather result in a ModuleNotFoundError, wouldn't they? HTH Sibylle From drsalists at gmail.com Sat Feb 13 14:12:50 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 13 Feb 2021 11:12:50 -0800 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On Sat, Feb 13, 2021 at 10:25 AM duncan smith wrote: > On 12/02/2021 03:04, Terry Reedy wrote: > > On 2/11/2021 3:22 PM, duncan smith wrote: > > > >> It seems that I can mutate a deque while iterating over it if I > >> assign to an index, but not if I append to it. Is this the intended > >> behaviour? > > What I was really wondering was whether the behaviour is as it is > because of the implementation or because it's how deques should ideally > behave. i.e. In my implementation do I stick strictly to the same API, > or allow it to differ? In some places I'm jumping through hoops to stick > to the API, and (when it comes to iteration) I'm jumping through > different hoops for different types of container (e.g. lists versus > deques). BTW, the reason I am implementing these at all is that my > containers are on-disk. Cheers. > > collections.deque appears to take the approach of "allow everything we can based on our implementation, and trust the client not to overuse features". In fact, in Python, "over abstraction" is often seen as a bad thing, mostly because it slows things down so much. If you want something more abstracted, you might have a look at: https://stromberg.dnsalias.org/~strombrg/linked-list/ https://pypi.org/project/linked_list_mod/ (Both URL's are about the same module) Note that linked_list_mod is quite a bit slower than a collections.deque. Deques use a clever-but-hidden trick to gain a lot of speed - it's really a linked list of built in lists, which gives better locality of reference that masks CPU caches very happy. linked_list_mod goes for abstraction and simplicity. From avigross at verizon.net Sat Feb 13 14:38:41 2021 From: avigross at verizon.net (Avi Gross) Date: Sat, 13 Feb 2021 14:38:41 -0500 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: <170c01d7023f$d5dd6310$81982930$@verizon.net> I agree both with the idea that it is not good to mutate things during iteration and that some things we want to do may seemingly require effectively something like a mutation. I want to consider what data structure might capture a normal activity like having a to-do-list for TODAY and another for further in the future. I might sit down in the morning and look at my day and the list of activities I was going to do. I might note new activities to add, some that are done or moot and can be removed and some that should be done earlier or deferred to later or even into the next day. This does not seem easy to do iteratively. Weirder, if I throw each item at the end, I end up with the same items in the same order. So creating a data structure (such as an object like a deque but with more specific functionality) might take some work. To begin, you might want an iteration protocol that locks it till done. Not necessarily because of mutation, though. Within the iteration you might have code asking for what I might consider delayed actions. You can ask for the current item to be deleted or moved to a data structure for the next day and it will not be done now but some reference might be stored inside the object such as a DELETE list and a MOVE list. You may also have lists with names like HIGH, MEDIUM and LOW or priorities from 1 to N. I don't mean python lists, just some kind of way of assigning some meaning to each item as you go. You may even want a way to break a task into multiple parts or declare a dependency between them such as one having to be done before the other. When you are done iterating, presumably the data structure will then reorder itself in a scenario where mutability is done harmlessly and a new list or deque or whatever is reconstituted and you can unlock. I do note that years ago I took a course in time management that ended up spending way too much time doing this kind of task on paper multiple time a day with lots of erasing or rewriting. The idea was to get more of the important things done. These days, I am so interrupt-driven that such a system is not useful albeit a nice automated way might be helpful as my day constantly mutates to become unrecognizable. There are project management tools along the lines I describe that try to manage timelines and dependencies across multiple groups and measure deliverables and note when something will cause delays in others and so on. Obviously, beyond the scope but my point is they do not necessarily operate in one pass over the list and are quite a bit more complex. -----Original Message----- From: Python-list On Behalf Of Dan Stromberg Sent: Saturday, February 13, 2021 2:13 PM To: duncan smith Cc: Python List Subject: Re: mutating a deque whilst iterating over it On Sat, Feb 13, 2021 at 10:25 AM duncan smith wrote: > On 12/02/2021 03:04, Terry Reedy wrote: > > On 2/11/2021 3:22 PM, duncan smith wrote: > > > >> It seems that I can mutate a deque while iterating over it > >> if I assign to an index, but not if I append to it. Is this the > >> intended behaviour? > > What I was really wondering was whether the behaviour is as it is > because of the implementation or because it's how deques should > ideally behave. i.e. In my implementation do I stick strictly to the > same API, or allow it to differ? In some places I'm jumping through > hoops to stick to the API, and (when it comes to iteration) I'm > jumping through different hoops for different types of container (e.g. > lists versus deques). BTW, the reason I am implementing these at all > is that my containers are on-disk. Cheers. > > collections.deque appears to take the approach of "allow everything > we can based on our implementation, and trust the client not to overuse features". In fact, in Python, "over abstraction" is often seen as a bad thing, mostly because it slows things down so much. If you want something more abstracted, you might have a look at: https://stromberg.dnsalias.org/~strombrg/linked-list/ https://pypi.org/project/linked_list_mod/ (Both URL's are about the same module) Note that linked_list_mod is quite a bit slower than a collections.deque. Deques use a clever-but-hidden trick to gain a lot of speed - it's really a linked list of built in lists, which gives better locality of reference that masks CPU caches very happy. linked_list_mod goes for abstraction and simplicity. -- https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Sat Feb 13 15:21:05 2021 From: PythonList at DancesWithMice.info (dn) Date: Sun, 14 Feb 2021 09:21:05 +1300 Subject: PSYCOPG2 In-Reply-To: References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> Message-ID: On 13/02/2021 18.34, Mladen Gogala via Python-list wrote: > On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > >> I am trying to write a program to open a PostgesSQL 13 database using >> psycopg2. All seems to work if I write direct to Python but if I write >> the script into IDLE it does not work with the IDLE Shell 3.9.1 >> reporting an error of no attribute 'connect'. >> >> I have tried many options to try and get this to work. Please copy-paste the code of at least one of these "options", together with the full error-listing. Before using the connect function, the module must be import-ed. Has this been done? If so, an error with connect() probably indicates a problem with the function call, eg locating the database. - as said, really difficult without seeing any code and the err.msgs generated! > It looks like your idle is not using the same interpreter that you are > using when writing direct code. Anyway, my advice would be to ditch Idle > and use VSCode. It's fabulous. Would it? Surely if the issue is 'connecting bits together', regardless one still has to learn the tool and how it works/expects things to be organised? So, rather than helping the OP with a Postgres/Python/psycopg2 linkage problem, hasn't (s)he now been presented with an extra learning load? Regardless, rather than recommending that people send their 'telemetry/tracking data' to MSFT, why not suggest VSCodium (https://vscodium.com/) - the same open-source IDE, before any such 'extras' are added. Disclaimer: I do not use or publish Idle, VS-Code, or VSCodium, and have nothing to gain/lose by MSFT collecting data about what you are doing with the help of 'their' product. -- Regards, =dn From tony.ogilvie at ogilvie89.plus.com Sat Feb 13 17:08:11 2021 From: tony.ogilvie at ogilvie89.plus.com (Tony Ogilvie) Date: Sat, 13 Feb 2021 22:08:11 -0000 Subject: PSYCOPG2 In-Reply-To: References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> Message-ID: <000501d70254$b8d9d130$2a8d7390$@ogilvie89.plus.com> Thank you I have tried Sublime 3 and the same thing happens. I do not think I have another version of Python on my PC. I am trying to look through my files to find out. Regards Tony -----Original Message----- From: Mladen Gogala Sent: 13 February 2021 05:35 To: python-list at python.org Subject: Re: PSYCOPG2 On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > I am trying to write a program to open a PostgesSQL 13 database using > psycopg2. All seems to work if I write direct to Python but if I write > the script into IDLE it does not work with the IDLE Shell 3.9.1 > reporting an error of no attribute 'connect'. > > > > I have tried many options to try and get this to work. > > > > Regards > > > > Tony It looks like your idle is not using the same interpreter that you are using when writing direct code. Anyway, my advice would be to ditch Idle and use VSCode. It's fabulous. -- Mladen Gogala Database Consultant https://dbwhisperer.wordpress.com From alan.gauld at yahoo.co.uk Sat Feb 13 13:11:40 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 13 Feb 2021 18:11:40 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 13/02/2021 16:09, Mr Flibble wrote: > On 13/02/2021 00:01, Alan Gauld wrote: >> I'm assuming it's a new executable interpreter that can run any >> valid python code. Is that correct? > > It is a universal *compiler* so it compiles the python code to byte code > and then optionally to machine code via a JIT which is then executed. OK, sorry for being dense, but just to be absolutely clear. You are going to create a Python compiler that will take existing Python code and output a byte code file. (I assume the byte code is not standard Python byte code?) And I assume the execution environment for the bytecode is part of your neos system? If that's correct, then how do you propose to deal with regular Python byte code? And what would the Python disassembler produce - Python assembler instructions or neos? -- 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 From ikorot01 at gmail.com Sat Feb 13 18:30:14 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Sat, 13 Feb 2021 15:30:14 -0800 Subject: New Python implementation In-Reply-To: References: Message-ID: Hi, But most importantly - what is the reason for this ? I mean - what problems the actual python compiler produce? Thank you. On Sat, Feb 13, 2021, 3:26 PM Alan Gauld via Python-list < python-list at python.org> wrote: > On 13/02/2021 16:09, Mr Flibble wrote: > > On 13/02/2021 00:01, Alan Gauld wrote: > >> I'm assuming it's a new executable interpreter that can run any > >> valid python code. Is that correct? > > > > It is a universal *compiler* so it compiles the python code to byte code > > and then optionally to machine code via a JIT which is then executed. > > OK, sorry for being dense, but just to be absolutely clear. > > You are going to create a Python compiler that will take existing > Python code and output a byte code file. (I assume the byte code > is not standard Python byte code?) And I assume the execution > environment for the bytecode is part of your neos system? > > If that's correct, then how do you propose to deal with > regular Python byte code? And what would the Python disassembler > produce - Python assembler instructions or neos? > > -- > 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 > From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 19:07:13 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 00:07:13 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 13/02/2021 18:11, Alan Gauld wrote: > On 13/02/2021 16:09, Mr Flibble wrote: >> On 13/02/2021 00:01, Alan Gauld wrote: >>> I'm assuming it's a new executable interpreter that can run any >>> valid python code. Is that correct? >> >> It is a universal *compiler* so it compiles the python code to byte code >> and then optionally to machine code via a JIT which is then executed. > > OK, sorry for being dense, but just to be absolutely clear. > > You are going to create a Python compiler that will take existing > Python code and output a byte code file. (I assume the byte code > is not standard Python byte code?) And I assume the execution > environment for the bytecode is part of your neos system? No neos is not a Python compiler: it is a *universal* compiler that can compile any programming language describable by a schema file and any language-specific semantic concepts. The byte code will be proprietary, yes, and will be executed by neos and/or JITed. > > If that's correct, then how do you propose to deal with > regular Python byte code? And what would the Python disassembler > produce - Python assembler instructions or neos? The neos Python implementation will not be dealing with Python byte code in any form whatsoever. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 19:09:26 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 00:09:26 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 13/02/2021 23:30, Igor Korot wrote: > Hi, > But most importantly - what is the reason for this ? > I mean - what problems the actual python compiler produce? > > Thank you. I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. /Flibble -- ? From rosuav at gmail.com Sat Feb 13 19:19:26 2021 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 14 Feb 2021 11:19:26 +1100 Subject: New Python implementation In-Reply-To: References: Message-ID: On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble wrote: > > On 13/02/2021 23:30, Igor Korot wrote: > > Hi, > > But most importantly - what is the reason for this ? > > I mean - what problems the actual python compiler produce? > > > > Thank you. > > I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. > Until you have actually produced a (mostly) compatible Python implementation, can you please stop making these repeated and baseless jabs at CPython's performance? You keep stating or hinting that CPython is somehow unnecessarily slow, but unless you have some code to back your claims, this is nothing but mudslinging. CPython is not as slow as you might think. And PyPy is highly efficient at what it does well. Show us that you can do better than these before you call them slow. At the absolute least, show that you have something that can run Python code. ChrisA From avigross at verizon.net Sat Feb 13 19:47:47 2021 From: avigross at verizon.net (Avi Gross) Date: Sat, 13 Feb 2021 19:47:47 -0500 Subject: New Python implementation In-Reply-To: References: Message-ID: <1c8401d7026b$041c2ab0$0c548010$@verizon.net> It is likely that people would understand better if spoken to properly so I have been listening and hopefully gaining a picture that I can share, and be corrected helpfully when wrong. My personal guess is that the project at hand is to do something very vaguely like what was done to the CURSES functionality ages ago in prehistory where lots of different terminals (and terminal emulators) used an assortment of control and escape sequences to make a text-based terminal do things like delete to the end of a line. The idea was to extract out all kinds of functionality used by pretty much all the terminals and save the info for say the hp2621 terminal either in a file with that name, or as entries in a file specifying many terminals or even in your environment. Then you made sure you had some variable like TERM set to hp2621 or whatever. If later you logged in on another kind of terminal, it would adjust dynamically for that without changing your program. When a program like vi(m) or emacs ran, it used the curses library which would dynamically reconfigure based on the terminal used and try to figure out the cheapest way (in terms of characters and I/O usually) to send extra escape sequences to update your screen as changes were made. Sometimes it would clear the screen and re-enter the new stuff and sometimes delete three lines then put in the replacement and so on. End of example. There are other examples like a format for documents that might take one of many ones like Word and make a common storage format that can easily be printed on any device that supports the features. The important aspect for me, is abstraction. My impression is the proposed project would abstract out the details of what any language can do and then examine one language after another (such as Ada or Python) and create some kind of description that can be stored, such as in a file. I have no idea what that might look like. I assume it would include what keywords there are or what variable names might look like or if some construct has an ending like "FI" or "endif" or "}" and it is only once this is completed, that the next phase can be used. It sounds like they would have what he considers a universal compiler that determines what language (perhaps even version) a file or group of files are using and then loads in info that metamorphizes it into an effective compiler for that language. It may not be that simple and I have no idea how it does that or how it outputs the result but it sounds like they have yet another language we might loosely compare to the byte stream used by JAVA and SCALA and some others that is half-digested and can be run by the JVM, or the Python version of something along those lines. In any case, I get the impression that this output will then look about the same no matter what language it came from. It will not require specific run-time environments but one overarching runtime that can run anything, again, using whatever abstraction or rules they come up with. And, in some cases, you may choose to go a step further and take this portable file format and compile it further down to an executable that runs on a specific machine and so on. I shudder at how well it will output error messages! Assuming this is feasible and well done, it might open quite a few doors in terms of designing both mini-languages and variants on existing ones and brand new ones with new ideas. You would have to find a way to describe your language as described above and as long as it is consistent in some ways, no need to ever build your own interpreter or compiler. It might be a bit like designing a new terminal (or just emulator) that has features you want. Mind you, some of the new features might require changes in the "Neo" something/data before it can be handled, but once added, any other language, within reason, might be able to add a similar feature and it should work. I hope I got this at least partially right and it is more informative that repeatedly telling people things like "Nope" as if this is a quiz and not an informative discussion. -----Original Message----- From: Python-list On Behalf Of Mr Flibble Sent: Saturday, February 13, 2021 7:07 PM To: python-list at python.org Subject: Re: New Python implementation On 13/02/2021 18:11, Alan Gauld wrote: > On 13/02/2021 16:09, Mr Flibble wrote: >> On 13/02/2021 00:01, Alan Gauld wrote: >>> I'm assuming it's a new executable interpreter that can run any >>> valid python code. Is that correct? >> >> It is a universal *compiler* so it compiles the python code to byte >> code and then optionally to machine code via a JIT which is then executed. > > OK, sorry for being dense, but just to be absolutely clear. > > You are going to create a Python compiler that will take existing > Python code and output a byte code file. (I assume the byte code is > not standard Python byte code?) And I assume the execution environment > for the bytecode is part of your neos system? No neos is not a Python compiler: it is a *universal* compiler that can compile any programming language describable by a schema file and any language-specific semantic concepts. The byte code will be proprietary, yes, and will be executed by neos and/or JITed. > > If that's correct, then how do you propose to deal with regular Python > byte code? And what would the Python disassembler produce - Python > assembler instructions or neos? The neos Python implementation will not be dealing with Python byte code in any form whatsoever. /Flibble -- ? -- https://mail.python.org/mailman/listinfo/python-list From ned at nedbatchelder.com Sat Feb 13 19:51:28 2021 From: ned at nedbatchelder.com (Ned Batchelder) Date: Sat, 13 Feb 2021 16:51:28 -0800 (PST) Subject: New Python implementation In-Reply-To: References: Message-ID: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> On Saturday, February 13, 2021 at 7:19:58 PM UTC-5, Chris Angelico wrote: > On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble > wrote: > > > > On 13/02/2021 23:30, Igor Korot wrote: > > > Hi, > > > But most importantly - what is the reason for this ? > > > I mean - what problems the actual python compiler produce? > > > > > > Thank you. > > > > I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. > > > Until you have actually produced a (mostly) compatible Python > implementation, can you please stop making these repeated and baseless > jabs at CPython's performance? You keep stating or hinting that > CPython is somehow unnecessarily slow, but unless you have some code > to back your claims, this is nothing but mudslinging. > > CPython is not as slow as you might think. And PyPy is highly > efficient at what it does well. Show us that you can do better than > these before you call them slow. > > At the absolute least, show that you have something that can run Python code. > > ChrisA The OP has been making these claims on IRC for a while (at least two years). He has never cared to substantiate them, or even participate in a civil and detailed discussion. He is either 1) smarter than all of us, or 2) woefully under-informed, or 3) trolling. Our best course is to ignore him until he has code we can try. --Ned. From mgogala at yahoo.com Sat Feb 13 20:07:49 2021 From: mgogala at yahoo.com (Mladen Gogala) Date: Sun, 14 Feb 2021 01:07:49 +0000 (UTC) Subject: PSYCOPG2 References: <000001d7016d$0d2831c0$27789540$@ogilvie89.plus.com> <000501d70254$b8d9d130$2a8d7390$@ogilvie89.plus.com> Message-ID: I don't have PSYCOPG2 on my system, but try doing the following from python: [mgogala at umajor ~]$ python3 Python 3.9.1 (default, Jan 20 2021, 00:00:00) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cx_Oracle >>> dir(cx_Oracle) ['ATTR_PURITY_DEFAULT', 'ATTR_PURITY_NEW', 'ATTR_PURITY_SELF', 'ApiType', 'BFILE', 'BINARY', 'BLOB', 'BOOLEAN', 'Binary', 'CLOB', 'CURSOR', 'Connection', 'Cursor', 'DATETIME', 'DBSHUTDOWN_ABORT', ------------ 'DBSHUTDOWN_FINAL', 'DBSHUTDOWN_IMMEDIATE', 'DBSHUTDOWN_TRANSACTIONAL', 'DBSHUTDOWN_TRANSACTIONAL_LOCAL', 'DB_TYPE_BFILE', 'DB_TYPE_BINARY_DOUBLE', 'DB_TYPE_BINARY_FLOAT', 'DB_TYPE_BINARY_INTEGER', 'DB_TYPE_BLOB', 'DB_TYPE_BOOLEAN', 'DB_TYPE_CHAR', 'DB_TYPE_CLOB', 'DB_TYPE_CURSOR', 'DB_TYPE_DATE', 'DB_TYPE_INTERVAL_DS', 'DB_TYPE_INTERVAL_YM', 'DB_TYPE_JSON', 'DB_TYPE_LONG', 'DB_TYPE_LONG_RAW', 'DB_TYPE_NCHAR', 'DB_TYPE_NCLOB', 'DB_TYPE_NUMBER', 'DB_TYPE_NVARCHAR', 'DB_TYPE_OBJECT', 'DB_TYPE_RAW', 'DB_TYPE_ROWID', 'DB_T ....................................... >>> conn=cx_Oracle.Connection("scott/tiger at ora19c") >>> Please use PSYCOPG2 instead of cx_Oracle. After you do it from python3 interpreter do it from Idle: On Sat, 13 Feb 2021 22:08:11 +0000, Tony Ogilvie wrote: > Thank you > > I have tried Sublime 3 and the same thing happens. I do not think I have > another version of Python on my PC. I am trying to look through my files > to find out. > > Regards > > Tony > > > -----Original Message----- > From: Mladen Gogala > Sent: 13 February 2021 05:35 To: python-list at python.org Subject: Re: > PSYCOPG2 > > On Fri, 12 Feb 2021 18:29:48 +0000, Tony Ogilvie wrote: > >> I am trying to write a program to open a PostgesSQL 13 database using >> psycopg2. All seems to work if I write direct to Python but if I write >> the script into IDLE it does not work with the IDLE Shell 3.9.1 >> reporting an error of no attribute 'connect'. >> >> >> >> I have tried many options to try and get this to work. >> >> >> >> Regards >> >> >> >> Tony > > It looks like your idle is not using the same interpreter that you are > using when writing direct code. Anyway, my advice would be to ditch Idle > and use VSCode. It's fabulous. -- Mladen Gogala Database Consultant https://dbwhisperer.wordpress.com From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 21:13:31 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 02:13:31 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 14/02/2021 00:19, Chris Angelico wrote: > On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble > wrote: >> >> On 13/02/2021 23:30, Igor Korot wrote: >>> Hi, >>> But most importantly - what is the reason for this ? >>> I mean - what problems the actual python compiler produce? >>> >>> Thank you. >> >> I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. >> > > Until you have actually produced a (mostly) compatible Python > implementation, can you please stop making these repeated and baseless > jabs at CPython's performance? You keep stating or hinting that > CPython is somehow unnecessarily slow, but unless you have some code > to back your claims, this is nothing but mudslinging. > > CPython is not as slow as you might think. And PyPy is highly > efficient at what it does well. Show us that you can do better than > these before you call them slow. > > At the absolute least, show that you have something that can run Python code. It isn't just me that is saying CPython is egregiously slow: it is at the bottom of the list as far as performance is concerned. Python is undoubtedly the biggest contributor to climate change of all the programming languages in mainstream use today. See: https://thenewstack.io/which-programming-languages-use-the-least-electricity/ /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 21:17:48 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 02:17:48 +0000 Subject: New Python implementation In-Reply-To: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> References: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> Message-ID: On 14/02/2021 00:51, Ned Batchelder wrote: > On Saturday, February 13, 2021 at 7:19:58 PM UTC-5, Chris Angelico wrote: >> On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble >> wrote: >>> >>> On 13/02/2021 23:30, Igor Korot wrote: >>>> Hi, >>>> But most importantly - what is the reason for this ? >>>> I mean - what problems the actual python compiler produce? >>>> >>>> Thank you. >>> >>> I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. >>> >> Until you have actually produced a (mostly) compatible Python >> implementation, can you please stop making these repeated and baseless >> jabs at CPython's performance? You keep stating or hinting that >> CPython is somehow unnecessarily slow, but unless you have some code >> to back your claims, this is nothing but mudslinging. >> >> CPython is not as slow as you might think. And PyPy is highly >> efficient at what it does well. Show us that you can do better than >> these before you call them slow. >> >> At the absolute least, show that you have something that can run Python code. >> >> ChrisA > > The OP has been making these claims on IRC for a while (at least two years). He has never cared to substantiate them, or even participate in a civil and detailed discussion. He is either 1) smarter than all of us, or 2) woefully under-informed, or 3) trolling. Our best course is to ignore him until he has code we can try. I am sure you are most annoyed that you can't ban me from Usenet, dear, like you banned me from IRC. You need to grow the fuck up. Your use of the words "all of us" is disingenuous, try "me" instead. "All of us" includes people as smart as me but can't be arsed fixing the Python space because they can just about live with the status quo. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 22:59:43 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 03:59:43 +0000 Subject: New Python implementation In-Reply-To: <87r1ljnwxq.fsf@nightsong.com> References: <87r1ljnwxq.fsf@nightsong.com> Message-ID: On 14/02/2021 03:35, Paul Rubin wrote: > Mr Flibble writes: >> I am creating neos as I need a performant scripting engine for my >> other major project "neoGFX" and I want to be able to support multiple >> popular scripting languages including Python. > > Is something wrong with Guile for that purpose? If yes, maybe you are > setting yourself up for the exact same obstacles ;-). NIH. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 23:08:51 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 04:08:51 +0000 Subject: New Python implementation In-Reply-To: <5b9f2356-481d-4e24-985c-b623a4fd067en@googlegroups.com> References: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> <5b9f2356-481d-4e24-985c-b623a4fd067en@googlegroups.com> Message-ID: On 14/02/2021 02:54, Mark Lawrence wrote: > On Sunday, February 14, 2021 at 2:18:03 AM UTC, Mr Flibble wrote: >> On 14/02/2021 00:51, Ned Batchelder wrote: > >>> The OP has been making these claims on IRC for a while (at least two years). He has never cared to substantiate them, or even participate in a civil and detailed discussion. He is either 1) smarter than all of us, or 2) woefully under-informed, or 3) trolling. Our best course is to ignore him until he has code we can try. >> I am sure you are most annoyed that you can't ban me from Usenet, dear, like you banned me from IRC. You need to grow the fuck up. > > I take it that you didn't write "How to win friends and influence people"? I don't suppose that the moderators will actually wake up and remove you from the mailing lists asap. I see you are just as prickly as Ned, Mark. May I suggest that you too grow a pair? I am not on the mailing list BTW; e-mail lists are an outmoded concept much like CPython. /Flibble -- ? From grant.b.edwards at gmail.com Sat Feb 13 22:26:32 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 14 Feb 2021 03:26:32 -0000 (UTC) Subject: New Python implementation References: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> Message-ID: On 2021-02-14, Ned Batchelder wrote: > On Saturday, February 13, 2021 at 7:19:58 PM UTC-5, Chris Angelico wrote: > >> At the absolute least, show that you have something that can run Python code. > > The OP has been making these claims on IRC for a (at least two > years). He has never cared to substantiate them, or even participate > in a civil and detailed discussion. He is either 1) smarter than > all of us, or 2) woefully under-informed, or 3) trolling. He posts using the name of a hand-puppet. I think that provides a bit of a clue as to which of the 3 is most likely. And it's not even a _real_ hand-puppet: it's a computer-generated hologram of a hand hand-puppet. From alan.gauld at yahoo.co.uk Sat Feb 13 19:52:43 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 14 Feb 2021 00:52:43 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 14/02/2021 00:07, Mr Flibble wrote: > On 13/02/2021 18:11, Alan Gauld wrote: >> You are going to create a Python compiler that will take existing >> Python code and output a byte code file. > > No neos is not a Python compiler: it is a *universal* compiler that > can compile any programming language describable by a schema file Yes, I understand that, but from the perspective of this list what you are doing is providing a tool (a combination of neos and a schema) that will take in Python source code and spit out neos byte code. So, to all intents and purposes it is a Python compiler (albeit capable of more when needed). >> If that's correct, then how do you propose to deal with >> regular Python byte code? And what would the Python disassembler >> produce - Python assembler instructions or neos? > > The neos Python implementation will not be dealing > with Python byte code in any form whatsoever. Ok but what do you do with the disassembler module? Will it read neos byte code instead of the Python codes? Also what about tools that work at the byte code level, I assume they will not work with neos either? That might include the profiler and debugger for example? Also what would happen with the interactive prompt (>>>) I'm assuming you'd expect users to continue using the CPython interpreter and only compile the source after it was working there? Like turning on the optimiser in a traditional compiled language like C. -- 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 From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 23:48:43 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 04:48:43 +0000 Subject: New Python implementation In-Reply-To: References: Message-ID: On 14/02/2021 00:52, Alan Gauld wrote: > On 14/02/2021 00:07, Mr Flibble wrote: >> On 13/02/2021 18:11, Alan Gauld wrote: > >>> You are going to create a Python compiler that will take existing >>> Python code and output a byte code file. >> >> No neos is not a Python compiler: it is a *universal* compiler that >> can compile any programming language describable by a schema file > > Yes, I understand that, but from the perspective of this list > what you are doing is providing a tool (a combination of neos > and a schema) that will take in Python source code and spit out > neos byte code. So, to all intents and purposes it is a Python > compiler (albeit capable of more when needed). > >>> If that's correct, then how do you propose to deal with >>> regular Python byte code? And what would the Python disassembler >>> produce - Python assembler instructions or neos? >> >> The neos Python implementation will not be dealing >> with Python byte code in any form whatsoever. > > Ok but what do you do with the disassembler module? > Will it read neos byte code instead of the Python codes? > Also what about tools that work at the byte code level, > I assume they will not work with neos either? > That might include the profiler and debugger for example? neos will include a language agnostic disassembler and debugger. > > Also what would happen with the interactive prompt (>>>) > I'm assuming you'd expect users to continue using the CPython > interpreter and only compile the source after it was working > there? Like turning on the optimiser in a traditional > compiled language like C. neos will include support for interactive sessions; no reason to use CPython at all. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sat Feb 13 23:50:02 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 04:50:02 +0000 Subject: New Python implementation In-Reply-To: References: <8a9e9d32-1404-4037-b888-5e710c2631cdn@googlegroups.com> Message-ID: <_Z1WH.34858$IR83.15982@fx34.ams4> On 14/02/2021 03:26, Grant Edwards wrote: > On 2021-02-14, Ned Batchelder wrote: >> On Saturday, February 13, 2021 at 7:19:58 PM UTC-5, Chris Angelico wrote: >> >>> At the absolute least, show that you have something that can run Python code. >> >> The OP has been making these claims on IRC for a (at least two >> years). He has never cared to substantiate them, or even participate >> in a civil and detailed discussion. He is either 1) smarter than >> all of us, or 2) woefully under-informed, or 3) trolling. > > He posts using the name of a hand-puppet. I think that provides a bit > of a clue as to which of the 3 is most likely. And it's not even a > _real_ hand-puppet: it's a computer-generated hologram of a hand > hand-puppet. lulz. If I am a troll then Elon Musk is also a troll. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 00:01:30 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 05:01:30 +0000 Subject: Sketch Message-ID: CPython *is* the dead parrot. It's time for Python to evolve out of the primordial soup. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 00:09:01 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 05:09:01 +0000 Subject: Sketch In-Reply-To: <5123fb54-a322-456e-9c6e-f4b912fdcaa9n@googlegroups.com> References: <5123fb54-a322-456e-9c6e-f4b912fdcaa9n@googlegroups.com> Message-ID: On 14/02/2021 05:04, Mark Lawrence wrote: > On Sunday, February 14, 2021 at 5:01:46 AM UTC, Mr Flibble wrote: >> CPython *is* the dead parrot. >> >> It's time for Python to evolve out of the primordial soup. >> >> /Flibble >> >> -- >> ? > > Says the bloke(?) who doesn't use mailing lists but does get here https://mail.python.org/pipermail/python-list/2021-February/900797.html I am using Usenet, dear. Apparently posts to comp.lang.python are copied to the mailing list which you worship like a god. /Flibble -- ? From ikorot01 at gmail.com Sun Feb 14 00:20:15 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Sat, 13 Feb 2021 21:20:15 -0800 Subject: Sketch In-Reply-To: References: <5123fb54-a322-456e-9c6e-f4b912fdcaa9n@googlegroups.com> Message-ID: Hi, On Sat, Feb 13, 2021, 9:12 PM Mr Flibble wrote: > On 14/02/2021 05:04, Mark Lawrence wrote: > > On Sunday, February 14, 2021 at 5:01:46 AM UTC, Mr Flibble wrote: > >> CPython *is* the dead parrot. > >> > >> It's time for Python to evolve out of the primordial soup. > >> > >> /Flibble > Is there a proof? Because I could say that JAVA sucks, but without proof it will be just words... Thank you. >> > >> -- > >> ? > > > > Says the bloke(?) who doesn't use mailing lists but does get here > https://mail.python.org/pipermail/python-list/2021-February/900797.html > > I am using Usenet, dear. Apparently posts to comp.lang.python are copied > to the mailing list which you worship like a god. > > /Flibble > > -- > ? > -- > https://mail.python.org/mailman/listinfo/python-list > From swistakm at gmail.com Sun Feb 14 04:10:11 2021 From: swistakm at gmail.com (=?utf-8?Q?Micha=C5=82_Jaworski?=) Date: Sun, 14 Feb 2021 10:10:11 +0100 Subject: Sketch In-Reply-To: References: Message-ID: Wow, that thread is entertaining. It seems that neos is one of it?s kind. What I hope is that it will support TempleOS. Going back going back to your original question Mr. Fibble. If ISO standard is what you really need to finish your project you can always take up this challenge and standardize the language yourself. From what I?ve learned already you have enough skills, experience and perseverance to complete such endeavor single-handedly. Micha? Jaworski From auriocus at gmx.de Sun Feb 14 04:15:47 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Sun, 14 Feb 2021 10:15:47 +0100 Subject: New Python implementation In-Reply-To: References: Message-ID: Am 14.02.21 um 01:19 schrieb Chris Angelico: > On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble > wrote: >> >> On 13/02/2021 23:30, Igor Korot wrote: >>> Hi, >>> But most importantly - what is the reason for this ? >>> I mean - what problems the actual python compiler produce? >>> >>> Thank you. >> >> I am creating neos as I need a performant scripting engine for my other major project "neoGFX" and I want to be able to support multiple popular scripting languages including Python. >> > > Until you have actually produced a (mostly) compatible Python > implementation, can you please stop making these repeated and baseless > jabs at CPython's performance? You keep stating or hinting that > CPython is somehow unnecessarily slow, but unless you have some code > to back your claims, this is nothing but mudslinging. This is a message to all commentators on this list: Mr Flibble is known on comp.lang.c++ for making very confident claims and announcements of the greatest software product since the invention of the wheel. He is indeed a capable C++ programmer, but he frequently underestimates the work needed for such big projects so that you can easily count them as vaporware for now. For example, he created his own "cross-platform, modern" GUI toolkit neoGFX[*] just because he thinks that QT is bad (it uses non-standard C++). Of course, cross-platform for now means it runs on Windows and anything else is far into the future, also the optical design looks modern / OK right now, but will look outdated soon. There is no evidence that any other designer will join the project to keep the look up to date. He wants that neoGFX is scriptable in Python, but instead of linking with CPython, he will write his own Python implementation instead, because CPython is slow/not clean/ whatever. He doesn't seem to understand that this is an enormous task on its own, because the interesting part of a scripting language is the standard library with many decade-years of work. So my advice is to waste your time in this discussion if you find it entertaining, but don't expect to have a usable product soon. Best regards, Christian [*] https://github.com/i42output/neoGFX From arj.python at gmail.com Sun Feb 14 04:42:46 2021 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 14 Feb 2021 13:42:46 +0400 Subject: Venv behaviour change py3.9 Message-ID: Greetings all, on 3.7 when i do $ python -m venv venv it creates a venv in venv folder but on 3.9 it returns no such file or directory os: windows. Any ideas on why the behaviour changes? From barry at barrys-emacs.org Sun Feb 14 09:45:07 2021 From: barry at barrys-emacs.org (Barry Scott) Date: Sun, 14 Feb 2021 14:45:07 +0000 Subject: Venv behaviour change py3.9 In-Reply-To: References: Message-ID: <7904EF80-DFA2-4A4A-852C-4B08F794B7C9@barrys-emacs.org> > On 14 Feb 2021, at 09:42, Abdur-Rahmaan Janhangeer wrote: > > Greetings all, > > on 3.7 when i do > > $ python -m venv venv > > it creates a venv in venv folder > > but on 3.9 it returns no such file or directory > > os: windows. Any ideas on why the behaviour changes? I did this on wndows 10 and no error seen: py -3.9 -m venv venv Are you running the version of python that you expect? What does python -V tell you? Can you cut-n-paste The command and its output? Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From ikorot01 at gmail.com Sun Feb 14 10:27:24 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Sun, 14 Feb 2021 07:27:24 -0800 Subject: Fwd: Sketch In-Reply-To: References: <5123fb54-a322-456e-9c6e-f4b912fdcaa9n@googlegroups.com> Message-ID: ---------- Forwarded message --------- From: Igor Korot Date: Sat, Feb 13, 2021, 9:20 PM Subject: Re: Sketch To: Mr Flibble Cc: Hi, On Sat, Feb 13, 2021, 9:12 PM Mr Flibble wrote: > On 14/02/2021 05:04, Mark Lawrence wrote: > > On Sunday, February 14, 2021 at 5:01:46 AM UTC, Mr Flibble wrote: > >> CPython *is* the dead parrot. > >> > >> It's time for Python to evolve out of the primordial soup. > >> > >> /Flibble > Is there a proof? Because I could say that JAVA sucks, but without proof it will be just words... Thank you. >> > >> -- > >> ? > > > > Says the bloke(?) who doesn't use mailing lists but does get here > https://mail.python.org/pipermail/python-list/2021-February/900797.html > > I am using Usenet, dear. Apparently posts to comp.lang.python are copied > to the mailing list which you worship like a god. > > /Flibble > > -- > ? > -- > https://mail.python.org/mailman/listinfo/python-list > From ikorot01 at gmail.com Sun Feb 14 10:33:25 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Sun, 14 Feb 2021 07:33:25 -0800 Subject: New Python implementation In-Reply-To: References: Message-ID: Of course not. Its like saying "JAVA sucks" without any citation or proof. And I'm just curious - why not use C directly, since he is so great developer for whatever task he needs to do? Fun time reading... Hope it will continue. Thank you. On Sun, Feb 14, 2021, 1:22 AM Christian Gollwitzer wrote: > Am 14.02.21 um 01:19 schrieb Chris Angelico: > > On Sun, Feb 14, 2021 at 11:14 AM Mr Flibble > > wrote: > >> > >> On 13/02/2021 23:30, Igor Korot wrote: > >>> Hi, > >>> But most importantly - what is the reason for this ? > >>> I mean - what problems the actual python compiler produce? > >>> > >>> Thank you. > >> > >> I am creating neos as I need a performant scripting engine for my other > major project "neoGFX" and I want to be able to support multiple popular > scripting languages including Python. > >> > > > > Until you have actually produced a (mostly) compatible Python > > implementation, can you please stop making these repeated and baseless > > jabs at CPython's performance? You keep stating or hinting that > > CPython is somehow unnecessarily slow, but unless you have some code > > to back your claims, this is nothing but mudslinging. > > This is a message to all commentators on this list: Mr Flibble is known > on comp.lang.c++ for making very confident claims and announcements of > the greatest software product since the invention of the wheel. > > He is indeed a capable C++ programmer, but he frequently underestimates > the work needed for such big projects so that you can easily count them > as vaporware for now. For example, he created his own "cross-platform, > modern" GUI toolkit neoGFX[*] just because he thinks that QT is bad (it > uses non-standard C++). Of course, cross-platform for now means it runs > on Windows and anything else is far into the future, also the optical > design looks modern / OK right now, but will look outdated soon. There > is no evidence that any other designer will join the project to keep the > look up to date. > > He wants that neoGFX is scriptable in Python, but instead of linking > with CPython, he will write his own Python implementation instead, > because CPython is slow/not clean/ whatever. He doesn't seem to > understand that this is an enormous task on its own, because the > interesting part of a scripting language is the standard library with > many decade-years of work. > > So my advice is to waste your time in this discussion if you find it > entertaining, but don't expect to have a usable product soon. > > Best regards, > > Christian > > [*] https://github.com/i42output/neoGFX > -- > https://mail.python.org/mailman/listinfo/python-list > From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 10:34:19 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 15:34:19 +0000 Subject: Sketch In-Reply-To: References: Message-ID: <0qbWH.34862$IR83.15371@fx34.ams4> On 14/02/2021 09:10, Micha? Jaworski wrote: > Wow, that thread is entertaining. It seems that neos is one of it?s kind. What I hope is that it will support TempleOS. > > Going back going back to your original question Mr. Fibble. If ISO standard is what you really need to finish your project you can always take up this challenge and standardize the language yourself. From what I?ve learned already you have enough skills, experience and perseverance to complete such endeavor single-handedly. If I standardized the language myself I couldn't call it "Python" as fixing Python requires changing it such as to make it unrecognisable as Python. /Flibble -- ? From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 10:43:33 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 15:43:33 +0000 Subject: Sketch In-Reply-To: References: Message-ID: On 14/02/2021 09:10, Micha? Jaworski wrote: > Wow, that thread is entertaining. It seems that neos is one of it?s kind. What I hope is that it will support TempleOS. > > Going back going back to your original question Mr. Fibble. If ISO standard is what you really need to finish your project you can always take up this challenge and standardize the language yourself. From what I?ve learned already you have enough skills, experience and perseverance to complete such endeavor single-handedly. Ah yes, the good old TempleOS equivalence ploy: typically used by backseat programmers and/or trolls to dismiss projects or project authors they deem to have no value based on subjective hyperbole rather than valid criticism based on objective fact. Usually they lack the skill to embark on such a project themselves so their invective tends to stem from feelings of inadequacy. Make yourself a cup of tea, dear. /Flibble -- ? From duncan at invalid.invalid Sun Feb 14 11:40:59 2021 From: duncan at invalid.invalid (duncan smith) Date: Sun, 14 Feb 2021 16:40:59 +0000 Subject: mutating a deque whilst iterating over it In-Reply-To: References: Message-ID: On 13/02/2021 19:12, Dan Stromberg wrote: > On Sat, Feb 13, 2021 at 10:25 AM duncan smith > wrote: > >> On 12/02/2021 03:04, Terry Reedy wrote: >>> On 2/11/2021 3:22 PM, duncan smith wrote: >>> >>>> It seems that I can mutate a deque while iterating over it if I >>>> assign to an index, but not if I append to it. Is this the intended >>>> behaviour? >> >> What I was really wondering was whether the behaviour is as it is >> because of the implementation or because it's how deques should ideally >> behave. i.e. In my implementation do I stick strictly to the same API, >> or allow it to differ? In some places I'm jumping through hoops to stick >> to the API, and (when it comes to iteration) I'm jumping through >> different hoops for different types of container (e.g. lists versus >> deques). BTW, the reason I am implementing these at all is that my >> containers are on-disk. Cheers. >> >> collections.deque appears to take the approach of "allow everything we > can based on our implementation, and trust the client not to overuse > features". > > In fact, in Python, "over abstraction" is often seen as a bad thing, mostly > because it slows things down so much. > > If you want something more abstracted, you might have a look at: > https://stromberg.dnsalias.org/~strombrg/linked-list/ > https://pypi.org/project/linked_list_mod/ > > (Both URL's are about the same module) > > Note that linked_list_mod is quite a bit slower than a collections.deque. > Deques use a clever-but-hidden trick to gain a lot of speed - it's really a > linked list of built in lists, which gives better locality of reference > that masks CPU caches very happy. linked_list_mod goes for abstraction and > simplicity. > I'm basically nicking the trick. I have a basic, single file, on-disk deque class that doesn't stick strictly to the Python deque API, then a second class that implements a deque as a Python deque containing instances of my basic on-disk deque class (with fixed size apart from the first and last instances). Of course, this could change when I get to testing / profiling. Cheers. Duncan From cl at isbd.net Sun Feb 14 15:50:32 2021 From: cl at isbd.net (Chris Green) Date: Sun, 14 Feb 2021 20:50:32 +0000 Subject: Is email.message.get() case insensitive for the header name? Message-ID: It isn't clear from the documentation. Does email.message.get() care about the case of the header it's getting? I checking mailing list mails and the "List-Id:" header is a bit 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will email.message.get("List-Id:", "unknown") find all of them? -- Chris Green ? From cl at isbd.net Sun Feb 14 16:14:06 2021 From: cl at isbd.net (Chris Green) Date: Sun, 14 Feb 2021 21:14:06 +0000 Subject: Change first occurrence of character x in a string - how? Message-ID: What's the easiest way to change the first occurrence of a specified character in a string? E.g. I want to change linux-raid.vger.kernel.org to linux-raid at vger.kernel.org, it's a fairly general requirement of needing to change '.' to '@'. Alternatively is there an RE 'match' function that would test if linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't really care if the '.' are all regarded as wild cards, the match will be accurate enough. -- Chris Green ? From python at mrabarnett.plus.com Sun Feb 14 16:36:02 2021 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 14 Feb 2021 21:36:02 +0000 Subject: Is email.message.get() case insensitive for the header name? In-Reply-To: References: Message-ID: <22887597-a210-6938-d562-fdeaf11b3117@mrabarnett.plus.com> On 2021-02-14 20:50, Chris Green wrote: > It isn't clear from the documentation. Does email.message.get() care > about the case of the header it's getting? > > I checking mailing list mails and the "List-Id:" header is a bit > 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will > email.message.get("List-Id:", "unknown") find all of them? > According to the specification that it follows, the field names are not case-sensitive. Incidentally, the colon is a separator and not part of the field name. From drsalists at gmail.com Sun Feb 14 16:36:28 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 14 Feb 2021 13:36:28 -0800 Subject: Change first occurrence of character x in a string - how? In-Reply-To: References: Message-ID: Check out re.sub's "count" parameter. https://stackoverflow.com/questions/3951660/how-to-replace-the-first-occurrence-of-a-regular-expression-in-python On Sun, Feb 14, 2021 at 1:20 PM Chris Green wrote: > What's the easiest way to change the first occurrence of a specified > character in a string? > > E.g. I want to change linux-raid.vger.kernel.org to > linux-raid at vger.kernel.org, it's a fairly general requirement of > needing to change '.' to '@'. > > Alternatively is there an RE 'match' function that would test if > linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > really care if the '.' are all regarded as wild cards, the match will > be accurate enough. > > -- > Chris Green > ? > -- > https://mail.python.org/mailman/listinfo/python-list > From python at mrabarnett.plus.com Sun Feb 14 16:39:49 2021 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 14 Feb 2021 21:39:49 +0000 Subject: Change first occurrence of character x in a string - how? In-Reply-To: References: Message-ID: On 2021-02-14 21:14, Chris Green wrote: > What's the easiest way to change the first occurrence of a specified > character in a string? > > E.g. I want to change linux-raid.vger.kernel.org to > linux-raid at vger.kernel.org, it's a fairly general requirement of > needing to change '.' to '@'. > > Alternatively is there an RE 'match' function that would test if > linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > really care if the '.' are all regarded as wild cards, the match will > be accurate enough. > Use the .replace method. Its 3rd argument is the maximum number of replacements, in this case 1: >>> s = 'linux-raid.vger.kernel.org' >>> s.replace('.', '@', 1) 'linux-raid at vger.kernel.org' From ned at nedbatchelder.com Sun Feb 14 16:36:52 2021 From: ned at nedbatchelder.com (Ned Batchelder) Date: Sun, 14 Feb 2021 13:36:52 -0800 (PST) Subject: Change first occurrence of character x in a string - how? In-Reply-To: References: Message-ID: <32865a8c-d528-47bb-a983-48339e6db776n@googlegroups.com> with_at = with_dots.replace(".", "@", 1) https://docs.python.org/3/library/stdtypes.html#str.replace --Ned. On Sunday, February 14, 2021 at 4:18:22 PM UTC-5, Chris Green wrote: > What's the easiest way to change the first occurrence of a specified > character in a string? > > E.g. I want to change linux-raid.vger.kernel.org to > linux... at vger.kernel.org, it's a fairly general requirement of > needing to change '.' to '@'. > > Alternatively is there an RE 'match' function that would test if > linux... at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > really care if the '.' are all regarded as wild cards, the match will > be accurate enough. > > -- > Chris Green > ? From gherron at digipen.edu Sun Feb 14 16:35:16 2021 From: gherron at digipen.edu (Gary Herron) Date: Sun, 14 Feb 2021 13:35:16 -0800 Subject: Change first occurrence of character x in a string - how? In-Reply-To: References: Message-ID: <29e439d2-2a8a-3d55-7e4a-64fc6c4b810a@digipen.edu> The string type has a replace function that does what you want. Except you can't change a string -- they are immutable -- so this creates a new string. >>> s = 'linux-raid.vger.kernel.org' >>> new_s = s.replace('.', '@', 1) >>> new_s 'linux-raid at vger.kernel.org' On 2/14/21 1:14 PM, cl at isbd.net wrote: > What's the easiest way to change the first occurrence of a specified > character in a string? > > E.g. I want to change linux-raid.vger.kernel.org to > linux-raid at vger.kernel.org, it's a fairly general requirement of > needing to change '.' to '@'. > > Alternatively is there an RE 'match' function that would test if > linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > really care if the '.' are all regarded as wild cards, the match will > be accurate enough. > -- Dr. Gary Herron Professor of Computer Science DigiPen Institute of Technology (425) 895-4418 From cl at isbd.net Sun Feb 14 16:54:07 2021 From: cl at isbd.net (Chris Green) Date: Sun, 14 Feb 2021 21:54:07 +0000 Subject: Change first occurrence of character x in a string - how? References: Message-ID: MRAB wrote: > On 2021-02-14 21:14, Chris Green wrote: > > What's the easiest way to change the first occurrence of a specified > > character in a string? > > > > E.g. I want to change linux-raid.vger.kernel.org to > > linux-raid at vger.kernel.org, it's a fairly general requirement of > > needing to change '.' to '@'. > > > > Alternatively is there an RE 'match' function that would test if > > linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > > really care if the '.' are all regarded as wild cards, the match will > > be accurate enough. > > > Use the .replace method. Its 3rd argument is the maximum number of > replacements, in this case 1: > > >>> s = 'linux-raid.vger.kernel.org' > >>> s.replace('.', '@', 1) > 'linux-raid at vger.kernel.org' Yes, thank you, simple! :-) -- Chris Green ? From cl at isbd.net Sun Feb 14 16:51:42 2021 From: cl at isbd.net (Chris Green) Date: Sun, 14 Feb 2021 21:51:42 +0000 Subject: Change first occurrence of character x in a string - how? References: <29e439d2-2a8a-3d55-7e4a-64fc6c4b810a@digipen.edu> Message-ID: Gary Herron wrote: > > On 2/14/21 1:14 PM, cl at isbd.net wrote: > > What's the easiest way to change the first occurrence of a specified > > character in a string? > > > > E.g. I want to change linux-raid.vger.kernel.org to > > linux-raid at vger.kernel.org, it's a fairly general requirement of > > needing to change '.' to '@'. > > > > Alternatively is there an RE 'match' function that would test if > > linux-raid at vger.kernel.org matches linux-raid.vger.kernel.org? I don't > > really care if the '.' are all regarded as wild cards, the match will > > be accurate enough. > > > The string type has a replace function that does what you want. > Except you can't change a string -- they are immutable -- so this > creates a new string. > > > >>> s = 'linux-raid.vger.kernel.org' > >>> new_s = s.replace('.', '@', 1) > >>> new_s > 'linux-raid at vger.kernel.org' > A new string is fine, thank you, that'll do what I need. Efficiency isn't a major issue with this. -- Chris Green ? From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 17:51:27 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 22:51:27 +0000 Subject: Change first occurrence of character x in a string - how? In-Reply-To: References: Message-ID: On 14/02/2021 21:14, Chris Green wrote: > What's the easiest way to change the first occurrence of a specified > character in a string? By using a grown up (i.e. non-toy) programming language. /Flibble -- ? From auriocus at gmx.de Sun Feb 14 18:00:47 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Mon, 15 Feb 2021 00:00:47 +0100 Subject: New Python implementation In-Reply-To: <87blcnnejf.fsf@nightsong.com> References: <87blcnnejf.fsf@nightsong.com> Message-ID: Am 14.02.21 um 11:12 schrieb Paul Rubin: > Christian Gollwitzer writes: >> He wants that neoGFX is scriptable in Python, but instead of linking >> with CPython, he will write his own Python implementation instead, >> because CPython is slow/not clean/ whatever. He doesn't seem to >> understand that this is an enormous task on its own, because the >> interesting part of a scripting language is the standard library with >> many decade-years of work. > > I wonder how big an issue the stdlib really is. Lots of it is written > in Python and can port to another interpreter. Lots more is CPython C > API bindings to external C libraries (e.g. OpenSSL) so porting those > would be a matter of rebinding those libraries to libffi in the cases > where that hasn't been done already. I'm not saying that it is unfeasible or very difficult. I'm saying that it is a lot of work, and for a single developer who has this as a side project / support for his graphics engine and who wants to beat existing implementations wrt. speed, I'm saying it is going to take a lot of time. It'definitely impossible by "defining a few JSON schema files", as Leigh claims with his "universal compiler". There definitely IS a lot of stuff in a baseline CPython interpreter - a (seemingly) simple thing like "print" will have an implementation of 1000 lines in C with all the formatting library, file I/O etc. Arbitrary precision integers - another library, networking - yet another and so on. > CPython really is pretty slow, maybe because it uses so much boxed data, > derps around with refcounts all the time, suffers memory fragmentation > from not having a relocating GC, etc. And that is before we even > mention the GIL. I don't argue with that. CPython is slow. But I'm arguing that you can't make it faster by multiple orders of magnitude unless you change the language. For numerical code, straight-forward C is usually 100x to 1000x faster than Python, and you can reach the same performance by giving up dynamic typing - Cython demonstrates this quite convincingly. If you don't want static typing (with types close to the machine like fixed-width integers) than you'll have to resort to a LOT of black magic to even come close (PyPy, modern JS engines, ....) Christian From flibble at i42.REMOVETHISBIT.co.uk Sun Feb 14 18:32:36 2021 From: flibble at i42.REMOVETHISBIT.co.uk (Mr Flibble) Date: Sun, 14 Feb 2021 23:32:36 +0000 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: On 14/02/2021 23:00, Christian Gollwitzer wrote: > Am 14.02.21 um 11:12 schrieb Paul Rubin: >> Christian Gollwitzer writes: >>> He wants that neoGFX is scriptable in Python, but instead of linking >>> with CPython, he will write his own Python implementation instead, >>> because CPython is slow/not clean/ whatever. He doesn't seem to >>> understand that this is an enormous task on its own, because the >>> interesting part of a scripting language is the standard library with >>> many decade-years of work. >> >> I wonder how big an issue the stdlib really is.? Lots of it is written >> in Python and can port to another interpreter.? Lots more is CPython C >> API bindings to external C libraries (e.g. OpenSSL) so porting those >> would be a matter of rebinding those libraries to libffi in the cases >> where that hasn't been done already. > > I'm not saying that it is unfeasible or very difficult. I'm saying that it is a lot of work, and for a single developer who has this as a side project / support for his graphics engine and who wants to beat existing implementations wrt. speed, I'm saying it is going to take a lot of time. It'definitely impossible by "defining a few JSON schema files", as Leigh claims with his "universal compiler". There definitely IS a lot of stuff in a baseline CPython interpreter - a (seemingly) simple thing like "print" will have an implementation of 1000 lines in C with all the formatting library, file I/O etc. Arbitrary precision integers - another library, networking - yet another and so on. There will only be one schema file and it is will be a relatively small task which certainly isn't "impossible": I should have a working implementation by the summer. As far as arbitrary precision integers are concerned I am well on the way to completing the "neonumeral" library (which also has arbitrary precision floats). As far as the standard library is concerned: that is already in Python so I should be able to support it with little effort; the only thing requiring more work would be the built-ins. > >> CPython really is pretty slow, maybe because it uses so much boxed data, >> derps around with refcounts all the time, suffers memory fragmentation >> from not having a relocating GC, etc.? And that is before we even >> mention the GIL. > > I don't argue with that. CPython is slow. But I'm arguing that you can't make it faster by multiple orders of magnitude unless you change the language. For numerical code, straight-forward C is usually 100x to 1000x faster than Python, and you can reach the same performance by giving up dynamic typing - Cython demonstrates this quite convincingly. If you don't want static typing (with types close to the machine like fixed-width integers) than you'll have to resort to a LOT of black magic to even come close (PyPy, modern JS engines, ....) I believe PyPy is only 4x faster than CPython on average and comes nowhere near close to JS JIT engines performance-wise. /Flibble -- ? From drsalists at gmail.com Sun Feb 14 19:30:44 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 14 Feb 2021 16:30:44 -0800 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: On Sun, Feb 14, 2021 at 3:05 PM Christian Gollwitzer wrote: > Am 14.02.21 um 11:12 schrieb Paul Rubin: > > Christian Gollwitzer writes: > >> He wants that neoGFX is scriptable in Python, but instead of linking > >> with CPython, he will write his own Python implementation instead, > >> because CPython is slow/not clean/ whatever. He doesn't seem to > >> understand that this is an enormous task on its own, because the > >> interesting part of a scripting language is the standard library with > >> many decade-years of work. > > > > I wonder how big an issue the stdlib really is. Lots of it is written > > in Python and can port to another interpreter. Lots more is CPython C > > API bindings to external C libraries (e.g. OpenSSL) so porting those > > would be a matter of rebinding those libraries to libffi in the cases > > where that hasn't been done already. > Hopefully CFFI, not libffi: https://cffi.readthedocs.io/en/latest/ I'm not saying that it is unfeasible or very difficult. I'm saying that > it is a lot of work It is. However, IronPython and Shedskin do not have a full Python standard library. I'd still call them "Python". From avigross at verizon.net Sun Feb 14 21:26:29 2021 From: avigross at verizon.net (Avi Gross) Date: Sun, 14 Feb 2021 21:26:29 -0500 Subject: Efficiency debates References: <09b101d70341$f80195d0$e804c170$.ref@verizon.net> Message-ID: <09b101d70341$f80195d0$e804c170$@verizon.net> I think we have discussed this a few times. There are tradeoffs in computer science and obviously a compiled language with some optimization using low-level data structures does much better at solving simple problems. Interpreted languages often have serious overhead to start with and allow all kinds of flexibility that comes with more costs such as functions that handle arbitrary types of arguments. When languages keep adding not only features but accommodate many programming styles such as object-oriented and functional or multiple ways to do the same thing, there is often more bloat. In python, there are almost always many ways to do anything! So, I find it easier to develop in such languages BUT if the program is to be run regularly and uses lots of resources and especially if it does not need many of the dynamic features, there are ways to try to tune it within Python or use a faster attached library of functions in languages like C for some parts or leaving Python entirely. If a program does not actually need much of what Python offers, fine. Use something else. I know in another language called R, that more and more parts are rewritten in a dialect of C/C++ so some things run quite fast if they call such functions. Users learn to use vectorized methods instead of loops to gain speed. I have recently seen discussions that some tried to solve using nontrivial regular expressions when simpler and faster methods using normal string functions would do. Unless that application also needed much more, it could easily be done in C or C++ or if needed in a very localized assembler. Python may be closer to one-size fits all but sometimes more than is needed. But it is not the only example of where people choose a sledge-hammer when a thumbtack will do. But as humans, we may do better working in ways that work well with our normal thinking process or one we can learn and feels natural. Every language I know has problems that look easy to solve using features in it and others that are painful to contemplate. Lately, I have done work combining Python parts with R parts to use the powerful features I already know how to use well in each. The new R STUDIO supports Python and quite a few other languages now as well as notebooks and document preparation and more. But I make no claim it is fast. It is very convenient and sometimes that is worth more especially for a one-off project. Those who want speed, go for it. If you can find libraries of functions or class prototypes that are just what you need, great. But if a language like Python has even more resources available in lots of modules or packages as well as more flexible data types, then maybe a hundred lines of that will be easier to write than thousands of lines elsewhere. How convenient is it to work with data.frame type objects in C/C++ as compared to using numpy and pandas? For many of us, we work with machines with ever more power and most of the time it just sits there idling. Now if you have something on servers that is running many simultaneous copies all the time to process complex requests from users, then efficiency should matter. If you pay for it or worry about how much electricity it uses, fine. This forum does not care if you prefer C/C++ and is meant to discuss Python for people interested in Python. Repeated attacks make people ignore the person and not take anything they say as meaningful. I tried sharing my understanding of a recent proposal and remain unconvinced it is trivial and certainly doubt that it is doable as it is too grandiose and suggests any imaginable computer language will trivially be handled. I am sure it would have fun dealing with a programming language in Hebrew with most text going from right to left but numbers the other way, and with added features built-in that nobody is using yet. Oh, I have no intention of doing so, but I suggest a more doable goal would be to be able to handle five procedural languages with no objects or functional programming before making bold claims. If that works, expand. A more efficient use of my time is to tell my mailer which messages to toss. From __peter__ at web.de Mon Feb 15 04:38:57 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 15 Feb 2021 10:38:57 +0100 Subject: Is email.message.get() case insensitive for the header name? In-Reply-To: References: Message-ID: On 14/02/2021 21:50, Chris Green wrote: > It isn't clear from the documentation. Does email.message.get() care > about the case of the header it's getting? > > I checking mailing list mails and the "List-Id:" header is a bit > 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will > email.message.get("List-Id:", "unknown") find all of them? Let's have a look: >>> import email.message >>> email.message.get Traceback (most recent call last): File "", line 1, in email.message.get AttributeError: module 'email.message' has no attribute 'get' OK, you probably meant >>> email.message.Message.get Enter the inspect module for a quick glance at the method's source: >>> import inspect >>> print(inspect.getsource(email.message.Message.get)) def get(self, name, failobj=None): """Get a header value. Like __getitem__() but return failobj instead of None when the field is missing. """ name = name.lower() for k, v in self._headers: if k.lower() == name: return self.policy.header_fetch_parse(k, v) return failobj Both the `name` argument and the header keys are converted to lowercase before the comparison, so yes, the method is case-insensitive (whether it should be casefold() doesn't matter for ascii-strings). From __peter__ at web.de Mon Feb 15 04:38:57 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 15 Feb 2021 10:38:57 +0100 Subject: Is email.message.get() case insensitive for the header name? In-Reply-To: References: Message-ID: On 14/02/2021 21:50, Chris Green wrote: > It isn't clear from the documentation. Does email.message.get() care > about the case of the header it's getting? > > I checking mailing list mails and the "List-Id:" header is a bit > 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will > email.message.get("List-Id:", "unknown") find all of them? Let's have a look: >>> import email.message >>> email.message.get Traceback (most recent call last): File "", line 1, in email.message.get AttributeError: module 'email.message' has no attribute 'get' OK, you probably meant >>> email.message.Message.get Enter the inspect module for a quick glance at the method's source: >>> import inspect >>> print(inspect.getsource(email.message.Message.get)) def get(self, name, failobj=None): """Get a header value. Like __getitem__() but return failobj instead of None when the field is missing. """ name = name.lower() for k, v in self._headers: if k.lower() == name: return self.policy.header_fetch_parse(k, v) return failobj Both the `name` argument and the header keys are converted to lowercase before the comparison, so yes, the method is case-insensitive (whether it should be casefold() doesn't matter for ascii-strings). From arj.python at gmail.com Mon Feb 15 04:46:29 2021 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 15 Feb 2021 13:46:29 +0400 Subject: Venv behaviour change py3.9 In-Reply-To: <7904EF80-DFA2-4A4A-852C-4B08F794B7C9@barrys-emacs.org> References: <7904EF80-DFA2-4A4A-852C-4B08F794B7C9@barrys-emacs.org> Message-ID: Well i am no longer on the PC but here are some more info: windows 10, 64bit I downloaded Python 3.9 yesterday, added the root folder to path renamed python.exe to py39.exe and did py39 -m venv venv the output was No such file or directory but i dont remember the exact phrase Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius On Sun, Feb 14, 2021 at 6:45 PM Barry Scott wrote: > > > > On 14 Feb 2021, at 09:42, Abdur-Rahmaan Janhangeer > wrote: > > > > Greetings all, > > > > on 3.7 when i do > > > > $ python -m venv venv > > > > it creates a venv in venv folder > > > > but on 3.9 it returns no such file or directory > > > > os: windows. Any ideas on why the behaviour changes? > > I did this on wndows 10 and no error seen: > > py -3.9 -m venv venv > > Are you running the version of python that you expect? > What does python -V tell you? > > Can you cut-n-paste The command and its output? > > Barry > > > > -- > > https://mail.python.org/mailman/listinfo/python-list > > > > From uri at speedy.net Mon Feb 15 05:01:30 2021 From: uri at speedy.net (=?UTF-8?B?15DXldeo15k=?=) Date: Mon, 15 Feb 2021 12:01:30 +0200 Subject: @unittest.skip doesn't print anything in Python <= 3.7 In-Reply-To: References: Message-ID: Hi Terry, Shai Berger found the bug and replied in Stack Overflow. Thanks, Uri. ???? uri at speedy.net On Fri, Feb 12, 2021 at 11:36 PM Terry Reedy wrote: > On 2/11/2021 3:25 PM, ???? wrote: > > Hi, > > > > > https://stackoverflow.com/questions/66161394/unittest-skip-doesnt-print-anything-in-python-3-7 > > > > We are using Django with unittest. Some tests are skipped with the > > @unittest.skip decorator. But if I run the tests with Python 3.6 or 3.7, > I > > get a number of tests passed (Ran 993 tests / OK), and if I run the same > > tests with Python 3.8, I get the same number of tests but with some tests > > skipped (Ran 993 tests / OK (skipped=4)). > > ... > > > I think the skipped tests are skipped in all Python versions, but in > Python > > 3.6 and 3.7 there is no output about them being skipped. Is it a bug? > > Perhaps you have discover a bug in 3.7 that was fixed in 3.8. Each new > version comes with a few hundred bug fixes, not just the new features, > although only the latter are featured in the new version announcement. > > If you are really concerned, find What's New in 3.8 and look changelog, > linked in the first paragraph, for 'unittest' issues. > > -- > Terry Jan Reedy > > > -- > https://mail.python.org/mailman/listinfo/python-list > From cl at isbd.net Mon Feb 15 05:31:01 2021 From: cl at isbd.net (Chris Green) Date: Mon, 15 Feb 2021 10:31:01 +0000 Subject: Is email.message.get() case insensitive for the header name? References: Message-ID: <54vpfh-4eqe.ln1@esprimo.zbmc.eu> Peter Otten <__peter__ at web.de> wrote: > On 14/02/2021 21:50, Chris Green wrote: > > > It isn't clear from the documentation. Does email.message.get() care > > about the case of the header it's getting? > > > > I checking mailing list mails and the "List-Id:" header is a bit > > 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will > > email.message.get("List-Id:", "unknown") find all of them? > Let's have a look: > > >>> import email.message > >>> email.message.get > Traceback (most recent call last): > File "", line 1, in > email.message.get > AttributeError: module 'email.message' has no attribute 'get' > > > OK, you probably meant > > >>> email.message.Message.get > > > > Enter the inspect module for a quick glance at the method's source: > > >>> import inspect > >>> print(inspect.getsource(email.message.Message.get)) > def get(self, name, failobj=None): > """Get a header value. > > Like __getitem__() but return failobj instead of None when the > field > is missing. > """ > name = name.lower() > for k, v in self._headers: > if k.lower() == name: > return self.policy.header_fetch_parse(k, v) > return failobj > > Both the `name` argument and the header keys are converted to lowercase > before the comparison, so yes, the method is case-insensitive (whether > it should be casefold() doesn't matter for ascii-strings). Excellent, thank you. -- Chris Green ? From eryksun at gmail.com Mon Feb 15 06:41:56 2021 From: eryksun at gmail.com (Eryk Sun) Date: Mon, 15 Feb 2021 05:41:56 -0600 Subject: Venv behaviour change py3.9 In-Reply-To: References: <7904EF80-DFA2-4A4A-852C-4B08F794B7C9@barrys-emacs.org> Message-ID: On 2/15/21, Abdur-Rahmaan Janhangeer wrote: > > I downloaded Python 3.9 yesterday, added the root folder to path > renamed python.exe to py39.exe and did > py39 -m venv venv > the output was > No such file or directory but i dont remember the exact phrase Probably you downloaded the embedded distribution, which does not included the venv package. Get the installer for the development distribution instead: https://www.python.org/ftp/python/3.9.1/python-3.9.1-amd64.exe Note that "python-3.9.1-amd64.exe" is an installer only. It does not run Python. If you run the installer again after a successful installation, it gives you the option to modify, repair, or uninstall the installation. By default, the development distribution installs for the current user in "%LocalAppData%\Programs\Python\Python[-32]". In the case of Python 3.9, "" is "39". The "-32" suffix is appended only for 32-bit Python. If you select to install Python for all users in the "Advanced Options" dialog, the default installation directory changes to "%ProgramFiles[(x86)]%\Python[-32]". Installing for all users requires administrator access at the time of installation, but not to run Python. However, if the base installation is in a secure system directory, administrator access will be required in order to install packages via pip (i.e. you'll need to use an elevated shell). This is a good choice if you develop with virtual environments or always install packages with the --user option instead of installing to the base installation. The "py" launcher is also installed by default. Normally the launcher is installed for all users in "%SystemRoot%". It can instead be installed for just the current user in %LocalAppData%\Programs\Python\Launcher". The installer has an option to associate .py files with the launcher, which enables running scripts directly from a CLI or GUI shell (e.g. by double clicking on a script). The launcher supports Unix shebang lines, if you're familiar with that. See the documentation for more details. There is also an option to configure the current user or system environment variables to run Python, which includes adding ".PY" to PATHEXT and adding the scripts and installation directories to PATH. The latter is required to run Python via the "python" command in a shell. That said, if the launcher is installed, then the "py" command is always available as an alternative to directly running "python", e.g. "py -m venv ". From arj.python at gmail.com Sun Feb 14 00:31:08 2021 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Sun, 14 Feb 2021 09:31:08 +0400 Subject: New Python implementation In-Reply-To: References: Message-ID: After reading the thread i'm like: where can i try it out ... On Thu, 11 Feb 2021, 16:38 Mr Flibble, wrote: > > Hi! > > I am starting work on creating a new Python implementation from scratch > using "neos" my universal compiler that can compile any programming > language. I envision this implementation to be significantly faster than > the currently extant Python implementations (which isn't a stretch given > how poorly they perform). > > Sample neos session (parsing a fibonacci program, neoscript rather than > Python in this case): > > neos 1.0.0.0 ED-209 > ] help > h(elp) > s(chema) Load language schema > l(oad) Load program > list List program > c(ompile) Compile program > r(un) Run program > ![] Evaluate expression (enter > interactive mode if expression omitted) > : Input (as stdin) > q(uit) Quit neos > lc List loaded concept libraries > t(race) <0|1|2|3|4|5> [] Compiler trace > m(etrics) Display metrics for running > programs > ] lc > [neos.core] (file:///D:\code\neos\build\win32\vs2019\x64\Release\core.ncl) > [neos.boolean] > [neos.language] > [neos.logic] > [neos.math] > [neos.module] > [neos.object] > [neos.string] > [neos.math.universal] > (file:///D:\code\neos\build\win32\vs2019\x64\Release\core.math.universal.ncl) > ] s neoscript > Loading schema 'neoscript'... > Language: Default neoGFX scripting language > Version: 1.0.0 > Copyright (C) 2019 Leigh Johnston > neoscript] l examples/neoscript/fibonacci.neo > neoscript] list > File 'examples/neoscript/fibonacci.neo': > -- neoscript example: Fibonacci > > using neos.string; > using neos.stream; > > import fn to_string(x : i32) -> string; > import fn to_integer(s : string) -> i32; > import proc input(s : out string); > import proc print(s : in string); > > -- functions are pure > def fn add(x, y : i32) -> i32 > { > return x + y; > } > def fn fib(x : i32) -> i32 > { > if (x < 2) > return 1; > else > return add(fib(x-1), fib(x-2)); > } > > -- procedures are impure > def proc main() > s : string; > { > print("Enter a positive " > "integer: "); > input(s); > print("Fibonacci(" + s + ") = " + to_string(fib(to_integer(s))) + > "\n"); > } > neoscript] t 1 > neoscript] c > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) > folding: string.utf8(g) <- string.utf8.character.alpha() > folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) > folding: string.utf8(gn) <- string.utf8.character.alpha() > folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) > folding: string.utf8(gni) <- string.utf8.character.alpha() > folded: string.utf8(gni) <- string.utf8.character.alpha() = > string.utf8(gnir) > folding: string.utf8(gnir) <- string.utf8.character.alpha() > folded: string.utf8(gnir) <- string.utf8.character.alpha() = > string.utf8(gnirt) > folding: string.utf8(gnirt) <- string.utf8.character.alpha() > folded: string.utf8(gnirt) <- string.utf8.character.alpha() = > string.utf8(gnirts) > folding: string.utf8(gnirts) <- string.utf8.character.period() > folded: string.utf8(gnirts) <- string.utf8.character.period() = > string.utf8(gnirts.) > folding: string.utf8(gnirts.) <- string.utf8.character.alpha() > folded: string.utf8(gnirts.) <- string.utf8.character.alpha() = > string.utf8(gnirts.s) > folding: string.utf8(gnirts.s) <- string.utf8.character.alpha() > folded: string.utf8(gnirts.s) <- string.utf8.character.alpha() = > string.utf8(gnirts.so) > folding: string.utf8(gnirts.so) <- string.utf8.character.alpha() > folded: string.utf8(gnirts.so) <- string.utf8.character.alpha() = > string.utf8(gnirts.soe) > folding: string.utf8(gnirts.soe) <- string.utf8.character.alpha() > folded: string.utf8(gnirts.soe) <- string.utf8.character.alpha() = > string.utf8(gnirts.soen) > folding: source.package.name() <- string.utf8(gnirts.soen) > folded: source.package.name() <- string.utf8(gnirts.soen) = > source.package.name(neos.string) > folding: source.package.import() <- source.package.name(neos.string) > folded: source.package.import() <- source.package.name(neos.string) = > source.package.import(neos.string) > folding: source.package.import(neos.string) <- > source.package.import(neos.string) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) > folding: string.utf8(g) <- string.utf8.character.alpha() > folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) > folding: string.utf8(gn) <- string.utf8.character.alpha() > folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) > folding: string.utf8(gni) <- string.utf8.character.alpha() > folded: string.utf8(gni) <- string.utf8.character.alpha() = > string.utf8(gnir) > folding: string.utf8(gnir) <- string.utf8.character.alpha() > folded: string.utf8(gnir) <- string.utf8.character.alpha() = > string.utf8(gnirt) > folding: string.utf8(gnirt) <- string.utf8.character.alpha() > folded: string.utf8(gnirt) <- string.utf8.character.alpha() = > string.utf8(gnirts) > folding: string.utf8(gnirts) <- string.utf8.character.underscore() > folded: string.utf8(gnirts) <- string.utf8.character.underscore() = > string.utf8(gnirts_) > folding: string.utf8(gnirts_) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = > string.utf8(gnirts_o) > folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = > string.utf8(gnirts_ot) > folding: language.identifier() <- string.utf8(gnirts_ot) > folded: language.identifier() <- string.utf8(gnirts_ot) = > language.identifier(to_string) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) > folding: string.utf8(r) <- string.utf8.character.alpha() > folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) > folding: string.utf8(re) <- string.utf8.character.alpha() > folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) > folding: string.utf8(reg) <- string.utf8.character.alpha() > folded: string.utf8(reg) <- string.utf8.character.alpha() = > string.utf8(rege) > folding: string.utf8(rege) <- string.utf8.character.alpha() > folded: string.utf8(rege) <- string.utf8.character.alpha() = > string.utf8(reget) > folding: string.utf8(reget) <- string.utf8.character.alpha() > folded: string.utf8(reget) <- string.utf8.character.alpha() = > string.utf8(regetn) > folding: string.utf8(regetn) <- string.utf8.character.alpha() > folded: string.utf8(regetn) <- string.utf8.character.alpha() = > string.utf8(regetni) > folding: string.utf8(regetni) <- string.utf8.character.underscore() > folded: string.utf8(regetni) <- string.utf8.character.underscore() = > string.utf8(regetni_) > folding: string.utf8(regetni_) <- string.utf8.character.alpha() > folded: string.utf8(regetni_) <- string.utf8.character.alpha() = > string.utf8(regetni_o) > folding: string.utf8(regetni_o) <- string.utf8.character.alpha() > folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = > string.utf8(regetni_ot) > folding: language.identifier() <- string.utf8(regetni_ot) > folded: language.identifier() <- string.utf8(regetni_ot) = > language.identifier(to_integer) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folded: source.package.import(neos.string) <- > source.package.import(neos.string) = () > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(m) > folding: string.utf8(m) <- string.utf8.character.alpha() > folded: string.utf8(m) <- string.utf8.character.alpha() = string.utf8(ma) > folding: string.utf8(ma) <- string.utf8.character.alpha() > folded: string.utf8(ma) <- string.utf8.character.alpha() = string.utf8(mae) > folding: string.utf8(mae) <- string.utf8.character.alpha() > folded: string.utf8(mae) <- string.utf8.character.alpha() = > string.utf8(maer) > folding: string.utf8(maer) <- string.utf8.character.alpha() > folded: string.utf8(maer) <- string.utf8.character.alpha() = > string.utf8(maert) > folding: string.utf8(maert) <- string.utf8.character.alpha() > folded: string.utf8(maert) <- string.utf8.character.alpha() = > string.utf8(maerts) > folding: string.utf8(maerts) <- string.utf8.character.period() > folded: string.utf8(maerts) <- string.utf8.character.period() = > string.utf8(maerts.) > folding: string.utf8(maerts.) <- string.utf8.character.alpha() > folded: string.utf8(maerts.) <- string.utf8.character.alpha() = > string.utf8(maerts.s) > folding: string.utf8(maerts.s) <- string.utf8.character.alpha() > folded: string.utf8(maerts.s) <- string.utf8.character.alpha() = > string.utf8(maerts.so) > folding: string.utf8(maerts.so) <- string.utf8.character.alpha() > folded: string.utf8(maerts.so) <- string.utf8.character.alpha() = > string.utf8(maerts.soe) > folding: string.utf8(maerts.soe) <- string.utf8.character.alpha() > folded: string.utf8(maerts.soe) <- string.utf8.character.alpha() = > string.utf8(maerts.soen) > folding: source.package.name() <- string.utf8(maerts.soen) > folded: source.package.name() <- string.utf8(maerts.soen) = > source.package.name(neos.stream) > folding: source.package.import() <- source.package.name(neos.stream) > folded: source.package.import() <- source.package.name(neos.stream) = > source.package.import(neos.stream) > folding: source.package.import(neos.stream) <- > source.package.import(neos.stream) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) > folding: string.utf8(tu) <- string.utf8.character.alpha() > folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) > folding: string.utf8(tup) <- string.utf8.character.alpha() > folded: string.utf8(tup) <- string.utf8.character.alpha() = > string.utf8(tupn) > folding: string.utf8(tupn) <- string.utf8.character.alpha() > folded: string.utf8(tupn) <- string.utf8.character.alpha() = > string.utf8(tupni) > folding: language.identifier() <- string.utf8(tupni) > folded: language.identifier() <- string.utf8(tupni) = > language.identifier(input) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) > folding: string.utf8(tn) <- string.utf8.character.alpha() > folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) > folding: string.utf8(tni) <- string.utf8.character.alpha() > folded: string.utf8(tni) <- string.utf8.character.alpha() = > string.utf8(tnir) > folding: string.utf8(tnir) <- string.utf8.character.alpha() > folded: string.utf8(tnir) <- string.utf8.character.alpha() = > string.utf8(tnirp) > folding: language.identifier() <- string.utf8(tnirp) > folded: language.identifier() <- string.utf8(tnirp) = > language.identifier(print) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folded: source.package.import(neos.stream) <- > source.package.import(neos.stream) = () > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) > folding: string.utf8(g) <- string.utf8.character.alpha() > folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) > folding: string.utf8(gn) <- string.utf8.character.alpha() > folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) > folding: string.utf8(gni) <- string.utf8.character.alpha() > folded: string.utf8(gni) <- string.utf8.character.alpha() = > string.utf8(gnir) > folding: string.utf8(gnir) <- string.utf8.character.alpha() > folded: string.utf8(gnir) <- string.utf8.character.alpha() = > string.utf8(gnirt) > folding: string.utf8(gnirt) <- string.utf8.character.alpha() > folded: string.utf8(gnirt) <- string.utf8.character.alpha() = > string.utf8(gnirts) > folding: string.utf8(gnirts) <- string.utf8.character.underscore() > folded: string.utf8(gnirts) <- string.utf8.character.underscore() = > string.utf8(gnirts_) > folding: string.utf8(gnirts_) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = > string.utf8(gnirts_o) > folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = > string.utf8(gnirts_ot) > folding: language.identifier() <- string.utf8(gnirts_ot) > folded: language.identifier() <- string.utf8(gnirts_ot) = > language.identifier(to_string) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) > folding: string.utf8(r) <- string.utf8.character.alpha() > folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) > folding: string.utf8(re) <- string.utf8.character.alpha() > folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) > folding: string.utf8(reg) <- string.utf8.character.alpha() > folded: string.utf8(reg) <- string.utf8.character.alpha() = > string.utf8(rege) > folding: string.utf8(rege) <- string.utf8.character.alpha() > folded: string.utf8(rege) <- string.utf8.character.alpha() = > string.utf8(reget) > folding: string.utf8(reget) <- string.utf8.character.alpha() > folded: string.utf8(reget) <- string.utf8.character.alpha() = > string.utf8(regetn) > folding: string.utf8(regetn) <- string.utf8.character.alpha() > folded: string.utf8(regetn) <- string.utf8.character.alpha() = > string.utf8(regetni) > folding: string.utf8(regetni) <- string.utf8.character.underscore() > folded: string.utf8(regetni) <- string.utf8.character.underscore() = > string.utf8(regetni_) > folding: string.utf8(regetni_) <- string.utf8.character.alpha() > folded: string.utf8(regetni_) <- string.utf8.character.alpha() = > string.utf8(regetni_o) > folding: string.utf8(regetni_o) <- string.utf8.character.alpha() > folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = > string.utf8(regetni_ot) > folding: language.identifier() <- string.utf8(regetni_ot) > folded: language.identifier() <- string.utf8(regetni_ot) = > language.identifier(to_integer) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) > folding: string.utf8(tu) <- string.utf8.character.alpha() > folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) > folding: string.utf8(tup) <- string.utf8.character.alpha() > folded: string.utf8(tup) <- string.utf8.character.alpha() = > string.utf8(tupn) > folding: string.utf8(tupn) <- string.utf8.character.alpha() > folded: string.utf8(tupn) <- string.utf8.character.alpha() = > string.utf8(tupni) > folding: language.identifier() <- string.utf8(tupni) > folded: language.identifier() <- string.utf8(tupni) = > language.identifier(input) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) > folding: string.utf8(tn) <- string.utf8.character.alpha() > folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) > folding: string.utf8(tni) <- string.utf8.character.alpha() > folded: string.utf8(tni) <- string.utf8.character.alpha() = > string.utf8(tnir) > folding: string.utf8(tnir) <- string.utf8.character.alpha() > folded: string.utf8(tnir) <- string.utf8.character.alpha() = > string.utf8(tnirp) > folding: language.identifier() <- string.utf8(tnirp) > folded: language.identifier() <- string.utf8(tnirp) = > language.identifier(print) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(d) > folding: string.utf8(d) <- string.utf8.character.alpha() > folded: string.utf8(d) <- string.utf8.character.alpha() = string.utf8(dd) > folding: string.utf8(dd) <- string.utf8.character.alpha() > folded: string.utf8(dd) <- string.utf8.character.alpha() = string.utf8(dda) > folding: language.identifier() <- string.utf8(dda) > folded: language.identifier() <- string.utf8(dda) = > language.identifier(add) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(y) > folding: language.identifier() <- string.utf8(y) > folded: language.identifier() <- string.utf8(y) = language.identifier(y) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(y) > folding: language.identifier() <- string.utf8(y) > folded: language.identifier() <- string.utf8(y) = language.identifier(y) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) > folding: string.utf8(b) <- string.utf8.character.alpha() > folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) > folding: string.utf8(bi) <- string.utf8.character.alpha() > folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) > folding: language.identifier() <- string.utf8(bif) > folded: language.identifier() <- string.utf8(bif) = > language.identifier(fib) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(d) > folding: string.utf8(d) <- string.utf8.character.alpha() > folded: string.utf8(d) <- string.utf8.character.alpha() = string.utf8(dd) > folding: string.utf8(dd) <- string.utf8.character.alpha() > folded: string.utf8(dd) <- string.utf8.character.alpha() = string.utf8(dda) > folding: language.identifier() <- string.utf8(dda) > folded: language.identifier() <- string.utf8(dda) = > language.identifier(add) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) > folding: string.utf8(b) <- string.utf8.character.alpha() > folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) > folding: string.utf8(bi) <- string.utf8.character.alpha() > folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) > folding: language.identifier() <- string.utf8(bif) > folded: language.identifier() <- string.utf8(bif) = > language.identifier(fib) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) > folding: string.utf8(b) <- string.utf8.character.alpha() > folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) > folding: string.utf8(bi) <- string.utf8.character.alpha() > folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) > folding: language.identifier() <- string.utf8(bif) > folded: language.identifier() <- string.utf8(bif) = > language.identifier(fib) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(x) > folding: language.identifier() <- string.utf8(x) > folded: language.identifier() <- string.utf8(x) = language.identifier(x) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(n) > folding: string.utf8(n) <- string.utf8.character.alpha() > folded: string.utf8(n) <- string.utf8.character.alpha() = string.utf8(ni) > folding: string.utf8(ni) <- string.utf8.character.alpha() > folded: string.utf8(ni) <- string.utf8.character.alpha() = string.utf8(nia) > folding: string.utf8(nia) <- string.utf8.character.alpha() > folded: string.utf8(nia) <- string.utf8.character.alpha() = > string.utf8(niam) > folding: language.identifier() <- string.utf8(niam) > folded: language.identifier() <- string.utf8(niam) = > language.identifier(main) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) > folding: string.utf8(tn) <- string.utf8.character.alpha() > folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) > folding: string.utf8(tni) <- string.utf8.character.alpha() > folded: string.utf8(tni) <- string.utf8.character.alpha() = > string.utf8(tnir) > folding: string.utf8(tnir) <- string.utf8.character.alpha() > folded: string.utf8(tnir) <- string.utf8.character.alpha() = > string.utf8(tnirp) > folding: language.identifier() <- string.utf8(tnirp) > folded: language.identifier() <- string.utf8(tnirp) = > language.identifier(print) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8( ) > folding: string.utf8( ) <- string.utf8.character.alpha() > folded: string.utf8( ) <- string.utf8.character.alpha() = string.utf8( > folding: string.utf8( <- string.utf8.character.alpha() > folded: string.utf8( <- string.utf8.character.alpha() = string.utf8( :r) > folding: string.utf8( :r) <- string.utf8.character.alpha() > folded: string.utf8( :r) <- string.utf8.character.alpha() = string.utf8( > :re) > folding: string.utf8( :re) <- string.utf8.character.alpha() > folded: string.utf8( :re) <- string.utf8.character.alpha() = string.utf8( > :reg) > folding: string.utf8( :reg) <- string.utf8.character.alpha() > folded: string.utf8( :reg) <- string.utf8.character.alpha() = string.utf8( > :rege) > folding: string.utf8( :rege) <- string.utf8.character.alpha() > folded: string.utf8( :rege) <- string.utf8.character.alpha() = > string.utf8( :reget) > folding: string.utf8( :reget) <- string.utf8.character.alpha() > folded: string.utf8( :reget) <- string.utf8.character.alpha() = > string.utf8( :regetn) > folding: string.utf8( :regetn) <- string.utf8.character.alpha() > folded: string.utf8( :regetn) <- string.utf8.character.alpha() = > string.utf8( :regetni) > folding: string.utf8( :regetni) <- string.utf8.character.alpha() > folded: string.utf8( :regetni) <- string.utf8.character.alpha() = > string.utf8( :regetni ) > folding: string.utf8( :regetni ) <- string.utf8.character.alpha() > folded: string.utf8( :regetni ) <- string.utf8.character.alpha() = > string.utf8( :regetni e) > folding: string.utf8( :regetni e) <- string.utf8.character.alpha() > folded: string.utf8( :regetni e) <- string.utf8.character.alpha() = > string.utf8( :regetni ev) > folding: string.utf8( :regetni ev) <- string.utf8.character.alpha() > folded: string.utf8( :regetni ev) <- string.utf8.character.alpha() = > string.utf8( :regetni evi) > folding: string.utf8( :regetni evi) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evi) <- string.utf8.character.alpha() = > string.utf8( :regetni evit) > folding: string.utf8( :regetni evit) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evit) <- string.utf8.character.alpha() = > string.utf8( :regetni eviti) > folding: string.utf8( :regetni eviti) <- string.utf8.character.alpha() > folded: string.utf8( :regetni eviti) <- string.utf8.character.alpha() = > string.utf8( :regetni evitis) > folding: string.utf8( :regetni evitis) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evitis) <- string.utf8.character.alpha() = > string.utf8( :regetni evitiso) > folding: string.utf8( :regetni evitiso) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evitiso) <- string.utf8.character.alpha() = > string.utf8( :regetni evitisop) > folding: string.utf8( :regetni evitisop) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop) <- string.utf8.character.alpha() = > string.utf8( :regetni evitisop ) > folding: string.utf8( :regetni evitisop ) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop ) <- string.utf8.character.alpha() > = string.utf8( :regetni evitisop a) > folding: string.utf8( :regetni evitisop a) <- string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a) <- string.utf8.character.alpha() > = string.utf8( :regetni evitisop a ) > folding: string.utf8( :regetni evitisop a ) <- > string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a ) <- > string.utf8.character.alpha() = string.utf8( :regetni evitisop a r) > folding: string.utf8( :regetni evitisop a r) <- > string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a r) <- > string.utf8.character.alpha() = string.utf8( :regetni evitisop a re) > folding: string.utf8( :regetni evitisop a re) <- > string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a re) <- > string.utf8.character.alpha() = string.utf8( :regetni evitisop a ret) > folding: string.utf8( :regetni evitisop a ret) <- > string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a ret) <- > string.utf8.character.alpha() = string.utf8( :regetni evitisop a retn) > folding: string.utf8( :regetni evitisop a retn) <- > string.utf8.character.alpha() > folded: string.utf8( :regetni evitisop a retn) <- > string.utf8.character.alpha() = string.utf8( :regetni evitisop a retnE) > folding: string.utf8( :regetni evitisop a retnE) <- string.utf8( :regetni > evitisop a retnE) > folded: string.utf8( :regetni evitisop a retnE) <- string.utf8( :regetni > evitisop a retnE) = string.utf8(Enter a positive integer: ) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tu) > folding: string.utf8(tu) <- string.utf8.character.alpha() > folded: string.utf8(tu) <- string.utf8.character.alpha() = string.utf8(tup) > folding: string.utf8(tup) <- string.utf8.character.alpha() > folded: string.utf8(tup) <- string.utf8.character.alpha() = > string.utf8(tupn) > folding: string.utf8(tupn) <- string.utf8.character.alpha() > folded: string.utf8(tupn) <- string.utf8.character.alpha() = > string.utf8(tupni) > folding: language.identifier() <- string.utf8(tupni) > folded: language.identifier() <- string.utf8(tupni) = > language.identifier(input) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(t) > folding: string.utf8(t) <- string.utf8.character.alpha() > folded: string.utf8(t) <- string.utf8.character.alpha() = string.utf8(tn) > folding: string.utf8(tn) <- string.utf8.character.alpha() > folded: string.utf8(tn) <- string.utf8.character.alpha() = string.utf8(tni) > folding: string.utf8(tni) <- string.utf8.character.alpha() > folded: string.utf8(tni) <- string.utf8.character.alpha() = > string.utf8(tnir) > folding: string.utf8(tnir) <- string.utf8.character.alpha() > folded: string.utf8(tnir) <- string.utf8.character.alpha() = > string.utf8(tnirp) > folding: language.identifier() <- string.utf8(tnirp) > folded: language.identifier() <- string.utf8(tnirp) = > language.identifier(print) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(() > folding: string.utf8(() <- string.utf8.character.alpha() > folded: string.utf8(() <- string.utf8.character.alpha() = string.utf8((i) > folding: string.utf8((i) <- string.utf8.character.alpha() > folded: string.utf8((i) <- string.utf8.character.alpha() = string.utf8((ic) > folding: string.utf8((ic) <- string.utf8.character.alpha() > folded: string.utf8((ic) <- string.utf8.character.alpha() = > string.utf8((icc) > folding: string.utf8((icc) <- string.utf8.character.alpha() > folded: string.utf8((icc) <- string.utf8.character.alpha() = > string.utf8((icca) > folding: string.utf8((icca) <- string.utf8.character.alpha() > folded: string.utf8((icca) <- string.utf8.character.alpha() = > string.utf8((iccan) > folding: string.utf8((iccan) <- string.utf8.character.alpha() > folded: string.utf8((iccan) <- string.utf8.character.alpha() = > string.utf8((iccano) > folding: string.utf8((iccano) <- string.utf8.character.alpha() > folded: string.utf8((iccano) <- string.utf8.character.alpha() = > string.utf8((iccanob) > folding: string.utf8((iccanob) <- string.utf8.character.alpha() > folded: string.utf8((iccanob) <- string.utf8.character.alpha() = > string.utf8((iccanobi) > folding: string.utf8((iccanobi) <- string.utf8.character.alpha() > folded: string.utf8((iccanobi) <- string.utf8.character.alpha() = > string.utf8((iccanobiF) > folding: string.utf8((iccanobiF) <- string.utf8((iccanobiF) > folded: string.utf8((iccanobiF) <- string.utf8((iccanobiF) = > string.utf8(Fibonacci() > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8( ) > folding: string.utf8( ) <- string.utf8.character.alpha() > folded: string.utf8( ) <- string.utf8.character.alpha() = string.utf8( =) > folding: string.utf8( =) <- string.utf8.character.alpha() > folded: string.utf8( =) <- string.utf8.character.alpha() = string.utf8( = ) > folding: string.utf8( = ) <- string.utf8.character.alpha() > folded: string.utf8( = ) <- string.utf8.character.alpha() = string.utf8( = > )) > folding: string.utf8( = )) <- string.utf8( = )) > folded: string.utf8( = )) <- string.utf8( = )) = string.utf8() = ) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(g) > folding: string.utf8(g) <- string.utf8.character.alpha() > folded: string.utf8(g) <- string.utf8.character.alpha() = string.utf8(gn) > folding: string.utf8(gn) <- string.utf8.character.alpha() > folded: string.utf8(gn) <- string.utf8.character.alpha() = string.utf8(gni) > folding: string.utf8(gni) <- string.utf8.character.alpha() > folded: string.utf8(gni) <- string.utf8.character.alpha() = > string.utf8(gnir) > folding: string.utf8(gnir) <- string.utf8.character.alpha() > folded: string.utf8(gnir) <- string.utf8.character.alpha() = > string.utf8(gnirt) > folding: string.utf8(gnirt) <- string.utf8.character.alpha() > folded: string.utf8(gnirt) <- string.utf8.character.alpha() = > string.utf8(gnirts) > folding: string.utf8(gnirts) <- string.utf8.character.underscore() > folded: string.utf8(gnirts) <- string.utf8.character.underscore() = > string.utf8(gnirts_) > folding: string.utf8(gnirts_) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_) <- string.utf8.character.alpha() = > string.utf8(gnirts_o) > folding: string.utf8(gnirts_o) <- string.utf8.character.alpha() > folded: string.utf8(gnirts_o) <- string.utf8.character.alpha() = > string.utf8(gnirts_ot) > folding: language.identifier() <- string.utf8(gnirts_ot) > folded: language.identifier() <- string.utf8(gnirts_ot) = > language.identifier(to_string) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(b) > folding: string.utf8(b) <- string.utf8.character.alpha() > folded: string.utf8(b) <- string.utf8.character.alpha() = string.utf8(bi) > folding: string.utf8(bi) <- string.utf8.character.alpha() > folded: string.utf8(bi) <- string.utf8.character.alpha() = string.utf8(bif) > folding: language.identifier() <- string.utf8(bif) > folded: language.identifier() <- string.utf8(bif) = > language.identifier(fib) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(r) > folding: string.utf8(r) <- string.utf8.character.alpha() > folded: string.utf8(r) <- string.utf8.character.alpha() = string.utf8(re) > folding: string.utf8(re) <- string.utf8.character.alpha() > folded: string.utf8(re) <- string.utf8.character.alpha() = string.utf8(reg) > folding: string.utf8(reg) <- string.utf8.character.alpha() > folded: string.utf8(reg) <- string.utf8.character.alpha() = > string.utf8(rege) > folding: string.utf8(rege) <- string.utf8.character.alpha() > folded: string.utf8(rege) <- string.utf8.character.alpha() = > string.utf8(reget) > folding: string.utf8(reget) <- string.utf8.character.alpha() > folded: string.utf8(reget) <- string.utf8.character.alpha() = > string.utf8(regetn) > folding: string.utf8(regetn) <- string.utf8.character.alpha() > folded: string.utf8(regetn) <- string.utf8.character.alpha() = > string.utf8(regetni) > folding: string.utf8(regetni) <- string.utf8.character.underscore() > folded: string.utf8(regetni) <- string.utf8.character.underscore() = > string.utf8(regetni_) > folding: string.utf8(regetni_) <- string.utf8.character.alpha() > folded: string.utf8(regetni_) <- string.utf8.character.alpha() = > string.utf8(regetni_o) > folding: string.utf8(regetni_o) <- string.utf8.character.alpha() > folded: string.utf8(regetni_o) <- string.utf8.character.alpha() = > string.utf8(regetni_ot) > folding: language.identifier() <- string.utf8(regetni_ot) > folded: language.identifier() <- string.utf8(regetni_ot) = > language.identifier(to_integer) > folding: string.utf8() <- string.utf8.character.alpha() > folded: string.utf8() <- string.utf8.character.alpha() = string.utf8(s) > folding: language.identifier() <- string.utf8(s) > folded: language.identifier() <- string.utf8(s) = language.identifier(s) > folding: string.utf8() <- string.utf8.character.LF() > folded: string.utf8() <- string.utf8.character.LF() = string.utf8( ) > folding: string.utf8( ) <- string.utf8( ) > folded: string.utf8( ) <- string.utf8( ) = string.utf8( ) > Compilation time: 336.892ms > neoscript] > > Message ends. > > /Flibble > > -- > ? > -- > https://mail.python.org/mailman/listinfo/python-list > From grant.b.edwards at gmail.com Sun Feb 14 18:01:23 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 14 Feb 2021 23:01:23 -0000 (UTC) Subject: Change first occurrence of character x in a string - how? References: Message-ID: On 2021-02-14, Mr Flibble wrote: > On 14/02/2021 21:14, Chris Green wrote: >> What's the easiest way to change the first occurrence of a specified >> character in a string? > > By using a grown up (i.e. non-toy) programming language. [gotta love slrn's scoring feature...] From alan.gauld at yahoo.co.uk Mon Feb 15 06:34:35 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Mon, 15 Feb 2021 11:34:35 +0000 Subject: Efficiency debates In-Reply-To: <09b101d70341$f80195d0$e804c170$@verizon.net> References: <09b101d70341$f80195d0$e804c170$.ref@verizon.net> <09b101d70341$f80195d0$e804c170$@verizon.net> Message-ID: On 15/02/2021 02:26, Avi Gross via Python-list wrote: > I think we have discussed this a few times. Indeed, many times! And there is a natural tendency for a group focused on a programming language to fixate on language improvements. But it's worth while to back up and look at real world scenarios too where choice of programming language is such a minor influence on performance that it is rarely even considered significant. Much more important are things like network speeds, database speeds, disk access speeds and overall architecture and design. These are the areas that give orders of magnitude performance improvement. Next comes algorithm design, caching models and the like. These give multiple factors of improvement. Finally, we come to language tweaks and choice of language where a doubling of performance might be attainable. (Language X being "10 times faster" than language Y rarely translates to a non-trivial application being 10 times faster!) Of course, it depends on the type of project and if its a high computational scenario things will likely be different. But for the big projects that run our lives - air traffic control, taxation, payroll, billing, banking and so on, choice of language comes way down the pecking order. What's that quote about premature optimization?... -- 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 From ethan at stoneleaf.us Mon Feb 15 13:09:47 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Mon, 15 Feb 2021 10:09:47 -0800 Subject: Mr. Flibble Message-ID: Thank you to those who pointed out this individual to the moderators. As Mr. Flibble accurately noted, he is not on the mailing list -- so his posts won't be here either. -- ~Ethan~ Python List Moderator From rust at thisisnotreal.com Mon Feb 15 13:08:48 2021 From: rust at thisisnotreal.com (rust buckett) Date: Mon, 15 Feb 2021 18:08:48 +0000 (UTC) Subject: Change first occurrence of character x in a string - how? References: Message-ID: Grant Edwards wrote: > On 2021-02-14, Mr Flibble wrote: >> On 14/02/2021 21:14, Chris Green wrote: >>> What's the easiest way to change the first occurrence of a specified >>> character in a string? >> >> By using a grown up (i.e. non-toy) programming language. > > > > [gotta love slrn's scoring feature...] > Yep. That's gonna save me some time. From PythonList at DancesWithMice.info Mon Feb 15 14:32:36 2021 From: PythonList at DancesWithMice.info (dn) Date: Tue, 16 Feb 2021 08:32:36 +1300 Subject: Is email.message.get() case insensitive for the header name? In-Reply-To: References: Message-ID: <7d5b30bf-153e-f09c-6118-0eb8a24381a9@DancesWithMice.info> On 15/02/2021 09.50, Chris Green wrote: > It isn't clear from the documentation. Does email.message.get() care > about the case of the header it's getting? > > I checking mailing list mails and the "List-Id:" header is a bit > 'mixed', i.e. it can be List-Id:, or List-ID: or list-id:, will > email.message.get("List-Id:", "unknown") find all of them? Case is (should be) irrelevant (as it is for most (parts of) Internet Protocols). Rather than the "Zen of Python", when it comes to IPs, "Postel's Law" applies (https://en.wikipedia.org/wiki/Robustness_principle). The library docs say it follows such. Web.Refs: https://docs.python.org/3/library/email.html <<< email ? An email and MIME handling package Source code: Lib/email/__init__.py The email package is a library for managing email messages. It is specifically not designed to do any sending of email messages to SMTP (RFC 2821), NNTP, or other servers; those are functions of modules such as smtplib and nntplib. The email package attempts to be as RFC-compliant as possible, supporting RFC 5233 and RFC 6532... >>> https://tools.ietf.org/html/rfc6532.html <<< 3. Changes to Message Header Fields To permit non-ASCII Unicode characters in field values, the header definition in [RFC5322] is extended to support the new format. The following sections specify the necessary changes to RFC 5322's ABNF. The syntax rules not mentioned below remain defined as in [RFC5322]. Note that this protocol does not change rules in RFC 5322 for defining header field names. The bodies of header fields are allowed to contain Unicode characters, but the header field names themselves must consist of ASCII characters only. Also note that messages in this format require the use of the SMTPUTF8 extension [RFC6531] to be transferred via SMTP. ... >>> https://tools.ietf.org/html/rfc5322 <<< RFC 5322 Internet Message Format October 2008 2.2. Header Fields Header fields are lines beginning with a field name, followed by a colon (":"), followed by a field body, and terminated by CRLF. A field name MUST be composed of printable US-ASCII characters (i.e., characters that have values between 33 and 126, inclusive), except colon. A field body may be composed of printable US-ASCII characters as well as the space (SP, ASCII value 32) and horizontal tab (HTAB, ASCII value 9) characters (together known as the white space characters, WSP). A field body MUST NOT include CR and LF except when used in "folding" and "unfolding", as described in section 2.2.3. All field bodies MUST conform to the syntax described in sections 3 and 4 of this specification. ... >>> -- Regards, =dn From roel at roelschroeven.net Mon Feb 15 15:37:14 2021 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 15 Feb 2021 21:37:14 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: Mr Flibble schreef op 15/02/2021 om 0:32: > On 14/02/2021 23:00, Christian Gollwitzer wrote: > I'm not saying that it is unfeasible or very difficult. I'm saying that it is a lot of work, and for a single developer who has this as a side project / support for his graphics engine and who wants to beat existing implementations wrt. speed, I'm saying it is going to take a lot of time. It'definitely impossible by "defining a few JSON schema files", as Leigh claims with his "universal compiler". There definitely IS a lot of stuff in a baseline CPython interpreter - a (seemingly) simple thing like "print" will have an implementation of 1000 lines in C with all the formatting library, file I/O etc. Arbitrary precision integers - another library, networking - yet another and so on. > > There will only be one schema file and it is will be a relatively small task which certainly isn't "impossible": I should have a working implementation by the summer. So your claim is that your compiler is able to, or will be able to, compile any language just by specifying a small schema file. Great! Do you maybe have a proof-of-concept? A simple language with a simple schema file to test the basic workings of your compiler, like your neoscript or perhaps something like a minimal variant of Python? I'm curious what such a schema file would like look, and especially how you use it to not only specify the syntax but also the semantics of the various languages. Is it your intention to not only compile procedural and object-oriented languages, or also functional languages such as Haskell, Ocaml, Scheme? -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones Roel Schroeven From ben.usenet at bsb.me.uk Mon Feb 15 16:47:22 2021 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Mon, 15 Feb 2021 21:47:22 +0000 Subject: Mr. Flibble References: Message-ID: <87mtw580lx.fsf@bsb.me.uk> Mr Flibble writes: > On 15/02/2021 18:09, Ethan Furman wrote: >> Thank you to those who pointed out this individual to the >> moderators. As Mr. Flibble accurately noted, he is not on the mailing >> list -- so his posts won't be here either. > > ORLY? You said you used Usenet (and your reply here was via Usenet). Usenet posts to comp.lang.python don't go to the mailing list (the "here" that Ethan is talking about). Mails to the list /are/ sent here, but it's one-way traffic. -- Ben. From grant.b.edwards at gmail.com Mon Feb 15 15:59:45 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 15 Feb 2021 20:59:45 -0000 (UTC) Subject: New Python implementation References: <87blcnnejf.fsf@nightsong.com> Message-ID: On 2021-02-15, Roel Schroeven wrote: > Is it your intention to not only compile procedural and object-oriented > languages, or also functional languages such as Haskell, Ocaml, Scheme? And Prolog! -- Grant From grant.b.edwards at gmail.com Mon Feb 15 17:02:41 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 15 Feb 2021 22:02:41 -0000 (UTC) Subject: Mr. Flibble References: <87mtw580lx.fsf@bsb.me.uk> Message-ID: On 2021-02-15, Ben Bacarisse wrote: > You said you used Usenet (and your reply here was via Usenet). > Usenet posts to comp.lang.python don't go to the mailing list (the > "here" that Ethan is talking about). Mails to the list /are/ sent > here, but it's one-way traffic. That's new -- it always used to be two-way. When did it change? -- Grant From ethan at stoneleaf.us Mon Feb 15 17:10:23 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Mon, 15 Feb 2021 14:10:23 -0800 Subject: Mr. Flibble In-Reply-To: References: <87mtw580lx.fsf@bsb.me.uk> Message-ID: <5e36b32f-8215-a8f7-34b5-d96b62cc7469@stoneleaf.us> On 2/15/21 2:02 PM, Grant Edwards wrote: > On 2021-02-15, Ben Bacarisse wrote: > >> You said you used Usenet (and your reply here was via Usenet). >> Usenet posts to comp.lang.python don't go to the mailing list (the >> "here" that Ethan is talking about). Mails to the list /are/ sent >> here, but it's one-way traffic. > > That's new -- it always used to be two-way. When did it change? It is two-way still (or we wouldn't have seen his posts to begin with). -- ~Ethan~ From ikorot01 at gmail.com Mon Feb 15 17:25:12 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Mon, 15 Feb 2021 16:25:12 -0600 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: And C. Thank you. On Mon, Feb 15, 2021, 3:56 PM Grant Edwards wrote: > On 2021-02-15, Roel Schroeven wrote: > > > Is it your intention to not only compile procedural and object-oriented > > languages, or also functional languages such as Haskell, Ocaml, Scheme? > > And Prolog! > > -- > Grant > > > > -- > https://mail.python.org/mailman/listinfo/python-list > From avigross at verizon.net Mon Feb 15 17:43:07 2021 From: avigross at verizon.net (Avi Gross) Date: Mon, 15 Feb 2021 17:43:07 -0500 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: <06aa01d703eb$ee353020$ca9f9060$@verizon.net> Grant, Haven't thought about Prolog in a LOOONG time but it had some wild twists on how to specify a problem that might not be trivial to integrate with other languages as our now seemingly censored person with much delusion of grandeur suggests. It is a language that does not specify what to do but more what rules an answer must abide by. Perhaps he should go to work for the Star Trek Federation and improving their Universal Translator that can learn any alien language in about two sentences. I am sure he will tell us it would be trivial for him or her along with other Fibbles he/she tells. Am I the only one who found it amusing, back to Python, that a recent attack on Python was about a fairly trivial problem to solve in most languages, let alone Python. Toy language does not normally apply to a fairly mature language, regularly extended to do many things in many ways, unless anything not fully standardized is a toy. I consider many such to become toys as they end up near the end of their lives and hard to extend further. I think the question was as simple as how to find the first period in a string (assuming it exists?) and replace it with an @ and not subsequent ones. Not very challenging even using very basic commands in a computer language. Computing 101? Can you name any language where that is hard to do from scratch? Sure, many will provide a ready-made function that does it in one line of code (or a partial line) but most languages let you use something like a loop that lets you look at one letter of a "string" variable at a time and perhaps copy it to a new one. A logical variable can be set so you conditionally replace just the first instance. Whether changed in place or in a copy, it seems trivial. So why snide comments that you need more than a toy language when this is precisely what is doable even in a toy language, but so commonly done that many better languages (and Python definitely is included) give you an assortment of built-in functionality to make it easy, and then dozens of other ways in modules you can load ... Now there are fairly complex things that a user cannot easily build from scratch or find a ready-made solution. There may well be say a PROLOG program that is simple and elegant and very hard to solve using Python, let alone a toy language. To me, all languages are toys, albeit for different age/experience groups. -----Original Message----- From: Python-list On Behalf Of Grant Edwards Sent: Monday, February 15, 2021 4:00 PM To: python-list at python.org Subject: Re: New Python implementation On 2021-02-15, Roel Schroeven wrote: > Is it your intention to not only compile procedural and > object-oriented languages, or also functional languages such as Haskell, Ocaml, Scheme? And Prolog! -- Grant -- https://mail.python.org/mailman/listinfo/python-list From buck.2019 at gmail.com Mon Feb 15 17:46:09 2021 From: buck.2019 at gmail.com (Buck Evan) Date: Mon, 15 Feb 2021 16:46:09 -0600 Subject: New Python implementation In-Reply-To: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> References: <1d43835e-fe70-d6b4-ab93-2859c77b9612@DancesWithMice.info> Message-ID: On Thu, Feb 11, 2021 at 1:49 PM dn via Python-list wrote: > When I first met it, one of the concepts I found difficult to 'wrap my > head around' was the idea that "open software" allowed folk to fork the > original work and 'do their own thing'. My thinking was (probably) > "surely, the original is the authoritative version". Having other > versions seemed an invitation to confusion and dilution. > > However, as soon as (open) software is made available, other people > start making it 'better' - whatever their own definition of "better". > > Yes, it is both a joy and a complication. > > ... > > Wishing you well. It seems (to (neos-ignorant) me at least) an ambitious > project. There are certainly times when 'execution speed' becomes a > major criteria. Many of us will look forward to (your development of) a > solution. Please let us know when it's ready for use/trials... > Well put! Thank you for this thoughtful and informative message. You obviously put substantial work into it. From roel at roelschroeven.net Mon Feb 15 17:24:36 2021 From: roel at roelschroeven.net (Roel Schroeven) Date: Mon, 15 Feb 2021 23:24:36 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: Grant Edwards schreef op 15/02/2021 om 21:59: > On 2021-02-15, Roel Schroeven wrote: > >> Is it your intention to not only compile procedural and object-oriented >> languages, or also functional languages such as Haskell, Ocaml, Scheme? > > And Prolog! Ha, yes, that one was the next one I thought about, but in the I decided to leave it out. -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones Roel Schroeven From PythonList at DancesWithMice.info Mon Feb 15 18:04:04 2021 From: PythonList at DancesWithMice.info (dn) Date: Tue, 16 Feb 2021 12:04:04 +1300 Subject: Mr. Flibble In-Reply-To: References: Message-ID: <1037fd50-6bc2-42cd-b58d-f72ab05341c6@DancesWithMice.info> On 16/02/2021 07.09, Ethan Furman wrote: > Thank you to those who pointed out this individual to the moderators. As > Mr. Flibble accurately noted, he is not on the mailing list -- so his > posts won't be here either. Appreciating the work you(s) invest on my/our behalf! -- Regards, =dn From grant.b.edwards at gmail.com Mon Feb 15 18:12:52 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 15 Feb 2021 23:12:52 -0000 (UTC) Subject: New Python implementation References: <87blcnnejf.fsf@nightsong.com> <06aa01d703eb$ee353020$ca9f9060$@verizon.net> Message-ID: On 2021-02-15, Avi Gross via Python-list wrote: > Haven't thought about Prolog in a LOOONG time but it had some wild > twists on how to specify a problem that might not be trivial to > integrate with other languages as our now seemingly censored person > with much delusion of grandeur suggests. It is a language that does > not specify what to do but more what rules an answer must abide by. Of all the languages I've used, Prolog was by far the hardest to get my head around. The dialect I used the most (which still wasn't much) was part of Digitalk's Smalltalk system. I don't recall if Digitalk Prolog was written entirely in Smalltalk, or if it was just integrated into the Smalltalk system as an opaque object. -- Grant From ben.usenet at bsb.me.uk Mon Feb 15 18:54:50 2021 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Mon, 15 Feb 2021 23:54:50 +0000 Subject: Mr. Flibble References: <87mtw580lx.fsf@bsb.me.uk> <5e36b32f-8215-a8f7-34b5-d96b62cc7469@stoneleaf.us> Message-ID: <87h7mc999x.fsf@bsb.me.uk> Ethan Furman writes: > On 2/15/21 2:02 PM, Grant Edwards wrote: >> On 2021-02-15, Ben Bacarisse wrote: >> >>> You said you used Usenet (and your reply here was via Usenet). >>> Usenet posts to comp.lang.python don't go to the mailing list (the >>> "here" that Ethan is talking about). Mails to the list /are/ sent >>> here, but it's one-way traffic. >> >> That's new -- it always used to be two-way. When did it change? > > It is two-way still (or we wouldn't have seen his posts to begin > with). Ah, my mistake. Sorry for the confusion. -- Ben. From drsalists at gmail.com Mon Feb 15 20:09:03 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 15 Feb 2021 17:09:03 -0800 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <06aa01d703eb$ee353020$ca9f9060$@verizon.net> Message-ID: On Mon, Feb 15, 2021 at 3:25 PM Grant Edwards wrote: > On 2021-02-15, Avi Gross via Python-list wrote: > Of all the languages I've used, Prolog was by far the hardest to get > my head around. The dialect I used the most (which still wasn't much) > was part of Digitalk's Smalltalk system. I don't recall if Digitalk > Prolog was written entirely in Smalltalk, or if it was just integrated > into the Smalltalk system as an opaque object. > I actually found Prolog to be a lot like /usr/bin/make. It's an OK language if everything you need to do can be solved well using a depth first search. Otherwise, it kind of gets in the way. From alan.gauld at yahoo.co.uk Mon Feb 15 19:29:22 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Feb 2021 00:29:22 +0000 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: On 15/02/2021 22:24, Roel Schroeven wrote: > Grant Edwards schreef op 15/02/2021 om 21:59: >> On 2021-02-15, Roel Schroeven wrote: >> >>> Is it your intention to not only compile procedural and object-oriented >>> languages, or also functional languages such as Haskell, Ocaml, Scheme? >> >> And Prolog! > > Ha, yes, that one was the next one I thought about, but in the I decided > to leave it out. Yes, Prolog is definitely different. When I was at Uni' in the mid 80s we all got taught Prolog because the Japanese had promised to produce a 5th generation computer by 1990 and it would be based on Prolog. We're still waiting, but in the meantime we got the internet and GUIs. Looks like Sun got it right - "the network is the computer"... -- 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 From ikorot01 at gmail.com Mon Feb 15 23:51:14 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Mon, 15 Feb 2021 22:51:14 -0600 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: Hi, guys, Let me try to throw in another one - PL/1. This guys used to be very popular with the accounting community... Thank you. On Mon, Feb 15, 2021 at 9:51 PM Alan Gauld via Python-list wrote: > > On 15/02/2021 22:24, Roel Schroeven wrote: > > Grant Edwards schreef op 15/02/2021 om 21:59: > >> On 2021-02-15, Roel Schroeven wrote: > >> > >>> Is it your intention to not only compile procedural and object-oriented > >>> languages, or also functional languages such as Haskell, Ocaml, Scheme? > >> > >> And Prolog! > > > > Ha, yes, that one was the next one I thought about, but in the I decided > > to leave it out. > > Yes, Prolog is definitely different. When I was at Uni' in the mid 80s > we all got taught Prolog because the Japanese had promised to produce > a 5th generation computer by 1990 and it would be based on Prolog. > We're still waiting, but in the meantime we got the internet and GUIs. > > Looks like Sun got it right - "the network is the computer"... > > -- > 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 From drsalists at gmail.com Mon Feb 15 23:57:27 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 15 Feb 2021 20:57:27 -0800 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: On Mon, Feb 15, 2021 at 8:52 PM Igor Korot wrote: > Hi, guys, > Let me try to throw in another one - PL/1. > This guys used to be very popular with the accounting community... > Actually PL/I is basically proprietary Pascal - from IBM. My Intro Comp Sci classes at the University of Cincinnati were in PL/I, because IBM had an office not far from the University, and they liked to hire interns from UCinci. I was told that otherwise the classes would've been in Pascal. From PythonList at DancesWithMice.info Tue Feb 16 00:36:38 2021 From: PythonList at DancesWithMice.info (dn) Date: Tue, 16 Feb 2021 18:36:38 +1300 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> On 16/02/2021 17.57, Dan Stromberg wrote: > On Mon, Feb 15, 2021 at 8:52 PM Igor Korot wrote: > >> Hi, guys, >> Let me try to throw in another one - PL/1. >> This guys used to be very popular with the accounting community... >> > > Actually PL/I is basically proprietary Pascal - from IBM. My Intro Comp > Sci classes at the University of Cincinnati were in PL/I, because IBM had > an office not far from the University, and they liked to hire interns from > UCinci. I was told that otherwise the classes would've been in Pascal. Might a coincidence of location have been conflated with language development? PL/I (note the Roman "one") was developed out of the IBM System/360 effort, ie one computer architecture for all types of users (cf different computers for 'commercial' and 'scientific' clients - which you can see again today in AWS' range of compute options, for example). It was to be 'one language to rule them all'. Initially, it was based on FORTRAN. We joked that it took all of the bad parts of FORTRAN and COBOL and mashed them into a single ... language. However, like many such efforts, it attempted to take 'the best' from many sources (including ALGOL). Sadly, (maybe) it, like Ada (another attempt to be 'all things to all men') only ever really existed in a niche market. Pascal, named after the mathematician and philosopher the French credit with 'inventing the computer', was developed in the European world - which even back-then had marked differences in thinking to the American approach/domination of computing. Prof Niklaus Wirth published a seminal book "Algorithms + Data Structures = Programs" (which I seem to have lost, somewhere in the mists of time). I don't think it gave examples in Pascal, but it did use a pseudo-code/-language which illuminated various ideas and ways of developing programmatic solutions. As I recall, it (and Pascal) was very ALGOL like, and thus heavily influenced by "stack architecture" (cf IBM's collections of "registers" in an ALU). Certainly the language was clearly based upon ALGOL-60. Clearly it led to the refinement and/or development of Pascal. Pascal's value as a teaching language was that it embodied many aspects of structured programming, and like Python, consisted of a limited range of items which could be learned very quickly (in contrast to PL/I's many 'bells and whistles'). Thus, once absorbed, learning attention could be directed to ComSc/algorithms + data! Pascal was also very efficient, to compile and to execute, which made it a competent fore-runner of Micro-Python (etc) in the micro and single-board computer arenae/arenas. Without Python, I think I'd prefer to use (an updated) UCSD-Pascal or Borland Turbo-Pascal to this very day! PL/I, not so much - even on a mainframe project! -- Regards, =dn From nad at python.org Tue Feb 16 00:59:52 2021 From: nad at python.org (Ned Deily) Date: Tue, 16 Feb 2021 00:59:52 -0500 Subject: [RELEASE] Python 3.7.10 and 3.6.13 security updates now available Message-ID: Python 3.7.10 and 3.6.13, the lastest security fix rollups for Python 3.7 and Python 3.6, are now available. You can find the release files, links to the changelogs, and more information here: https://www.python.org/downloads/release/python-3710/ https://www.python.org/downloads/release/python-3613/ These releases are source code only; Windows and macOS binary installers are not provided for security fix releases. Note that Python 3.9 is now the latest feature release series of Python 3. You should consider upgrading to 3.9 as soon as practical. Get the latest release of 3.9.x here: https://www.python.org/downloads/ Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. https://www.python.org/psf-landing/ -- Ned Deily nad at python.org -- [] From drsalists at gmail.com Tue Feb 16 01:05:32 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 15 Feb 2021 22:05:32 -0800 Subject: New Python implementation In-Reply-To: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: On Mon, Feb 15, 2021 at 9:37 PM dn via Python-list wrote: > On 16/02/2021 17.57, Dan Stromberg wrote: > > On Mon, Feb 15, 2021 at 8:52 PM Igor Korot wrote: > > > >> Hi, guys, > >> Let me try to throw in another one - PL/1. > >> This guys used to be very popular with the accounting community... > >> > > > > Actually PL/I is basically proprietary Pascal - from IBM. My Intro Comp > > Sci classes at the University of Cincinnati were in PL/I, because IBM had > > an office not far from the University, and they liked to hire interns > from > > UCinci. I was told that otherwise the classes would've been in Pascal. > > > Might a coincidence of location have been conflated with language > development? > Nah. All 3 are in the Algol family: Algol, Pascal, PL/I. I'll grant you that PL/I is a "big language" though. It didn't rely on external libraries as much as it should have. From auriocus at gmx.de Tue Feb 16 02:25:00 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 16 Feb 2021 08:25:00 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: Am 15.02.21 um 21:37 schrieb Roel Schroeven: > > So your claim is that your compiler is able to, or will be able to, > compile any language just by specifying a small schema file. Great! > > Do you maybe have a proof-of-concept? A simple language with a simple > schema file to test the basic workings of your compiler, Here is the git repo: https://github.com/i42output/neos under languages/ you'll find different schema files. Christian From auriocus at gmx.de Tue Feb 16 02:35:28 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 16 Feb 2021 08:35:28 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: Am 16.02.21 um 06:36 schrieb dn: > Pascal's value as a teaching language was that it embodied many aspects > of structured programming, and like Python, consisted of a limited range > of items which could be learned very quickly (in contrast to PL/I's many > 'bells and whistles'). ROFL. Maybe that was true for Python when it was first invented. Today it is not "a few simple things". Even just the core language, anything that's built into the interpreter if you leave out any standard function, is enormous. To name a few: List comprehension, format strings, iterator protocol, asynchronous programming, everything called __dunderland. A minimal language with only very few basic rules, that would be Scheme e.g. Of course, it doesn't mean that Scheme is easier to program, but it is easier to write a compiler for it than for Python. That is a misundestanding often presented - a language that is simple in the sense of having a few simple rules, is usually hard to use. (e.g. Brainfuck). A language which is easy to use, often comes with a large variety of building blocks, to give you the right tool to choose for the job at hands (e.g. Python), and therefore is "complex". Christian From tarjei at purelymail.com Tue Feb 16 03:57:38 2021 From: tarjei at purelymail.com (Tarjei =?utf-8?Q?B=C3=A6rland?=) Date: Tue, 16 Feb 2021 09:57:38 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: <87a6s41jb1.fsf@purelymail.com> Christian Gollwitzer writes: > Am 16.02.21 um 06:36 schrieb dn: >> Pascal's value as a teaching language was that it embodied many aspects >> of structured programming, and like Python, consisted of a limited range >> of items which could be learned very quickly (in contrast to PL/I's many >> 'bells and whistles'). > > ROFL. Maybe that was true for Python when it was first invented. Today > it is not "a few simple things". Even just the core language, anything > that's built into the interpreter if you leave out any standard > function, is enormous. To name a few: List comprehension, format > strings, iterator protocol, asynchronous programming, everything called > __dunderland. A minimal language with only very few basic rules, that > would be Scheme e.g. Of course, it doesn't mean that Scheme is easier to > program, but it is easier to write a compiler for it than for Python. > > That is a misundestanding often presented - a language that is simple in > the sense of having a few simple rules, is usually hard to use. (e.g. > Brainfuck). A language which is easy to use, often comes with a large > variety of building blocks, to give you the right tool to choose for the > job at hands (e.g. Python), and therefore is "complex". > > Christian In Norway, where I try to teach mathematics to highschoolers, programming has recently entered the teaching of stem subjects. Even if Python is my choice language for personal projects, I am not certain it is the right language to use in a classroom context. My feeling is that Python comes with way too much packed in, making it very hard for the students to get to a level where they can sit down and be creative with their own programming. You either guide them very, very deliberately, exposing piece by piece of the language ... or you let them loose, having to explain the difference in scoping between list comprehensions and for loops after three weeks. I am exaggerating ... a little. I am not sure I agree that a language like Scheme or Logo or Brainfuck, with their small number of building blocks, would be harder to learn. To me, Python is the lego boxes from the early 2000s, where there were so many specialized pieces that you felt that the original design might as well be the only design. Regards, Tarjei From david at lowryduda.com Tue Feb 16 10:12:53 2021 From: david at lowryduda.com (David Lowry-Duda) Date: Tue, 16 Feb 2021 10:12:53 -0500 Subject: New Python implementation In-Reply-To: <87a6s41jb1.fsf@purelymail.com> References: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: > In Norway, where I try to teach mathematics to highschoolers, > programming has recently entered the teaching of stem subjects. > > Even if Python is my choice language for personal projects, I am not > certain it is the right language to use in a classroom context. > ... > I am not sure I agree that a language like Scheme or Logo or > Brainfuck, with their small number of building blocks, would be harder > to learn. Does this mean that you also try to teach programming to highschoolers, or is there a different (maybe dedicated) teacher to that? What language do they use? And does it influence math education at all? (Coming from someone who sometimes tries to teach undergraduates about math). - David Lowry-Duda From carlosandrews926 at gmail.com Tue Feb 16 05:04:11 2021 From: carlosandrews926 at gmail.com (Carlos Andrews) Date: Tue, 16 Feb 2021 11:04:11 +0100 Subject: SSL/TLS certificate verification suddenly broken, Python 3 on Windows 10 Message-ID: Hi All, I ran into an error I, so far, cannot explain regarding Python's general ability to communicate via SSL/TLS. I'm using Python a lot to communicate with web servers and APIs, which worked just fine until yesterday (or somewhen late last week). I first noticed yesterday, when a requests-based call to a local web server with a self-signed certificate failed. No worries, I thought, passing the "verify=False" parameter to the request fixed the issue. Later on I used the same call to a public web server with a valid, CA-signed certificate and got the same error: SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)')) That caused me to stop and try simple calls like import requests resp = requests.request('GET', 'https://www.nytimes.com/') to fail alike. And I surely would not turn off certificate verification to public websites. First assuming a network connection problem I tried curl, openssl or a web browser, all worked fine. Only Python fails. I checked the installed certificate bundle, all correct and even upgraded it to the latest version. No effect. I replaced it with the one curl is using and that curl managed to verify the cert with. No effect. By that time I was using a Python 3.7.9 installation on Windows 10 that ran fine for months (and also before upgrading to 3.7.9). I tried upgrading certifi and requests to the latest versions, which also caused the same SSLError, so I downloaded the wheel packages and forced a local upgrade - to no help. After that I deleted the whole Python installation directory and replaced it with a backup copy of a known-working version from a month ago. The error kept appearing. I then uninstalled Python completely, rebooted and installed Python 3.9.1, downloaded from python.org. The first to commands to issue were: C:\Users\Carlos>python -V Python 3.9.1 C:\Users\Carlos>pip list Package Version ---------- ------- pip 20.2.3 setuptools 49.2.1 Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)'))) - skipping So there went my theory of the requests module... It already happens with the Python base installation (urllib3?). Obviously a freshly installed Python with no modifications and no other modules installed fails to verify each and every certificate. I can rule out network errors as other machines using the same Internet breakout work just fine with the same code. And it happens using a web proxy and using no web proxy at all. Aunty Google always tells me to set "verify=False" but that can't be the solution for *this* problem. Unfortunately I have no idea where to look next - not with a fresh installation failing. Does anybody have a useful pointer for me? TIA! Regards, Carlos From alan.gauld at yahoo.co.uk Tue Feb 16 06:03:33 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Tue, 16 Feb 2021 11:03:33 +0000 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: On 16/02/2021 07:35, Christian Gollwitzer wrote: > Am 16.02.21 um 06:36 schrieb dn: >> Pascal's value as a teaching language was that it embodied many aspects >> of structured programming, and like Python, consisted of a limited range >> of items which could be learned very quickly > > ROFL. Maybe that was true for Python when it was first invented. Today > it is not "a few simple things". Even just the core language, Python v1 was a good teaching language. v2 complicated it a bit but it was still usable. v3 is no longer a good teaching language (unless maybe you are teaching CompSci at university.) In fact in v3 things are so complex that I seriously considered dropping Python as the core language for my programming tutorial. Until I started looking for an alternative, and there really isn't anything much better. At least not that can also be used for real projects once you've learned it. But the sort of change that has made it complicated for beginners is range(). range() used to be simple - it returned a list of numbers in the range specified. The hardest thing to explain was why it stopped one short of the upper limit. Now range returns a "range object". Say what? How do explain a range object to a beginner? And you can't avoid it because the name pops up in the interpreter. And that's just one example, the language is now full of meta goodness that makes it incomprehensible to beginners. In a teaching environment, with a teacher present to answer questions, it's probably usable, but for a self guided course it's increasingly inscrutable. -- 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 From andersonwillsam at gmail.com Tue Feb 16 10:09:05 2021 From: andersonwillsam at gmail.com (Will Anderson) Date: Tue, 16 Feb 2021 10:09:05 -0500 Subject: IDLE Message-ID: <2F82C467-2B1D-49EE-A668-451A1C46C3E6@hxcore.ol> Hi, I hope you are having a good day. I have a small IDLE problem and can?t seem to fix it. I have a .py file that I want to open using IDLE but there is no option I have even tried totally wiping python and reinstalling it nothing seems to work. Please help. ? ? Will Anderson [1]andersonwillsam at gmail.com [2]Website ? ? References Visible links 1. mailto:andersonwillsam at gmail.com 2. https://sites.google.com/view/willanderson/home From swistakm at gmail.com Tue Feb 16 11:51:27 2021 From: swistakm at gmail.com (=?utf-8?Q?Micha=C5=82_Jaworski?=) Date: Tue, 16 Feb 2021 17:51:27 +0100 Subject: SSL/TLS certificate verification suddenly broken, Python 3 on Windows 10 In-Reply-To: References: Message-ID: <0482C8E2-61E5-47E9-9027-D80F5B1EA00F@gmail.com> I?ve had similar issue today on macOS when trying to download something from PyPI with Python 3.9.1 but I didn?t try to debug it and just moved on to different things. Maybe we both have outdated ca bundles? Micha? Jaworski > Wiadomo?? napisana przez Carlos Andrews w dniu 16.02.2021, o godz. 16:42: > > ?Hi All, > > I ran into an error I, so far, cannot explain regarding Python's general > ability to communicate via SSL/TLS. > > I'm using Python a lot to communicate with web servers and APIs, which > worked just fine until yesterday (or somewhen late last week). > > I first noticed yesterday, when a requests-based call to a local web server > with a self-signed certificate failed. No worries, I thought, passing the > "verify=False" parameter to the request fixed the issue. > > Later on I used the same call to a public web server with a valid, > CA-signed certificate and got the same error: > SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: unable to get local issuer certificate > (_ssl.c:1123)')) > > That caused me to stop and try simple calls like > import requests > resp = requests.request('GET', 'https://www.nytimes.com/') > to fail alike. And I surely would not turn off certificate verification to > public websites. > > First assuming a network connection problem I tried curl, openssl or a web > browser, all worked fine. Only Python fails. > > I checked the installed certificate bundle, all correct and even upgraded > it to the latest version. No effect. I replaced it with the one curl is > using and that curl managed to verify the cert with. No effect. > > By that time I was using a Python 3.7.9 installation on Windows 10 that ran > fine for months (and also before upgrading to 3.7.9). > > I tried upgrading certifi and requests to the latest versions, which also > caused the same SSLError, so I downloaded the wheel packages and forced a > local upgrade - to no help. > > After that I deleted the whole Python installation directory and replaced > it with a backup copy of a known-working version from a month ago. The > error kept appearing. > > I then uninstalled Python completely, rebooted and installed Python 3.9.1, > downloaded from python.org. > > The first to commands to issue were: > C:\Users\Carlos>python -V > Python 3.9.1 > > C:\Users\Carlos>pip list > Package Version > ---------- ------- > pip 20.2.3 > setuptools 49.2.1 > Could not fetch URL https://pypi.org/simple/pip/: There was a problem > confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', > port=443): Max retries exceeded with url: /simple/pip/ (Caused by > SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] > certificate verify failed: unable to get local issuer certificate > (_ssl.c:1123)'))) - skipping > > So there went my theory of the requests module... It already happens with > the Python base installation (urllib3?). Obviously a freshly installed > Python with no modifications and no other modules installed fails to verify > each and every certificate. > > I can rule out network errors as other machines using the same Internet > breakout work just fine with the same code. And it happens using a web > proxy and using no web proxy at all. > > Aunty Google always tells me to set "verify=False" but that can't be the > solution for *this* problem. Unfortunately I have no idea where to look > next - not with a fresh installation failing. > > Does anybody have a useful pointer for me? TIA! > > Regards, > Carlos > -- > https://mail.python.org/mailman/listinfo/python-list From avigross at verizon.net Tue Feb 16 11:51:39 2021 From: avigross at verizon.net (Avi Gross) Date: Tue, 16 Feb 2021 11:51:39 -0500 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: <033701d70483$ff2dd6a0$fd8983e0$@verizon.net> Christian, Thanks for sharing. I took a look and he does have a few schemas for Ada and C from TWO YEARS ago. Nothing about the infinite number of other languages he plans on supporting, let alone Python. And what he has is likely not enough to do what he claims he can do easily and rapidly. What gets me is that many languages severely overload the use of some characters and tokens so they can mean many things based on the context and capturing that is much harder than declaring what is a keyword. Worse, some languages like PERL make so many things optional, that you can write very brief programs that keep implicitly assuming the previous part stored results in $_ and seem at first to be magical as the actual code does not seem connected to anything. I am not so sure there is a reasonable way to program ALL existing language his way & to have one ring-like compiler to rule them all, albeit you might be able to consolidate several somewhat similar languages. I also wonder how efficient such a universal compiler (maybe technically not a compiler) would be but if it was only used once, maybe not. But didn't he also say this thing would work in an interactive mode line by line? It reminds me of when I was studying concepts about various takes on a Turing Machine for my thesis. It has been proven that a Turing Machine can theoretically solve any problem you can solve with a non-quantum computer. I emphasize it is theoretical because we are talking about an infinite tape with squares containing symbols that are read by a head that moves over it either to the left or right based on the current state and so on. Fairly simple programs like copying a million instances of "1" in a row can take quite a while and really complex programs need near-infinite times or infinitesimal time per step. What is POSSIBLE is far from useful. I feel the same way about NEOS. Given a sufficiently advanced and convoluted schema you can write a sufficiently convoluted computer program that might halt with an answer -- meaning it will compile a valid program written in a language that is completely defined by that schema and perhaps additional info. We know it can be done because each language has existing compilers and/or interpreters that do so, without an explicit schema. But to have a program that can take any schema whatsoever and do what is needed is a bit much. Existing languages were simply not designed with this in mind and new/old languages might feel constrained about designing new features that will not be able to fit within an existing schema. In particular, how do you handle multiple versions of a language like Python 2.X and the incompatible Python 3.X and the eventual re-re-designed Python 4.Y? They all may be placed in files ending in .py! There is nothing wrong with thinking out of the box or making grand plans. But I have known people ranging from overly optimistic to manic who think nothing of making extraordinary claims and may actually believe it. I would not be shocked if a subset of what is being suggested for NEOS might be done by a large team in a few decades but by then, we may all be using quantum computers and a whole new set of languages to take advantage of new paradigms like superposition ... -----Original Message----- From: Python-list On Behalf Of Christian Gollwitzer Sent: Tuesday, February 16, 2021 2:25 AM To: python-list at python.org Subject: Re: New Python implementation Am 15.02.21 um 21:37 schrieb Roel Schroeven: > > So your claim is that your compiler is able to, or will be able to, > compile any language just by specifying a small schema file. Great! > > Do you maybe have a proof-of-concept? A simple language with a simple > schema file to test the basic workings of your compiler, Here is the git repo: https://github.com/i42output/neos under languages/ you'll find different schema files. Christian -- https://mail.python.org/mailman/listinfo/python-list From mats at wichmann.us Tue Feb 16 11:52:53 2021 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 16 Feb 2021 09:52:53 -0700 Subject: IDLE In-Reply-To: <2F82C467-2B1D-49EE-A668-451A1C46C3E6@hxcore.ol> References: <2F82C467-2B1D-49EE-A668-451A1C46C3E6@hxcore.ol> Message-ID: <9ca1cf18-bd56-7ecf-60fb-c5fc1fae615a@wichmann.us> On 2/16/21 8:09 AM, Will Anderson wrote: > Hi, I hope you are having a good day. I have a small IDLE problem and > can?t seem to fix it. I have a .py file that I want to open using IDLE but > there is no option I have even tried totally wiping python and > reinstalling it nothing seems to work. Please help. Can you describe what you mean by "there is no option"? Normally, you click on the File menu, then click on Open. If you don't see these, maybe you have the wrong thing open in the first place? From ben.usenet at bsb.me.uk Tue Feb 16 12:58:47 2021 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Tue, 16 Feb 2021 17:58:47 +0000 Subject: New Python implementation References: <87blcnnejf.fsf@nightsong.com> <033701d70483$ff2dd6a0$fd8983e0$@verizon.net> Message-ID: <875z2r99ns.fsf@bsb.me.uk> "Avi Gross" writes: > Thanks for sharing. I took a look and he does have a few schemas for Ada and > C from TWO YEARS ago. Nothing about the infinite number of other languages > he plans on supporting, let alone Python. And what he has is likely not > enough to do what he claims he can do easily and rapidly. The C schema says almost nothing about C. It lists one kind of comment and a few type names. Significantly, it says almost nothing about the semantics of even the tiny fragment of C presented. Attempts at a universal compiler stalled in the 1980s (though there may have been some new developments since I stopped looking) because expressing the semantics of different languages is so very hard. In fact, much of the interest in pursuing the idea came from benefits that would be derived simply from having a language's semantics formally described. I don't think there is anything to see here. If the author had come up with some new ways to tackle any of the problems, he would be telling people about these, not saying "be patient" (and bad-mouthing CPython). -- Ben. From tjreedy at udel.edu Tue Feb 16 13:09:09 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 16 Feb 2021 13:09:09 -0500 Subject: IDLE In-Reply-To: <9ca1cf18-bd56-7ecf-60fb-c5fc1fae615a@wichmann.us> References: <2F82C467-2B1D-49EE-A668-451A1C46C3E6@hxcore.ol> <9ca1cf18-bd56-7ecf-60fb-c5fc1fae615a@wichmann.us> Message-ID: On 2/16/2021 11:52 AM, Mats Wichmann wrote: > On 2/16/21 8:09 AM, Will Anderson wrote: >> ??? Hi, I hope you are having a good day. I have a small IDLE problem and >> ??? can?t seem to fix it. I have a .py file that I want to open using >> IDLE but >> ??? there is no option I have even tried totally wiping python and >> ??? reinstalling it nothing seems to work. Please help. > > Can you describe what you mean by "there is no option"? > > Normally, you click on the File menu, then click on Open. If you don't > see these, maybe you have the wrong thing open in the first place? Will, include what version of what operating system, the python versions you have and where obtained, whether you can run python itself, and how you tried run IDLE and open a file. -- Terry Jan Reedy From auriocus at gmx.de Tue Feb 16 13:31:49 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Tue, 16 Feb 2021 19:31:49 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: I agree to all the rest of your post, but this: Am 16.02.21 um 09:57 schrieb Tarjei B?rland: > I am not sure I agree that a language like Scheme or Logo or Brainfuck, with > their small number of building blocks, would be harder to learn. is strange. I'm not sure, have you actually looked at Brainfuck? Maybe there is also confusion what means "learning" a programming language. For me, learning a language does not mean to remember the rules and keywords, but to be able to write useful programs. Indeed, Brainfuck with its 8 commands is easy to remember, but it comes at a very high price: you can't do anything useful with it with reasonable effort. It is unusable even for pure computer science stuff. It is easy to see that BF is Turing complete, so please write a BF program to compute the ackermann function. Should be easy, just three rules ;) I'd definitely choose Python to do it here. In that sense, Scheme also appears to be the Brainfuck of functional programming to me. It is not much more than the pure untyped lambda calculus, and by definition this allows you to compute anything, just like Brainfuck is a Turing machine. Actually it is impressive that you can write actual useful code with such a minimalist language (infix math? Pure bloat!). OTOH it feels like "assembly" compared to more evolved functional languages like, e.g. Haskell. Christian From torriem at gmail.com Tue Feb 16 14:51:21 2021 From: torriem at gmail.com (Michael Torrie) Date: Tue, 16 Feb 2021 12:51:21 -0700 Subject: New Python implementation In-Reply-To: <875z2r99ns.fsf@bsb.me.uk> References: <87blcnnejf.fsf@nightsong.com> <033701d70483$ff2dd6a0$fd8983e0$@verizon.net> <875z2r99ns.fsf@bsb.me.uk> Message-ID: <18d97a02-8333-fe93-546f-5d57368dd7ce@gmail.com> On 2/16/21 10:58 AM, Ben Bacarisse wrote: > Attempts at a universal compiler stalled in the 1980s (though there may > have been some new developments since I stopped looking) because > expressing the semantics of different languages is so very hard. In > fact, much of the interest in pursuing the idea came from benefits that > would be derived simply from having a language's semantics formally > described. > > I don't think there is anything to see here. If the author had come up > with some new ways to tackle any of the problems, he would be telling> people about these, not saying "be patient" (and bad-mouthing CPython). Indeed, in all seriousness if he is successful, I look forward to reading his PhD dissertation, because it would be worthy of a PhD, especially if he made some breakthroughs in metacompiler design. His comments don't give me hope, though. Seems a bit paradoxical to me to, on the one hand, express a desire to build a Python implementation, but on the other hand, mock Python as a toy language. Why bother with Python at all? I wish him luck and maybe he'll eventually come back to the community with something to show and impress with. From kevinmwilson1956 at yahoo.com Tue Feb 16 15:09:08 2021 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Tue, 16 Feb 2021 20:09:08 +0000 (UTC) Subject: Python 2.7 and 3.9 References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> Message-ID: <1129940616.2323576.1613506148454@mail.yahoo.com> My employer has hundreds of scripts in 2.7, but I'm writing new scripts in 3.9! I'm running into 'invalid syntax' errors.I have to maintain the 'Legacy' stuff, and I need to mod the path et al., to execute 3.7 w/o doing damage to the 'Legacy' stuff...IDEA' are Welcome! KMW John 1:4? "In him was life; and the life was the light of men." From ethan at stoneleaf.us Tue Feb 16 15:19:23 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Tue, 16 Feb 2021 12:19:23 -0800 Subject: Python 2.7 and 3.9 In-Reply-To: <1129940616.2323576.1613506148454@mail.yahoo.com> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> Message-ID: <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> On 2/16/21 12:09 PM, Kevin M. Wilson via Python-list wrote: > My employer has hundreds of scripts in 2.7, but I'm writing new scripts in 3.9! I'm running into 'invalid syntax' errors.I have to maintain the 'Legacy' stuff, and I need to mod the path et al., to execute 3.7 w/o doing damage to the 'Legacy' stuff...IDEA' are Welcome! My first idea/request: have a blank line, a line with only a '--' (without quotes), and then your signature at the bottom of your posts. White space aids readability and readability counts. :) How are those scripts being run? Microsoft Windows or Unix/Linux/BSD? Typically, the first line of a script will say which version of Python is needed. For example, on a *nix type system: #!/usr/bin/python2 -- ~Ethan~ From tarjei at purelymail.com Tue Feb 16 16:08:08 2021 From: tarjei at purelymail.com (Tarjei =?utf-8?Q?B=C3=A6rland?=) Date: Tue, 16 Feb 2021 22:08:08 +0100 Subject: New Python implementation In-Reply-To: References: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: <878s7n201z.fsf@purelymail.com> David Lowry-Duda writes: >> In Norway, where I try to teach mathematics to highschoolers, >> programming has recently entered the teaching of stem subjects. >> >> Even if Python is my choice language for personal projects, I am not >> certain it is the right language to use in a classroom context. >> ... >> I am not sure I agree that a language like Scheme or Logo or >> Brainfuck, with their small number of building blocks, would be harder >> to learn. > > Does this mean that you also try to teach programming to highschoolers, > or is there a different (maybe dedicated) teacher to that? What language > do they use? And does it influence math education at all? (Coming from > someone who sometimes tries to teach undergraduates about math). > > - David Lowry-Duda Yes, that also means that mathematics teachers are teaching programming as well. For my part, it's a welcome change, and I've already been teaching another programming course for a couple of years, but a lot of teachers are having to start programming alongside their students. I don't have any numbers for this, but I'd be surprised if less than 95% of all teachers used Python for this. (I know of no exception.) I think it's too soon to tell whether it affects the education. However, I would have liked to better know the motivation for including it. Python seems like one of several good choices if you want to manipulate mathematical objects, perhaps mixing in som symbolic algebra via Sympy, and other "high level concepts". However, if the aim is for the students to quickly experience what it's like to design their own simple algorithm without excessive guidance, Python might not then be the optimal choice. - Tarjei B?rland PS: I can't remember in what context I visited it, but thanks for an inspiring site. From ethan at stoneleaf.us Tue Feb 16 16:16:40 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Tue, 16 Feb 2021 13:16:40 -0800 Subject: Python 2.7 and 3.9 In-Reply-To: <36696864.2332692.1613508918901@mail.yahoo.com> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> <36696864.2332692.1613508918901@mail.yahoo.com> Message-ID: <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> Kevin, please reply to the list (preferably Reply-to-list, or Reply-all), that way others can chime in with help. On 2/16/21 12:55 PM, Kevin M. Wilson wrote: > Windows 7 OS, and typically run in conjunction with testing SSD', as for > stand alone scripts. > Those require: python BogusFile.py. I too was expecting users to type: > python my_Script.py! I'm afraid I have no experience with the above, hopefully somebody else on the list does. -- ~Ethan~ From tarjei at purelymail.com Tue Feb 16 16:22:23 2021 From: tarjei at purelymail.com (Tarjei =?utf-8?Q?B=C3=A6rland?=) Date: Tue, 16 Feb 2021 22:22:23 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: <877dn71ze8.fsf@purelymail.com> Christian Gollwitzer writes: > I agree to all the rest of your post, but this: > > Am 16.02.21 um 09:57 schrieb Tarjei B?rland: >> I am not sure I agree that a language like Scheme or Logo or Brainfuck, with >> their small number of building blocks, would be harder to learn. > > > is strange. I'm not sure, have you actually looked at Brainfuck? Maybe > there is also confusion what means "learning" a programming language. > For me, learning a language does not mean to remember the rules and > keywords, but to be able to write useful programs. Indeed, Brainfuck > with its 8 commands is easy to remember, but it comes at a very high > price: you can't do anything useful with it with reasonable effort. It > is unusable even for pure computer science stuff. It is easy to see that > BF is Turing complete, so please write a BF program to compute the > ackermann function. Should be easy, just three rules ;) I'd definitely > choose Python to do it here. > > In that sense, Scheme also appears to be the Brainfuck of functional > programming to me. It is not much more than the pure untyped lambda > calculus, and by definition this allows you to compute anything, just > like Brainfuck is a Turing machine. Actually it is impressive that you > can write actual useful code with such a minimalist language (infix > math? Pure bloat!). OTOH it feels like "assembly" compared to more > evolved functional languages like, e.g. Haskell. > > Christian To me, it depends on what you want out of including programming in mathematics education. Sure, Brainfuck is two steps too far, but Scheme or Logo I'd wager be excellent languages to get the students into computational thinking. Haskell might be a good choice as well, I do not have enough experience with it to say. If the aim is to quickly get the students to "be creative" with programming by themselves, my feeling is that Python is too unwieldy for a beginner. In a programming course I am teaching, one of the goals is for the students to distinguish "high level" and "low level" languages. I've used Brainfuck as an example of a programming language at a low level of abstraction. That session is often the most engaging throughout the year. The students are sitting writing their own code after a few minutes. They get the feeling of designing their own computational procedure much quicker than in Python. (Yes, of course, the introductory excercises in Python are a bit more advanced than "add two numbers".) I am honestly not sure what quite what my feelings are regarding this, perhaps Python is the best of all possible options. - Tarjei Note, I am emphatically saying this in the context of a maths class. From drsalists at gmail.com Tue Feb 16 16:42:13 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Tue, 16 Feb 2021 13:42:13 -0800 Subject: New Python implementation In-Reply-To: <877dn71ze8.fsf@purelymail.com> References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> <877dn71ze8.fsf@purelymail.com> Message-ID: On Tue, Feb 16, 2021 at 1:23 PM Tarjei B?rland via Python-list < python-list at python.org> wrote: > Sure, Brainfuck is two steps too far, but Scheme or Logo I'd wager be > excellent languages to get the students into computational > thinking. Haskell might be a good choice as well, I do not have enough > experience with it to say. > I am not a Haskell expert by any stretch. But I did play with it a bit. It's a fascinating language. But I think the language is hobbled by poor error messages from the main compiler, GHC. I've been told GHC has a rather elegant implementation, but that came at the cost of the quality of error messages. https://www.reddit.com/r/haskell/comments/54l3ug/readable_error_messages_like_in_elm/ There was a project to produce a somewhat restricted Haskell implementation with better error messages, but sadly that project is no longer maintained. https://wiki.haskell.org/Hugs From skip.montanaro at gmail.com Tue Feb 16 16:57:56 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 16 Feb 2021 15:57:56 -0600 Subject: Python 0.9.1 Message-ID: A note to webmaster at python.org from an astute user named Hiromi in Japan* referred us to Guido's shell archives for the 0.9.1 release from 1991. As that wasn't listed in the historical releases README file: https://legacy.python.org/download/releases/src/README I pulled the shar files (and a patch), then made a few tweaks to get it to build: % ./python >>> print 'hello world!' hello world! >>> import sys >>> dir(sys) ['argv', 'exit', 'modules', 'path', 'ps1', 'ps2', 'stderr', 'stdin', 'stdout'] >>> sys.modules {'builtin': ; 'sys': ; '__main__': } >>> sys.exit(0) I then pushed the result to a Github repo: https://github.com/smontanaro/python-0.9.1 There is a new directory named "shar" with the original files, a small README file and a compile.patch file between the original code and the runnable code. It was a pleasant diversion for a couple hours. I was tired of shovelling snow anyway... Thank you, Hiromi. Skip * Hiromi is bcc'd on this note in case he cares to comment. I didn't want to publish his email beyond the bounds of the webmaster alias without his permission. From robertvstepp at gmail.com Tue Feb 16 17:23:27 2021 From: robertvstepp at gmail.com (boB Stepp) Date: Tue, 16 Feb 2021 16:23:27 -0600 Subject: New Python implementation In-Reply-To: References: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: On 21/02/16 11:03AM, Alan Gauld wrote: >Python v1 was a good teaching language. v2 complicated it a bit >but it was still usable. v3 is no longer a good teaching language >(unless maybe you are teaching CompSci at university.) [...] >And that's just one example, the language is now full of meta goodness >that makes it incomprehensible to beginners. In a teaching environment, >with a teacher present to answer questions, it's probably usable, >but for a self guided course it's increasingly inscrutable. Hmm. I'm not sure I can agree, Alan. My son took to Python 3 like a duck to water. Occasionally he has had questions for me, but, for the most part, he has been entirely on his own with no issues. He now has several projects that others are using, including a significant update to someone else's project he was interested online to both update the Python and Qt. Yes, there is a ton of meta-goodness in Python, but most of it can be ignored to be able to *just use it*. My wife is using Python 3 in a robotics class she teaches and her high school students find it accessible. AP computer science second semester uses Python. I really don't think it is much of a problem for most people. Of course on the Tutor list there often seems to be some greatly puzzled people, but I think their issues stem from *never* having tried to do anything even remotely technical other than clicking around in the GUI programs they have become comfortable with. -- Wishing you only the best, boB Stepp From guido at python.org Tue Feb 16 17:44:20 2021 From: guido at python.org (Guido van Rossum) Date: Tue, 16 Feb 2021 14:44:20 -0800 Subject: [Python-Dev] Python 0.9.1 In-Reply-To: References: Message-ID: Awesome, Skip! Was there a date somewhere? I can't recall if this would have been the first open source release (from just about 30 years ago, sometime in February 1991) or some time later in the same year? On Tue, Feb 16, 2021 at 1:57 PM Skip Montanaro wrote: > A note to webmaster at python.org from an astute user named Hiromi in Japan* referred > us to Guido's shell archives for the 0.9.1 release from 1991. As that > wasn't listed in the historical releases README file: > > https://legacy.python.org/download/releases/src/README > > I pulled the shar files (and a patch), then made a few tweaks to get it to > build: > > % ./python > >>> print 'hello world!' > hello world! > >>> import sys > >>> dir(sys) > ['argv', 'exit', 'modules', 'path', 'ps1', 'ps2', 'stderr', 'stdin', > 'stdout'] > >>> sys.modules > {'builtin': ; 'sys': ; '__main__': '__main__'>} > >>> sys.exit(0) > > I then pushed the result to a Github repo: > > https://github.com/smontanaro/python-0.9.1 > > There is a new directory named "shar" with the original files, a small > README file and a compile.patch file between the original code and the > runnable code. > > It was a pleasant diversion for a couple hours. I was tired of shovelling > snow anyway... Thank you, Hiromi. > > Skip > > * Hiromi is bcc'd on this note in case he cares to comment. I didn't want > to publish his email beyond the bounds of the webmaster alias without his > permission. > > _______________________________________________ > Python-Dev mailing list -- python-dev at python.org > To unsubscribe send an email to python-dev-leave at python.org > https://mail.python.org/mailman3/lists/python-dev.python.org/ > Message archived at > https://mail.python.org/archives/list/python-dev at python.org/message/VZYELIYAQWUHHGIIEPPJFREDX6F24KMN/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* From Richard at Damon-Family.org Tue Feb 16 17:50:27 2021 From: Richard at Damon-Family.org (Richard Damon) Date: Tue, 16 Feb 2021 17:50:27 -0500 Subject: Python 2.7 and 3.9 In-Reply-To: <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> <36696864.2332692.1613508918901@mail.yahoo.com> <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> Message-ID: <13d23f31-f932-9d0c-148d-74b35608b143@Damon-Family.org> On 2/16/21 4:16 PM, Ethan Furman wrote: > Kevin, please reply to the list (preferably Reply-to-list, or > Reply-all), that way others can chime in with help. > > On 2/16/21 12:55 PM, Kevin M. Wilson wrote: > >> Windows 7 OS, and typically run in conjunction with testing SSD', as >> for stand alone scripts. >> Those require: python BogusFile.py. I too was expecting users to >> type: python my_Script.py! > > I'm afraid I have no experience with the above, hopefully somebody > else on the list does. > > -- > ~Ethan~ It depends a lot on how everything was installed and how the path was setup. You will at least need the version 2 and version 3 pythons to be given different names, like python3 and then start the python 3 scripts with python3 my_script.py -- Richard Damon From roel at roelschroeven.net Tue Feb 16 16:42:39 2021 From: roel at roelschroeven.net (Roel Schroeven) Date: Tue, 16 Feb 2021 22:42:39 +0100 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> Message-ID: Christian Gollwitzer schreef op 16/02/2021 om 8:25: > Am 15.02.21 um 21:37 schrieb Roel Schroeven: >> >> So your claim is that your compiler is able to, or will be able to, >> compile any language just by specifying a small schema file. Great! >> >> Do you maybe have a proof-of-concept? A simple language with a simple >> schema file to test the basic workings of your compiler, > > Here is the git repo: > > https://github.com/i42output/neos > > under languages/ you'll find different schema files. I saw that, and I saw the schema files. I had a look at the one for C, because I don't know the first thing about Ada, and it's not nearly enough to describe even the tiniest subset of C. And I saw the example session he posted here, where he supposedly compiles something, but doesn't even run it. It looked like that compilation did nothing but folding and folding and folding. And he didn't run it! So it looks like that's the status of the project now: a compilation step that does /something/, but apparently doesn't result in anything runnable. And some work-in-progress (seemingly) schema files, but nothing concrete yet. But I wanted to give Mr Flibble to benefit of the doubt, and asked more explicitly about the status of the project. Apparently I was too late, Mr Flibble was already banned, but I didn't know that yet. I've thougt about downloading the whole thing and trying to build it. But I'd have to install Visual Studio 2019 first and probably some dependencies. It didn't seem worth the effort. Regards, Roel -- "Honest criticism is hard to take, particularly from a relative, a friend, an acquaintance, or a stranger." -- Franklin P. Jones Roel Schroeven From mats at wichmann.us Tue Feb 16 18:14:23 2021 From: mats at wichmann.us (Mats Wichmann) Date: Tue, 16 Feb 2021 16:14:23 -0700 Subject: [Python-Dev] Python 0.9.1 In-Reply-To: References: Message-ID: On 2/16/21 3:44 PM, Guido van Rossum wrote: > Awesome, Skip! > > Was there a date somewhere? I can't recall if this would have been the > first open source release (from just about 30 years ago, sometime in > February 1991) or some time later in the same year? Guido van Rossum unread, Python 0.9.1 part 01/21 XThis is Python, an extensible interpreted programming language that Xcombines remarkable power with very clear syntax. X XThis is version 0.9 (the first beta release), patchlevel 2/19/91 From guido at python.org Tue Feb 16 18:17:34 2021 From: guido at python.org (Guido van Rossum) Date: Tue, 16 Feb 2021 15:17:34 -0800 Subject: [Python-Dev] Re: Python 0.9.1 In-Reply-To: References: Message-ID: On Tue, Feb 16, 2021 at 2:59 PM Senthil Kumaran wrote: > On Tue, Feb 16, 2021 at 1:58 PM Skip Montanaro > wrote: > >> >> I then pushed the result to a Github repo: >> >> https://github.com/smontanaro/python-0.9.1 >> > > Wow. Was white-space not significant in this release of Python? I see the > lack of indentation in the first Python programs. > Indentation most certainly was significant from day 0. I suspect what happened is that these files got busted somehow by the extraction process used by Skip or Hiromi. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* From hjp-python at hjp.at Tue Feb 16 18:19:01 2021 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 17 Feb 2021 00:19:01 +0100 Subject: New Python implementation In-Reply-To: References: Message-ID: <20210216231901.GA27806@hjp.at> On 2021-02-14 00:52:43 +0000, Alan Gauld via Python-list wrote: > On 14/02/2021 00:07, Mr Flibble wrote: > > The neos Python implementation will not be dealing > > with Python byte code in any form whatsoever. > > Ok but what do you do with the disassembler module? What do PyPy, Jython, IronPython etc. do with the disassembler module? My guess is that they simply don't implement it. It's tightly coupled to the CPython implementation and useless on any other implementation. A disassembler module for their respective bytecode or machine language might be useful, but that wouldn't be compatible with CPython's disassembler in input nor output. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From skip.montanaro at gmail.com Tue Feb 16 18:49:49 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 16 Feb 2021 17:49:49 -0600 Subject: [Python-Dev] Re: Python 0.9.1 In-Reply-To: References: Message-ID: > > Wow. Was white-space not significant in this release of Python? I see the >> lack of indentation in the first Python programs. >> > > Indentation most certainly was significant from day 0. I suspect what > happened is that these files got busted somehow by the extraction process > used by Skip or Hiromi. > Yes, that's certainly possible. While it's nice that Google has archived this stuff, their faithfulness to the original formats leaves a bit to be desired (and gmane still doesn't work for me, eliminating that option). Guido's messages are displayed as HTML, and I saw no way to get at the raw Usenet messages. I just copied the shar data and saved the result. It seems clear that tabs copied as spaces. The Makefile indentation was hosed up. It should have dawned on me that the .py, .c and .h files would be messed up as well. I was only concerned with building the interpreter. If someone knows how to get the original Usenet messages from what Google published, let me know. Skip > From hjp-python at hjp.at Tue Feb 16 19:17:47 2021 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 17 Feb 2021 01:17:47 +0100 Subject: Best practices for software architecture in Python In-Reply-To: References: <602397a3$0$12711$426a74cc@news.free.fr> <60251ead$0$27902$e4fe514c@news.xs4all.nl> Message-ID: <20210217001747.GB27806@hjp.at> On 2021-02-11 08:54:11 -0500, Henning Follmann wrote: > On 2021-02-11, Oscar wrote: > > In article , > > Henning Follmann wrote: > >>On 2021-02-10, Python wrote: > >>> and would like to study in-depth an existing open source > >>> application in order to study how to organize classes hierarchy, > >>> modules, packages, etc. which one would you recommend ? > >> > >>Looks like you (the project leader?) needs training, not the > >>software engineers. > >> > >>"Making Things Happen" by Scott Berkun > > > > This looks like a very interesting book to add to my reading list, but > > how do you think it will help the OP with his/her quest? > > > Well the question makes it very obvious that it is a leadership > issue. Does he really think giving all engineers the Gang of 4 > book will magically lead to a well run OOP project. Actually he was asking for "an existing open source application", not a book. I think dissecting a non-trivial open source project over the course of a semester would be a great idea for a university course (sort of like Tananbaum did with Minix). I'm not at all convinced that it's a good idea for the OP's team. While reading other people's code is certainly useful for picking up patterns and idiomatic style, it is much less clear that you get why the author structured the code this way and how to structure it for your own project. At the very least this would require a lot of discussion in the team (basically a code review), especially if the code in question doesn't have anything to do with your own project. A book or a course is probably better to pick up the basics. One important question is whether there already is someone on the team who is already an experienced OO programmer (and who can therefore take the technical lead, coach their team-mates, etc.) or whether all of them have the same (lack of) experience. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From skip.montanaro at gmail.com Tue Feb 16 19:22:00 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 16 Feb 2021 18:22:00 -0600 Subject: [Python-Dev] Re: Python 0.9.1 In-Reply-To: References: Message-ID: > If someone knows how to get the original Usenet messages from what Google published, let me know. Seems the original shar is there buried in a Javascript string toward the end of the file. I think I've got a handle on it, though it will take a Python script to massage back into correct format. Skip From arj.python at gmail.com Tue Feb 16 21:12:52 2021 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 17 Feb 2021 06:12:52 +0400 Subject: New Python implementation In-Reply-To: <87a6s41jb1.fsf@purelymail.com> References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: Greetings list, > Even if Python is my choice language for personal projects, I am not certain it is the right language to use in a classroom context. This sums the view of most teachers in my country. In here for A level at Cambridge for Computer Studies you can choose either Java, or VB or Python The teachers' logic seems to tell them that VB is the simplest of all and more fitted for students. Since we organise the local Python usergroup , we have been encouraging the adoption of Python. This happens from experience when teachers think for students, they think student will think like that etc The way schools examinations are set up, learning programming is a bore. Programming requires experimentation and projects. The students must be permitted to explore the wide deep sea that is Python. On one of my projects on Github, i have a toy language, someone from Slovakia (14 years old) built an IDE for it, what was needed was only guidance where he was stuck. The hurdle with Python if any is the setting up and getting the command 'python' to appear in the terminal, which is very easy to get up and running nowadays. When i was in high school, i did not take Computer Studies, but was learning programming on my own, including Python. The irony is that my friends who were learning Python got disgusted with it. Loops and functions turned out to be hard for them. That's because learning for the exam makes you learn the language close to theory. Some commandline stuffs and some numbers stuffs surely is not exiting. Mastery comes with projects, exciting ones. Then whatever the syllabus requires becomes easy. It's a means to an end rather than the end in itself. The teachers' reaction is a reaction to the design of the syllabus. The folks seem to think that let's water it down to a very theoretical approach, strike out practise, strike out the fun out of it and sure the students will find it easier. Since effort is disliked by humans, less effort in learning programming will make students happy. Then, if it was no Python at that time, it might be no Python for life. With that mindset ongoing, those students think they know Python, they studied it, but they missed the whole thing. Forest, trees and leaves. They know only the color of the sign board leading to the place. Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From skip.montanaro at gmail.com Tue Feb 16 22:00:59 2021 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 16 Feb 2021 21:00:59 -0600 Subject: [Python-Dev] Re: Python 0.9.1 In-Reply-To: <20210217040844.1bb391be@zenbook> References: <20210217040844.1bb391be@zenbook> Message-ID: > Also mind > http://www.dalkescientific.com/writings/diary/archive/2009/03/27/python_0_9_1p1.html > for result comparison. Thanks, Paul. I had lost track of Andrew. Good to know he's still out there. I wonder why his tar file was never sucked up into the historical releases page. Whew! My stupid little extraction script did a reasonable job. I see plenty of differences, but a cursory examination shows they are only in leading whitespace. Where I translated "\t" to TAB, it seems Andrew used a suitable number of spaces. Python modules/scripts seem more plausibly indented, and the couple I tried worked, so I'm a bit more confident I have things right: % PYTHONPATH=lib ./src/python >>> import string >>> print string.upper('hello world!') HELLO WORLD! >>> % ./src/python lib/fact.py 99999 [3, 3, 41, 271] 4096 [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] The tests don't pass though. 1 * 1 raises an integer overflow exception: >>> 1 * 1 Unhandled exception: run-time error: integer overflow Stack backtrace (innermost last): File "", line 1 I'll let someone figure that out. :-) At any rate, the git repo has been updated. Skip From ikorot01 at gmail.com Tue Feb 16 22:02:53 2021 From: ikorot01 at gmail.com (Igor Korot) Date: Tue, 16 Feb 2021 21:02:53 -0600 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: Hi, On Tue, Feb 16, 2021, 8:15 PM Abdur-Rahmaan Janhangeer wrote: > Greetings list, > > > Even if Python is my choice language for personal projects, I am not > certain it > is the right language to use in a classroom context. > > This sums the view of most teachers in my country. In here for A level > at Cambridge for Computer Studies you can choose either Java, or VB or > Python > > The teachers' logic seems to tell them that VB is the simplest of all and > more fitted for students. Since we organise the local Python usergroup > , > we have been encouraging the adoption of Python. This happens from > experience when teachers think for students, they think student will think > like that etc > How old are the teachers? And is it for school or university? Thank you. > The way schools examinations are set up, learning programming is a bore. > Programming requires experimentation and projects. The students must be > permitted to explore the wide deep sea that is Python. On one of my > projects > on Github, i have a toy language, someone from Slovakia (14 years old) > built > an IDE for it, what was needed was only guidance where he was stuck. > > The hurdle with Python if any is the setting up and getting the command > 'python' > to appear in the terminal, which is very easy to get up and running > nowadays. > > When i was in high school, i did not take Computer Studies, but was > learning programming > on my own, including Python. The irony is that my friends who were learning > Python > got disgusted with it. Loops and functions turned out to be hard for them. > That's because > learning for the exam makes you learn the language close to theory. Some > commandline > stuffs and some numbers stuffs surely is not exiting. Mastery comes with > projects, exciting ones. > Then whatever the syllabus requires becomes easy. It's a means to an end > rather than the end > in itself. > > The teachers' reaction is a reaction to the design of the syllabus. The > folks seem to think that let's > water it down to a very theoretical approach, strike out practise, strike > out the fun out of it and > sure the students will find it easier. Since effort is disliked by humans, > less effort in learning programming > will make students happy. > > Then, if it was no Python at that time, it might be no Python for life. > With that mindset ongoing, > those students think they know Python, they studied it, but they missed the > whole thing. Forest, > trees and leaves. They know only the color of the sign board leading to the > place. > > Kind Regards, > > Abdur-Rahmaan Janhangeer > about | blog > > github > Mauritius > -- > https://mail.python.org/mailman/listinfo/python-list > From arj.python at gmail.com Tue Feb 16 22:15:10 2021 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 17 Feb 2021 07:15:10 +0400 Subject: New Python implementation In-Reply-To: References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> Message-ID: Greetings, age: After university to retirement level: school, A Level is high school, not university From jfong at ms4.hinet.net Tue Feb 16 22:24:30 2021 From: jfong at ms4.hinet.net (Jach Feng) Date: Tue, 16 Feb 2021 19:24:30 -0800 (PST) Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? Message-ID: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> I am experimenting with multithreading-socket these days. I build a server to handle each client in a separate thread. All are running on my local PC. It works fine except the listen() method. I set listen(2) and expect to see "error" when more clients than "the maximum number of queued connections" trying to connect the server. But, no error!! Even 4 clients can run normally without problem. Am I misunderstanding the meaning of this argument? --Jach From jsf80238 at gmail.com Tue Feb 16 23:10:02 2021 From: jsf80238 at gmail.com (Jason Friedman) Date: Tue, 16 Feb 2021 21:10:02 -0700 Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? In-Reply-To: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> References: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> Message-ID: > > I set listen(2) and expect to see "error" when more clients than "the > maximum number of queued connections" trying to connect the server. But, no > error!! Even 4 clients can run normally without problem. > > Am I misunderstanding the meaning of this argument? > https://docs.python.org/3/library/socket.html#socket.socket.listen: Enable a server to accept connections. If backlog is specified ... it specifies the number of unaccepted connections that the system will allow before refusing new connections. So I read that to say that the listen method will accept as many connection as it can handle, and will put into a backlog those it cannot. Your argument of 2 tells the method to allow up to 2 not-yet-accepted connection requests. From kushal at locationd.net Tue Feb 16 23:04:54 2021 From: kushal at locationd.net (Kushal Kumaran) Date: Tue, 16 Feb 2021 20:04:54 -0800 Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? In-Reply-To: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> (Jach Feng's message of "Tue, 16 Feb 2021 19:24:30 -0800 (PST)") References: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> Message-ID: <87blcjibkp.fsf@copper.locationd.net> On Tue, Feb 16 2021 at 07:24:30 PM, Jach Feng wrote: > I am experimenting with multithreading-socket these days. I build a > server to handle each client in a separate thread. All are running on > my local PC. It works fine except the listen() method. > > I set listen(2) and expect to see "error" when more clients than "the > maximum number of queued connections" trying to connect the > server. But, no error!! Even 4 clients can run normally without > problem. > > Am I misunderstanding the meaning of this argument? > The argument to listen specifies the maximum number of "outstanding" connection requests. These are connections for which the TCP handshake has completed, but for which the application has not called accept. With your multi-threaded application, I assume each new connection request gets picked up immediately by an accept call, so the queue does not generally grow. If you want a limit on the number of concurrent clients you want to handle, you'll have to implement that yourself. If you're using the threading module, threading.Semaphore will let you implement a simple system. -- regards, kushal From avigross at verizon.net Tue Feb 16 23:42:39 2021 From: avigross at verizon.net (Avi Gross) Date: Tue, 16 Feb 2021 23:42:39 -0500 Subject: School Python References: <0b4601d704e7$527c8e10$f775aa30$.ref@verizon.net> Message-ID: <0b4601d704e7$527c8e10$f775aa30$@verizon.net> I wonder if someone has come up with a sort of Python environment that lets kids play with more fundamental parts of the language that lets them get educated without the confusion. I mean a limited subset and with some additions/modifications. Someone mentioned how something like range(1,10) is confusing as it now not only does not produce a list on 1 to 9 or 1 to 10 but produces an object that only can be viewed well by doing more advanced things like iterating it. So why not have a module called something like EDUCATION which is loaded into the school version automagically and implements what you want. Make a function called SchoolTimeRANGE strange(here, there) (or whatever) that returns something like list( range(here, there)) so the student never sees a range object or yet knows there are objects to object to. If you want it to include the last item, include "there". Want it to start at 0 or 1, do that. As I see it, really limited languages make you work hard. Some of the LISP variants I used ages ago were so damn simple that you had programs largely consisting of combinations of CAR and CDR so dealing with some nested list data structure was painful enough that people had functions with name like CDDADAR to access some particular part. The same goes for various simple and limited languages that can do anything but won't keep a student in a room. Python is not limited and should not be but it should be taught progressively so basic computer concepts are learned before you learn arguably better ways. A beautiful thing about a list is it can be reused. Something with an iterator control can mysteriously be drained. So what is wrong with much of basic python, especially slightly extended? Feel free to tell them to use, strange() above for now as it lets them see what is happening step by step and mention that LATER they can (or must) switch to other functions normally used that may be more efficient or general. What I like about good parts of Python and that makes it good for teaching is that much can be written in almost normal English. Do you even need to use range(1,6) when you can ask the students to just type: numbers = [ 1, 2, 3, 4, 5 ] for index in numbers: ... Yes, later, introduce ways to loop from 1 to N by using better methods. List comprehensions? Why introduce them at all as most other languages do not have them and they are just syntactic sugar. If the goal is to introduce children to simple algorithms, keep them simple. Forget elegance or efficiency or being pythonic. But past a certain point, when they are ready, sure, add more. At some point it is helpful to learn that instead of keeping multiple arrays or variables in parallel, you could capture them in one object and tell the object what to do with itself and so on. Maybe later, show some tricks with functional programming. But don't START with elegant recursion methods. I see no major barrier to teaching using python for children who can handle indentation ? albeit they still have to learn to balance parentheses and quotes (sometimes) and brackets and braces ... What I think is good is that they can practice in front of an interpreter and get immediate results, not like I did with index cards that were handed in and returned a day later, or having to wait a long time for a compile to complete, with errors. From jfong at ms4.hinet.net Wed Feb 17 01:19:58 2021 From: jfong at ms4.hinet.net (Jach Feng) Date: Tue, 16 Feb 2021 22:19:58 -0800 (PST) Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? In-Reply-To: References: <87blcjibkp.fsf@copper.locationd.net> <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> Message-ID: <2974aba6-f96c-4ed8-91bd-791f4ca1610dn@googlegroups.com> Kushal Kumaran ? 2021?2?17? ?????12:11:04 [UTC+8] ?????? > On Tue, Feb 16 2021 at 07:24:30 PM, Jach Feng wrote: > > I am experimenting with multithreading-socket these days. I build a > > server to handle each client in a separate thread. All are running on > > my local PC. It works fine except the listen() method. > > > > I set listen(2) and expect to see "error" when more clients than "the > > maximum number of queued connections" trying to connect the > > server. But, no error!! Even 4 clients can run normally without > > problem. > > > > Am I misunderstanding the meaning of this argument? > > > The argument to listen specifies the maximum number of "outstanding" > connection requests. These are connections for which the TCP handshake > has completed, but for which the application has not called accept. > With your multi-threaded application, I assume each new connection > request gets picked up immediately by an accept call, so the queue does > not generally grow. > > If you want a limit on the number of concurrent clients you want to > handle, you'll have to implement that yourself. If you're using the > threading module, threading.Semaphore will let you implement a simple > system. > > -- > regards, > kushal You are right! I do misunderstand its meaning:-( After the server accepts the 1st connection and paused temperately, I saw the 2nd and 3rd connection is in pending, and the 4th one was rejected immediately. Thank you (and Jason) for clarifying this mystery:-) --Jach From klsshaeffer at icloud.com Wed Feb 17 03:25:46 2021 From: klsshaeffer at icloud.com (Karen Shaeffer) Date: Wed, 17 Feb 2021 00:25:46 -0800 Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? In-Reply-To: References: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> Message-ID: <5B03A584-DC5B-4A37-B3A4-454095FC869E@icloud.com> > On Feb 16, 2021, at 8:10 PM, Jason Friedman wrote: > >> >> I set listen(2) and expect to see "error" when more clients than "the >> maximum number of queued connections" trying to connect the server. But, no >> error!! Even 4 clients can run normally without problem. >> >> Am I misunderstanding the meaning of this argument? >> > > https://docs.python.org/3/library/socket.html#socket.socket.listen: > Enable a server to accept connections. If backlog is specified ... it > specifies the number of unaccepted connections that the system will allow > before refusing new connections. > > So I read that to say that the listen method will accept as many connection > as it can handle, and will put into a backlog those it cannot. Your > argument of 2 tells the method to allow up to 2 not-yet-accepted connection > requests. > -- Hi Jason, The backlog parameter specifies the number of connection requests that the kernel network stack has waiting for the application layer to process. So, it?s at a lower level than the listen system call, which is the application layer API into the kernel network stack that simply establishes the socket. Listen doesn?t actually touch any data. Once the accept system call has touched it, then the network stack no longer counts it in the backlog. Backlog is a network stack queue associated with the application socket. The backlog is managed by the network driver software. Moving bits down there is extremely efficient. And the driver wouldn?t process and pass packets up the stack, if the backlog was maxed out. That would be very inefficient ? rather the driver would drop the packets at the network driver ring buffer in such case. That?s at the API into the network stack looking up from the network driver. Here is a good description from the perspective of the bottom of the tcp ip stack API into the network card driver, discussing the processing of packets depending on state of the backlog for the socket. http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html Humbly, Karen From klsshaeffer at icloud.com Wed Feb 17 04:01:30 2021 From: klsshaeffer at icloud.com (Karen Shaeffer) Date: Wed, 17 Feb 2021 01:01:30 -0800 Subject: What's the meaning the "backlog" in the socket.listen(backlog) is? In-Reply-To: <5B03A584-DC5B-4A37-B3A4-454095FC869E@icloud.com> References: <19667ff0-893e-4152-9174-5f5b18b08504n@googlegroups.com> <5B03A584-DC5B-4A37-B3A4-454095FC869E@icloud.com> Message-ID: > On Feb 17, 2021, at 12:25 AM, Karen Shaeffer via Python-list wrote: > > > >> On Feb 16, 2021, at 8:10 PM, Jason Friedman wrote: >> >>> >>> I set listen(2) and expect to see "error" when more clients than "the >>> maximum number of queued connections" trying to connect the server. But, no >>> error!! Even 4 clients can run normally without problem. >>> >>> Am I misunderstanding the meaning of this argument? >>> >> >> https://docs.python.org/3/library/socket.html#socket.socket.listen: >> Enable a server to accept connections. If backlog is specified ... it >> specifies the number of unaccepted connections that the system will allow >> before refusing new connections. >> >> So I read that to say that the listen method will accept as many connection >> as it can handle, and will put into a backlog those it cannot. Your >> argument of 2 tells the method to allow up to 2 not-yet-accepted connection >> requests. >> -- > > Hi Jason, > The backlog parameter specifies the number of connection requests that the kernel network stack has waiting for the application layer to process. So, it?s at a lower level than the listen system call, which is the application layer API into the kernel network stack that simply establishes the socket. Listen doesn?t actually touch any data. Once the accept system call has touched it, then the network stack no longer counts it in the backlog. Backlog is a network stack queue associated with the application socket. The backlog is managed by the network driver software. Moving bits down there is extremely efficient. And the driver wouldn?t process and pass packets up the stack, if the backlog was maxed out. That would be very inefficient ? rather the driver would drop the packets at the network driver ring buffer in such case. That?s at the API into the network stack looking up from the network driver. > > Here is a good description from the perspective of the bottom of the tcp ip stack API into the network card driver, discussing the processing of packets depending on state of the backlog for the socket. > > http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html > The tcp ip stack software is the archetypical example of copy-on-write code. The packet comes over the wire and is copied onto the network driver ring buffer. Then, if the socket backlog is less than full, the network driver software copies the packet from the network driver ring buffer onto the very bottom layer of the ip stack. The data is never moved (copied) again, as it flows up the layers of the tcp ip stack, only pointers are used by each layer of the stack to maintain access to the data. Finally, the application will copy the data from the kernel memory over to application user space memory with a socket read call. It?s very beautiful code. Karen. From lukasz at langa.pl Wed Feb 17 07:50:06 2021 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Wed, 17 Feb 2021 13:50:06 +0100 Subject: [RELEASE] Python 3.9.2rc1 and 3.8.8rc1 are now available for testing Message-ID: I?m happy to announce two release candidates today: Python 3.9.2rc1, and Python 3.8.8rc1. Get them from: https://www.python.org/downloads/release/python-392rc1/ https://www.python.org/downloads/release/python-388rc1/ Unless critical issues are discovered, both release candidates will become their respective final versions on Monday, March 1st. Following that, the last full regular maintenance release of Python 3.8 is planned for May 3rd 2021, after which it will shift to source releases only for security bug fixes only. Maintenance releases for the 3.9 series will continue at regular bi-monthly intervals, with 3.9.3 planned for early May 2021. Notable security content in today?s releases bpo-42967 : Fix web cache poisoning vulnerability by defaulting the query args separator to &, and allowing the user to choose a custom separator. bpo-42938 : Avoid static buffers when computing the repr of ctypes.c_double and ctypes.c_longdouble values. What?s new? The Python 3.9 series contains many new features and optimizations over 3.8. See the ?What?s New in Python 3.9 ? document for more information about features included in the 3.9 series. We also have a detailed change log for 3.9.2rc1 specifically. Detailed information about all changes made in version 3.8.8rc1 specifically can be found in its change log . We hope you enjoy those new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. Your friendly release team, Ned Deily @nad Steve Dower @steve.dower ?ukasz Langa @ambv From tjol at tjol.eu Wed Feb 17 09:09:12 2021 From: tjol at tjol.eu (Thomas Jollans) Date: Wed, 17 Feb 2021 15:09:12 +0100 Subject: Python 2.7 and 3.9 In-Reply-To: <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> <36696864.2332692.1613508918901@mail.yahoo.com> <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> Message-ID: <70c842e6-4747-ff58-b20e-6d1fe6e34a6e@tjol.eu> On 16/02/2021 22:16, Ethan Furman wrote: > Kevin, please reply to the list (preferably Reply-to-list, or > Reply-all), that way others can chime in with help. > > On 2/16/21 12:55 PM, Kevin M. Wilson wrote: > >> Windows 7 OS, and typically run in conjunction with testing SSD', as >> for stand alone scripts. >> Those require: python BogusFile.py. I too was expecting users to >> type: python my_Script.py! On Windows, you should use the py.exe launcher: py -2 python2_script.py to run an old script, and py -3 python3_script.py or py python3_script.py to launch a new script. AKAIK, the launcher is always installed with recent versions of Python on Windows. You could set up the PATH such that 'python' is python 2.7, and 'py' calls python 3.x. Have a look at the docs to figure about what other options py.exe gives you (such as shebang lines) Docs: https://docs.python.org/3/using/windows.html#python-launcher-for-windows PEP: https://www.python.org/dev/peps/pep-0397 -- Thomas From python at mrabarnett.plus.com Wed Feb 17 09:44:32 2021 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 17 Feb 2021 14:44:32 +0000 Subject: Python 2.7 and 3.9 In-Reply-To: <70c842e6-4747-ff58-b20e-6d1fe6e34a6e@tjol.eu> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> <36696864.2332692.1613508918901@mail.yahoo.com> <5a51c438-d682-25a7-2263-a58741d574c0@stoneleaf.us> <70c842e6-4747-ff58-b20e-6d1fe6e34a6e@tjol.eu> Message-ID: On 2021-02-17 14:09, Thomas Jollans wrote: > On 16/02/2021 22:16, Ethan Furman wrote: >> Kevin, please reply to the list (preferably Reply-to-list, or >> Reply-all), that way others can chime in with help. >> >> On 2/16/21 12:55 PM, Kevin M. Wilson wrote: >> >>> Windows 7 OS, and typically run in conjunction with testing SSD', as >>> for stand alone scripts. >>> Those require: python BogusFile.py. I too was expecting users to >>> type: python my_Script.py! > > On Windows, you should use the py.exe launcher: > > py -2 python2_script.py > > to run an old script, and > > py -3 python3_script.py > > or > > py python3_script.py > > to launch a new script. AKAIK, the launcher is always installed with > recent versions of Python on Windows. > The scripts simply need to start with a shebang line that specifies the Python version. Then it's just: py python2_script.py py python3_script.py > > You could set up the PATH such that 'python' is python 2.7, and 'py' > calls python 3.x. Have a look at the docs to figure about what other > options py.exe gives you (such as shebang lines) > > Docs: > https://docs.python.org/3/using/windows.html#python-launcher-for-windows > > PEP: https://www.python.org/dev/peps/pep-0397 > From cl at isbd.net Wed Feb 17 10:40:27 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 15:40:27 +0000 Subject: I need some help interpreting this error Message-ID: I'm running this using Python 3.7 on a Linux system. Most of the time (i.e. for a couple of days now) the program has been satifactorily delivering mail messages, hundreds of them. However one mail message has provoked the following error:- chris at cheddar$ tail mail.err Traceback (most recent call last): File "/home/chris/.mutt/bin/filter.py", line 95, in if sbstrip in msghdr["subject"]: TypeError: argument of type 'Header' is not iterable But msghdr["subject"] is surely just a string isn't it? Why is it complaining about something of type 'Header'? As I said the program has been running happily for a couple of days with no errors, I guess it must be something strange in a mail that has broken things - but what? Full program listed below:- #!/usr/bin/python3 # # # license Apache v2 (http://www.apache.org/licenses/LICENSE-2.0) # author Chris Green - chris at isbd.co.uk # # # # Mail filtering script # import mailbox import os import sys import time import mailLib import shlex # # # Redirect any exceptions to a file # sys.stderr = open("/home/chris/tmp/mail.err", 'a') # # # Some constants (i.e. configuration) # home = "/home/chris" logfile = home + "/tmp/mail.log" filtfile = home + "/.mutt/filter" mldir = home + "/mail/" indir = mldir + "In/" # # # Set to log to mail.log in ~/tmp with name 'filter' and the envelope/from # log = mailLib.initLog("filter") # # # Initialise destination mailbox name to its default "In/default" # dest = indir + "default" # # # Read the message from standard input and make a message object from it # msg = mailbox.MaildirMessage(sys.stdin.buffer.read()) # # # Extract various headers and the envelope/from # msghdr = {} msghdr["to"] = msg.get("To", "unknown").lower() msghdr["subject"] = msg.get("Subject", "unknown") msghdr["list-id"] = msg.get("List-Id", "unknown").lower() msghdr["list-post"] = msg.get("List-Post", "unknown").lower() msghdr["x-mailing-list"] = msg.get("X-Mailing-List", "unknown").lower() msghdr["unknown"] = "unknown" # # # See if there's a match in our filter file # f = open(filtfile, 'r') for ln in f: # for each line in filter if ln[0] == '#': # ignore comments continue # # # split the line into fields, shlex.split() does quoted strings, add a field # to create a dummy fourth field if there isn't one in the filter file # fld = shlex.split(ln) fld.append("XXXXYYYYZZZZ") # # # copy the fields into better named variables # nm = fld[0] # name/alias destdir = fld[1] + "/" # the destination directory header = fld[2] # the header to find the match in address = fld[3].lower() # list address to match sbstrip = '[' + fld[4] + ']' # string to strip out of subject # # # Does the address in the header match this entry # if (address in msghdr[header]): # # # set the destination directory # dest = mldir + destdir + nm # # # Strip out list name (4th field) from subject if it's there # if sbstrip in msghdr["subject"]: msg.replace_header("Subject", msghdr["subject"].replace(sbstrip, '')) # # # we've found a match so assume we won't get another # break # # # deliver the message # mailLib.deliverMdMsg(dest, msg, log) -- Chris Green ? From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 17 11:03:32 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 17 Feb 2021 10:03:32 -0600 Subject: I need some help interpreting this error In-Reply-To: References: Message-ID: On 2021-02-17 at 15:40:27 +0000, Chris Green wrote: > I'm running this using Python 3.7 on a Linux system. > > Most of the time (i.e. for a couple of days now) the program has been > satifactorily delivering mail messages, hundreds of them. However one > mail message has provoked the following error:- > > chris at cheddar$ tail mail.err > Traceback (most recent call last): > File "/home/chris/.mutt/bin/filter.py", line 95, in > if sbstrip in msghdr["subject"]: > TypeError: argument of type 'Header' is not iterable > > > But msghdr["subject"] is surely just a string isn't it? Why is it > complaining about something of type 'Header'? Isn't it? ;-) First step: Print msghdr["subject"] and its type to know for sure. The worst case is that you'll verify your assumption. IIRC, the subject header is actually optional. Maybe someone sent a message without a subject? Is msghdr["subject"] None? From cl at isbd.net Wed Feb 17 11:42:03 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 16:42:03 +0000 Subject: I need some help interpreting this error References: Message-ID: 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2021-02-17 at 15:40:27 +0000, > Chris Green wrote: > > > I'm running this using Python 3.7 on a Linux system. > > > > Most of the time (i.e. for a couple of days now) the program has been > > satifactorily delivering mail messages, hundreds of them. However one > > mail message has provoked the following error:- > > > > chris at cheddar$ tail mail.err > > Traceback (most recent call last): > > File "/home/chris/.mutt/bin/filter.py", line 95, in > > if sbstrip in msghdr["subject"]: > > TypeError: argument of type 'Header' is not iterable > > > > > > But msghdr["subject"] is surely just a string isn't it? Why is it > > complaining about something of type 'Header'? > > Isn't it? ;-) > > First step: Print msghdr["subject"] and its type to know for sure. The > worst case is that you'll verify your assumption. > The documentation says "Headers are represented by customized subclasses of str", so it's a sub-class of str. > IIRC, the subject header is actually optional. Maybe someone sent a > message without a subject? Is msghdr["subject"] None? If you look at the code (and the documentation) if there's no subject header I'll get the string "unknown", I've also tried sending myself an E-Mail with no header and not provoked the error. -- Chris Green ? From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 17 12:04:28 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 17 Feb 2021 11:04:28 -0600 Subject: I need some help interpreting this error In-Reply-To: References: Message-ID: On 2021-02-17 at 16:42:03 +0000, Chris Green wrote: > 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > > On 2021-02-17 at 15:40:27 +0000, > > Chris Green wrote: > > > > > I'm running this using Python 3.7 on a Linux system. > > > > > > Most of the time (i.e. for a couple of days now) the program has been > > > satifactorily delivering mail messages, hundreds of them. However one > > > mail message has provoked the following error:- > > > > > > chris at cheddar$ tail mail.err > > > Traceback (most recent call last): > > > File "/home/chris/.mutt/bin/filter.py", line 95, in > > > if sbstrip in msghdr["subject"]: > > > TypeError: argument of type 'Header' is not iterable > > > > > > > > > But msghdr["subject"] is surely just a string isn't it? Why is it > > > complaining about something of type 'Header'? > > > > Isn't it? ;-) > > > > First step: Print msghdr["subject"] and its type to know for sure. The > > worst case is that you'll verify your assumption. > > > The documentation says "Headers are represented by customized > subclasses of str", so it's a sub-class of str. So we still don't know what the content of msghdr["subject"] is at the time the error occurs. I don't mean to sound harsh, but that the documentation and the code are correct, and that they match, remain assumptions. Sometimes, seeing an actual value tells you what went wrong (e.g., "oh, that's the sender's address, not the receiver's address," "oh, that's my 'time' class, not the one from the standard library"). The traceback tells you that msghdr["subject"] is of type Header. Is Header a sub-class of str? Again, the worst case of looking at the value (whether in a log or in a debugger) is that you verify your assumption. > > IIRC, the subject header is actually optional. Maybe someone sent a > > message without a subject? Is msghdr["subject"] None? > > If you look at the code (and the documentation) if there's no subject > header I'll get the string "unknown", I've also tried sending myself > an E-Mail with no header and not provoked the error. That's good news about subject-less emails not generating an error, and separate (possibly related) good news about your code handling an email without a subject header. ;-) From cl at isbd.net Wed Feb 17 11:52:55 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 16:52:55 +0000 Subject: I need some help interpreting this error References: Message-ID: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> Stefan Ram wrote: > Chris Green writes: > >But msghdr["subject"] is surely just a string isn't it? Why is it > >complaining about something of type 'Header'? > > What would you do to debug-print the type of an object? > I don't know, what would I do? :-) Without knowing what provokes the problem I could be waiting for days or weeks even before I see the error again. As I'd need to print the type for every message I'd get some big logs or I'd need to add a try: except to trap the specific error. -- Chris Green ? From cl at isbd.net Wed Feb 17 12:31:31 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 17:31:31 +0000 Subject: I need some help interpreting this error References: Message-ID: 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2021-02-17 at 16:42:03 +0000, > Chris Green wrote: > > > 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > > > On 2021-02-17 at 15:40:27 +0000, > > > Chris Green wrote: > > > > > > > I'm running this using Python 3.7 on a Linux system. > > > > > > > > Most of the time (i.e. for a couple of days now) the program has been > > > > satifactorily delivering mail messages, hundreds of them. However one > > > > mail message has provoked the following error:- > > > > > > > > chris at cheddar$ tail mail.err > > > > Traceback (most recent call last): > > > > File "/home/chris/.mutt/bin/filter.py", line 95, in > > > > if sbstrip in msghdr["subject"]: > > > > TypeError: argument of type 'Header' is not iterable > > > > > > > > > > > > But msghdr["subject"] is surely just a string isn't it? Why is it > > > > complaining about something of type 'Header'? > > > > > > Isn't it? ;-) > > > > > > First step: Print msghdr["subject"] and its type to know for sure. The > > > worst case is that you'll verify your assumption. > > > > > The documentation says "Headers are represented by customized > > subclasses of str", so it's a sub-class of str. > > So we still don't know what the content of msghdr["subject"] is at the > time the error occurs. I don't mean to sound harsh, but that the > documentation and the code are correct, and that they match, remain > assumptions. Sometimes, seeing an actual value tells you what went > wrong (e.g., "oh, that's the sender's address, not the receiver's > address," "oh, that's my 'time' class, not the one from the standard > library"). > > The traceback tells you that msghdr["subject"] is of type Header. Is > Header a sub-class of str? > That's exactly what puzzled me! The line that gets the value is:- msghdr["subject"] = msg.get("Subject", "unknown") What I need to know is how that can return a value of type Header, and not a str. > Again, the worst case of looking at the value (whether in a log or in a > debugger) is that you verify your assumption. > > > > IIRC, the subject header is actually optional. Maybe someone sent a > > > message without a subject? Is msghdr["subject"] None? > > > > If you look at the code (and the documentation) if there's no subject > > header I'll get the string "unknown", I've also tried sending myself > > an E-Mail with no header and not provoked the error. > > That's good news about subject-less emails not generating an error, and > separate (possibly related) good news about your code handling an email > without a subject header. ;-) I think the only sane approach at the moment may be to add a try: except: and output some diagnostic information. Though there may still be an issue when trying to output the "what is it" object to the error log of course. -- Chris Green ? From stestagg at gmail.com Wed Feb 17 12:42:10 2021 From: stestagg at gmail.com (Stestagg) Date: Wed, 17 Feb 2021 17:42:10 +0000 Subject: I need some help interpreting this error In-Reply-To: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> References: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> Message-ID: I don't particularly like to encourage this shotgun help request because, as previous commenter suggests, debugging this yourself is best. Sometimes debugging is super hard, and especially so when uncommon situations occur, but it's always far easier to debug things when you have visibility into the system under test. However, in this case, the email code is super complex, and this scenario also looks very uncommon, but not unique: ( https://github.com/Sydius/mbox-to-txt/issues/2), so you successfully nerd-sniped me :). My *guess*, from reading the python standard library source code is that you came across an email with some content in the subject line that is considered a "surrogate", roughly, some badly encoded unicode or binary data in it. When this happens, the code in some situations (depending on the policy...) may return a header.Header() instance, rather than a headerregistry.UniqueUnstructuredHeader (which would have had a headerregistry.BaseHeader (mro: str) dynamically attached). header.Header() does not inherit from str, and thus would throw the traceback you observed. Your suggestion of a try: catch: may make sense, alternately, you could wrap the result in a call to str(): if sbstrip in str(msghdr["subject"]): which should attempt to encode the binary into some form of string object for comparison (I haven't checked exactly what would happen, beyond: it tries). It should be possible to create a test mbox with some funky bytes in the subject, and try to reproduce it that way. Steve On Wed, Feb 17, 2021 at 5:07 PM Chris Green wrote: > Stefan Ram wrote: > > Chris Green writes: > > >But msghdr["subject"] is surely just a string isn't it? Why is it > > >complaining about something of type 'Header'? > > > > What would you do to debug-print the type of an object? > > > I don't know, what would I do? :-) > > Without knowing what provokes the problem I could be waiting for days > or weeks even before I see the error again. As I'd need to print the > type for every message I'd get some big logs or I'd need to add a try: > except to trap the specific error. > > -- > Chris Green > ? > -- > https://mail.python.org/mailman/listinfo/python-list > From cl at isbd.net Wed Feb 17 12:36:48 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 17:36:48 +0000 Subject: I need some help interpreting this error References: Message-ID: Stefan Ram wrote: > Chris Green writes: > > chris at cheddar$ tail mail.err > > Traceback (most recent call last): > > File "/home/chris/.mutt/bin/filter.py", line 95, in > > if sbstrip in msghdr["subject"]: > > TypeError: argument of type 'Header' is not iterable > >But msghdr["subject"] is surely just a string isn't it? Why is it > >complaining about something of type 'Header'? > > I presume that the error message has been edited (abbreviated). > > In "if sbstrip in msghdr["subject"]:", there is no argument. > > But the error message says "argument of ...". > > When something that is not iterable is presented to a for loop, > the error message does not mention "argument": > I have output everything that appears, I've not changed it at all. It's the whole content of the file ~/tmp/mail.err as it's the only error that has occurred for the last day or so. The error log is created by the line:- sys.stderr = open("/home/chris/tmp/mail.err", 'a') So that's everything that was output to stderr. I think you are puzzled in the same way that I was, the error message doesn't make a lot of sense. > |>>> for i in 0: > |... print(i) > |... > |Traceback (most recent call last): > | File "", line 1, in > |TypeError: 'int' object is not iterable > > . > > -- Chris Green ? From stestagg at gmail.com Wed Feb 17 12:52:26 2021 From: stestagg at gmail.com (Stestagg) Date: Wed, 17 Feb 2021 17:52:26 +0000 Subject: I need some help interpreting this error In-Reply-To: References: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> Message-ID: Some sources, in case they help: Message.get() calls policy.header_fetch_parse ( https://github.com/python/cpython/blob/cd80f430daa7dfe7feeb431ed34f88db5f64aa30/Lib/email/message.py#L471 ) Compat32.header_fetch_parse calls self._sanitize_header ( https://github.com/python/cpython/blob/cd80f430daa7dfe7feeb431ed34f88db5f64aa30/Lib/email/_policybase.py#L311 ) _sanitize_header calls _has_surrogates ( https://github.com/python/cpython/blob/cd80f430daa7dfe7feeb431ed34f88db5f64aa30/Lib/email/_policybase.py#L287 ) _has_surrogates check: https://github.com/python/cpython/blob/cd80f430daa7dfe7feeb431ed34f88db5f64aa30/Lib/email/utils.py#L51 On Wed, Feb 17, 2021 at 5:42 PM Stestagg wrote: > I don't particularly like to encourage this shotgun help request because, > as previous commenter suggests, debugging this yourself is best. > > Sometimes debugging is super hard, and especially so when uncommon > situations occur, but it's always far easier to debug things when you have > visibility into the system under test. > > However, in this case, the email code is super complex, and this scenario > also looks very uncommon, but not unique: ( > https://github.com/Sydius/mbox-to-txt/issues/2), so you successfully > nerd-sniped me :). > > My *guess*, from reading the python standard library source code is that > you came across an email with some content in the subject line that is > considered a "surrogate", roughly, some badly encoded unicode or binary > data in it. > > When this happens, the code in some situations (depending on the > policy...) may return a header.Header() instance, rather than a > headerregistry.UniqueUnstructuredHeader (which would have had a > headerregistry.BaseHeader (mro: str) dynamically attached). > > header.Header() does not inherit from str, and thus would throw the > traceback you observed. > > Your suggestion of a try: catch: may make sense, alternately, you could > wrap the result in a call to str(): > > if sbstrip in str(msghdr["subject"]): > > which should attempt to encode the binary into some form of string object > for comparison (I haven't checked exactly what would happen, beyond: it > tries). > > It should be possible to create a test mbox with some funky bytes in the > subject, and try to reproduce it that way. > > Steve > > > On Wed, Feb 17, 2021 at 5:07 PM Chris Green wrote: > >> Stefan Ram wrote: >> > Chris Green writes: >> > >But msghdr["subject"] is surely just a string isn't it? Why is it >> > >complaining about something of type 'Header'? >> > >> > What would you do to debug-print the type of an object? >> > >> I don't know, what would I do? :-) >> >> Without knowing what provokes the problem I could be waiting for days >> or weeks even before I see the error again. As I'd need to print the >> type for every message I'd get some big logs or I'd need to add a try: >> except to trap the specific error. >> >> -- >> Chris Green >> ? >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From cl at isbd.net Wed Feb 17 12:54:53 2021 From: cl at isbd.net (Chris Green) Date: Wed, 17 Feb 2021 17:54:53 +0000 Subject: I need some help interpreting this error References: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> Message-ID: Stestagg wrote: > I don't particularly like to encourage this shotgun help request because, > as previous commenter suggests, debugging this yourself is best. > > Sometimes debugging is super hard, and especially so when uncommon > situations occur, but it's always far easier to debug things when you have > visibility into the system under test. > > However, in this case, the email code is super complex, and this scenario > also looks very uncommon, but not unique: ( > https://github.com/Sydius/mbox-to-txt/issues/2), so you successfully > nerd-sniped me :). > > My *guess*, from reading the python standard library source code is that > you came across an email with some content in the subject line that is > considered a "surrogate", roughly, some badly encoded unicode or binary > data in it. > > When this happens, the code in some situations (depending on the policy...) > may return a header.Header() instance, rather than a > headerregistry.UniqueUnstructuredHeader > (which would have had a headerregistry.BaseHeader (mro: str) dynamically > attached). > > header.Header() does not inherit from str, and thus would throw the > traceback you observed. > Ah, thank you, a possible explanation. > Your suggestion of a try: catch: may make sense, alternately, you could > wrap the result in a call to str(): > > if sbstrip in str(msghdr["subject"]): > > which should attempt to encode the binary into some form of string object > for comparison (I haven't checked exactly what would happen, beyond: it > tries). > Yes, I did consider the str() approach but it feels a bit like making the problem go away without actually fixing it. However since the code in question is only 'cosmetic' (removing unwanted [list name] from the subject, it's not all *that* important to handle it properly. I just need to stop the error from killing my program. > It should be possible to create a test mbox with some funky bytes in the > subject, and try to reproduce it that way. > That's a point, with the clues you have given me I can try some 'bad' subject text and see if I can reproduce the error. Thanks again. -- Chris Green ? From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 17 13:23:21 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 17 Feb 2021 12:23:21 -0600 Subject: I need some help interpreting this error In-Reply-To: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> References: <78uvfh-2fnq.ln1@esprimo.zbmc.eu> Message-ID: On 2021-02-17 at 16:52:55 +0000, Chris Green wrote: > Stefan Ram wrote: > > Chris Green writes: > > >But msghdr["subject"] is surely just a string isn't it? Why is it > > >complaining about something of type 'Header'? > > > > What would you do to debug-print the type of an object? > > > I don't know, what would I do? :-) > > Without knowing what provokes the problem I could be waiting for days > or weeks even before I see the error again. As I'd need to print the > type for every message I'd get some big logs or I'd need to add a try: > except to trap the specific error. An intermittent problem! They're our favorite! ;-) Seriously, though, do you have a message that provokes the problem? Is there a log at all? Can you re-run that message through the code, in a debugger or otherwise? From jpic at yourlabs.org Wed Feb 17 13:18:01 2021 From: jpic at yourlabs.org (J. Pic) Date: Wed, 17 Feb 2021 19:18:01 +0100 Subject: Python 2.7 and 3.9 In-Reply-To: <1129940616.2323576.1613506148454@mail.yahoo.com> References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> Message-ID: The best would be to upgrade the scripts, did you try them with 2to3 ? It should do most of the work, if not all. https://docs.python.org/3/library/2to3.html From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 17 13:29:33 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 17 Feb 2021 12:29:33 -0600 Subject: I need some help interpreting this error In-Reply-To: References: Message-ID: On 2021-02-17 at 17:36:48 +0000, Chris Green wrote: > Stefan Ram wrote: > > Chris Green writes: > > > chris at cheddar$ tail mail.err > > > Traceback (most recent call last): > > > File "/home/chris/.mutt/bin/filter.py", line 95, in > > > if sbstrip in msghdr["subject"]: > > > TypeError: argument of type 'Header' is not iterable > > >But msghdr["subject"] is surely just a string isn't it? Why is it > > >complaining about something of type 'Header'? > > > > I presume that the error message has been edited (abbreviated). > > > > In "if sbstrip in msghdr["subject"]:", there is no argument. > > > > But the error message says "argument of ...". > > > > When something that is not iterable is presented to a for loop, > > the error message does not mention "argument": > > > I have output everything that appears, I've not changed it at all. > It's the whole content of the file ~/tmp/mail.err as it's the only > error that has occurred for the last day or so. The error log is > created by the line:- > > sys.stderr = open("/home/chris/tmp/mail.err", 'a') > > So that's everything that was output to stderr. > > I think you are puzzled in the same way that I was, the error message > doesn't make a lot of sense. At some point, the internal code for the "in" operator is likely iterating over the elements of msghdr["subject"]. That error message doesn't make a lot of sense if msghdr["subject"] is a sub-class of str. It makes more sense if msghdr["subject"] is something else. IMO, you need more information in the log, a try/except block to prevent the code from crashing, and, yes, perhaps some patience to wait for it to happen again. Sometimes, developing software isn't all fortune, fame, and glory. ;-) From alan.gauld at yahoo.co.uk Tue Feb 16 21:00:55 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 17 Feb 2021 02:00:55 +0000 Subject: New Python implementation In-Reply-To: References: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> Message-ID: On 16/02/2021 22:23, boB Stepp wrote: >> And that's just one example, the language is now full of meta goodness >> that makes it incomprehensible to beginners. > > Hmm. I'm not sure I can agree, Alan. My son took to Python 3 like a duck to > water. That's interesting. I knew you were teaching him but not how he got on. Good for him. My comments stem from the feedback emails I get from my tutorial. People get messages like "foo is not an iterable" or references to range objects and such and it confuses them. I never got those kinds of messages for the v.1 tutorial... > Yes, there is a ton of meta-goodness in Python, but most of it can be ignored > to be able to *just use it*. But the problem I see is that you can't ignore it because it bubbles to the surface in error messages. And if you don't know what it means you don't know that you can ignore it! That's where a teacher/mentor comes in, they can say "Oh that's OK just ignore it!" but if you are on your own you think "Oh no! What do I do now?" But as I say, I can't find anything better so I'll stick with it for now. -- 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 From alan.gauld at yahoo.co.uk Tue Feb 16 21:18:33 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 17 Feb 2021 02:18:33 +0000 Subject: New Python implementation In-Reply-To: <877dn71ze8.fsf@purelymail.com> References: <87blcnnejf.fsf@nightsong.com> <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <87a6s41jb1.fsf@purelymail.com> <877dn71ze8.fsf@purelymail.com> Message-ID: On 16/02/2021 21:22, Tarjei B?rland via Python-list wrote: > To me, it depends on what you want out of including programming in > mathematics education. That's a really important subclass distinction. If programming is seen as an adjunct to math then the aims can be simplified considerably since you are only interested in pure computation. Things like networking, interfacing to peripherals and the like can be ignored. Likewise you probably don't care about creating large projects wit multiple files etc. With those constraints there are probably better languages than python. You mention Logo and I had fun with that back in the 80s and early 90s. But ultimately it wasn't suitable for the kind of real-world programming I needed. That's why I chose python for my tutorial. Its not only teachable at a basic level but it is actually usable on larger, real-world type projects once you've learned it. You never need to throw away your skills. > If the aim is to quickly get the students to "be creative" with > programming by themselves, my feeling is that Python is too unwieldy for > a beginner. Don't underestimate the interactive prompt. It gives instant feedback and is moire usable for beginners than most Lisp-style REPLs. Logo works too of course. But almost anything you can do in Logo you can do almost as easily in Python. Be it list handling or turtle graphics. > minutes. They get the feeling of designing their own computational > procedure much quicker than in Python. (Yes, of course, the introductory > excercises in Python are a bit more advanced than "add two numbers".) But they don't need to be. My tutor starts off with precisely that... > I am honestly not sure what quite what my feelings are regarding this, > perhaps Python is the best of all possible options. Its a good compromise. Its got faults (see my other post!) but I haven't found anything clearly better. -- 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 From tjreedy at udel.edu Wed Feb 17 12:27:03 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 17 Feb 2021 12:27:03 -0500 Subject: I need some help interpreting this error In-Reply-To: References: Message-ID: On 2/17/2021 10:40 AM, Chris Green wrote: > I'm running this using Python 3.7 on a Linux system. > > Most of the time (i.e. for a couple of days now) the program has been > satifactorily delivering mail messages, hundreds of them. However one > mail message has provoked the following error:- > > chris at cheddar$ tail mail.err > Traceback (most recent call last): > File "/home/chris/.mutt/bin/filter.py", line 95, in > if sbstrip in msghdr["subject"]: > TypeError: argument of type 'Header' is not iterable > > > But msghdr["subject"] is surely just a string isn't it? Obviously not. > Why is it > complaining about something of type 'Header'? Because you tried to iterate it. Header is defined in email.header (find 'class Header'). It has a __str__ to turn one into a string. I have never read the email doc so I have no idea if 'subject' being a Header is a bug. Grepping email package for case-sensitive word 'Header' also returns 3 comment saying that something might be a Header, so stringify it. I have the impression that these might have been added after the original code, perhaps in response to error reports. In any case, you can do the same. > As I said the program has been running happily for a couple of days > with no errors, I guess it must be something strange in a mail that > has broken things - but what? To determine that, look at (after logging or saving) the raw email and maybe the resulting Message (using msg.as_string). > # Read the message from standard input and make a message object from it > # > msg = mailbox.MaildirMessage(sys.stdin.buffer.read()) raw = sys.stdin.buffer.read() # So can save msg = mailbox.MaildirMessage(raw) > msghdr["subject"] = msg.get("Subject", "unknown") ... > if sbstrip in msghdr["subject"]: Replace with sub = msghdr["subject"] if 'Header' in str(sub.__class__): # Or import email.message.class and use isinstance # stringify or skip or ??? else: > msg.replace_header("Subject", msghdr["subject"].replace(sbstrip, -- Terry Jan Reedy From mal at europython.eu Thu Feb 18 10:08:33 2021 From: mal at europython.eu (M.-A. Lemburg) Date: Thu, 18 Feb 2021 16:08:33 +0100 Subject: EuroPython 2021: Volunteering Message-ID: The EuroPython 2021 organization is starting and we're looking for more help with running the conference. * EuroPython 2021 * https://ep2021.europython.eu/ For EP2021, we are using a slightly different approach compared to previous years: - All new volunteers will first join the Plaza ? our central get-together place for all team members ? and only later enter the various work groups (WGs) we have for running the conference. - Additionally, we will have on-boarding calls with everyone to get to know each other and give an overview to the structures, information and groups we have available, as well as the timeline. If you are interested in helping, please write to volunteers at europython.eu. Our team will then answer any questions you may have and get you signed up for the next on-boarding call. Help spread the word -------------------- Please help us spread this message by sharing it on your social networks as widely as possible. Thank you ! Link to the blog post: https://blog.europython.eu/europytho-2021-volunteerng/ Tweet: https://twitter.com/europython/status/1362416745814888451 Enjoy, -- EuroPython 2021 Team https://www.europython-society.org/ From Bischoop at vimart.net Thu Feb 18 10:22:08 2021 From: Bischoop at vimart.net (Bischoop) Date: Thu, 18 Feb 2021 15:22:08 -0000 (UTC) Subject: Problem when scraping the 100 Movie titles. Message-ID: I'm learning Scraping actually and would like to scrape the movie titles from https://www.empireonline.com/movies/features/best-movies-2 . In the course I was learning I was supposed to do it with bs4: titles = soup.find_all(name = 'h3', class_ = 'title') but after after a while I guess the site has changed and now the class is: jsx-2692754980

100) Stand By Me

but anyway if I do try get those titles by name and class, my list is empty: titles = soup.find_all(name = 'h3', class_ = 'jsx-2692754980') I tried also selenium and manage get those titles with: driver.get('https://www.empireonline.com/movies/features/best-movies-2') #driver.find_element_by_xpath('/html/body/div/div[3]/div[5]/button[2]').click() titles = driver.find_elements_by_css_selector("h3.jsx-2692754980") tit=[] for e in titles: tit.append(e.text) print(tit) But in Chrome I get a popup asking to accept cookies and I need to click to accept them. Is someone here who knows how can I get those titles with BeautifulSoup and how to deal with cookies if using Selenium? -- Thanks From avigross at verizon.net Thu Feb 18 12:26:11 2021 From: avigross at verizon.net (Avi Gross) Date: Thu, 18 Feb 2021 12:26:11 -0500 Subject: New Python implementation In-Reply-To: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> References: <62bfd3a1-d4f0-c753-6c01-ad0e9070cd85@DancesWithMice.info> <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> Message-ID: <04b001d7061b$26f541d0$74dfc570$@verizon.net> Dennis made the interesting comment "... Python has too much built in ..." I understand his point. At the same time, I wonder what most people using computers today, or in the future, need. Given serious amounts of computer power, what many people may want is higher-level ways to get things done without worrying how they are done. Python, like many such languages, has a very basic core that is augmented by what could be libraries, packages, modules and so on but have been chosen to be built-in to one distribution or another. Some people and organizations use some things so commonly, they want python to start up automatically loading say numpy and pandas and other such things. They may not care if the programmer knows how to make a linked list or binary tree data structure. Many such details are encapsulated within objects built and tested already. I have seen subjects taught at various levels and python might qualify too. I took a Physics course that required Calculus and used it to derive formulas and other things. Others took one that sort of threw equations at you without much explanation. I have even seen a course called Physics for Poets. But at least the poets taking it knew science existed and perhaps to take it seriously when others who had studied it better shared their results, even if they have no interest in the methods. We routinely have people learn how to use Word Processors or Spreadsheets with no clue on how to build such a thing or anything about the Object models used within or even knowing there is such a thing. Do they need to know how to use the embedded methods to extend things with Visual Basic or Javascript? They like getting closer to a WYSIWYG interface that handles most of their usual needs and perhaps farm out harder things to experts when needed. So what if you teach some aspects of python that are needed all over, like how to make things conditional or in a loop, but not how to make every possible data structure. What if you deliberately do not teach functional aspects of the language at first or ever? For some people that is enough to enable them to then use additional instructions on how to find prepared and tested chunks to use, even if not always optimally or efficiently. For those who really want to be programmers, that still may actually be enough if their task is to work using the tools we have developed, not in making new tools from scratch. Quite a bit of programming today consists of reading manual pages and cobbling together chunks that together do the job. But obviously I would choose the classes where I understood more. Many here would. But where does it end? Do most of us know how compilers or interpreters get built or do we just work on top of existing implementations others make available? Can you build an operating system from Scratch or make microchips to run them on? If the goal is Computer USE literacy, I think python has more than enough if you include the modules that make hard things easy. Just a thought. Admittedly it is hard these days to give a homework assignment when the student can find a trivial way to get the result and not do the hard work. -----Original Message----- From: Python-list On Behalf Of Dennis Lee Bieber Sent: Thursday, February 18, 2021 12:45 AM To: python-list at python.org Subject: Re: New Python implementation On Tue, 16 Feb 2021 11:03:33 +0000, Alan Gauld via Python-list declaimed the following: >On 16/02/2021 07:35, Christian Gollwitzer wrote: >> Am 16.02.21 um 06:36 schrieb dn: >>> Pascal's value as a teaching language was that it embodied many >>> aspects of structured programming, and like Python, consisted of a >>> limited range of items which could be learned very quickly >> >> ROFL. Maybe that was true for Python when it was first invented. >> Today it is not "a few simple things". Even just the core language, > >Python v1 was a good teaching language. v2 complicated it a bit but it >was still usable. v3 is no longer a good teaching language (unless >maybe you are teaching CompSci at university.) > >In fact in v3 things are so complex that I seriously considered >dropping Python as the core language for my programming tutorial. >Until I started looking for an alternative, and there really isn't >anything much better. At least not that can also be used for real >projects once you've learned it. Depending upon the course intentions, I'd say Python is useful for teaching general programming and getting to usable real-world programs. For CompSci /theory/, OTOH, Python has too much built in, and would get in the way of having someone implement things like linked-lists, deques, hashed structures -- ie; the stuff that lies behind all those Python built-ins. Pascal, Modula-2 (or is it up to 3 now), or one of the other system programming languages: Edison from https://www.amazon.com/Programming-personal-computer-Brinch-Hansen/dp/013730 2673 Implement a hashed-head multiple-linked list using Kemeny&Kurtz level BASIC! (My algorithms instructor allowed the class to use any language on that he could read -- so FORTRAN, BASIC, Pascal, Sigma Meta-Symbol, COBOL... No Snobol, LISP, or APL -- for that final project: a phone book directory/look-up system). Interestingly, I've only seen a hashed-head multiple-linked list structure used in one real world application: The Commodore Amiga file system. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list From aakashjana2002 at gmail.com Thu Feb 18 12:43:02 2021 From: aakashjana2002 at gmail.com (Aakash Jana) Date: Thu, 18 Feb 2021 23:13:02 +0530 Subject: Problem when scraping the 100 Movie titles. In-Reply-To: References: Message-ID: I have done some webscraping before i think you need to get a slightly more tactical way to get these titles scraped . Try to see what classes identify the cards (in which movie title is given) and then try to pull the heading out of those. Try to get the divs in a list , something like this "
" in my case and then try to pull the h3 tag out of it . Onething to note is react os single page heavy webapps have seemed to be difficult to scrape maybe beautiful isnt made for JSX . On Thu, Feb 18, 2021 at 9:09 PM Bischoop wrote: > > I'm learning Scraping actually and would like to scrape the movie titles > from https://www.empireonline.com/movies/features/best-movies-2 . > In the course I was learning I was supposed to do it with bs4: > titles = soup.find_all(name = 'h3', class_ = 'title') > > but after after a while I guess the site has changed and now the class > is: jsx-2692754980 > >

100) Stand By Me

> > but anyway if I do try get those titles by name and class, my list is > empty: > titles = soup.find_all(name = 'h3', class_ = 'jsx-2692754980') > > I tried also selenium and manage get those titles with: > driver.get('https://www.empireonline.com/movies/features/best-movies-2') > > #driver.find_element_by_xpath('/html/body/div/div[3]/div[5]/button[2]').click() > > titles = driver.find_elements_by_css_selector("h3.jsx-2692754980") > > tit=[] > for e in titles: > tit.append(e.text) > > print(tit) > > But in Chrome I get a popup asking to accept cookies and I need to > click to accept them. > > Is someone here who knows how can I get those titles with BeautifulSoup > and how to deal with > cookies if using Selenium? > > -- > Thanks > -- > https://mail.python.org/mailman/listinfo/python-list > From malthabit at yahoo.com Thu Feb 18 12:53:39 2021 From: malthabit at yahoo.com (Mustafa Althabit) Date: Thu, 18 Feb 2021 17:53:39 +0000 (UTC) Subject: Fw: Scipy installation In-Reply-To: <164334651.2417108.1613669290348@mail.yahoo.com> References: <164334651.2417108.1613669290348.ref@mail.yahoo.com> <164334651.2417108.1613669290348@mail.yahoo.com> Message-ID: <550101968.2135453.1613670819901@mail.yahoo.com> Hi,I am trying to install Scipy but it failed, I have python 3.9.?I need your assistance with that.? Thank you?Mustafa Althabit8133825988 From pbryan at anode.ca Thu Feb 18 13:06:40 2021 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 18 Feb 2021 18:06:40 +0000 Subject: Fw: Scipy installation In-Reply-To: <550101968.2135453.1613670819901@mail.yahoo.com> References: <164334651.2417108.1613669290348.ref@mail.yahoo.com> <164334651.2417108.1613669290348@mail.yahoo.com> <550101968.2135453.1613670819901@mail.yahoo.com> Message-ID: <010d0177b6529169-ffeb7e04-4f76-4c23-8dbd-953626c7a0cc-000000@ca-central-1.amazonses.com> Can you describe what you tried, and how it failed? Pasting error messages and such would be helpful. On Thu, 2021-02-18 at 17:53 +0000, Mustafa Althabit via Python-list wrote: > ? > > ?? Hi,I am trying to install Scipy but it failed, I have python > 3.9.?I need your assistance with that.? > Thank you?Mustafa Althabit8133825988? From mats at wichmann.us Thu Feb 18 13:21:52 2021 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 18 Feb 2021 11:21:52 -0700 Subject: Problem when scraping the 100 Movie titles. In-Reply-To: References: Message-ID: <4af7159a-ceb6-4709-dff1-f9ee59398d29@wichmann.us> On 2/18/21 10:43 AM, Aakash Jana wrote: > I have done some webscraping before i think you need to get a slightly more > tactical way to get these titles scraped . > Try to see what classes identify the cards (in which movie title is given) > and then try to pull the heading out of those. > Try to get the divs in a list , something like this "
class="jsx-2692754980 listicle-item-image ">" in my case and then try to > pull > the h3 tag out of it . Onething to note is react os single page heavy > webapps have seemed to be difficult to scrape maybe beautiful > isnt made for JSX . > > On Thu, Feb 18, 2021 at 9:09 PM Bischoop wrote: > >> >> I'm learning Scraping actually and would like to scrape the movie titles >> from https://www.empireonline.com/movies/features/best-movies-2 . >> In the course I was learning I was supposed to do it with bs4: Just in general, most websites don't want you to scrape them, and some go to considerable efforts to make it difficult, and some explicitly disallow downloading any content except for caching purposes. If the website provides an API, that's how they expect you go consume data that isn't render through a web browser. Just sayin' ... there's no reason not to learn the concepts of web scraping but should ALSO be aware of terms of use. From pieter-l at vanoostrum.org Thu Feb 18 13:44:40 2021 From: pieter-l at vanoostrum.org (Pieter van Oostrum) Date: Thu, 18 Feb 2021 19:44:40 +0100 Subject: Python 2.7 and 3.9 References: <1129940616.2323576.1613506148454.ref@mail.yahoo.com> <1129940616.2323576.1613506148454@mail.yahoo.com> <77492f2f-80d0-d984-7132-0429684d2f13@stoneleaf.us> Message-ID: Ethan Furman writes: > On 2/16/21 12:09 PM, Kevin M. Wilson via Python-list wrote: > >> My employer has hundreds of scripts in 2.7, but I'm writing new >> scripts in 3.9! I'm running into 'invalid syntax' errors.I have to >> maintain the 'Legacy' stuff, and I need to mod the path et al., to >> execute 3.7 w/o doing damage to the 'Legacy' stuff...IDEA' are >> Welcome! > > My first idea/request: have a blank line, a line with only a '--' > (without quotes), and then your signature at the bottom of your posts. > White space aids readability and readability counts. :) The separator line should be '-- ' (without quotes), i.e. with a trailing space. -- Pieter van Oostrum www: http://pieter.vanoostrum.org/ PGP key: [8DAE142BE17999C4] From nospam at yrl.co.uk Thu Feb 18 17:47:44 2021 From: nospam at yrl.co.uk (Elliott Roper) Date: Thu, 18 Feb 2021 22:47:44 +0000 (UTC) Subject: New Python implementation References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> Message-ID: Avi and Dennis-- Two thoughtful replies to a deep and interesting question. You have prodded me to poke my head over the wall to offer a real world point of view. In the early days before Modula II, I was contracting to a company, quite large and respected, that had just chucked out Ratfor and adopted Pascal as their main development tool on VAX-VMS. With long hindsight it was a not insignificant factor in their going bust. I was happily developing some of the best code I have ever written using Macro on a J-11 PDP 11/73, so I was an innocent bystander, with my own OS, with 'borrowed' XDT and CRC table look-up software, courtesy of Dave Cutler and Stu Wecker respectively. It was a front end for the main project, supporting 1024 terminals feeding 200 transactions a second into the VAX over raw ethernet on a DEQNA. So I sure learned how to do linked lists, and do them quickly. The main team was sharing a VAX-750. Watching them trying to use a teaching language to do real world work was not a joy to behold. You have both hit on a real-world problem. Script Kiddies and Stack Exchange A comp sci course must use a real-world language to send confident practitioners into the real world. Python is an excellent choice in that regard. Dennis' point about it being too good is valid. If it were my course (and there is no chance of that) I'd do an extra credit module where they have to mine and critique the cPython source etc. for lists and comprehensions and itertools and all their uncles and aunts. After all c is the nearest they will get to the metal. I know this has to work. Two or three of the guys on that project were John Lion's co-authors of the Red Book on Unix internals. They were awesome! (I told you this was very long hindsight didn't I?) On 18 Feb 2021 at 17:26:11 GMT, ""Avi Gross"" wrote: > Dennis made the interesting comment "... Python has too much built in ..." > > I understand his point. At the same time, I wonder what most people using > computers today, or in the future, need. Given serious amounts of computer > power, what many people may want is higher-level ways to get things done > without worrying how they are done. Python, like many such languages, has a > very basic core that is augmented by what could be libraries, packages, > modules and so on but have been chosen to be built-in to one distribution or > another. > > Some people and organizations use some things so commonly, they want python > to start up automatically loading say numpy and pandas and other such > things. They may not care if the programmer knows how to make a linked list > or binary tree data structure. Many such details are encapsulated within > objects built and tested already. > > I have seen subjects taught at various levels and python might qualify too. > I took a Physics course that required Calculus and used it to derive > formulas and other things. Others took one that sort of threw equations at > you without much explanation. I have even seen a course called Physics for > Poets. But at least the poets taking it knew science existed and perhaps to > take it seriously when others who had studied it better shared their > results, even if they have no interest in the methods. > > We routinely have people learn how to use Word Processors or Spreadsheets > with no clue on how to build such a thing or anything about the Object > models used within or even knowing there is such a thing. Do they need to > know how to use the embedded methods to extend things with Visual Basic or > Javascript? They like getting closer to a WYSIWYG interface that handles > most of their usual needs and perhaps farm out harder things to experts when > needed. > > So what if you teach some aspects of python that are needed all over, like > how to make things conditional or in a loop, but not how to make every > possible data structure. What if you deliberately do not teach functional > aspects of the language at first or ever? For some people that is enough to > enable them to then use additional instructions on how to find prepared and > tested chunks to use, even if not always optimally or efficiently. For those > who really want to be programmers, that still may actually be enough if > their task is to work using the tools we have developed, not in making new > tools from scratch. Quite a bit of programming today consists of reading > manual pages and cobbling together chunks that together do the job. > > But obviously I would choose the classes where I understood more. Many here > would. But where does it end? Do most of us know how compilers or > interpreters get built or do we just work on top of existing implementations > others make available? Can you build an operating system from Scratch or > make microchips to run them on? > > If the goal is Computer USE literacy, I think python has more than enough if > you include the modules that make hard things easy. > > Just a thought. Admittedly it is hard these days to give a homework > assignment when the student can find a trivial way to get the result and not > do the hard work. > > > -----Original Message----- > From: Python-list On > Behalf Of Dennis Lee Bieber > Sent: Thursday, February 18, 2021 12:45 AM > To: python-list at python.org > Subject: Re: New Python implementation > > On Tue, 16 Feb 2021 11:03:33 +0000, Alan Gauld via Python-list > declaimed the following: > >> On 16/02/2021 07:35, Christian Gollwitzer wrote: >>> Am 16.02.21 um 06:36 schrieb dn: >>>> Pascal's value as a teaching language was that it embodied many >>>> aspects of structured programming, and like Python, consisted of a >>>> limited range of items which could be learned very quickly >>> >>> ROFL. Maybe that was true for Python when it was first invented. >>> Today it is not "a few simple things". Even just the core language, >> >> Python v1 was a good teaching language. v2 complicated it a bit but it >> was still usable. v3 is no longer a good teaching language (unless >> maybe you are teaching CompSci at university.) >> >> In fact in v3 things are so complex that I seriously considered >> dropping Python as the core language for my programming tutorial. >> Until I started looking for an alternative, and there really isn't >> anything much better. At least not that can also be used for real >> projects once you've learned it. > > Depending upon the course intentions, I'd say Python is useful for > teaching general programming and getting to usable real-world programs. > > For CompSci /theory/, OTOH, Python has too much built in, and would > get in the way of having someone implement things like linked-lists, deques, > hashed structures -- ie; the stuff that lies behind all those Python > built-ins. Pascal, Modula-2 (or is it up to 3 now), or one of the other > system programming languages: Edison from > https://www.amazon.com/Programming-personal-computer-Brinch-Hansen/dp/013730 > 2673 > Implement a hashed-head multiple-linked list using Kemeny&Kurtz > level BASIC! (My algorithms instructor allowed the class to use any language > on that he could read -- so FORTRAN, BASIC, Pascal, Sigma Meta-Symbol, > COBOL... No Snobol, LISP, or APL -- for that final project: a phone book > directory/look-up system). Interestingly, I've only seen a hashed-head > multiple-linked list structure used in one real world application: The > Commodore Amiga file system. -- To de-mung my e-mail address:- fsnospam$elliott$$ PGP Fingerprint: 1A96 3CF7 637F 896B C810 E199 7E5C A9E4 8E59 E248 From drsalists at gmail.com Fri Feb 19 01:31:27 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Thu, 18 Feb 2021 22:31:27 -0800 Subject: [Python-Dev] Re: Python 0.9.1 In-Reply-To: References: Message-ID: On Thu, Feb 18, 2021 at 9:39 PM David Mertz wrote: > As Skip pointed out to me privately, there are some minor limitations with > this version. E.g.: > > % python > >>> import glob > >>> import sys > >>> print 'hello' > hello > >>> print 2+2 > 4 > >>> print 2*2 > Unhandled exception: run-time error: integer overflow > Stack backtrace (innermost last): > File "", line 1 > Huh. I wonder what's different about my build: $ /usr/local/cpython-0.9/bin/python below cmd output started 2021 Thu Feb 18 10:24:00 PM PST >>> 2*2 4 >>> print 2*2 4 >>> You can download a script to build it and a bunch of other python versions at https://stromberg.dnsalias.org/~strombrg/cpythons/ It includes all the tarballs you should need, at least for Debian. I believe I used it on CentOS recently as well. I haven't tried it on Ubuntu in a while. It depends on https://stromberg.dnsalias.org/~strombrg/cobble.html - and I'd like to think that's its only external dependency. HTH From smitp2802 at gmail.com Fri Feb 19 01:27:19 2021 From: smitp2802 at gmail.com (Smit Patel) Date: Fri, 19 Feb 2021 11:57:19 +0530 Subject: Startup failure Message-ID: I recently downloaded python from your website and when I started using it, it worked correctly but when I installed the random2 module it showed startup failure and won't work again. So, I uninstalled it and downloaded it again but it is showing the same problem of startup failure. Let me know if there is a way to resolve the problem. Thank you From auriocus at gmx.de Fri Feb 19 02:08:33 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Fri, 19 Feb 2021 08:08:33 +0100 Subject: Python 0.9.1 In-Reply-To: References: Message-ID: Am 16.02.21 um 22:57 schrieb Skip Montanaro: > A note to webmaster at python.org from an astute user named Hiromi in > Japan* referred > us to Guido's shell archives for the 0.9.1 release from 1991. > I then pushed the result to a Github repo: > > https://github.com/smontanaro/python-0.9.1 > That's a nice find! Reading the README, it occured to me that it refers to the shell, awk and perl as contenders for Python[1], but not to Tcl. I would have thought that in 1991, Tcl was one of the obvious choices as an extension language. At that time, it had already progressed to version 6 [2] Was Guido not aware of Tcl, or did he not think that it is a contender in the same area? Christian [1] "Python, an extensible interpreted programming language [...] can be used instead of shell, Awk or Perl scripts, to write prototypes of real applications, or as an extension language of large systems, you name it." [2] https://wiki.tcl-lang.org/page/Tcl+chronology From alan.gauld at yahoo.co.uk Fri Feb 19 06:23:03 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 19 Feb 2021 11:23:03 +0000 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> Message-ID: On 19/02/2021 03:51, Dennis Lee Bieber wrote: > They chose Pascal as being more modern, and something taught in schools > (yeah, like TurboPascal is going to be a good introduction to writing > software for real-time ground control of satellites). Funnily enough it was. Or at least for real-time telecomms control. We wrote all our real-time stuff on VAX and later PC using Pascal from the mid 80s through to early 1990s when we switched to C++. But TurboPascal was not much like Pascal, it had all the theoretical bits by-passed or removed. I still use Pascal in the shape of Delphi for building windows GUI apps today... But Delphi bears even less resemblance to Wirth's Pascal, in fact its quite similar to Python in many ways. -- 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 From alan.gauld at yahoo.co.uk Fri Feb 19 06:25:01 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 19 Feb 2021 11:25:01 +0000 Subject: Startup failure In-Reply-To: References: Message-ID: On 19/02/2021 06:27, Smit Patel wrote: > I recently downloaded python from your website and when I started using it, > it worked correctly but when I installed the random2 module it showed > startup failure and won't work again. > So, I uninstalled it and downloaded it again but it is showing the same > problem of startup failure. Can you send us more details about what exactly happens. How are you running it? What OS? What error messages are you getting (in full please) -- 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 From dciprus at cisco.com Fri Feb 19 08:02:37 2021 From: dciprus at cisco.com (Dan Ciprus (dciprus)) Date: Fri, 19 Feb 2021 13:02:37 +0000 Subject: Startup failure In-Reply-To: References: Message-ID: It would be nice if you could provide a bit more details ... Exceptions/logs etc. ________________________________________ From: Python-list on behalf of Smit Patel Sent: Friday, February 19, 2021 1:27 AM To: python-list at python.org Subject: Startup failure I recently downloaded python from your website and when I started using it, it worked correctly but when I installed the random2 module it showed startup failure and won't work again. So, I uninstalled it and downloaded it again but it is showing the same problem of startup failure. Let me know if there is a way to resolve the problem. Thank you -- https://mail.python.org/mailman/listinfo/python-list From lukasz at langa.pl Fri Feb 19 11:33:25 2021 From: lukasz at langa.pl (=?utf-8?Q?=C5=81ukasz_Langa?=) Date: Fri, 19 Feb 2021 17:33:25 +0100 Subject: [RELEASE] Python 3.9.2 and 3.8.8 are now available Message-ID: <83AAC61C-9EBC-40DA-A07B-F7C5F6F307C3@langa.pl> Convinced of the wonders of free two-day deliveries, I?m pleased to present you Python 3.9.2 and 3.8.8. Get them from: https://www.python.org/downloads/release/python-392/ https://www.python.org/downloads/release/python-388/ Next up, the last full regular maintenance release of Python 3.8 is planned for May 3rd 2021, after which it will shift to source releases only for security bug fixes only. Maintenance releases for the 3.9 series will continue at regular bi-monthly intervals, with 3.9.3 planned for early May 2021. Why the expedited final release? This release, just as the candidate before it, contains two security fixes: bpo-42938 : Avoid static buffers when computing the repr of ctypes.c_double and ctypes.c_longdouble values. This issue was assigned CVE-2021-3177 . bpo-42967 : Fix web cache poisoning vulnerability by defaulting the query args separator to &, and allowing the user to choose a custom separator. This issue was assigned CVE-2021-23336 . Since the announcement of the release candidates for 3.9.2 on 3.8.8, we received a number of inquiries from end users urging us to expedite the final releases due to the security content, especially CVE-2021-3177 . This took us somewhat by surprise since we believed security content is cherry-picked by downstream distributors from source either way, and the RC releases provide installers for everybody else interested in upgrading in the meantime. It turns out that release candidates are mostly invisible to the community and in many cases cannot be used due to upgrade processes which users have in place. In turn, the other active release managers and I decided to stop providing release candidates for bugfix versions. Starting from now on after the initial 3.x.0 final release, all subsequent releases are going to be provided as is in bi-monthly intervals. The release calendar PEPs for 3.8 and 3.9 have been updated accordingly. On the severity of CVE-2021-3177 We recommend you upgrade your systems to Python 3.8.8 or 3.9.2. Our understanding is that while the CVE is listed as ?remote code execution?, practical exploits of this vulnerability as such are very unlikely due the following conditions needing to be met for successful RCE: pass an untrusted floating point number from a remote party to ctypes.c_double.from_param (note: Python floating point numbers were not affected); have that object be passed to repr() (for instance through logging); have that float point number be valid machine code; have the buffer overflow overwrite the stack at exactly the right place for the code to get executed. In fact, Red Hat?s evaluation of the vulnerability was consistent with ours. They write: ?the highest threat from this vulnerability is to system availability .? To be sure, denial of service through malicious input is also a serious issue. Thus, to help the community members for whom the release candidate was insufficient, we are releasing the final versions of 3.9.2 and 3.8.8 today. What?s new? The Python 3.9 series contains many new features and optimizations over 3.8. See the ?What?s New in Python 3.9 2 ? document for more information about features included in the 3.9 series. We also have a detailed change log for 3.9.2rc1 specifically. The final release only contains a single bugfix over the release candidate. Detailed information about all changes made in version 3.8.8rc1 specifically can be found in its respective changelog . The final version contains no changes over the release candidate. We hope you enjoy those new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. Your friendly release team, Ned Deily @nad Steve Dower @steve.dower ?ukasz Langa @ambv From avigross at verizon.net Fri Feb 19 11:49:25 2021 From: avigross at verizon.net (Avi Gross) Date: Fri, 19 Feb 2021 11:49:25 -0500 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> Message-ID: <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Some of us here go way back and have stories to tell of what we did even before Python existed. I won't rehash my history here now except to say I did use PASCAL in graduate school and my first job before switching to C which was less annoying to use. What I am interested in, in this forum, is how Python grew and specifically what motivated adding new features. I see it as a bit more like a Camel created when a committee got together and decided to create a horse and one of them wanted it to also do well in a desert and so on. For teaching purposes, it can be useful to have a minimalist design and a way to catch lots of errors such as by strong typing. Some of that may also be useful in the real world. But in re-teaching someone now in another language, I keep running into the fact that when I use newer and more powerful features they feel overwhelmed as they vaguely remember the built-in way and the new way uses a piping metaphor they are not familiar with. I have had others who started with the new ways and don't even want to know how an earlier version of the language did it. In the real world, having to read, let alone maintain, code that others have had a hand in shaping and reshaping can be hard work if each person did things their own way. We have discussed the many ways you can format text in python and if a program uses them all, here and there, ... But for an individual programmer, it is great to use whichever method feels best for you, and especially if you came to python from another language that method was borrowed from or vice versa. Being a rich language has pro's and cons. LISP only had cons. -----Original Message----- From: Python-list On Behalf Of Alan Gauld via Python-list Sent: Friday, February 19, 2021 6:23 AM To: python-list at python.org Subject: Re: New Python implementation On 19/02/2021 03:51, Dennis Lee Bieber wrote: > They chose Pascal as being more modern, and something taught in > schools (yeah, like TurboPascal is going to be a good introduction to > writing software for real-time ground control of satellites). Funnily enough it was. Or at least for real-time telecomms control. We wrote all our real-time stuff on VAX and later PC using Pascal from the mid 80s through to early 1990s when we switched to C++. But TurboPascal was not much like Pascal, it had all the theoretical bits by-passed or removed. I still use Pascal in the shape of Delphi for building windows GUI apps today... But Delphi bears even less resemblance to Wirth's Pascal, in fact its quite similar to Python in many ways. -- 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 From grant.b.edwards at gmail.com Fri Feb 19 10:15:12 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 19 Feb 2021 15:15:12 -0000 (UTC) Subject: New Python implementation References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> Message-ID: On 2021-02-19, Alan Gauld via Python-list wrote: > On 19/02/2021 03:51, Dennis Lee Bieber wrote: > >> They chose Pascal as being more modern, and something taught in >> schools (yeah, like TurboPascal is going to be a good introduction >> to writing software for real-time ground control of satellites). > > Funnily enough it was. Or at least for real-time telecomms control. > We wrote all our real-time stuff on VAX and later PC using Pascal > from the mid 80s through to early 1990s when we switched to C++. > But TurboPascal was not much like Pascal, it had all the > theoretical bits by-passed or removed. Back in the 80's we wrote real-time embedded software for cellular telephone radios in Pascal. We even wrote the OS kernel in Pascal. It worked great and was less error-prone than C. -- Grant From grant.b.edwards at gmail.com Fri Feb 19 12:21:36 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 19 Feb 2021 17:21:36 -0000 (UTC) Subject: New Python implementation References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Message-ID: On 2021-02-19, Avi Gross via Python-list wrote: > Some of us here go way back and have stories to tell of what we did even > before Python existed. I won't rehash my history here now except to say I > did use PASCAL in graduate school and my first job before switching to C > which was less annoying to use. ITYM Pascal. ;) -- Grant From mstemper at gmail.com Fri Feb 19 13:14:57 2021 From: mstemper at gmail.com (Michael F. Stemper) Date: Fri, 19 Feb 2021 12:14:57 -0600 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Message-ID: On 19/02/2021 10.49, Avi Gross wrote: > But for an individual programmer, it is great to use whichever method feels > best for you, and especially if you came to python from another language > that method was borrowed from or vice versa. Being a rich language has pro's > and cons. LISP only had cons. -- Michael F. Stemper If you take cranberries and stew them like applesauce they taste much more like prunes than rhubarb does. From bschollnick at schollnick.net Fri Feb 19 13:31:12 2021 From: bschollnick at schollnick.net (Benjamin Schollnick) Date: Fri, 19 Feb 2021 13:31:12 -0500 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Message-ID: >> that method was borrowed from or vice versa. Being a rich language has pro's >> and cons. LISP only had cons. Now, Now. That?s certainly not correct. LISP does have a few Pros. Namely Job security. You?ll have a hard time replacing a experienced and professional LISP programmer. - Benjamin From avigross at verizon.net Fri Feb 19 14:01:54 2021 From: avigross at verizon.net (Avi Gross) Date: Fri, 19 Feb 2021 14:01:54 -0500 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Message-ID: <066801d706f1$b0926c70$11b74550$@verizon.net> Benjamin, I wonder if you understood my intended meaning not about the plusses and minuses of using a language like LISP but that it is fundamentally build on using the CONS concept to make lists in a poetic way but has no PROSE. Not only does every language have what I meant by the usual meaning of pros and cons, but it depends on what other languages you are comparing it to, what kind of work you use the language for, is it for prototyping or final and efficient use, will someone else be extending or maintaining it, and which side of the bed you woke up on. I used to be a fan of brevity as in whatever make me type less. But over time, many functions you call now have so many arguments, that I am now a fan of specifying the names of each argument as in function_name(arg1=value1, arg3=value3, ...) because it makes it much clearer what you want and prevents a certain class of errors. Nonetheless, I despise very long variable names, even when the editor allows for name completion. I thus like to place many commands on multiple lines to be read somewhat vertically and short lines. Others prefer the opposite. If a language hinders this style of multi-line, it is a plus or minus depending. (cons "A" (cons "v" (cons "I" nil))) -----Original Message----- From: Python-list On Behalf Of Benjamin Schollnick Sent: Friday, February 19, 2021 1:31 PM To: Michael F. Stemper Cc: python-list at python.org Subject: Re: New Python implementation >> that method was borrowed from or vice versa. Being a rich language >> has pro's and cons. LISP only had cons. Now, Now. That?s certainly not correct. LISP does have a few Pros. Namely Job security. You?ll have a hard time replacing a experienced and professional LISP programmer. - Benjamin -- https://mail.python.org/mailman/listinfo/python-list From alan.gauld at yahoo.co.uk Fri Feb 19 15:00:58 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 19 Feb 2021 20:00:58 +0000 Subject: New Python implementation In-Reply-To: References: <82vr2gptod52qdnh6uj1gau3tbrcenim26@4ax.com> <04b001d7061b$26f541d0$74dfc570$@verizon.net> <03d401d706df$2e5c17e0$8b1447a0$@verizon.net> Message-ID: On 19/02/2021 18:14, Michael F. Stemper wrote: >> and cons. LISP only had cons. :-) LOL -- 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 From nospam at please.ty Sat Feb 20 06:13:30 2021 From: nospam at please.ty (jak) Date: Sat, 20 Feb 2021 12:13:30 +0100 Subject: issue with seaborn References: Message-ID: Il 20/02/2021 01:56, Dino ha scritto: > > trying to do some dayaviz with Italian Covid Open Data ( > https://github.com/italia/covid19-opendata-vaccini/ ) > > here's how I pull my data: > ____________________________ > import sys > import urllib.request > import pandas as pd > import ssl > ssl._create_default_https_context = ssl._create_unverified_context > > URL = > "https://github.com/italia/covid19-opendata-vaccini/blob/master/dati/somministrazioni-vaccini-latest.csv?raw=true" > > > with urllib.request.urlopen(URL) as url: > ??? df = pd.read_csv(url) > ____________________________ > > One of my diagrams came out screwed up today, and I am having a hard > time understanding what went wrong: > > https://imgur.com/a/XTd4akn > > Any ideas? > > Thanks I don't think this is the cause of your problem and in addition I don't know about pandas. In any case you send pandas some records that contain the date in string format and this gives the alphabetic continuity but if the data contained time holes, these would not be represented in your graph. Maybe you should add an intermediate step and convert strings dates to datetime format before you create the chart (but perhaps pandas takes care of this. I don't know this). cheers. From reto at labrat.space Sat Feb 20 08:07:08 2021 From: reto at labrat.space (Reto) Date: Sat, 20 Feb 2021 14:07:08 +0100 Subject: issue with seaborn In-Reply-To: References: Message-ID: <20210220130708.dheug3k5ntr77shq@feather.localdomain> Don't have the original email, hence replying this way. On Sat, Feb 20, 2021 at 12:13:30PM +0100, jak wrote: > Il 20/02/2021 01:56, Dino ha scritto: > > > > trying to do some dayaviz with Italian Covid Open Data ( > > https://github.com/italia/covid19-opendata-vaccini/ ) > > > > here's how I pull my data: > > ____________________________ > > import sys > > import urllib.request > > import pandas as pd > > import ssl > > ssl._create_default_https_context = ssl._create_unverified_context > > > > URL = "https://github.com/italia/covid19-opendata-vaccini/blob/master/dati/somministrazioni-vaccini-latest.csv?raw=true" > > > > > > with urllib.request.urlopen(URL) as url: > > ??? df = pd.read_csv(url) > > ____________________________ > > > > One of my diagrams came out screwed up today, and I am having a hard > > time understanding what went wrong: > > > > https://imgur.com/a/XTd4akn > > > > Any ideas? > > > > Thanks > > > I don't think this is the cause of your problem and in addition I don't > know about pandas. In any case you send pandas some records that contain > the date in string format and this gives the alphabetic continuity but > if the data contained time holes, these would not be represented in your > graph. Maybe you should add an intermediate step and convert strings > dates to datetime format before you create the chart (but perhaps pandas > takes care of this. I don't know this). Pretty much what he said... Parse the dates. Oh and you generally don't need the dance with urllib, pandas can do that for you. ``` data_url = r"https://github.com/italia/covid19-opendata-vaccini/blob/master/dati/somministrazioni-vaccini-latest.csv?raw=true" df = pd.read_csv(data_url, parse_dates=True, index_col="data_somministrazione") plt.figure(figsize=(15,10)) plt.xticks(rotation=70) sns.lineplot(x=df.index, y="prima_dose", data=df, hue="nome_area", ci=None) ``` Yields: https://labrat.space/irc/3b0be1f11e6c687b/download%20(1).png Cheers, Reto From jcasale at activenetwerx.com Sat Feb 20 09:36:11 2021 From: jcasale at activenetwerx.com (Joseph L. Casale) Date: Sat, 20 Feb 2021 14:36:11 +0000 Subject: Overriding property types on instances from a library Message-ID: I have some code that makes use of the typing module. This code creates several instances of objects it creates from a library that has some issues. For example, I have multiple list comps that iterate properties of those instance and the type checker fails with: Expected type 'collections.Iterable', got '() -> Any' instead How can I override the type with a hint on a property of those instances? Thanks, jlc From tmrsg11 at gmail.com Sat Feb 20 09:40:48 2021 From: tmrsg11 at gmail.com (C W) Date: Sat, 20 Feb 2021 09:40:48 -0500 Subject: Is there a way to subtract 3 from every digit of a number? Message-ID: Hello everyone, I'm curious if there is a way take number and back each digit by 3 ? 2342 becomes 9019 8475 becomes 5142 5873 becomes 2540 The tricky part is that 2 becomes 9, not -1. Here's my toy example and what I attempted, > test_series = pd.Series(list(['2342', '8475', '5873'])) > test_series 0 2342 1 8475 2 5873 dtype: object > test_series.str.split('') [, 2, 3, 4, 2, ] [, 8, 4, 7, 5, ] [, 5, 8, 7, 3, ] dtype: object What a good approach to this? Is there a method or function that should be handling this? Thanks so much! Mike From cousinstanley at gmail.com Sat Feb 20 09:41:40 2021 From: cousinstanley at gmail.com (Cousin Stanley) Date: Sat, 20 Feb 2021 07:41:40 -0700 Subject: issue with seaborn References: Message-ID: Dino wrote: > trying to do some dayaviz with Italian Covid Open Data ( > https://github.com/italia/covid19-opendata-vaccini/ ) > > here's how I pull my data: > ____________________________ > import sys > import urllib.request > import pandas as pd > import ssl > ssl._create_default_https_context = ssl._create_unverified_context > > URL = > "https://github.com/italia/covid19-opendata-vaccini/blob/master/dati/somministrazioni-vaccini-latest.csv?raw=true" > > with urllib.request.urlopen(URL) as url: > df = pd.read_csv(url) > ____________________________ > > One of my diagrams came out screwed up today, and I am having a hard > time understanding what went wrong: > > https://imgur.com/a/XTd4akn > > Any ideas? > I first downloaded a local copy of the .csv file using .... wget URL Then the python code below following the plot parameters shown in your imgur.com image which was executed in a jupyter notebook .... # it_covid.py ----------------------------------------------- import pandas as pd import seaborn as sns import numpy as np import matplotlib.pyplot as plt df = pd.read_csv( 'data/somministrazioni-vaccini-latest.csv' ) plt.figure( figsize = ( 20 , 10 ) ) plt.xticks( rotation = 70 ) sns.lineplot( x = "data_somministrazione" , y = "prima_dose" , data = df , hue = "nome_area" , ci = None ) plt.show() # ----------------------------------------------------------- The resulting plot doesn't seem to be cluttered as the one that you posted .... http://csphx.net/image/it_covid.png -- Stanley C. Kitching Human Being Phoenix, Arizona From 2QdxY4RzWzUUiLuE at potatochowder.com Sat Feb 20 09:59:08 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sat, 20 Feb 2021 08:59:08 -0600 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: On 2021-02-20 at 09:40:48 -0500, C W wrote: > Hello everyone, > > I'm curious if there is a way take number and back each digit by 3 ? > > 2342 becomes 9019 > 8475 becomes 5142 > 5873 becomes 2540 > > The tricky part is that 2 becomes 9, not -1. > > Here's my toy example and what I attempted, > > test_series = pd.Series(list(['2342', '8475', '5873'])) > > test_series > 0 2342 > 1 8475 > 2 5873 > dtype: object > > > test_series.str.split('') > [, 2, 3, 4, 2, ] > [, 8, 4, 7, 5, ] > [, 5, 8, 7, 3, ] > dtype: object > > What a good approach to this? Is there a method or function that should be > handling this? I'm assuming that this is homework or some other academic exercise, so I'm being deliberately vague on some of the details. That said: Break it down. (1) Write a function that takes a number and returns the result of subtracting three from it. This function should also handle the "special" cases of 0, 1, and 2. Look up the modulo operator for a better way than actually special-casing them. (2) Python has several ways of building a list by transforming the elements of a list one at a time and building a new list from the results. Consider a simple iterative approach, but also look up the builtin "map" function and "list comprehensions." One interesting decision is where to convert the individual digits of the original numbers from strings to integers. There are arguments for doing it in either of the parts I've just outlined, as well as making it a sort of Part 1a and applying both Part 1 and Part 1a to each digit. > Thanks so much! HTH, Dan From wolfgang at stoecher.com Sat Feb 20 02:25:29 2021 From: wolfgang at stoecher.com (Wolfgang =?utf-8?b?U3TDtmNoZXI=?=) Date: Sat, 20 Feb 2021 08:25:29 +0100 Subject: use set notation for repr of dict_keys? Message-ID: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> Having a dict like d = {'one': 1, 'two': 2} the representation of its keys repr(d.keys()) gives "dict_keys(['one', 'two'])" But since the keys are unique, wouldn't a representation using the set notation be more intuitive, i.e. what about changing the output of dict_keys.__repr__ to "dict_keys({'one', 'two'})" (using curly braces instead of brackets) Wolfgang From python at mrabarnett.plus.com Sat Feb 20 11:47:17 2021 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 20 Feb 2021 16:47:17 +0000 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: <65315b7f-b8eb-f6a0-2eaa-291741c7894d@mrabarnett.plus.com> On 2021-02-20 14:40, C W wrote: > Hello everyone, > > I'm curious if there is a way take number and back each digit by 3 ? > > 2342 becomes 9019 > 8475 becomes 5142 > 5873 becomes 2540 > > The tricky part is that 2 becomes 9, not -1. > > Here's my toy example and what I attempted, >> test_series = pd.Series(list(['2342', '8475', '5873'])) >> test_series > 0 2342 > 1 8475 > 2 5873 > dtype: object > >> test_series.str.split('') > [, 2, 3, 4, 2, ] > [, 8, 4, 7, 5, ] > [, 5, 8, 7, 3, ] > dtype: object > > What a good approach to this? Is there a method or function that should be > handling this? > Have a look at the 'translate' method of the 'str' class. From nospam at please.ty Sat Feb 20 12:02:31 2021 From: nospam at please.ty (jak) Date: Sat, 20 Feb 2021 18:02:31 +0100 Subject: Is there a way to subtract 3 from every digit of a number? References: Message-ID: Il 20/02/2021 15:40, C W ha scritto: > Hello everyone, > > I'm curious if there is a way take number and back each digit by 3 ? > > 2342 becomes 9019 > 8475 becomes 5142 > 5873 becomes 2540 > > The tricky part is that 2 becomes 9, not -1. > > Here's my toy example and what I attempted, >> test_series = pd.Series(list(['2342', '8475', '5873'])) >> test_series > 0 2342 > 1 8475 > 2 5873 > dtype: object > >> test_series.str.split('') > [, 2, 3, 4, 2, ] > [, 8, 4, 7, 5, ] > [, 5, 8, 7, 3, ] > dtype: object > > What a good approach to this? Is there a method or function that should be > handling this? > > Thanks so much! > > Mike > >>> num='0123456789' >>> n=8475 >>> sn = '' >>> for x in str(n): sn += num[(int(x) - 3) % 10] >>> int(sn) 5142 >>> From drsalists at gmail.com Sat Feb 20 13:20:42 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 20 Feb 2021 10:20:42 -0800 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: Convert to a str. Convert to a list of ints, one for each digit Add 7 mod 10, for each digit in the list Convert to a list of single-character str's Catenate those str's back together Convert to a single int On Sat, Feb 20, 2021 at 6:45 AM C W wrote: > Hello everyone, > > I'm curious if there is a way take number and back each digit by 3 ? > > 2342 becomes 9019 > 8475 becomes 5142 > 5873 becomes 2540 > > The tricky part is that 2 becomes 9, not -1. > > Here's my toy example and what I attempted, > > test_series = pd.Series(list(['2342', '8475', '5873'])) > > test_series > 0 2342 > 1 8475 > 2 5873 > dtype: object > > > test_series.str.split('') > [, 2, 3, 4, 2, ] > [, 8, 4, 7, 5, ] > [, 5, 8, 7, 3, ] > dtype: object > > What a good approach to this? Is there a method or function that should be > handling this? > > Thanks so much! > > Mike > -- > https://mail.python.org/mailman/listinfo/python-list > From grant.b.edwards at gmail.com Sat Feb 20 12:31:09 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sat, 20 Feb 2021 17:31:09 -0000 (UTC) Subject: Is there a way to subtract 3 from every digit of a number? References: <65315b7f-b8eb-f6a0-2eaa-291741c7894d@mrabarnett.plus.com> Message-ID: On 2021-02-20, MRAB wrote: > Have a look at the 'translate' method of the 'str' class. That's very clever, but being too clever on homework assignemnts doesn't always get a good grade. If they've just studied iteration, the modulus operator, and int/str conversions, then I'd avise using the "dumb" method. -- Grant From tjreedy at udel.edu Sat Feb 20 12:59:00 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 20 Feb 2021 12:59:00 -0500 Subject: use set notation for repr of dict_keys? In-Reply-To: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> Message-ID: On 2/20/2021 2:25 AM, Wolfgang St?cher wrote: > Having a dict like > ? d = {'one': 1, 'two': 2} > the representation of its keys > ? repr(d.keys()) > gives > ? "dict_keys(['one', 'two'])" > > But since the keys are unique, wouldn't a representation using the set > notation > be more intuitive, i.e. what about changing the output of > dict_keys.__repr__ to > ????"dict_keys({'one', 'two'})" > (using curly braces instead of brackets) From 3.0 to 3.7?, when dict keys were unordered, that might have made sense. But now that dict keys are insertion ordered, I think the list brackets suggesting a significant key order is better. There is also the issue that representation changes can break code and therefore need substantial reason. -- Terry Jan Reedy From grant.b.edwards at gmail.com Sat Feb 20 13:42:27 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sat, 20 Feb 2021 18:42:27 -0000 (UTC) Subject: Is there a way to subtract 3 from every digit of a number? References: Message-ID: On 2021-02-20, Dan Stromberg wrote: > Convert to a str. > Convert to a list of ints, one for each digit > Add 7 mod 10, for each digit in the list I'd probably subtract 3 (mod 10), so as to more obviously match the stated requirement. > Convert to a list of single-character str's > Catenate those str's back together > Convert to a single int From tjreedy at udel.edu Sat Feb 20 13:51:56 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 20 Feb 2021 13:51:56 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: On 2/20/2021 12:02 PM, jak wrote: > Il 20/02/2021 15:40, C W ha scritto: >> Hello everyone, >> >> I'm curious if there is a way take number and back each digit by 3 ? >> >> 2342 becomes 9019 >> 8475 becomes 5142 >> 5873 becomes 2540 >> >> The tricky part is that 2 becomes 9, not -1. >> >> Here's my toy example and what I attempted, >>> test_series = pd.Series(list(['2342', '8475', '5873'])) >>> test_series >> 0??? 2342 >> 1??? 8475 >> 2??? 5873 >> dtype: object >> >>> test_series.str.split('') >> [, 2, 3, 4, 2, ] >> [, 8, 4, 7, 5, ] >> [, 5, 8, 7, 3, ] >> dtype: object >> >> What a good approach to this? Is there a method or function that >> should be >> handling this? MRAB gave the proper answer -- str.translate (and str.maketrans. > >>> num='0123456789' > >>> n=8475 > >>> sn = '' > >>> for x in str(n): > ???? sn += num[(int(x) - 3) % 10] > >>> int(sn) > 5142 This works, but suggesting to beginners that they build strings with += is an O(n*n) trap. Try it with a string of millions of digits. Much better to use str.join ''.join(num[(int(c)-3) % 10] for c in '9876543210') #'6543210987' Even better, improve your string lookup idea to avoid the arithmetic. lookup1 = '7890123456' ''.join(lookup1[int(c)] for c in '9876543210') #'6543210987' To avoid the int call, make a lookup dictionary lookup2 = {a:b for a, b in zip('0123456789', '7890123456')} ''.join(lookup2[c] for c in '9876543210') #'6543210987' To run faster, use the str methods maketrans and translate to do the same thing. lookup3 = str.maketrans('0123456789', '7890123456') '9876543210'.translate(lookup3) #'6543210987' Note that "built-in function" str.maketrans is in effect a static method of the str class and is not an instance method. '0123456789'.maketrans('7890123456') does not work. The reason is that the first argument can be a dict instead of a string. Indeed, the dict could be the char-char mapping above created with the dict comprehension. Also, the resulting dict maps unicode ordinals to unicode ordinals, rather than chars to chars, because at the C level, a string *is* a sequence of unsigned ints with a PyObject wrapper. >>> lookup3 {48: 55, 49: 56, 50: 57, 51: 48, 52: 49, 53: 50, 54: 51, 55: 52, 56: 53, 57: 54} In Python, this is {ord(a):ord(b) for a, b in zip('0123456789', '7890123456')} -- Terry Jan Reedy From PythonList at DancesWithMice.info Sat Feb 20 15:00:48 2021 From: PythonList at DancesWithMice.info (dn) Date: Sun, 21 Feb 2021 09:00:48 +1300 Subject: use set notation for repr of dict_keys? In-Reply-To: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> Message-ID: <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> On 20/02/2021 20.25, Wolfgang St?cher wrote: > Having a dict like > ? d = {'one': 1, 'two': 2} > the representation of its keys > ? repr(d.keys()) > gives > ? "dict_keys(['one', 'two'])" > > But since the keys are unique, wouldn't a representation using the set > notation > be more intuitive, i.e. what about changing the output of > dict_keys.__repr__ to > ????"dict_keys({'one', 'two'})" > (using curly braces instead of brackets) When considering the data-returned, the logic of formatting as a set makes sense. So, why did the Python-gods decide otherwise? Let's start by asking what it actually is: >>> d = {'one': 1, 'two': 2} >>> repr(d.keys()) "dict_keys(['one', 'two'])" >>> k = d.keys() >>> type( k ) So, the output is not a set (as you say) but nor (as apparently-indicated by the square-brackets) is it actually a list! Not much help there, then. So, let's use help() to see if that helps, hah! (long listing, so not reproduced here). No joy there either. Is it actually one of our 'standard' collections at all? >>> k is dict False >>> k is list False >>> k is set False >>> k is tuple False OK, that makes reasonable sense. Perhaps dict_keys are a sub-class then? >>> isinstance( k, dict ) False >>> isinstance( k, list ) False >>> isinstance( k, set ) False >>> isinstance( k, tuple ) False Still going 'nowhere' fast! It is (apparently) reported as a list, and we'd like to think of it as a set. So, compare help() output with the attributes of list and set (and/or other collections). There are considerable differences (again, not reproduced here due to length). However, still not revealing any answers! If we de-construct the data contained in a dictionary, then as well as the keys, we should consider the values: >>> d {'one': 1, 'two': 2} >>> k = d.keys() >>> k dict_keys(['one', 'two']) >>> v = d.values() >>> v dict_values([1, 2]) Hah, they are (apparently) considered a list as well, but have another distinct type/are another custom-object. Still not making progress though! We've looked at the data/the output and found nothing much! Now, let's totally invert our view of the matter: Instead of deconstructing the original dictionary, consider the purpose of repr()? <<>> #repr Thus, we should be able to take the output of repr() and re-create the original object. Because a dictionary consists of key-value pairs, we will need both 'sets' of components: >>> new_d = dict( zip( k, v ) ) >>> new_d {'one': 1, 'two': 2} Ahah! Now, we realise that whereas a list-like #list data structure maintains the sequence of its elements, a set #set is not required to do so. Thus, if "k" were a set, what is produced on your machine may be different to what happens on mine/no guarantees: Possibly @Wolfgang's machine = >>> k { 'one', 'two' } Possibly @dn's machine = >>> k { 'two', 'one' } Thus no guarantee that when we try to re-combine keys and values they would correspond correctly! - and if we applied the same to data - even worse: combinatorial issue! Web.Refs: #repr: https://docs.python.org/3/reference/datamodel.html#basic-customization #list: and #set: https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy -- Regards, =dn From avigross at verizon.net Sat Feb 20 17:13:21 2021 From: avigross at verizon.net (Avi Gross) Date: Sat, 20 Feb 2021 17:13:21 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <65315b7f-b8eb-f6a0-2eaa-291741c7894d@mrabarnett.plus.com> Message-ID: <1afc01d707d5$99938790$ccba96b0$@verizon.net> Wouldn't it be nice, Grant, if Homework was assigned with statements like: "Using only the features of the language covered up to chapter 3, meaning individual variables and lists of them and simple loops and only using the arithmetic built-in variable of +, -, % ... Solve this problem ...." But there is an actual silly model and application to this homework assignment. Consider the kind of lock shown in the video (or skip the video) that has three or more wheels of sorts containing digits 0-9 and you rotate each wheel to a setting read down or across like 359. https://www.youtube.com/watch?v=BMeqkUiui20&feature=emb_logo If you are lazy, you can put the lock on your locker and move each wheel the same number of units in one direction. It is now securely locked and might show 682 or 026 and if nobody touches it and perturbs the setting, you can come back and perturb it back three units the other way (or continue seven more) and open it. See? A Very practical (albeit impractical) example of how this might be fractionally useful! I wrote a solution to the problem the student asked for that I chose not to share here that is one line of code including an embedded list comprehension to do the loop. If a student of mine in a beginning class offered me that solution, I would be fairly certain it was NOT their work, though, nor what I wanted them to do. Now the translate method, albeit elegant, is again not likely to be the one wanted as they probably have no idea that functionality exists. Heck, in some languages, they may not yet know looping constructs exist and be asked to use something like a GOTO! LOL! And, somewhere out there is something that implements the commonly (at least in the past) rot13 semi-cryptography of rotating the alphabet for fun and profit. You probably can load such a module and find a function that can rotate a numeric string by 3 or -3 and use that for a trivial solution. None of the above should be considered as having done the darn assignment as requested. However, if a student gave me a decent solution and ADDED that some search and research suggested other advanced methods they might use on the job later, sure, maybe they get extra credit. -----Original Message----- From: Python-list On Behalf Of Grant Edwards Sent: Saturday, February 20, 2021 12:31 PM To: python-list at python.org Subject: Re: Is there a way to subtract 3 from every digit of a number? On 2021-02-20, MRAB wrote: > Have a look at the 'translate' method of the 'str' class. That's very clever, but being too clever on homework assignemnts doesn't always get a good grade. If they've just studied iteration, the modulus operator, and int/str conversions, then I'd avise using the "dumb" method. -- Grant -- https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Sat Feb 20 17:51:32 2021 From: PythonList at DancesWithMice.info (dn) Date: Sun, 21 Feb 2021 11:51:32 +1300 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: <62f13df2-bca6-9e74-87b5-20e420df7388@DancesWithMice.info> On 21/02/2021 06.02, jak wrote: > Il 20/02/2021 15:40, C W ha scritto: >> Hello everyone, >> >> I'm curious if there is a way take number and back each digit by 3 ? >> >> 2342 becomes 9019 >> 8475 becomes 5142 >> 5873 becomes 2540 >> >> The tricky part is that 2 becomes 9, not -1. >> >> Here's my toy example and what I attempted, >>> test_series = pd.Series(list(['2342', '8475', '5873'])) >>> test_series >> 0??? 2342 >> 1??? 8475 >> 2??? 5873 >> dtype: object >> >>> test_series.str.split('') >> [, 2, 3, 4, 2, ] >> [, 8, 4, 7, 5, ] >> [, 5, 8, 7, 3, ] >> dtype: object >> >> What a good approach to this? Is there a method or function that >> should be >> handling this? >> >> Thanks so much! >> >> Mike >> > >>>> num='0123456789' >>>> n=8475 >>>> sn = '' >>>> for x in str(n): > ????sn += num[(int(x) - 3) % 10] > > ???? >>>> int(sn) > 5142 >>>> This code doesn't *look* correct (in the original post, via email reflector) because the loop is not indented Per previous respondents identifying it as likely to be an 'homework assignment', does it help the student if you/me/we "give" the answer? How has the student proven that (s)he has learned the material? (apologies for criticism: I readily assume your motivation was to be helpful) The problem is a Caesar Cipher - disguised, because most examples/usage of such is for alphanumeric messages. This topic is often used for ComSc examples to demonstrate modulo arithmetic and/or circular data structures, eg a bounded-queue (per other's responses). -- Regards, =dn From ming at pgp.cool Sat Feb 20 22:12:24 2021 From: ming at pgp.cool (Ming) Date: Sun, 21 Feb 2021 11:12:24 +0800 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: <20210221031220.GA15@pgp.cool> On Sat, Feb 20, 2021 at 09:40:48AM -0500, C W wrote: > Hello everyone, > > I'm curious if there is a way take number and back each digit by 3 ? > > 2342 becomes 9019 > 8475 becomes 5142 > 5873 becomes 2540 > > The tricky part is that 2 becomes 9, not -1. > [...] I just wrote a very short code can fulfill your needs: a = 2342 b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) It does the following things: 1. Convert a number into a string, and then convert this string into a list of single characters. 2. Write a lamdba expression to apply your conversion rules to a single-character type number (just subtract 3 and then modulo 10). 3. Apply the lambda expression to the above string list through map. 4. Finally join the modified list into a string and convert it into an integer. -- OpenPGP fingerprint: 3C47 5977 4819 267E DD64 C7E4 6332 5675 A739 C74E -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From drsalists at gmail.com Sat Feb 20 23:49:15 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 20 Feb 2021 20:49:15 -0800 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: <20210221031220.GA15@pgp.cool> References: <20210221031220.GA15@pgp.cool> Message-ID: On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: > I just wrote a very short code can fulfill your needs: > > a = 2342 > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) > I tend to favor plenty of temporary variables with descriptive names, but this is indeed short. Apart from that, you may find that using a generator expression is shorter and clearer than map+lambda. It should allow to additionally eliminate the list conversion. So in the terse form you've got there, it'd be more like: b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) But in real life, I'd try to use descriptive variable names for some of the subexpressions in that. This makes reading and debugging simpler, which is important because the maintenance phase of software is almost always much longer and costly than the development phase. And although you could do a generator expression for each of the different parts of (int(x) - 3) % 10, I kinda like having a named function for just that piece. So maybe: def rot_3(character): """Convert to int, subtract 3 and mod 10.""" digit = int(character) assert 0 <= digit <= 9 return (digit - 3) % 10 def descriptive_minus_three_caesar(input_number): """Convert to a -3 caesar cypher on an integer.""" string_number = str(input_number) rotated_digits = (rot_3(character) for character in string_number) output_string = ''.join(str(digit) for digit in rotated_digits) output_number = int(output_string) return output_number From rosuav at gmail.com Sat Feb 20 23:57:59 2021 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 21 Feb 2021 15:57:59 +1100 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: On Sun, Feb 21, 2021 at 3:50 PM Dan Stromberg wrote: > > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: > > > I just wrote a very short code can fulfill your needs: > > > > a = 2342 > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) > > > I tend to favor plenty of temporary variables with descriptive names, but > this is indeed short. > > Apart from that, you may find that using a generator expression is shorter > and clearer than map+lambda. It should allow to additionally eliminate the > list conversion. For what it's worth, map doesn't require list conversion either - it's perfectly happy (as are most things in Python) to iterate over a string. ChrisA From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Feb 21 00:05:29 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sat, 20 Feb 2021 23:05:29 -0600 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: On 2021-02-20 at 20:49:15 -0800, Dan Stromberg wrote: > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: > > > I just wrote a very short code can fulfill your needs: > > > > a = 2342 > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) > > > I tend to favor plenty of temporary variables with descriptive names, but > this is indeed short. > > Apart from that, you may find that using a generator expression is shorter > and clearer than map+lambda. It should allow to additionally eliminate the > list conversion. > > So in the terse form you've got there, it'd be more like: > b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) > > But in real life, I'd try to use descriptive variable names for some of the > subexpressions in that. This makes reading and debugging simpler, which is > important because the maintenance phase of software is almost always much > longer and costly than the development phase. And although you could do a > generator expression for each of the different parts of (int(x) - 3) % 10, > I kinda like having a named function for just that piece. > > So maybe: > def rot_3(character): > """Convert to int, subtract 3 and mod 10.""" > digit = int(character) > assert 0 <= digit <= 9 > return (digit - 3) % 10 > > > def descriptive_minus_three_caesar(input_number): > """Convert to a -3 caesar cypher on an integer.""" > string_number = str(input_number) > rotated_digits = (rot_3(character) for character in string_number) > output_string = ''.join(str(digit) for digit in rotated_digits) > output_number = int(output_string) > return output_number >>> descriptive_minus_three_caesar('38') 5 The problem is underspecified, and the examples are lacking, but based on the phrase "each digit" and the examples that contain a 3, I'd prefer to see "38" become "05." From tmrsg11 at gmail.com Sun Feb 21 09:12:33 2021 From: tmrsg11 at gmail.com (C W) Date: Sun, 21 Feb 2021 09:12:33 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: Thanks so much everyone, I appreciate it! Ming, your solution is awesome. More importantly, very clear explanations on how and why. So, I appreciate that. Thanks again, cheers! Mike On Sun, Feb 21, 2021 at 12:08 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > On 2021-02-20 at 20:49:15 -0800, > Dan Stromberg wrote: > > > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: > > > > > I just wrote a very short code can fulfill your needs: > > > > > > a = 2342 > > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) > > > > > I tend to favor plenty of temporary variables with descriptive names, but > > this is indeed short. > > > > Apart from that, you may find that using a generator expression is > shorter > > and clearer than map+lambda. It should allow to additionally eliminate > the > > list conversion. > > > > So in the terse form you've got there, it'd be more like: > > b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) > > > > But in real life, I'd try to use descriptive variable names for some of > the > > subexpressions in that. This makes reading and debugging simpler, which > is > > important because the maintenance phase of software is almost always much > > longer and costly than the development phase. And although you could do > a > > generator expression for each of the different parts of (int(x) - 3) % > 10, > > I kinda like having a named function for just that piece. > > > > So maybe: > > def rot_3(character): > > """Convert to int, subtract 3 and mod 10.""" > > digit = int(character) > > assert 0 <= digit <= 9 > > return (digit - 3) % 10 > > > > > > def descriptive_minus_three_caesar(input_number): > > """Convert to a -3 caesar cypher on an integer.""" > > string_number = str(input_number) > > rotated_digits = (rot_3(character) for character in string_number) > > output_string = ''.join(str(digit) for digit in rotated_digits) > > output_number = int(output_string) > > return output_number > > >>> descriptive_minus_three_caesar('38') > 5 > > The problem is underspecified, and the examples are lacking, but based > on the phrase "each digit" and the examples that contain a 3, I'd prefer > to see "38" become "05." > -- > https://mail.python.org/mailman/listinfo/python-list > From tmrsg11 at gmail.com Sun Feb 21 09:21:28 2021 From: tmrsg11 at gmail.com (C W) Date: Sun, 21 Feb 2021 09:21:28 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: I do want to follow up, if I may. In Ming's example, a = 2342 b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) What's the best approach to apply to a dataframe column, rather than just one value? Here's my attempt using df[col_1''].apply(), df['col_1'].apply(lambda:a int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a)))))) Thanks! On Sun, Feb 21, 2021 at 9:12 AM C W wrote: > Thanks so much everyone, I appreciate it! > > Ming, your solution is awesome. More importantly, very clear explanations > on how and why. So, I appreciate that. > > Thanks again, cheers! > > Mike > > On Sun, Feb 21, 2021 at 12:08 AM <2QdxY4RzWzUUiLuE at potatochowder.com> > wrote: > >> On 2021-02-20 at 20:49:15 -0800, >> Dan Stromberg wrote: >> >> > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: >> > >> > > I just wrote a very short code can fulfill your needs: >> > > >> > > a = 2342 >> > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) >> > > >> > I tend to favor plenty of temporary variables with descriptive names, >> but >> > this is indeed short. >> > >> > Apart from that, you may find that using a generator expression is >> shorter >> > and clearer than map+lambda. It should allow to additionally eliminate >> the >> > list conversion. >> > >> > So in the terse form you've got there, it'd be more like: >> > b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) >> > >> > But in real life, I'd try to use descriptive variable names for some of >> the >> > subexpressions in that. This makes reading and debugging simpler, >> which is >> > important because the maintenance phase of software is almost always >> much >> > longer and costly than the development phase. And although you could >> do a >> > generator expression for each of the different parts of (int(x) - 3) % >> 10, >> > I kinda like having a named function for just that piece. >> > >> > So maybe: >> > def rot_3(character): >> > """Convert to int, subtract 3 and mod 10.""" >> > digit = int(character) >> > assert 0 <= digit <= 9 >> > return (digit - 3) % 10 >> > >> > >> > def descriptive_minus_three_caesar(input_number): >> > """Convert to a -3 caesar cypher on an integer.""" >> > string_number = str(input_number) >> > rotated_digits = (rot_3(character) for character in string_number) >> > output_string = ''.join(str(digit) for digit in rotated_digits) >> > output_number = int(output_string) >> > return output_number >> >> >>> descriptive_minus_three_caesar('38') >> 5 >> >> The problem is underspecified, and the examples are lacking, but based >> on the phrase "each digit" and the examples that contain a 3, I'd prefer >> to see "38" become "05." >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From tmrsg11 at gmail.com Sun Feb 21 09:28:39 2021 From: tmrsg11 at gmail.com (C W) Date: Sun, 21 Feb 2021 09:28:39 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: I got it to work! I defined a separate function, and put it into df['col_1'].apply(). Not the most elegant, but it worked. I'm also curious how people on this mailing list would do it. Cheers! On Sun, Feb 21, 2021 at 9:21 AM C W wrote: > I do want to follow up, if I may. In Ming's example, > > a = 2342 > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) > > What's the best approach to apply to a dataframe column, rather than just > one value? Here's my attempt using df[col_1''].apply(), > df['col_1'].apply(lambda:a int("".join(map(lambda x: str((int(x)-3)%10) > ,list(str(a)))))) > > Thanks! > > On Sun, Feb 21, 2021 at 9:12 AM C W wrote: > >> Thanks so much everyone, I appreciate it! >> >> Ming, your solution is awesome. More importantly, very clear explanations >> on how and why. So, I appreciate that. >> >> Thanks again, cheers! >> >> Mike >> >> On Sun, Feb 21, 2021 at 12:08 AM <2QdxY4RzWzUUiLuE at potatochowder.com> >> wrote: >> >>> On 2021-02-20 at 20:49:15 -0800, >>> Dan Stromberg wrote: >>> >>> > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: >>> > >>> > > I just wrote a very short code can fulfill your needs: >>> > > >>> > > a = 2342 >>> > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) >>> > > >>> > I tend to favor plenty of temporary variables with descriptive names, >>> but >>> > this is indeed short. >>> > >>> > Apart from that, you may find that using a generator expression is >>> shorter >>> > and clearer than map+lambda. It should allow to additionally >>> eliminate the >>> > list conversion. >>> > >>> > So in the terse form you've got there, it'd be more like: >>> > b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) >>> > >>> > But in real life, I'd try to use descriptive variable names for some >>> of the >>> > subexpressions in that. This makes reading and debugging simpler, >>> which is >>> > important because the maintenance phase of software is almost always >>> much >>> > longer and costly than the development phase. And although you could >>> do a >>> > generator expression for each of the different parts of (int(x) - 3) % >>> 10, >>> > I kinda like having a named function for just that piece. >>> > >>> > So maybe: >>> > def rot_3(character): >>> > """Convert to int, subtract 3 and mod 10.""" >>> > digit = int(character) >>> > assert 0 <= digit <= 9 >>> > return (digit - 3) % 10 >>> > >>> > >>> > def descriptive_minus_three_caesar(input_number): >>> > """Convert to a -3 caesar cypher on an integer.""" >>> > string_number = str(input_number) >>> > rotated_digits = (rot_3(character) for character in >>> string_number) >>> > output_string = ''.join(str(digit) for digit in rotated_digits) >>> > output_number = int(output_string) >>> > return output_number >>> >>> >>> descriptive_minus_three_caesar('38') >>> 5 >>> >>> The problem is underspecified, and the examples are lacking, but based >>> on the phrase "each digit" and the examples that contain a 3, I'd prefer >>> to see "38" become "05." >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >>> >> From avigross at verizon.net Sun Feb 21 09:38:15 2021 From: avigross at verizon.net (Avi Gross) Date: Sun, 21 Feb 2021 09:38:15 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: <016801d7085f$30b93b40$922bb1c0$@verizon.net> Mike, You moved the goalpost. Some of us here have been speculating you were asking what we call a homework question here. The problem seemed to be the kind asked for that can be done using fairly simple commands in python combined together. Of course, some of the answers posted used ideas usually not taught early and that had to be explained. The one you liked uses anonymous functions handed to a function that repeatedly applies it to a list of items created from taking a number apart after it is I string form and then recombines it. My method is straightforward enough and similar to another posting because it just follows the logic. >>> start = 1234567890987654321 >>> int(''.join([str((int(dig)+3) % 10) for dig in str(start)])) 4567890123210987654 But you just moved the goalpost by talking about using a data.frame as that (and I assume numpy and pandas) are not very basic Python. So think about it. You have a column in a data.frame. How do you apply other transformations to it? In one sense, a column in a data.frame is just one of many kinds of ordered collects in Python, not much different than a list. How do you apply a set of instructions to take in one collection and replace it with another computed item by item? Since you know about making your own functions, you know that a clean way of doing many things is to encapsulate the gory details in a function and call it the usual way to apply the transformation. Sure, you could use another anonymous function and make it messier to read. And, if you know of the capabilities of a data.frame structure, you use the method that it already offers and hand it your function in one of multiple ways. Can you satisfy our curiosity about what this functionality is for, now that it seems you may have a bigger purpose? Or, is it HW for a more advanced class? -----Original Message----- From: Python-list On Behalf Of C W Sent: Sunday, February 21, 2021 9:21 AM To: Python Subject: Re: Is there a way to subtract 3 from every digit of a number? I do want to follow up, if I may. In Ming's example, a = 2342 b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) What's the best approach to apply to a dataframe column, rather than just one value? Here's my attempt using df[col_1''].apply(), df['col_1'].apply(lambda:a int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a)))))) Thanks! On Sun, Feb 21, 2021 at 9:12 AM C W wrote: > Thanks so much everyone, I appreciate it! > > Ming, your solution is awesome. More importantly, very clear > explanations on how and why. So, I appreciate that. > > Thanks again, cheers! > > Mike > > On Sun, Feb 21, 2021 at 12:08 AM <2QdxY4RzWzUUiLuE at potatochowder.com> > wrote: > >> On 2021-02-20 at 20:49:15 -0800, >> Dan Stromberg wrote: >> >> > On Sat, Feb 20, 2021 at 7:13 PM Ming wrote: >> > >> > > I just wrote a very short code can fulfill your needs: >> > > >> > > a = 2342 >> > > b = int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a))))) >> > > >> > I tend to favor plenty of temporary variables with descriptive >> > names, >> but >> > this is indeed short. >> > >> > Apart from that, you may find that using a generator expression is >> shorter >> > and clearer than map+lambda. It should allow to additionally >> > eliminate >> the >> > list conversion. >> > >> > So in the terse form you've got there, it'd be more like: >> > b = int(''.join(str((int(x) - 3) % 10) for x in str(a)) >> > >> > But in real life, I'd try to use descriptive variable names for >> > some of >> the >> > subexpressions in that. This makes reading and debugging simpler, >> which is >> > important because the maintenance phase of software is almost >> > always >> much >> > longer and costly than the development phase. And although you >> > could >> do a >> > generator expression for each of the different parts of (int(x) - >> > 3) % >> 10, >> > I kinda like having a named function for just that piece. >> > >> > So maybe: >> > def rot_3(character): >> > """Convert to int, subtract 3 and mod 10.""" >> > digit = int(character) >> > assert 0 <= digit <= 9 >> > return (digit - 3) % 10 >> > >> > >> > def descriptive_minus_three_caesar(input_number): >> > """Convert to a -3 caesar cypher on an integer.""" >> > string_number = str(input_number) >> > rotated_digits = (rot_3(character) for character in string_number) >> > output_string = ''.join(str(digit) for digit in rotated_digits) >> > output_number = int(output_string) >> > return output_number >> >> >>> descriptive_minus_three_caesar('38') >> 5 >> >> The problem is underspecified, and the examples are lacking, but >> based on the phrase "each digit" and the examples that contain a 3, >> I'd prefer to see "38" become "05." >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Sun Feb 21 09:41:00 2021 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 22 Feb 2021 01:41:00 +1100 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: <016801d7085f$30b93b40$922bb1c0$@verizon.net> References: <20210221031220.GA15@pgp.cool> <016801d7085f$30b93b40$922bb1c0$@verizon.net> Message-ID: On Mon, Feb 22, 2021 at 1:39 AM Avi Gross via Python-list wrote: > But you just moved the goalpost by talking about using a data.frame as that > (and I assume numpy and pandas) are not very basic Python. Given that the original post mentioned a pd.Series, I don't know how far the goalposts actually moved :) ChrisA From tmrsg11 at gmail.com Sun Feb 21 09:47:44 2021 From: tmrsg11 at gmail.com (C W) Date: Sun, 21 Feb 2021 09:47:44 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> <016801d7085f$30b93b40$922bb1c0$@verizon.net> Message-ID: Hey Avi, I am a long time R user now using Python. So, this is my attempt to master the language. The problem for me is that I often have an idea about how things are done in R, but not sure to what functions are available in Python. I hope that clears up some confusion. Cheer! On Sun, Feb 21, 2021 at 9:44 AM Chris Angelico wrote: > On Mon, Feb 22, 2021 at 1:39 AM Avi Gross via Python-list > wrote: > > But you just moved the goalpost by talking about using a data.frame as > that > > (and I assume numpy and pandas) are not very basic Python. > > Given that the original post mentioned a pd.Series, I don't know how > far the goalposts actually moved :) > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From avigross at verizon.net Sun Feb 21 09:49:55 2021 From: avigross at verizon.net (Avi Gross) Date: Sun, 21 Feb 2021 09:49:55 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> <016801d7085f$30b93b40$922bb1c0$@verizon.net> Message-ID: <01a401d70860$d1dddde0$759999a0$@verizon.net> Chris, I admit I must have missed that. I was trying to understand the overall request. I do most of my data.frame work in another language ? I will say that there are many problems that live at various levels. The original request could have been about how o covert a 1-digit integer which would have been simple enough. Instead it asked for any integer to be viewed in some way as a collection of single digits and manipulated individually. What we have now in effect with a column of a data.frame is a collection of those collections. If next he askes to convert all columns of the data.frame, we get to a collection of collections of collections ? But realistically, some of those collections already have methods in place so no need for something like writing code nesting loops within loops within loops. I deleted all the messages and I am asking myself if anyone else provided advice or actual code that zoomed in one how to do it to a series. You clearly saw it. -----Original Message----- From: Python-list On Behalf Of Chris Angelico Sent: Sunday, February 21, 2021 9:41 AM Cc: Python Subject: Re: Is there a way to subtract 3 from every digit of a number? On Mon, Feb 22, 2021 at 1:39 AM Avi Gross via Python-list wrote: > But you just moved the goalpost by talking about using a data.frame as > that (and I assume numpy and pandas) are not very basic Python. Given that the original post mentioned a pd.Series, I don't know how far the goalposts actually moved :) ChrisA -- https://mail.python.org/mailman/listinfo/python-list From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Feb 21 10:20:35 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 21 Feb 2021 09:20:35 -0600 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> Message-ID: On 2021-02-21 at 09:28:39 -0500, C W wrote: > I got it to work! I defined a separate function, and put it into > df['col_1'].apply(). > > Not the most elegant, but it worked. I'm also curious how people on this > mailing list would do it. I don't know anything about pandas, but for one string of digits (there's no clear requirements for how to handle leading zeros in the input or the output), I'd end up with something like this: OFF_BY_3_MAPPING = dict(zip('0123456789', '7890123456')) def off_by_3(digits): return ''.join(OFF_BY_3_MAPPING[c] for c in digits) From avigross at verizon.net Sun Feb 21 10:34:32 2021 From: avigross at verizon.net (Avi Gross) Date: Sun, 21 Feb 2021 10:34:32 -0500 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: <20210221031220.GA15@pgp.cool> <016801d7085f$30b93b40$922bb1c0$@verizon.net> Message-ID: <023b01d70867$0d71e260$2855a720$@verizon.net> Ah, that is an interesting, Mike, but not an informative answer. My question is where the specific problem came from. Yes, someone used to R and coming to Python might work at adjusting to what is different and how to get things done. I do that all the time as one hobby is learning lots of languages and assessing them against each other. So care to share your solution in R which I would assume you could do easily? My quick and dirty attempt, of no interest to the python community, using the R form of integer that has a maximum, and the pipe operator that will not be in standard R for another iteration, is this: ## R code using pipes to convert an integer ## to another integer by subtracting 3 ## from each digit and wrapping around from ## 2 to 9 and so on, meaning modulo 10 ## Load libraries to be used library(dplyr) ## define function to return subtraction by N mod 10 rotdown <- function(dig, by=3) (dig -by) %% 10 start <- 123456789L ## Using pipes that send output between operators start %>% as.character %>% strsplit(split="") %>% unlist %>% as.integer %>% rotdown %>% as.character %>% paste(collapse="") %>% as.integer When run: > start %>% + as.character %>% + strsplit(split="") %>% + unlist %>% + as.integer %>% + rotdown %>% + as.character %>% + paste(collapse="") %>% + as.integer [1] 890123456 The above is not meant to be efficient and I could do better if I take more than a few minutes but is straightforward and uses the vectorized approach so no obvious loops are needed. -----Original Message----- From: Python-list On Behalf Of C W Sent: Sunday, February 21, 2021 9:48 AM To: Chris Angelico Cc: Python Subject: Re: Is there a way to subtract 3 from every digit of a number? Hey Avi, I am a long time R user now using Python. So, this is my attempt to master the language. The problem for me is that I often have an idea about how things are done in R, but not sure to what functions are available in Python. I hope that clears up some confusion. Cheer! On Sun, Feb 21, 2021 at 9:44 AM Chris Angelico wrote: > On Mon, Feb 22, 2021 at 1:39 AM Avi Gross via Python-list > wrote: > > But you just moved the goalpost by talking about using a data.frame > > as > that > > (and I assume numpy and pandas) are not very basic Python. > > Given that the original post mentioned a pd.Series, I don't know how > far the goalposts actually moved :) > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list From stestagg at gmail.com Sun Feb 21 11:02:39 2021 From: stestagg at gmail.com (Stestagg) Date: Sun, 21 Feb 2021 16:02:39 +0000 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: <023b01d70867$0d71e260$2855a720$@verizon.net> References: <20210221031220.GA15@pgp.cool> <016801d7085f$30b93b40$922bb1c0$@verizon.net> <023b01d70867$0d71e260$2855a720$@verizon.net> Message-ID: With numpy and pandas, it's almost always best to start off with the simple, obvious solution. In your case, I would recommend defining a function, and calling `Series.map`, passing in that function. Sometimes, however, with large datasets, it's possible to use some pandas/numpy tricks to significantly speed up execution. Here's an example that runs about 5x faster than the previous example on a 1-million item array. (non-scientific testing). The downside of this approach is you have to do some mucking about with numpy's data types to do it, which can end up with hard-to-read solutions: def sub3(series): chars = series.values.astype(str) intvals = chars.view('int8') subbed = np.mod(intvals - ord('0') - 3, 10) + ord('0') subbed_chars = np.where(intvals, subbed, intvals).view(chars.dtype) return pd.Series(subbed_chars) For example, let's create a series with 1 million items: num_lengths = np.power(10, np.random.randint(1, 7, size=1_000_000)) test_series = pd.Series(np.random.randint(0, num_lengths, size=1_000_000)).astype(str) calling: sub3(test_series) takes ~ 600ms and returns the array. Whereas the lambda technique takes 3s for me: test_series.map(lambda a: int("".join(map(lambda x: str((int(x)-3)%10) ,list(str(a)))))) How the numpy approach works: 1. series.values returns a numpy array of the series data 2. .astype(str) - makes numpy turn the array into a native string array (as opposed to an array of python string onbjects). Numpy arrays are fixed-width (dynamically chosen width to hold the largest string in the array), so each element is zero-byte padded to be the correct width. In this case, this is fine, as we're dealing with numbers 3. chars.view('int8') - creates a zero-copy view of the array, with each byte as its own element. I'm assuming you're using ascii numbers here, so this is safe. For example the digit '1' will be represented as an array element with value 49 (ascii '1'). 4. To convert, say, '49' to '1', we can subtract the ascii value for '0' (48) from each element. Most mathematical operations in numpy are performed element-wise, so for example 'my_array - 3' subtracts 3 from each item 5. The actual per-character maths is done using element-wise operations, before we add the ord('0') back to each number to convert the decimal value back to equivalent ascii character. 6. Now we have a large 1-d array of the correctly adjusted digits, but we need to reconstruct the original joined-up numbers. 7. np.where(intvals, a, b) is a really nice numpy builtin: https://numpy.org/doc/stable/reference/generated/numpy.where.html. It's used here to put back the 'zero byte' padding values from the original numpy array 8. .view(chars.dtype) creates a fixed-size string view, of the corect dimensions based on the original chars array. 9. Finally convert the numpy array back to a pandas series object and return. On Sun, Feb 21, 2021 at 3:37 PM Avi Gross via Python-list < python-list at python.org> wrote: > Ah, that is an interesting, Mike, but not an informative answer. My > question is where the specific problem came from. Yes, someone used to R > and coming to Python might work at adjusting to what is different and how > to > get things done. I do that all the time as one hobby is learning lots of > languages and assessing them against each other. > > So care to share your solution in R which I would assume you could do > easily? > > My quick and dirty attempt, of no interest to the python community, using > the R form of integer that has a maximum, and the pipe operator that will > not be in standard R for another iteration, is this: > > ## R code using pipes to convert an integer > ## to another integer by subtracting 3 > ## from each digit and wrapping around from > ## 2 to 9 and so on, meaning modulo 10 > > ## Load libraries to be used > library(dplyr) > > ## define function to return subtraction by N mod 10 > rotdown <- function(dig, by=3) (dig -by) %% 10 > > start <- 123456789L > > ## Using pipes that send output between operators > > start %>% > as.character %>% > strsplit(split="") %>% > unlist %>% > as.integer %>% > rotdown %>% > as.character %>% > paste(collapse="") %>% > as.integer > > When run: > > > start %>% > + as.character %>% > + strsplit(split="") %>% > + unlist %>% > + as.integer %>% > + rotdown %>% > + as.character %>% > + paste(collapse="") %>% > + as.integer > [1] 890123456 > > The above is not meant to be efficient and I could do better if I take more > than a few minutes but is straightforward and uses the vectorized approach > so no obvious loops are needed. > > > > > > > -----Original Message----- > From: Python-list On > Behalf Of C W > Sent: Sunday, February 21, 2021 9:48 AM > To: Chris Angelico > Cc: Python > Subject: Re: Is there a way to subtract 3 from every digit of a number? > > Hey Avi, > > I am a long time R user now using Python. So, this is my attempt to master > the language. > > The problem for me is that I often have an idea about how things are done > in > R, but not sure to what functions are available in Python. > > I hope that clears up some confusion. > > Cheer! > > On Sun, Feb 21, 2021 at 9:44 AM Chris Angelico wrote: > > > On Mon, Feb 22, 2021 at 1:39 AM Avi Gross via Python-list > > wrote: > > > But you just moved the goalpost by talking about using a data.frame > > > as > > that > > > (and I assume numpy and pandas) are not very basic Python. > > > > Given that the original post mentioned a pd.Series, I don't know how > > far the goalposts actually moved :) > > > > ChrisA > > -- > > https://mail.python.org/mailman/listinfo/python-list > > > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list > From fundegayatri at gmail.com Mon Feb 22 00:05:16 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Sun, 21 Feb 2021 21:05:16 -0800 (PST) Subject: Logging with 2 process in application Message-ID: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Hello, Greetings!! Have a good day! This is regarding logging issue i am facing in my application. My requirement is to create log on daily basis while my application is running, So to do this i am creating new log file at midnight by comparing the day it starts and enter to new day with the while loop continuously checking on date. In my application i have 2 processes, So what my observation is on the day of start of application both process are able to log into the file, but as new day starts new file getting created and only main process log are getting written into new file, and other process is still writing to old day log. So could you please help me to understand this issue and it will be great to know solution if you can help me with this. Thanks in advance! From drsalists at gmail.com Mon Feb 22 00:17:25 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 21 Feb 2021 21:17:25 -0800 Subject: Logging with 2 process in application In-Reply-To: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: On Sun, Feb 21, 2021 at 9:10 PM gayatri funde wrote: > Hello, > > Greetings!! Have a good day! > > This is regarding logging issue i am facing in my application. My > requirement is to create log on daily basis while my application is > running, So to do this i am creating new log file at midnight by comparing > the day it starts and enter to new day with the while loop continuously > checking on date. > > In my application i have 2 processes, So what my observation is on the day > of start of application both process are able to log into the file, but as > new day starts new file getting created and only main process log are > getting written into new file, and other process is still writing to old > day log. > > So could you please help me to understand this issue and it will be great > to know solution if you can help me with this. > Is it possible each process has open a different "file" on the same pathname, with only one actually being visible in the filesystem? Linuxes and Unixes allow such things. I am unaware of Windows being powerful enough to do so, and besides there you'd probably use the Event Log anyway. If that's the case, I do not know of a Python logging-module way of correcting the problem, but you could introduce a third process that is used just for logging, and have the original two send their log messages to the new 3rd logging process. From rosuav at gmail.com Mon Feb 22 00:19:06 2021 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 22 Feb 2021 16:19:06 +1100 Subject: Logging with 2 process in application In-Reply-To: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: On Mon, Feb 22, 2021 at 4:11 PM gayatri funde wrote: > > Hello, > > Greetings!! Have a good day! > > This is regarding logging issue i am facing in my application. My requirement is to create log on daily basis while my application is running, So to do this i am creating new log file at midnight by comparing the day it starts and enter to new day with the while loop continuously checking on date. > > In my application i have 2 processes, So what my observation is on the day of start of application both process are able to log into the file, but as new day starts new file getting created and only main process log are getting written into new file, and other process is still writing to old day log. > > So could you please help me to understand this issue and it will be great to know solution if you can help me with this. > What makes the decision to create a new file? How is that done? If you're closing the old one and opening a new one, both processes will have to do it; if you're renaming it away and then closing and opening with the same name, one process has to do the rename, and then the other has to just close/open. It may be easier and cleaner to make use of a separate logging facility. Many operating systems come with them. ChrisA From fundegayatri at gmail.com Mon Feb 22 00:39:33 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Sun, 21 Feb 2021 21:39:33 -0800 (PST) Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: > On Sun, Feb 21, 2021 at 9:10 PM gayatri funde > wrote: > > Hello, > > > > Greetings!! Have a good day! > > > > This is regarding logging issue i am facing in my application. My > > requirement is to create log on daily basis while my application is > > running, So to do this i am creating new log file at midnight by comparing > > the day it starts and enter to new day with the while loop continuously > > checking on date. > > > > In my application i have 2 processes, So what my observation is on the day > > of start of application both process are able to log into the file, but as > > new day starts new file getting created and only main process log are > > getting written into new file, and other process is still writing to old > > day log. > > > > So could you please help me to understand this issue and it will be great > > to know solution if you can help me with this. > > > Is it possible each process has open a different "file" on the same > pathname, with only one actually being visible in the filesystem? > > Linuxes and Unixes allow such things. I am unaware of Windows being > powerful enough to do so, and besides there you'd probably use the Event > Log anyway. > > If that's the case, I do not know of a Python logging-module way of > correcting the problem, but you could introduce a third process that is > used just for logging, and have the original two send their log messages to > the new 3rd logging process. Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. Thank you for your reply. From rosuav at gmail.com Mon Feb 22 00:44:55 2021 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 22 Feb 2021 16:44:55 +1100 Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: On Mon, Feb 22, 2021 at 4:41 PM gayatri funde wrote: > > On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: > > On Sun, Feb 21, 2021 at 9:10 PM gayatri funde > > wrote: > > > Hello, > > > > > > Greetings!! Have a good day! > > > > > > This is regarding logging issue i am facing in my application. My > > > requirement is to create log on daily basis while my application is > > > running, So to do this i am creating new log file at midnight by comparing > > > the day it starts and enter to new day with the while loop continuously > > > checking on date. > > > > > > In my application i have 2 processes, So what my observation is on the day > > > of start of application both process are able to log into the file, but as > > > new day starts new file getting created and only main process log are > > > getting written into new file, and other process is still writing to old > > > day log. > > > > > > So could you please help me to understand this issue and it will be great > > > to know solution if you can help me with this. > > > > > Is it possible each process has open a different "file" on the same > > pathname, with only one actually being visible in the filesystem? > > > > Linuxes and Unixes allow such things. I am unaware of Windows being > > powerful enough to do so, and besides there you'd probably use the Event > > Log anyway. > > > > If that's the case, I do not know of a Python logging-module way of > > correcting the problem, but you could introduce a third process that is > > used just for logging, and have the original two send their log messages to > > the new 3rd logging process. > > > Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. > > Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. > Thank you for your reply. > You'll need to show your code. Most likely, though, BOTH processes need to independently update to the new file. ChrisA From fundegayatri at gmail.com Mon Feb 22 00:46:57 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Sun, 21 Feb 2021 21:46:57 -0800 (PST) Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: On Monday, February 22, 2021 at 10:49:36 AM UTC+5:30, Chris Angelico wrote: > On Mon, Feb 22, 2021 at 4:11 PM gayatri funde wrote: > > > > Hello, > > > > Greetings!! Have a good day! > > > > This is regarding logging issue i am facing in my application. My requirement is to create log on daily basis while my application is running, So to do this i am creating new log file at midnight by comparing the day it starts and enter to new day with the while loop continuously checking on date. > > > > In my application i have 2 processes, So what my observation is on the day of start of application both process are able to log into the file, but as new day starts new file getting created and only main process log are getting written into new file, and other process is still writing to old day log. > > > > So could you please help me to understand this issue and it will be great to know solution if you can help me with this. > > > What makes the decision to create a new file? How is that done? If > you're closing the old one and opening a new one, both processes will > have to do it; if you're renaming it away and then closing and opening > with the same name, one process has to do the rename, and then the > other has to just close/open. > > It may be easier and cleaner to make use of a separate logging > facility. Many operating systems come with them. > > ChrisA By checking the new day start continuously, I am able to create new file before that i am clearing old day file handler. My doubt is Main process able to find the new day file handler but why not the other process. And before creating new file handler, i am clearing old file handler. So how other process is still have access to old day File handler. I am having little confusion here. Thank you for your reply! From fundegayatri at gmail.com Mon Feb 22 00:57:33 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Sun, 21 Feb 2021 21:57:33 -0800 (PST) Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> Message-ID: <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> On Monday, February 22, 2021 at 11:15:27 AM UTC+5:30, Chris Angelico wrote: > On Mon, Feb 22, 2021 at 4:41 PM gayatri funde wrote: > > > > On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: > > > On Sun, Feb 21, 2021 at 9:10 PM gayatri funde > > > wrote: > > > > Hello, > > > > > > > > Greetings!! Have a good day! > > > > > > > > This is regarding logging issue i am facing in my application. My > > > > requirement is to create log on daily basis while my application is > > > > running, So to do this i am creating new log file at midnight by comparing > > > > the day it starts and enter to new day with the while loop continuously > > > > checking on date. > > > > > > > > In my application i have 2 processes, So what my observation is on the day > > > > of start of application both process are able to log into the file, but as > > > > new day starts new file getting created and only main process log are > > > > getting written into new file, and other process is still writing to old > > > > day log. > > > > > > > > So could you please help me to understand this issue and it will be great > > > > to know solution if you can help me with this. > > > > > > > Is it possible each process has open a different "file" on the same > > > pathname, with only one actually being visible in the filesystem? > > > > > > Linuxes and Unixes allow such things. I am unaware of Windows being > > > powerful enough to do so, and besides there you'd probably use the Event > > > Log anyway. > > > > > > If that's the case, I do not know of a Python logging-module way of > > > correcting the problem, but you could introduce a third process that is > > > used just for logging, and have the original two send their log messages to > > > the new 3rd logging process. > > > > > > Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. > > > > Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. > > Thank you for your reply. > > > You'll need to show your code. Most likely, though, BOTH processes > need to independently update to the new file. > > ChrisA I have 2 files mainModule.py and loggingModule.py files as below: In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. loggingModule.py import logging import os, sys import os.path import datetime from threading import Thread import time firstTime = "false" def initialize_logger(fileName): global firstTime try: logger = logging.getLogger() logger.setLevel(logging.DEBUG) output_dir = os.getcwd() if firstTime == "true": for handler in logger.handlers[:]: # get rid of existing old handlers logger.removeHandler(handler) # create debug file handler and set level to debug try: handler = logging.FileHandler(os.path.join(output_dir, fileName), "w") except: print("problem to create log") handler.setLevel(logging.DEBUG) formatter = logging.Formatter("[%(levelname)s] (%(threadName)-30s) %(asctime)s %(message)s ") handler.setFormatter(formatter) logger.addHandler(handler) firstTime = "true" except Exception as ex: exc_type, exc_obj, tb = sys.exc_info() template = "An exception of type {0} occurred at {1}. Arguments:\n{2!r}" message = template.format(type(ex).__name__, tb.tb_lineno, ex.args) logging.error(message) def daily_log(): global firstTime try: now = datetime.datetime.now() log_day = now.day initialize_logger("Log_start.log") while True: currentDate = datetime.datetime.now().day time.sleep(60) if currentDate != log_day: # New day started initialize_logger("Log_continue.log") except Exception as ex: exc_type, exc_obj, tb = sys.exc_info() template = "An exception of type {0} occurred at {1}. Arguments:\n{2!r}" message = template.format(type(ex).__name__, tb.tb_lineno, ex.args) logging.error(message) daily_log() mainModule.py import Logic_Check import logging import multiprocessing from loggingModule import * def child_Process(var1): while True: time.sleep(10) logging.info('Log from Child Process') if __name__ == "__main__": var1 = "LotsOfSunshine" time.sleep(1) logging.info("Log from Main process") child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) child_Multiprocess.start() From rosuav at gmail.com Mon Feb 22 01:03:27 2021 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 22 Feb 2021 17:03:27 +1100 Subject: Logging with 2 process in application In-Reply-To: <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> Message-ID: On Mon, Feb 22, 2021 at 5:01 PM gayatri funde wrote: > I have 2 files mainModule.py and loggingModule.py files as below: > In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. > > def child_Process(var1): > while True: > time.sleep(10) > logging.info('Log from Child Process') > > if __name__ == "__main__": > var1 = "LotsOfSunshine" > time.sleep(1) > logging.info("Log from Main process") > > child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) > child_Multiprocess.start() > When you spawn a subprocess, its variables are completely separate from the parent. I suspect that you'll do far FAR better with threading here, rather than trying to share things across processes. ChrisA From fundegayatri at gmail.com Mon Feb 22 01:12:46 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Sun, 21 Feb 2021 22:12:46 -0800 (PST) Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> Message-ID: On Monday, February 22, 2021 at 11:33:57 AM UTC+5:30, Chris Angelico wrote: > On Mon, Feb 22, 2021 at 5:01 PM gayatri funde wrote: > > I have 2 files mainModule.py and loggingModule.py files as below: > > In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. > > > > def child_Process(var1): > > while True: > > time.sleep(10) > > logging.info('Log from Child Process') > > > > if __name__ == "__main__": > > var1 = "LotsOfSunshine" > > time.sleep(1) > > logging.info("Log from Main process") > > > > child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) > > child_Multiprocess.start() > > > When you spawn a subprocess, its variables are completely separate > from the parent. I suspect that you'll do far FAR better with > threading here, rather than trying to share things across processes. > > ChrisA Thank you Chris! But i have need of creating a another process instead of thread for application performance stand point. Just i was trying to log both process events in a single file and just wanted to create each day new log for easy debug. From __peter__ at web.de Mon Feb 22 05:44:31 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 22 Feb 2021 11:44:31 +0100 Subject: Logging with 2 process in application In-Reply-To: <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> Message-ID: On 22/02/2021 06:57, gayatri funde wrote: > On Monday, February 22, 2021 at 11:15:27 AM UTC+5:30, Chris Angelico wrote: >> On Mon, Feb 22, 2021 at 4:41 PM gayatri funde wrote: >>> >>> On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: >>>> On Sun, Feb 21, 2021 at 9:10 PM gayatri funde >>>> wrote: >>>>> Hello, >>>>> >>>>> Greetings!! Have a good day! >>>>> >>>>> This is regarding logging issue i am facing in my application. My >>>>> requirement is to create log on daily basis while my application is >>>>> running, So to do this i am creating new log file at midnight by comparing >>>>> the day it starts and enter to new day with the while loop continuously >>>>> checking on date. >>>>> >>>>> In my application i have 2 processes, So what my observation is on the day >>>>> of start of application both process are able to log into the file, but as >>>>> new day starts new file getting created and only main process log are >>>>> getting written into new file, and other process is still writing to old >>>>> day log. >>>>> >>>>> So could you please help me to understand this issue and it will be great >>>>> to know solution if you can help me with this. >>>>> >>>> Is it possible each process has open a different "file" on the same >>>> pathname, with only one actually being visible in the filesystem? >>>> >>>> Linuxes and Unixes allow such things. I am unaware of Windows being >>>> powerful enough to do so, and besides there you'd probably use the Event >>>> Log anyway. >>>> >>>> If that's the case, I do not know of a Python logging-module way of >>>> correcting the problem, but you could introduce a third process that is >>>> used just for logging, and have the original two send their log messages to >>>> the new 3rd logging process. >>> >>> >>> Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. >>> >>> Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. >>> Thank you for your reply. >>> >> You'll need to show your code. Most likely, though, BOTH processes >> need to independently update to the new file. >> >> ChrisA > > > I have 2 files mainModule.py and loggingModule.py files as below: > In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. > > loggingModule.py [...] > def daily_log(): > global firstTime > > try: > now = datetime.datetime.now() > log_day = now.day > initialize_logger("Log_start.log") > while True: Unless there is an exception you are forever stuck in this loop... > currentDate = datetime.datetime.now().day > time.sleep(60) > > if currentDate != log_day: # New day started > initialize_logger("Log_continue.log") > > except Exception as ex: > exc_type, exc_obj, tb = sys.exc_info() > template = "An exception of type {0} occurred at {1}. Arguments:\n{2!r}" > message = template.format(type(ex).__name__, tb.tb_lineno, ex.args) > logging.error(message) > > > daily_log() > > > mainModule.py > > import Logic_Check > import logging > import multiprocessing > from loggingModule import * ... and as the import implicitly invokes daily_log() you won't get here, i. e. the code below is not executed. > def child_Process(var1): > while True: > time.sleep(10) > logging.info('Log from Child Process') > > if __name__ == "__main__": > var1 = "LotsOfSunshine" > time.sleep(1) > logging.info("Log from Main process") > > child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) > child_Multiprocess.start() > From __peter__ at web.de Mon Feb 22 05:44:31 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 22 Feb 2021 11:44:31 +0100 Subject: Logging with 2 process in application In-Reply-To: <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> Message-ID: On 22/02/2021 06:57, gayatri funde wrote: > On Monday, February 22, 2021 at 11:15:27 AM UTC+5:30, Chris Angelico wrote: >> On Mon, Feb 22, 2021 at 4:41 PM gayatri funde wrote: >>> >>> On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: >>>> On Sun, Feb 21, 2021 at 9:10 PM gayatri funde >>>> wrote: >>>>> Hello, >>>>> >>>>> Greetings!! Have a good day! >>>>> >>>>> This is regarding logging issue i am facing in my application. My >>>>> requirement is to create log on daily basis while my application is >>>>> running, So to do this i am creating new log file at midnight by comparing >>>>> the day it starts and enter to new day with the while loop continuously >>>>> checking on date. >>>>> >>>>> In my application i have 2 processes, So what my observation is on the day >>>>> of start of application both process are able to log into the file, but as >>>>> new day starts new file getting created and only main process log are >>>>> getting written into new file, and other process is still writing to old >>>>> day log. >>>>> >>>>> So could you please help me to understand this issue and it will be great >>>>> to know solution if you can help me with this. >>>>> >>>> Is it possible each process has open a different "file" on the same >>>> pathname, with only one actually being visible in the filesystem? >>>> >>>> Linuxes and Unixes allow such things. I am unaware of Windows being >>>> powerful enough to do so, and besides there you'd probably use the Event >>>> Log anyway. >>>> >>>> If that's the case, I do not know of a Python logging-module way of >>>> correcting the problem, but you could introduce a third process that is >>>> used just for logging, and have the original two send their log messages to >>>> the new 3rd logging process. >>> >>> >>> Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. >>> >>> Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. >>> Thank you for your reply. >>> >> You'll need to show your code. Most likely, though, BOTH processes >> need to independently update to the new file. >> >> ChrisA > > > I have 2 files mainModule.py and loggingModule.py files as below: > In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. > > loggingModule.py [...] > def daily_log(): > global firstTime > > try: > now = datetime.datetime.now() > log_day = now.day > initialize_logger("Log_start.log") > while True: Unless there is an exception you are forever stuck in this loop... > currentDate = datetime.datetime.now().day > time.sleep(60) > > if currentDate != log_day: # New day started > initialize_logger("Log_continue.log") > > except Exception as ex: > exc_type, exc_obj, tb = sys.exc_info() > template = "An exception of type {0} occurred at {1}. Arguments:\n{2!r}" > message = template.format(type(ex).__name__, tb.tb_lineno, ex.args) > logging.error(message) > > > daily_log() > > > mainModule.py > > import Logic_Check > import logging > import multiprocessing > from loggingModule import * ... and as the import implicitly invokes daily_log() you won't get here, i. e. the code below is not executed. > def child_Process(var1): > while True: > time.sleep(10) > logging.info('Log from Child Process') > > if __name__ == "__main__": > var1 = "LotsOfSunshine" > time.sleep(1) > logging.info("Log from Main process") > > child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) > child_Multiprocess.start() > From phd at phdru.name Mon Feb 22 06:17:11 2021 From: phd at phdru.name (Oleg Broytman) Date: Mon, 22 Feb 2021 12:17:11 +0100 Subject: Cheetah3 3.2.6.post1 Message-ID: <20210222111711.GA20801@phdru.name> Hello! I'm pleased to announce version 3.2.6.post1, the 1st post-release for release 3.2.6 of branch 3.2 of CheetahTemplate3. What's new in CheetahTemplate3 ============================== Improvement and refactoring in CI and tests with ``tox``. There were no changes in the main code, there is no need to upgrade unless you gonna run tests. The contributors for this release are Andrew J. Hesford and Victor Stinner. Many thanks! This is the first release that provide binary wheels for Python 3.9. Tests: - Add Python 3.9 to ``tox.ini``. - Refactor ``tox.ini``. CI: - Run tests with Python 3.9 at Travis and AppVeyor. - Run tests for Python 3.4 with ``tox`` under Python 3.5. What is CheetahTemplate3 ======================== Cheetah3 is a free and open source template engine. It's a fork of the original CheetahTemplate library. Python 2.7 or 3.4+ is required. Where is CheetahTemplate3 ========================= Site: https://cheetahtemplate.org/ Development: https://github.com/CheetahTemplate3 Download: https://pypi.org/project/Cheetah3/3.2.6.post1 News and changes: https://cheetahtemplate.org/news.html StackOverflow: https://stackoverflow.com/questions/tagged/cheetah Example ======= Below is a simple example of some Cheetah code, as you can see it's practically Python. You can import, inherit and define methods just like in a regular Python module, since that's what your Cheetah templates are compiled to :) :: #from Cheetah.Template import Template #extends Template #set $people = [{'name' : 'Tom', 'mood' : 'Happy'}, {'name' : 'Dick', 'mood' : 'Sad'}, {'name' : 'Harry', 'mood' : 'Hairy'}] How are you feeling?
    #for $person in $people
  • $person['name'] is $person['mood']
  • #end for
Oleg. -- Oleg Broytman https://phdru.name/ phd at phdru.name Programmers don't die, they just GOSUB without RETURN. From hjp-python at hjp.at Mon Feb 22 07:25:03 2021 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 22 Feb 2021 13:25:03 +0100 Subject: Is there a way to subtract 3 from every digit of a number? In-Reply-To: References: Message-ID: <20210222122503.GA12069@hjp.at> On 2021-02-20 13:51:56 -0500, Terry Reedy wrote: > On 2/20/2021 12:02 PM, jak wrote: > > >>> sn = '' > > >>> for x in str(n): > > ???? sn += num[(int(x) - 3) % 10] > > > This works, but suggesting to beginners that they build strings with += is > an O(n*n) trap. Try it with a string of millions of digits. The problem with trying is that it might just work. CPython has a nice optimization for the common case (the variable at the left side is the only reference to the str) which makes that O(n). Other Python implementations may not have that optimization (PyPy doesn't, I would assume that Jypthon or IronPython don't either because their method of garbage collection would make it hard). So for a beginner, the question is: Do you care about performance on Python implementations you don't use? For a use-case you currently don't have? hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From vinicius_costamarques at hotmail.com Mon Feb 22 14:00:07 2021 From: vinicius_costamarques at hotmail.com (Vinicius Costa Marques) Date: Mon, 22 Feb 2021 19:00:07 +0000 Subject: Deleting Python 3.8.5 In-Reply-To: References: Message-ID: Hello there Python team, I?m having this problem were I installed Python 3.9.2 and then went to unistall 3.8.5 but here is the problem the version 3.8.5 dosen?t get deleted properly. The uninstall program says that everything worked but the files for 3.8.5 still exist algong with 3.9.2 can someone help me? From PythonList at DancesWithMice.info Mon Feb 22 18:57:15 2021 From: PythonList at DancesWithMice.info (dn) Date: Tue, 23 Feb 2021 12:57:15 +1300 Subject: Deleting Python 3.8.5 In-Reply-To: References: Message-ID: On 23/02/2021 08.00, Vinicius Costa Marques wrote: > Hello there Python team, I?m having this problem were I installed Python 3.9.2 and then went to unistall 3.8.5 but here is the problem the version 3.8.5 dosen?t get deleted properly. The uninstall program says that everything worked but the files for 3.8.5 still exist algong with 3.9.2 can someone help me? Removal varies by Operating System! Regardless, it's likely problematic trying to remove the 'old', *after* installing the 'new'. Perhaps remove any and all versions, ensure the system is 'clean', then start-again... -- Regards, =dn From tjreedy at udel.edu Mon Feb 22 18:36:06 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 22 Feb 2021 18:36:06 -0500 Subject: Deleting Python 3.8.5 In-Reply-To: References: Message-ID: On 2/22/2021 2:00 PM, Vinicius Costa Marques wrote: > Hello there Python team, I?m having this problem were I installed Python 3.9.2 and then went to unistall 3.8.5 but here is the problem the version 3.8.5 dosen?t get deleted properly. The uninstall program says that everything worked but the files for 3.8.5 still exist algong with 3.9.2 can someone help me? The 3.8 directory should still be there if you added anything thing, such as to site-packages, but the stuff added by the installer should be gone. -- Terry Jan Reedy From Bischoop at vimart.net Mon Feb 22 19:41:14 2021 From: Bischoop at vimart.net (Bischoop) Date: Tue, 23 Feb 2021 00:41:14 -0000 (UTC) Subject: Deleting Python 3.8.5 References: Message-ID: On 2021-02-22, Vinicius Costa Marques wrote: > Hello there Python team, I?m having this problem were I installed >Python 3.9.2 and then went to unistall 3.8.5 but here is the problem >the version 3.8.5 dosen?t get deleted properly. >The uninstall program says that everything worked but the files >for 3.8.5 still exist algong with 3.9.2 can someone help me? I wouldn't do that, you can meet missing libraries for Py3.9.2 and then need to install Py3.8 again. Just wait with uninstalling Py3.8 for a while. From fundegayatri at gmail.com Tue Feb 23 01:17:17 2021 From: fundegayatri at gmail.com (gayatri funde) Date: Mon, 22 Feb 2021 22:17:17 -0800 (PST) Subject: Logging with 2 process in application In-Reply-To: References: <7f03f7ea-c945-41dc-8e72-3db857a7eadfn@googlegroups.com> <5ffe01ac-0bbe-4785-8772-998e17a695edn@googlegroups.com> Message-ID: <3a999666-365f-435f-8310-85cc4527274cn@googlegroups.com> On Monday, February 22, 2021 at 4:14:53 PM UTC+5:30, Peter Otten wrote: > On 22/02/2021 06:57, gayatri funde wrote: > > On Monday, February 22, 2021 at 11:15:27 AM UTC+5:30, Chris Angelico wrote: > >> On Mon, Feb 22, 2021 at 4:41 PM gayatri funde wrote: > >>> > >>> On Monday, February 22, 2021 at 10:47:57 AM UTC+5:30, Dan Stromberg wrote: > >>>> On Sun, Feb 21, 2021 at 9:10 PM gayatri funde > >>>> wrote: > >>>>> Hello, > >>>>> > >>>>> Greetings!! Have a good day! > >>>>> > >>>>> This is regarding logging issue i am facing in my application. My > >>>>> requirement is to create log on daily basis while my application is > >>>>> running, So to do this i am creating new log file at midnight by comparing > >>>>> the day it starts and enter to new day with the while loop continuously > >>>>> checking on date. > >>>>> > >>>>> In my application i have 2 processes, So what my observation is on the day > >>>>> of start of application both process are able to log into the file, but as > >>>>> new day starts new file getting created and only main process log are > >>>>> getting written into new file, and other process is still writing to old > >>>>> day log. > >>>>> > >>>>> So could you please help me to understand this issue and it will be great > >>>>> to know solution if you can help me with this. > >>>>> > >>>> Is it possible each process has open a different "file" on the same > >>>> pathname, with only one actually being visible in the filesystem? > >>>> > >>>> Linuxes and Unixes allow such things. I am unaware of Windows being > >>>> powerful enough to do so, and besides there you'd probably use the Event > >>>> Log anyway. > >>>> > >>>> If that's the case, I do not know of a Python logging-module way of > >>>> correcting the problem, but you could introduce a third process that is > >>>> used just for logging, and have the original two send their log messages to > >>>> the new 3rd logging process. > >>> > >>> > >>> Just to clarify, file names are different as i am appending date to each file name. On new day start main process is writing to new day file and another process is still writing to old date file. This i am trying on Linux system. > >>> > >>> Thanks for suggestion of creating one dedicated process for logging. But if you can help to find any is other reason why second process not able to find the new day file handler object. > >>> Thank you for your reply. > >>> > >> You'll need to show your code. Most likely, though, BOTH processes > >> need to independently update to the new file. > >> > >> ChrisA > > > > > > I have 2 files mainModule.py and loggingModule.py files as below: > > In loggingModule.py file i am managing new log to create , which i am importing to mainModule.py file. > > > > loggingModule.py > [...] > > def daily_log(): > > global firstTime > > > > try: > > now = datetime.datetime.now() > > log_day = now.day > > initialize_logger("Log_start.log") > > while True: > Unless there is an exception you are forever stuck in this loop... > > currentDate = datetime.datetime.now().day > > time.sleep(60) > > > > if currentDate != log_day: # New day started > > initialize_logger("Log_continue.log") > > > > except Exception as ex: > > exc_type, exc_obj, tb = sys.exc_info() > > template = "An exception of type {0} occurred at {1}. Arguments:\n{2!r}" > > message = template.format(type(ex).__name__, tb.tb_lineno, ex.args) > > logging.error(message) > > > > > > daily_log() > > > > > > mainModule.py > > > > import Logic_Check > > import logging > > import multiprocessing > > from loggingModule import * > ... and as the import implicitly invokes daily_log() you won't get here, > i. e. the code below is not executed. > > def child_Process(var1): > > while True: > > time.sleep(10) > > logging.info('Log from Child Process') > > > > if __name__ == "__main__": > > var1 = "LotsOfSunshine" > > time.sleep(1) > > logging.info("Log from Main process") > > > > child_Multiprocess = multiprocessing.Process(target=child_Process, args=(var1,)) > > child_Multiprocess.start() > > daily_log() call is necessary in loggingModule.py because if we import loggingModule.py module into mainModule.py, Import won't execute daily_log() function by itself, either I make explicit call of daily_log() in mainModule.py or loggingModule.py From adam.preble at gmail.com Tue Feb 23 11:48:12 2021 From: adam.preble at gmail.com (adam....@gmail.com) Date: Tue, 23 Feb 2021 08:48:12 -0800 (PST) Subject: Pip standard error warning about dependency resolver Message-ID: <017cf5f7-f577-4e54-8703-67a3cea95ce6n@googlegroups.com> I started seeing this sometimes from pip: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts. Yeah, sure, that's something to consider. We seem fine with the new resolver. Is there a way to suppress it? We have some back end operations that fail when we get output on standard error, and they're dying from that notice. From random832 at fastmail.com Wed Feb 24 00:27:09 2021 From: random832 at fastmail.com (Random832) Date: Wed, 24 Feb 2021 00:27:09 -0500 Subject: use set notation for repr of dict_keys? In-Reply-To: <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> Message-ID: <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> On Sat, Feb 20, 2021, at 15:00, dn via Python-list wrote: > So, the output is not a set (as you say) but nor (as > apparently-indicated by the square-brackets) is it actually a list! To be clear, it is an instance of collections.abc.Set, and supports most binary operators that sets support. I was surprised, though, to find that you can't remove items directly from the key set, or in general update it in place with &= or -= (these operators work, but give a new set object). AIUI the keys, values, and items collections have always had the ordering guarantee that iterating over them while not modifying the underlying dictionary will give the same order each time [with respect to each other, and possibly also with respect to iterating over the original dictionary to obtain the keys] From rosuav at gmail.com Wed Feb 24 00:40:32 2021 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 24 Feb 2021 16:40:32 +1100 Subject: use set notation for repr of dict_keys? In-Reply-To: <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> Message-ID: On Wed, Feb 24, 2021 at 4:29 PM Random832 wrote: > > AIUI the keys, values, and items collections have always had the ordering guarantee that iterating over them while not modifying the underlying dictionary will give the same order each time [with respect to each other, and possibly also with respect to iterating over the original dictionary to obtain the keys] > Correct, on all counts. I believe the old guarantee (before insertion order was maintained) was that *any* change could change the iteration order, but that .items(), .keys(), and .values() (and their iter* counterparts) would always change together. But in practice, I believe this kind of code has always been safe: for key in some_dict: some_dict[key] += 1 I can't find anywhere in the docs that says that changes to *values* (without changing the set of keys) won't change iteration order, but given how common this kind of code is, I would expect that it's at least a de facto guarantee. ChrisA From Marco.Sulla.Python at gmail.com Wed Feb 24 02:59:30 2021 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Wed, 24 Feb 2021 08:59:30 +0100 Subject: use set notation for repr of dict_keys? In-Reply-To: <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> Message-ID: On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > I was surprised, though, to find that you can't remove items directly from the key set, or in general update it in place with &= or -= (these operators work, but give a new set object). This is because they are a view. Changing the key object means you will change the underlying dict. Probably not that you want or expect. You can just "cast" them into a "real" set object. There was a discussion to implement the whole Set interface for dicts. Currently, only `|` is supported. From nospam at please.ty Wed Feb 24 05:32:29 2021 From: nospam at please.ty (jak) Date: Wed, 24 Feb 2021 11:32:29 +0100 Subject: Idle Python issue Message-ID: Hello everybody, I encounter a problem using Idle Python in Windows when I use utf8 characters longer than 2 bytes such as the character representing the smile emoticon: :-) that is this: ? Try to write this in Idle: "?".encode('utf8') b'\xf0\x9f\x98\x8a' now try to write this: "".encode('utf8') now position the cursor between the double quotes and paste the smile character and try to add some text to the string (eg: 'the smile'). You may notice problems with editing. Is there any way to prevent this from happening? It is an annoying problem. Thanks for your attention. cheers From research at johnohagan.com Wed Feb 24 06:35:32 2021 From: research at johnohagan.com (John O'Hagan) Date: Wed, 24 Feb 2021 22:35:32 +1100 Subject: Tkinter long-running window freezes Message-ID: <20210224220031.5ce59f6b@e7240.home> Hi list I have a 3.9 tkinter interface that displays data from an arbitrary number of threads, each of which runs for an arbitrary period of time. A frame opens in the root window when each thread starts and closes when it stops. Widgets in the frame and the root window control the thread and how the data is displayed. This works well for several hours, but over time the root window becomes unresponsive and eventually freezes and goes grey. No error messages are produced in the terminal. Here is some minimal, non-threaded code that reproduces the problem on my system (Xfce4 on Debian testing): from tkinter import * from random import randint root = Tk() def display(label): label.destroy() label = Label(text=randint(0, 9)) label.pack() root.after(100, display, label) display(Label()) mainloop() This opens a tiny window that displays a random digit on a new label every .1 second. (Obviously I could do this by updating the text rather than recreating the label, but my real application has to destroy widgets and create new ones). This works for 3-4 hours, but eventually the window freezes. The process uses about 26 Mb of memory at first, and this gradually increases to around 30 or so by the time it freezes. Any ideas what could be causing this, or even how to approach debugging or workarounds? Thanks -- John From python at mrabarnett.plus.com Wed Feb 24 08:07:24 2021 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 24 Feb 2021 13:07:24 +0000 Subject: Tkinter long-running window freezes In-Reply-To: <20210224220031.5ce59f6b@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> Message-ID: <9284d32a-d9a3-8335-ab54-13192a7c156f@mrabarnett.plus.com> On 2021-02-24 11:35, John O'Hagan wrote: > Hi list > > I have a 3.9 tkinter interface that displays data from an arbitrary > number of threads, each of which runs for an arbitrary period of time. > A frame opens in the root window when each thread starts and closes > when it stops. Widgets in the frame and the root window control the > thread and how the data is displayed. > > This works well for several hours, but over time the root window > becomes unresponsive and eventually freezes and goes grey. No error > messages are produced in the terminal. > > Here is some minimal, non-threaded code that reproduces the problem on > my system (Xfce4 on Debian testing): > > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > label.destroy() > label = Label(text=randint(0, 9)) > label.pack() > root.after(100, display, label) > > display(Label()) > mainloop() > > This opens a tiny window that displays a random digit on a new label > every .1 second. (Obviously I could do this by updating the text rather > than recreating the label, but my real application has to destroy > widgets and create new ones). > > This works for 3-4 hours, but eventually the window freezes. > > The process uses about 26 Mb of memory at first, and this gradually > increases to around 30 or so by the time it freezes. > > Any ideas what could be causing this, or even how to approach debugging > or workarounds? > The problem might be that you're adding the label using .pack but not removing it with .pack_forget when you destroy it. Try doing both: from tkinter import * from random import randint root = Tk() def display(label): if label is not None: label.pack_forget() label.destroy() label = Label(text=randint(0, 9)) label.pack() root.after(100, display, label) display(None) mainloop() From antoon.pardon at vub.be Wed Feb 24 08:13:43 2021 From: antoon.pardon at vub.be (Antoon Pardon) Date: Wed, 24 Feb 2021 14:13:43 +0100 Subject: python 2.6: Need some advise for installing modules on a legacy system Message-ID: I need to do some development on this legacy system. It only runs python2.6 and there is little hope of installing an other version. How can I best proceed to install modules for working with mysql and ldap? -- Antoon. From random832 at fastmail.com Wed Feb 24 09:00:21 2021 From: random832 at fastmail.com (Random832) Date: Wed, 24 Feb 2021 09:00:21 -0500 Subject: use set notation for repr of dict_keys? In-Reply-To: References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> Message-ID: On Wed, Feb 24, 2021, at 02:59, Marco Sulla wrote: > On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > > I was surprised, though, to find that you can't remove items directly from the key set, or in general update it in place with &= or -= (these operators work, but give a new set object). > > This is because they are a view. Changing the key object means you > will change the underlying dict. Probably not that you want or expect. Why wouldn't it be what I want or expect? Java allows exactly this [and it's the only way provided to, for example, remove all keys matching a predicate in a single pass... an operation that Python sets don't support either] > You can just "cast" them into a "real" set object. > > There was a discussion to implement the whole Set interface for dicts. > Currently, only `|` is supported. From drsalists at gmail.com Wed Feb 24 09:08:38 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 24 Feb 2021 06:08:38 -0800 Subject: python 2.6: Need some advise for installing modules on a legacy system In-Reply-To: References: Message-ID: I don't think pip supports 2.x anymore. You might be able to: 1) Look up what versions of your desired modules support Python 2.x on pypi's website 2) Install them on another system that has Python 3.x using pip 3) Copy them to the moribund system 4) Test On Wed, Feb 24, 2021 at 5:15 AM Antoon Pardon wrote: > I need to do some development on this legacy system. It only runs > python2.6 and there is little hope of installing an other version. How > can I best proceed to install modules for working with mysql and ldap? > > -- > Antoon. > -- > https://mail.python.org/mailman/listinfo/python-list > From liedtke at punkt.de Wed Feb 24 05:36:01 2021 From: liedtke at punkt.de (Lars Liedtke) Date: Wed, 24 Feb 2021 11:36:01 +0100 Subject: Pip standard error warning about dependency resolver In-Reply-To: <017cf5f7-f577-4e54-8703-67a3cea95ce6n@googlegroups.com> References: <017cf5f7-f577-4e54-8703-67a3cea95ce6n@googlegroups.com> Message-ID: <32bfb486-41f1-fb40-a7f6-9072a1137708@punkt.de> I understand your problem and I know that sometimes it is not possible to do it differently. But as far as my understanding goes, your backend operations should not die on outputs on stderr. I understand that is what return values are for and as long as the return value is 0 everything went without error, even though there might be output on stderr. That said. As far as I know you could try the commandline option for using the new resolver explicitly. I don't know if there is an option for "silent" Cheers Lars Am 23.02.21 um 17:48 schrieb adam.... at gmail.com: > I started seeing this sometimes from pip: > > After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts. > > Yeah, sure, that's something to consider. We seem fine with the new resolver. Is there a way to suppress it? We have some back end operations that fail when we get output on standard error, and they're dying from that notice. -- --- punkt.de GmbH Lars Liedtke .infrastructure Kaiserallee 13a 76133 Karlsruhe Tel. +49 721 9109 500 https://infrastructure.punkt.de info at punkt.de AG Mannheim 108285 Gesch?ftsf?hrer: J?rgen Egeling, Daniel Lienert, Fabian Stein From lucas at bourneuf.net Wed Feb 24 09:29:58 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 15:29:58 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error Message-ID: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Hi everyone, (Sorry for the double-send if any, i'm not sure the first send was performed, maybe because of bounce errors according to mailman.) I'm currently trying to understand an error when using the dokuwikixmlrpc python module, allowing to easily work with DokuWiki RPC interface. Another description of the problem : https://github.com/kynan/dokuwikixmlrpc/issues/8 Here is the code, tailored to work with the DokuWiki RPC interface: from urllib.parse import urlencode import xmlrpc.client as xmlrpclib URL = 'wiki.example.net' USER = 'user' PASSWD = 'password' USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' script = '/lib/exe/xmlrpc.php' url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) xmlrpclib.Transport.user_agent = USER_AGENT xmlrpclib.SafeTransport.user_agent = USER_AGENT proxy = xmlrpclib.ServerProxy(url) v = proxy.dokuwiki.getVersion() print(v) When ran with Python 3.7 (a personnal debian server, or a personal windows computer), i obtain the expected 'Release 2018-04-22a "Greebo"' as ouput. When ran with Python 3.9 (my personnal, manjaro machine), i obtain the following stacktrace: Traceback (most recent call last): File "/home/project/read.py", line 32, in v = proxy.dokuwiki.getVersion() File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__ return self.__send(self.__name, args) File "/usr/lib/python3.9/xmlrpc/client.py", line 1456, in __request response = self.__transport.request( File "/usr/lib/python3.9/xmlrpc/client.py", line 1160, in request return self.single_request(host, handler, request_body, verbose) File "/usr/lib/python3.9/xmlrpc/client.py", line 1190, in single_request raise ProtocolError( xmlrpc.client.ProtocolError: I don't have the possibility to test this on python 3.8 specifically, but since the XML and XMLRPC modules have been updated in 3.8, and since 3.9 doesn't seems to introduce any change for them, i would expect 3.8 to introduce some change that dokuwikixmlrpc has somehow to take into consideration. Can anyone help me with that one ? I don't know anything about RPC and XML, i don't know what i need to do know to fix dokuwikixmlrpc. Best regard, --lucas From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 24 10:20:00 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 24 Feb 2021 09:20:00 -0600 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: On 2021-02-24 at 15:29:58 +0100, lucas wrote: > I'm currently trying to understand an error when using the dokuwikixmlrpc > python module, allowing to easily work with DokuWiki RPC interface. > > Another description of the problem : > https://github.com/kynan/dokuwikixmlrpc/issues/8 > > Here is the code, tailored to work with the DokuWiki RPC interface: > > from urllib.parse import urlencode > import xmlrpc.client as xmlrpclib > > URL = 'wiki.example.net' > USER = 'user' > PASSWD = 'password' > USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' > > script = '/lib/exe/xmlrpc.php' > url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) > xmlrpclib.Transport.user_agent = USER_AGENT > xmlrpclib.SafeTransport.user_agent = USER_AGENT > proxy = xmlrpclib.ServerProxy(url) > > v = proxy.dokuwiki.getVersion() > print(v) > > When ran with Python 3.7 (a personnal debian server, or a personal windows > computer), i obtain the expected 'Release 2018-04-22a "Greebo"' as ouput. > When ran with Python 3.9 (my personnal, manjaro machine), i obtain the > following stacktrace: > > Traceback (most recent call last): > File "/home/project/read.py", line 32, in > v = proxy.dokuwiki.getVersion() > File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__ > return self.__send(self.__name, args) > File "/usr/lib/python3.9/xmlrpc/client.py", line 1456, in __request > response = self.__transport.request( > File "/usr/lib/python3.9/xmlrpc/client.py", line 1160, in request > return self.single_request(host, handler, request_body, verbose) > File "/usr/lib/python3.9/xmlrpc/client.py", line 1190, in > single_request > raise ProtocolError( > xmlrpc.client.ProtocolError: wiki.example.net/lib/exe/xmlrpc.php: 401 Unauthorized> At the risk of stating the obvious, it might actually be an authentication problem. In addition to double checking the password: (1) make sure all of your certificates (under Arch Linux, on which Manjaro is based), that's the ca-certificates package) are up to date; and (2) check with whoever owns the wiki about any other certificates they require. After that, all I know about XML RPC is to avoid it. :-) > I don't have the possibility to test this on python 3.8 specifically, but > since the XML and XMLRPC modules have been updated in 3.8, and since 3.9 > doesn't seems to introduce any change for them, i would expect 3.8 to > introduce some change that dokuwikixmlrpc has somehow to take into > consideration. > > Can anyone help me with that one ? I don't know anything about RPC and XML, > i don't know what i need to do know to fix dokuwikixmlrpc. From drsalists at gmail.com Wed Feb 24 10:53:58 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 24 Feb 2021 07:53:58 -0800 Subject: python 2.6: Need some advise for installing modules on a legacy system In-Reply-To: References: Message-ID: You also could try getting the modules (of suitable versions) you need from their homepage, possibly github, and then use the setup.py to install your packages. pypi usually has a link to a project's homepage. On Wed, Feb 24, 2021 at 6:08 AM Dan Stromberg wrote: > > I don't think pip supports 2.x anymore. > > You might be able to: > 1) Look up what versions of your desired modules support Python 2.x on > pypi's website > 2) Install them on another system that has Python 3.x using pip > 3) Copy them to the moribund system > 4) Test > > > On Wed, Feb 24, 2021 at 5:15 AM Antoon Pardon > wrote: > >> I need to do some development on this legacy system. It only runs >> python2.6 and there is little hope of installing an other version. How >> can I best proceed to install modules for working with mysql and ldap? >> >> -- >> Antoon. >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From ethan at stoneleaf.us Wed Feb 24 11:12:58 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 24 Feb 2021 08:12:58 -0800 Subject: name for a mutually inclusive relationship Message-ID: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> I'm looking for a name for a group of options that, when one is specified, all of them must be specified. For contrast, - radio buttons: a group of options where only one can be specified (mutually exclusive) - check boxes: a group of options that are independent of each other (any number of them may be specified) - ???: a group of options where, if one is specified, all must be specified (mutually inclusive) So far, I have come up with: - the Three Musketeers - clique - club - best friends - tight knit - group Is there a name out there already to describe that concept? -- ~Ethan~ From tjreedy at udel.edu Wed Feb 24 10:18:35 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 24 Feb 2021 10:18:35 -0500 Subject: Idle Python issue In-Reply-To: References: Message-ID: On 2/24/2021 5:32 AM, jak wrote: > Hello everybody, > I encounter a problem using Idle Python in Windows when I use utf8 > characters longer than 2 bytes such as the character representing the > smile emoticon: The problem is with 'astral' unicode characters, those not in the Basic Multilingual Plane (BMP). tcl/tk does not directly support them. > :-) > that is this: > ? > Try to write this in Idle: > "?".encode('utf8') > b'\xf0\x9f\x98\x8a' Up until 1 1/2 years ago, you could not do this. Now you can, as long as you do not try to edit anything after the astral character. I thought I added something to the doc about this, but cannot find it, so it should be easier to find. > now try to write this: > "".encode('utf8') > now position the cursor between the double quotes and paste the smile > character Up until 1.5 years ago, this would have crashed either the window or IDLE itself. For input, if one wants to edit, one is still better off using \U000##### excapes. At least now print('\U00011111'), for instance, works to display the character is the OS font system supports it. > and try to add some text to the string (eg: 'the smile'). > You may notice problems with editing. > Is there any way to prevent this from happening? It is an annoying problem. Help the tcl/tk people to add full unicode support to tcl/tk. ;-) They know it is needed. I don't know what their timetable is now. -- Terry Jan Reedy From tjreedy at udel.edu Wed Feb 24 11:03:30 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 24 Feb 2021 11:03:30 -0500 Subject: Tkinter long-running window freezes In-Reply-To: <20210224220031.5ce59f6b@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> Message-ID: On 2/24/2021 6:35 AM, John O'Hagan wrote: > Hi list > > I have a 3.9 tkinter interface that displays data from an arbitrary > number of threads, each of which runs for an arbitrary period of time. > A frame opens in the root window when each thread starts and closes > when it stops. Widgets in the frame and the root window control the > thread and how the data is displayed. > > This works well for several hours, but over time the root window > becomes unresponsive and eventually freezes and goes grey. No error > messages are produced in the terminal. > > Here is some minimal, non-threaded code that reproduces the problem on > my system (Xfce4 on Debian testing): I am trying this out on Windows 10, with a wider label (so I can move the window) and a button that changes when pressed, and a sequential counter. Will report when the Window freezes, or maybe a day if not. > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > label.destroy() > label = Label(text=randint(0, 9)) > label.pack() > root.after(100, display, label) > > display(Label()) > mainloop() You could try with .grid instead. > This opens a tiny window that displays a random digit on a new label > every .1 second. (Obviously I could do this by updating the text rather > than recreating the label, but my real application has to destroy > widgets and create new ones). Plus you seem to have a memory leak and may need to replicate that. > This works for 3-4 hours, but eventually the window freezes. > > The process uses about 26 Mb of memory at first, and this gradually > increases to around 30 or so by the time it freezes. -- Terry Jan Reedy From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 24 11:28:43 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 24 Feb 2021 10:28:43 -0600 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: On 2021-02-24 at 08:12:58 -0800, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is specified, all of them must be specified. > > For contrast, > > - radio buttons: a group of options where only one can be specified (mutually exclusive) > - check boxes: a group of options that are independent of each other (any number of > them may be specified) > > - ???: a group of options where, if one is specified, all must be specified (mutually > inclusive) I've run across this before, and almost always end up incorporating one option or the other. For example, consider a program's output. By default, it goes to stdout, but the program also supports plain output, logging, and syslog. So instead of mutually inclusive (for lack of a better phrase right now) options: --output-disposition [logging|syslog|flatfile] --output-options [depends on --output-disposition] do this: --output-to-log logging-options --output-to-syslog syslog-options --output-to-plain-file plain-file-options aka three mutually *exclusive* options. > So far, I have come up with: > > - the Three Musketeers > - clique > - club > - best friends > - tight knit > - group > > Is there a name out there already to describe that concept? Codependent? Circularly dependent? Entangled? From lucas at bourneuf.net Wed Feb 24 11:25:01 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 17:25:01 +0100 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: Hi ! In case you didn't though about that, in argparse, MutuallyExclusiveGroup is used for the mutually exclusive logic. You may use the same nomenclature, which happens to be IMHO much clearer than the one you came up with. In GUIs, i guess that such an option would be implemented by a checkbox that, when checked, enables the widgets associated to all the mutually inclusive options. Best regards, --lucas On 24/02/2021 17:12, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is > specified, all of them must be specified. > > For contrast, > > - radio buttons: a group of options where only one can be specified > (mutually exclusive) > - check boxes:?? a group of options that are independent of each other > (any number of > ???????????????? them may be specified) > > - ???: a group of options where, if one is specified, all must be > specified (mutually > ?????? inclusive) > > So far, I have come up with: > > - the Three Musketeers > - clique > - club > - best friends > - tight knit > - group > > Is there a name out there already to describe that concept? > > -- > ~Ethan~ From lucas at bourneuf.net Wed Feb 24 11:25:15 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 17:25:15 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: Hi, thanks for your answer ! I updated everything, including certificates, while upgrading to python 3.9, and retried today (no new certificates to install). I am the administrator of the wiki i try to access, and didn't do black magic in the configuration.. The error really seems to came from 3.8 or 3.9, since i can still reach the wiki nominally with my (some being non-updated) machines using python 3.7. This didn't evolve since i discovered the problem few days ago. --lucas On 24/02/2021 16:20, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > On 2021-02-24 at 15:29:58 +0100, > lucas wrote: > >> I'm currently trying to understand an error when using the dokuwikixmlrpc >> python module, allowing to easily work with DokuWiki RPC interface. >> >> Another description of the problem : >> https://github.com/kynan/dokuwikixmlrpc/issues/8 >> >> Here is the code, tailored to work with the DokuWiki RPC interface: >> >> from urllib.parse import urlencode >> import xmlrpc.client as xmlrpclib >> >> URL = 'wiki.example.net' >> USER = 'user' >> PASSWD = 'password' >> USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' >> >> script = '/lib/exe/xmlrpc.php' >> url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) >> xmlrpclib.Transport.user_agent = USER_AGENT >> xmlrpclib.SafeTransport.user_agent = USER_AGENT >> proxy = xmlrpclib.ServerProxy(url) >> >> v = proxy.dokuwiki.getVersion() >> print(v) >> >> When ran with Python 3.7 (a personnal debian server, or a personal windows >> computer), i obtain the expected 'Release 2018-04-22a "Greebo"' as ouput. >> When ran with Python 3.9 (my personnal, manjaro machine), i obtain the >> following stacktrace: >> >> Traceback (most recent call last): >> File "/home/project/read.py", line 32, in >> v = proxy.dokuwiki.getVersion() >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__ >> return self.__send(self.__name, args) >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1456, in __request >> response = self.__transport.request( >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1160, in request >> return self.single_request(host, handler, request_body, verbose) >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1190, in >> single_request >> raise ProtocolError( >> xmlrpc.client.ProtocolError: > wiki.example.net/lib/exe/xmlrpc.php: 401 Unauthorized> > > At the risk of stating the obvious, it might actually be an > authentication problem. In addition to double checking the password: > > (1) make sure all of your certificates (under Arch Linux, on which > Manjaro is based), that's the ca-certificates package) are up to date; > and > > (2) check with whoever owns the wiki about any other certificates they > require. > > After that, all I know about XML RPC is to avoid it. :-) > >> I don't have the possibility to test this on python 3.8 specifically, but >> since the XML and XMLRPC modules have been updated in 3.8, and since 3.9 >> doesn't seems to introduce any change for them, i would expect 3.8 to >> introduce some change that dokuwikixmlrpc has somehow to take into >> consideration. >> >> Can anyone help me with that one ? I don't know anything about RPC and XML, >> i don't know what i need to do know to fix dokuwikixmlrpc. From rosuav at gmail.com Wed Feb 24 12:00:07 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Feb 2021 04:00:07 +1100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: On Thu, Feb 25, 2021 at 2:02 AM lucas wrote: > > Hi everyone, > > (Sorry for the double-send if any, i'm not sure the first send was > performed, maybe because of bounce errors according to mailman.) > > > I'm currently trying to understand an error when using the > dokuwikixmlrpc python module, allowing to easily work with DokuWiki RPC > interface. > > Another description of the problem : > https://github.com/kynan/dokuwikixmlrpc/issues/8 > > Here is the code, tailored to work with the DokuWiki RPC interface: > > from urllib.parse import urlencode > import xmlrpc.client as xmlrpclib > > URL = 'wiki.example.net' > USER = 'user' > PASSWD = 'password' > USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' > > script = '/lib/exe/xmlrpc.php' > url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) > xmlrpclib.Transport.user_agent = USER_AGENT > xmlrpclib.SafeTransport.user_agent = USER_AGENT > proxy = xmlrpclib.ServerProxy(url) > > v = proxy.dokuwiki.getVersion() > print(v) > > When ran with Python 3.7 (a personnal debian server, or a personal > windows computer), i obtain the expected 'Release 2018-04-22a "Greebo"' > as ouput. > When ran with Python 3.9 (my personnal, manjaro machine), i obtain the > following stacktrace: > > Traceback (most recent call last): > File "/home/project/read.py", line 32, in > v = proxy.dokuwiki.getVersion() > File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__ > return self.__send(self.__name, args) > File "/usr/lib/python3.9/xmlrpc/client.py", line 1456, in __request > response = self.__transport.request( > File "/usr/lib/python3.9/xmlrpc/client.py", line 1160, in request > return self.single_request(host, handler, request_body, verbose) > File "/usr/lib/python3.9/xmlrpc/client.py", line 1190, in > single_request > raise ProtocolError( > xmlrpc.client.ProtocolError: wiki.example.net/lib/exe/xmlrpc.php: 401 Unauthorized> > A properly-formed URL will start with a protocol. I don't know specifically what changed, but it's looking like something started rejecting malformed URLs. Try adding "http://" or "https://" to your URL (whichever is appropriate) and see if both versions will accept it. ChrisA From lucas at bourneuf.net Wed Feb 24 12:35:30 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 18:35:30 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: On 24/02/2021 18:00, Chris Angelico wrote: > On Thu, Feb 25, 2021 at 2:02 AM lucas wrote: >> >> Hi everyone, >> >> (Sorry for the double-send if any, i'm not sure the first send was >> performed, maybe because of bounce errors according to mailman.) >> >> >> I'm currently trying to understand an error when using the >> dokuwikixmlrpc python module, allowing to easily work with DokuWiki RPC >> interface. >> >> Another description of the problem : >> https://github.com/kynan/dokuwikixmlrpc/issues/8 >> >> Here is the code, tailored to work with the DokuWiki RPC interface: >> >> from urllib.parse import urlencode >> import xmlrpc.client as xmlrpclib >> >> URL = 'wiki.example.net' >> USER = 'user' >> PASSWD = 'password' >> USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' >> >> script = '/lib/exe/xmlrpc.php' >> url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) >> xmlrpclib.Transport.user_agent = USER_AGENT >> xmlrpclib.SafeTransport.user_agent = USER_AGENT >> proxy = xmlrpclib.ServerProxy(url) >> >> v = proxy.dokuwiki.getVersion() >> print(v) >> >> When ran with Python 3.7 (a personnal debian server, or a personal >> windows computer), i obtain the expected 'Release 2018-04-22a "Greebo"' >> as ouput. >> When ran with Python 3.9 (my personnal, manjaro machine), i obtain the >> following stacktrace: >> >> Traceback (most recent call last): >> File "/home/project/read.py", line 32, in >> v = proxy.dokuwiki.getVersion() >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1116, in __call__ >> return self.__send(self.__name, args) >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1456, in __request >> response = self.__transport.request( >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1160, in request >> return self.single_request(host, handler, request_body, verbose) >> File "/usr/lib/python3.9/xmlrpc/client.py", line 1190, in >> single_request >> raise ProtocolError( >> xmlrpc.client.ProtocolError: > wiki.example.net/lib/exe/xmlrpc.php: 401 Unauthorized> >> > > A properly-formed URL will start with a protocol. I don't know > specifically what changed, but it's looking like something started > rejecting malformed URLs. Try adding "http://" or "https://" to your > URL (whichever is appropriate) and see if both versions will accept > it. > > ChrisA > I did that, obtaining the following URL https://wiki.[?]/lib/exe/xmlrpc.php?u=[?]&p=[?] on my two currently available computer (laptop on 3.9, remote on 3.7), and the results is the same. For information, i'm uploading the same python program to my remote server (debian, 3.7), and running it with the same parameters as my laptop (manjaro, 3.9). My laptop is getting the 401, my server is getting the expected dokuwiki version. --lucas From rosuav at gmail.com Wed Feb 24 12:48:14 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Feb 2021 04:48:14 +1100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: On Thu, Feb 25, 2021 at 4:36 AM lucas wrote: > > A properly-formed URL will start with a protocol. I don't know > > specifically what changed, but it's looking like something started > > rejecting malformed URLs. Try adding "http://" or "https://" to your > > URL (whichever is appropriate) and see if both versions will accept > > it. > > > > ChrisA > > > > I did that, obtaining the following URL > > https://wiki.[?]/lib/exe/xmlrpc.php?u=[?]&p=[?] > > on my two currently available computer (laptop on 3.9, remote on 3.7), > and the results is the same. > > For information, i'm uploading the same python program to my remote > server (debian, 3.7), and running it with the same parameters as my > laptop (manjaro, 3.9). My laptop is getting the 401, my server is > getting the expected dokuwiki version. (I'm aware that you have some other actual domain, but I'll continue using "wiki.example.net" as per your original post.) Is it possible that there's some kind of server-based restriction? What happens if you call socket.gethostbyname("wiki.example.net") on both the laptop and the server - do you get back the same IP address? (Or use gethostbyname_ex, or possibly getaddrinfo if ipv6 support matters.) Also, just to make sure there's nothing stupid happening, try printing out the URL on both machines. Obviously censor the password before sharing it here, but mainly, make sure that the two are generating the exact same URL, just in case. Both are running 3.7+, so dict iteration order shouldn't be getting in your way, but I've seen crazier things before :) ChrisA From lucas at bourneuf.net Wed Feb 24 13:11:02 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 19:11:02 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> Message-ID: <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> On 24/02/2021 18:48, Chris Angelico wrote: > On Thu, Feb 25, 2021 at 4:36 AM lucas wrote: >>> A properly-formed URL will start with a protocol. I don't know >>> specifically what changed, but it's looking like something started >>> rejecting malformed URLs. Try adding "http://" or "https://" to your >>> URL (whichever is appropriate) and see if both versions will accept >>> it. >>> >>> ChrisA >>> >> >> I did that, obtaining the following URL >> >> https://wiki.[?]/lib/exe/xmlrpc.php?u=[?]&p=[?] >> >> on my two currently available computer (laptop on 3.9, remote on 3.7), >> and the results is the same. >> >> For information, i'm uploading the same python program to my remote >> server (debian, 3.7), and running it with the same parameters as my >> laptop (manjaro, 3.9). My laptop is getting the 401, my server is >> getting the expected dokuwiki version. > > (I'm aware that you have some other actual domain, but I'll continue > using "wiki.example.net" as per your original post.) > > Is it possible that there's some kind of server-based restriction? > What happens if you call socket.gethostbyname("wiki.example.net") on > both the laptop and the server - do you get back the same IP address? > (Or use gethostbyname_ex, or possibly getaddrinfo if ipv6 support > matters.) > > Also, just to make sure there's nothing stupid happening, try printing > out the URL on both machines. Obviously censor the password before > sharing it here, but mainly, make sure that the two are generating the > exact same URL, just in case. Both are running 3.7+, so dict iteration > order shouldn't be getting in your way, but I've seen crazier things > before :) > > ChrisA > Thanks for taking time to help me ! I added socket.gethostbyname("wiki.example.net") (i removed the https:// since it, obviously now i think about it, led to a socket error) in the program, so i could verify both the URL and IP are equivalent. I got the exact same URL and IP. To be sure, i let python run the comparison instead of only relying on my eyes. >>> 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' == 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' True >>> 'xx.xxx.xxx.197' == 'xx.xxx.xxx.197' True You gave me an idea: i checked the nginx log of the server hosting the dokuwiki instance, and got something of interest : [SERVER IP] - - [24/Feb/2021:19:08:31 +0100] "POST /lib/exe/xmlrpc.php?u=[USER]&p=[PASSWORD] HTTP/1.1" 200 209 "-" "Python-xmlrpc/3.7" [LAPTOP IP] - - [24/Feb/2021:19:08:35 +0100] "POST /lib/exe/xmlrpc.php HTTP/1.1" 401 433 "-" "Python-xmlrpc/3.9" It seems that the laptop is not sending the arguments, despite them being fed in the python code ? Now i think about it, my remote server host both the python program into 3.7, and the dokuwiki. One may think it could be the source of the problem. To prove it's not, i will test with another laptop (the one under windows, python 3.7, which successfully accessed the wiki while i was discovering the error on my manjaro laptop) as soon as possible. --lucas From rosuav at gmail.com Wed Feb 24 13:22:29 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Feb 2021 05:22:29 +1100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> Message-ID: On Thu, Feb 25, 2021 at 5:12 AM lucas wrote: > > On 24/02/2021 18:48, Chris Angelico wrote: > I added socket.gethostbyname("wiki.example.net") (i removed the https:// > since it, obviously now i think about it, led to a socket error) > in the program, so i could verify both the URL and IP are equivalent. > > I got the exact same URL and IP. To be sure, i let python run the > comparison instead of only relying on my eyes. > > >>> 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' == > 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' > True > >>> 'xx.xxx.xxx.197' == 'xx.xxx.xxx.197' > True Those URLs were printed out from each script, just before attempting the call? > You gave me an idea: i checked the nginx log of the server hosting the > dokuwiki instance, and got something of interest : > > [SERVER IP] - - [24/Feb/2021:19:08:31 +0100] "POST > /lib/exe/xmlrpc.php?u=[USER]&p=[PASSWORD] HTTP/1.1" 200 209 "-" > "Python-xmlrpc/3.7" > [LAPTOP IP] - - [24/Feb/2021:19:08:35 +0100] "POST /lib/exe/xmlrpc.php > HTTP/1.1" 401 433 "-" "Python-xmlrpc/3.9" > > It seems that the laptop is not sending the arguments, despite them > being fed in the python code ? Fascinating! Well, that does at least simplify things somewhat - instead of "why is this coming back 401", it's "why is this not sending credentials". > Now i think about it, my remote server host both the python program into > 3.7, and the dokuwiki. One may think it could be the source of the problem. > To prove it's not, i will test with another laptop (the one under > windows, python 3.7, which successfully accessed the wiki while i was > discovering the error on my manjaro laptop) as soon as possible. > More data is always good. ChrisA From lucas at bourneuf.net Wed Feb 24 14:13:11 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 20:13:11 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> Message-ID: <375f3055-3b46-f4b7-4a09-e8ffd40631f9@bourneuf.net> On 24/02/2021 19:22, Chris Angelico wrote: > On Thu, Feb 25, 2021 at 5:12 AM lucas wrote: >> >> On 24/02/2021 18:48, Chris Angelico wrote: >> I added socket.gethostbyname("wiki.example.net") (i removed the https:// >> since it, obviously now i think about it, led to a socket error) >> in the program, so i could verify both the URL and IP are equivalent. >> >> I got the exact same URL and IP. To be sure, i let python run the >> comparison instead of only relying on my eyes. >> >> >>> 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' == >> 'https://wiki.example.net/lib/exe/xmlrpc.php?u=user&p=password' >> True >> >>> 'xx.xxx.xxx.197' == 'xx.xxx.xxx.197' >> True > > Those URLs were printed out from each script, just before attempting the call? Yes. The program is that one : import socket import xmlrpc.client as xmlrpclib from xml.parsers.expat import ExpatError from urllib.parse import urlencode URL = 'https://wiki.example.net' USER_AGENT = 'DokuWikiXMLRPC 1.0 for testing' script = '/lib/exe/xmlrpc.php' url = URL + script + '?' + urlencode({'u': USER, 'p': PASSWD}) print(url) print(socket.gethostbyname('wiki.example.net')) # xmlrpclib.Transport.user_agent = USER_AGENT # xmlrpclib.SafeTransport.user_agent = USER_AGENT proxy = xmlrpclib.ServerProxy(url) v = proxy.dokuwiki.getVersion() print(v) > >> You gave me an idea: i checked the nginx log of the server hosting the >> dokuwiki instance, and got something of interest : >> >> [SERVER IP] - - [24/Feb/2021:19:08:31 +0100] "POST >> /lib/exe/xmlrpc.php?u=[USER]&p=[PASSWORD] HTTP/1.1" 200 209 "-" >> "Python-xmlrpc/3.7" >> [LAPTOP IP] - - [24/Feb/2021:19:08:35 +0100] "POST /lib/exe/xmlrpc.php >> HTTP/1.1" 401 433 "-" "Python-xmlrpc/3.9" >> >> It seems that the laptop is not sending the arguments, despite them >> being fed in the python code ? > > Fascinating! Well, that does at least simplify things somewhat - > instead of "why is this coming back 401", it's "why is this not > sending credentials". Yes, we are going forward :) >> > > More data is always good. > > ChrisA I tested from the windows computer (Python 3.8, it appears, not 3.7 as i thought), and got the following nginx log: [LAPTOP IP] - - [24/Feb/2021:20:06:42 +0100] "POST /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" "DokuWikiXMLRPC 1.0 for testing windows" That other laptop also had an ubuntu installed, with python 3.6.9, so i ran the program and got the expected output, and the following nginx log: [LAPTOP IP] - - [24/Feb/2021:20:04:04 +0100] "POST /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" "DokuWikiXMLRPC 1.0 for testing ubuntu" Both accessed correctly the dokuwiki version. Unless this is a platform specific problem, it seems to narrow it to 3.9. --lucas From rosuav at gmail.com Wed Feb 24 14:21:06 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Feb 2021 06:21:06 +1100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: <375f3055-3b46-f4b7-4a09-e8ffd40631f9@bourneuf.net> References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> <375f3055-3b46-f4b7-4a09-e8ffd40631f9@bourneuf.net> Message-ID: On Thu, Feb 25, 2021 at 6:14 AM lucas wrote: > I tested from the windows computer (Python 3.8, it appears, not 3.7 as i > thought), and got the following nginx log: > > [LAPTOP IP] - - [24/Feb/2021:20:06:42 +0100] "POST > /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" > "DokuWikiXMLRPC 1.0 for testing windows" > > That other laptop also had an ubuntu installed, with python 3.6.9, so i > ran the program and got the expected output, and the following nginx log: > [LAPTOP IP] - - [24/Feb/2021:20:04:04 +0100] "POST > /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" > "DokuWikiXMLRPC 1.0 for testing ubuntu" > > Both accessed correctly the dokuwiki version. Unless this is a platform > specific problem, it seems to narrow it to 3.9. > Curious. I think, at this point, we need a repeatable test case. Wonder how hard it would be to make a single Python script that has a tiny server and a tiny client, and tries to connect them. ChrisA From Marco.Sulla.Python at gmail.com Wed Feb 24 15:10:51 2021 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Wed, 24 Feb 2021 21:10:51 +0100 Subject: use set notation for repr of dict_keys? In-Reply-To: References: <20210220082529.Horde.TykxeHt_vaZg4j210vHQM1N@wmail.sprit.org> <0dd1fd10-d02c-5c12-a95a-6f43c3eed0f1@DancesWithMice.info> <361cc065-c020-4b30-bcd3-5ade64c0a868@www.fastmail.com> Message-ID: On Wed, 24 Feb 2021 at 15:02, Random832 wrote: > On Wed, Feb 24, 2021, at 02:59, Marco Sulla wrote: > > On Wed, 24 Feb 2021 at 06:29, Random832 wrote: > > > I was surprised, though, to find that you can't remove items directly from the key set, or in general update it in place with &= or -= (these operators work, but give a new set object). > > > > This is because they are a view. Changing the key object means you > > will change the underlying dict. Probably not that you want or expect. > > Why wouldn't it be what I want or expect? Java allows exactly this I didn't know this. I like Java, but IMHO it's quite confusing that you can remove a key from a Map using the keys object. In my mind it's more natural to think views as read-only, while changes can be done only using the original object. But maybe my mind has too strict bounds. > [and it's the only way provided to, for example, remove all keys matching a > predicate in a single pass... an operation that Python sets don't support either] I hope indeed that someday Python can do: filtered_dict = a_dict - a_set From carlamolinagrane at gmail.com Wed Feb 24 14:36:58 2021 From: carlamolinagrane at gmail.com (Carla Molina) Date: Wed, 24 Feb 2021 20:36:58 +0100 Subject: Bug report Message-ID: I found the following bug (python 3.9.1) when multiplying an array by several variables without parentheses; look at the following example: import numpy as np NR = 0.25 N = 60461826 initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) print('First result ' +str(initialINCIDENCE)) initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) initialINCIDENCE = initialINCIDENCE*(N/(100000*7*NR)) print('Second result ' +str(initialINCIDENCE)) The result given is: First result [ 345.49614857 -7267.86283429 10006.94459429 2739.08176 -4528.78107429 -11796.64390857 5478.16352 ] Second result [ 345.49614857 17274.80742857 34549.61485714 51824.42228571 69099.22971429 86374.03714286 103648.84457143] Clearly both are different, and in particular the first one has no sense to me. Thank you, Carla. From alan.gauld at yahoo.co.uk Wed Feb 24 15:40:04 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Wed, 24 Feb 2021 20:40:04 +0000 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: On 24/02/2021 16:12, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is specified, all of them must be specified. > > For contrast, > > - radio buttons: a group of options where only one can be specified (mutually exclusive) > - check boxes: a group of options that are independent of each other (any number of > them may be specified) > > - ???: a group of options where, if one is specified, all must be specified (mutually > inclusive) Given that radio buttons and check boxes are all effectively using boolean states, doesn't this mean none of the group or all of the group? In which case it's a single boolean value - a check box that controls all options. I suspect I'm missing something... -- 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 From ethan at stoneleaf.us Wed Feb 24 15:45:17 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 24 Feb 2021 12:45:17 -0800 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: On 2/24/21 8:28 AM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > Entangled? Hey, I like that one! ;-) -- ~Ethan~ From __peter__ at web.de Wed Feb 24 15:57:29 2021 From: __peter__ at web.de (Peter Otten) Date: Wed, 24 Feb 2021 21:57:29 +0100 Subject: Bug report In-Reply-To: References: Message-ID: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> On 24/02/2021 20:36, Carla Molina wrote: > I found the following bug (python 3.9.1) when multiplying an array by > several variables without parentheses; look at the following example: > > import numpy as np > > NR = 0.25 > N = 60461826 > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) > print('First result ' +str(initialINCIDENCE)) > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*(N/(100000*7*NR)) > print('Second result ' +str(initialINCIDENCE)) > > The result given is: > > First result [ 345.49614857 -7267.86283429 10006.94459429 2739.08176 > -4528.78107429 -11796.64390857 5478.16352 ] > Second result [ 345.49614857 17274.80742857 34549.61485714 > 51824.42228571 69099.22971429 86374.03714286 103648.84457143] > > Clearly both are different, and in particular the first one has no sense to > me. This is not a bug. Have a look at the array's dtype: >>> n = 60461826 >>> a = np.array([1, 50, 100, 150, 200, 250, 300]) >>> a.dtype dtype('int32') A 32-bit integer cannot hold the result of, e. g. 50 * n, the result is unhelpfully clipped. One possible fix is to specify the array type: >>> b = np.array([1, 50, 100, 150, 200, 250, 300], dtype=float) >>> b * n array([6.04618260e+07, 3.02309130e+09, 6.04618260e+09, 9.06927390e+09, 1.20923652e+10, 1.51154565e+10, 1.81385478e+10]) From __peter__ at web.de Wed Feb 24 15:57:29 2021 From: __peter__ at web.de (Peter Otten) Date: Wed, 24 Feb 2021 21:57:29 +0100 Subject: Bug report In-Reply-To: References: Message-ID: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> On 24/02/2021 20:36, Carla Molina wrote: > I found the following bug (python 3.9.1) when multiplying an array by > several variables without parentheses; look at the following example: > > import numpy as np > > NR = 0.25 > N = 60461826 > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) > print('First result ' +str(initialINCIDENCE)) > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*(N/(100000*7*NR)) > print('Second result ' +str(initialINCIDENCE)) > > The result given is: > > First result [ 345.49614857 -7267.86283429 10006.94459429 2739.08176 > -4528.78107429 -11796.64390857 5478.16352 ] > Second result [ 345.49614857 17274.80742857 34549.61485714 > 51824.42228571 69099.22971429 86374.03714286 103648.84457143] > > Clearly both are different, and in particular the first one has no sense to > me. This is not a bug. Have a look at the array's dtype: >>> n = 60461826 >>> a = np.array([1, 50, 100, 150, 200, 250, 300]) >>> a.dtype dtype('int32') A 32-bit integer cannot hold the result of, e. g. 50 * n, the result is unhelpfully clipped. One possible fix is to specify the array type: >>> b = np.array([1, 50, 100, 150, 200, 250, 300], dtype=float) >>> b * n array([6.04618260e+07, 3.02309130e+09, 6.04618260e+09, 9.06927390e+09, 1.20923652e+10, 1.51154565e+10, 1.81385478e+10]) From drsalists at gmail.com Wed Feb 24 16:00:20 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 24 Feb 2021 13:00:20 -0800 Subject: Bug report In-Reply-To: References: Message-ID: I'm getting: /usr/local/cpython-2.7/bin/python (2.7.16) bad ('numpy version:', '1.16.6') Traceback (most recent call last): File "./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.0371429 != 86374.0371429 /usr/local/cpython-3.0/bin/python (3.0.1) bad No numpy found /usr/local/cpython-3.1/bin/python (3.1.5) bad No numpy found /usr/local/cpython-3.2/bin/python (3.2.5) bad No numpy found /usr/local/cpython-3.3/bin/python (3.3.7) bad No numpy found /usr/local/cpython-3.4/bin/python (3.4.8) bad No numpy found /usr/local/cpython-3.5/bin/python (3.5.5) bad numpy version: 1.18.5 Traceback (most recent call last): File "./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.03714285714 != 86374.03714285715 /usr/local/cpython-3.6/bin/python (3.6.0) bad numpy version: 1.18.1 Traceback (most recent call last): File "./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.03714285714 != 86374.03714285715 /usr/local/cpython-3.7/bin/python (3.7.0) bad numpy version: 1.19.0 Traceback (most recent call last): File "./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.03714285714 != 86374.03714285715 /usr/local/cpython-3.8/bin/python (3.8.0) bad numpy version: 1.19.0 Traceback (most recent call last): File "./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.03714285714 != 86374.03714285715 /usr/local/cpython-3.9/bin/python (3.9.0) bad numpy version: 1.19.4 Traceback (most recent call last): File "/home/dstromberg/src/stack-overflow,python-list/numpy-initial-incidence/./nii", line 31, in assert left == right, "{} != {}".format(left, right) AssertionError: 86374.03714285714 != 86374.03714285715 So the difference is tiny for me, and can be imputed to rounding error. Multiplying the big terms first before dividing naturally gives less rounding error. As far as why your install is having problems, I don't really know. What version of numpy are you using? On Wed, Feb 24, 2021 at 12:12 PM Carla Molina wrote: > I found the following bug (python 3.9.1) when multiplying an array by > several variables without parentheses; look at the following example: > > import numpy as np > > NR = 0.25 > N = 60461826 > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) > print('First result ' +str(initialINCIDENCE)) > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*(N/(100000*7*NR)) > print('Second result ' +str(initialINCIDENCE)) > > The result given is: > > First result [ 345.49614857 -7267.86283429 10006.94459429 2739.08176 > -4528.78107429 -11796.64390857 5478.16352 ] > Second result [ 345.49614857 17274.80742857 34549.61485714 > 51824.42228571 69099.22971429 86374.03714286 103648.84457143] > > Clearly both are different, and in particular the first one has no sense to > me. > Thank you, > > Carla. > -- > https://mail.python.org/mailman/listinfo/python-list > From drsalists at gmail.com Wed Feb 24 16:03:41 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 24 Feb 2021 13:03:41 -0800 Subject: Bug report In-Reply-To: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> References: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> Message-ID: On Wed, Feb 24, 2021 at 12:58 PM Peter Otten <__peter__ at web.de> wrote: > On 24/02/2021 20:36, Carla Molina wrote: > This is not a bug. Have a look at the array's dtype: > > >>> n = 60461826 > >>> a = np.array([1, 50, 100, 150, 200, 250, 300]) > >>> a.dtype > dtype('int32') > I'm getting dtypes of float64. From ethan at stoneleaf.us Wed Feb 24 16:05:05 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 24 Feb 2021 13:05:05 -0800 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> On 2/24/21 12:40 PM, Alan Gauld via Python-list wrote: > On 24/02/2021 16:12, Ethan Furman wrote: >> I'm looking for a name for a group of options that, when one is specified, all of them must be specified. >> >> For contrast, >> >> - radio buttons: a group of options where only one can be specified (mutually exclusive) >> - check boxes: a group of options that are independent of each other (any number of >> them may be specified) >> >> - ???: a group of options where, if one is specified, all must be specified (mutually >> inclusive) > > Given that radio buttons and check boxes are all effectively > using boolean states, doesn't this mean none of the group > or all of the group? > > In which case it's a single boolean value - a check box that > controls all options. > > I suspect I'm missing something... > radio buttons (none or one): t-shirt size: Small Medium Large check boxes (none or one or several or all): sandwich toppings: lettuce tomato onion cheese entangled (none or all): image size override: height width -- ~Ethan~ From __peter__ at web.de Wed Feb 24 16:15:19 2021 From: __peter__ at web.de (Peter Otten) Date: Wed, 24 Feb 2021 22:15:19 +0100 Subject: Bug report In-Reply-To: References: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> Message-ID: <4fef8d82-9747-2d8e-a564-861670e69656@web.de> On 24/02/2021 22:03, Dan Stromberg wrote: > On Wed, Feb 24, 2021 at 12:58 PM Peter Otten <__peter__ at web.de> wrote: > >> On 24/02/2021 20:36, Carla Molina wrote: >> This is not a bug. Have a look at the array's dtype: >> >> >>> n = 60461826 >> >>> a = np.array([1, 50, 100, 150, 200, 250, 300]) >> >>> a.dtype >> dtype('int32') >> > I'm getting dtypes of float64. When you run the snippet above or > import numpy as np > > NR = 0.25 > N = 60461826 > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) here, i. e. after the division? initialINCIDENCE*N should be an int32 array, but dividing by (100000*7*NR) returns an dtype=float64 array. Switching back to my modified example: >>> a/42 array([0.02380952, 1.19047619, 2.38095238, 3.57142857, 4.76190476, 5.95238095, 7.14285714]) >>> _.dtype dtype('float64') From __peter__ at web.de Wed Feb 24 16:15:19 2021 From: __peter__ at web.de (Peter Otten) Date: Wed, 24 Feb 2021 22:15:19 +0100 Subject: Bug report In-Reply-To: References: <5ae85a18-66b5-1514-af6a-1c6ed66d2de6@web.de> Message-ID: <4fef8d82-9747-2d8e-a564-861670e69656@web.de> On 24/02/2021 22:03, Dan Stromberg wrote: > On Wed, Feb 24, 2021 at 12:58 PM Peter Otten <__peter__ at web.de> wrote: > >> On 24/02/2021 20:36, Carla Molina wrote: >> This is not a bug. Have a look at the array's dtype: >> >> >>> n = 60461826 >> >>> a = np.array([1, 50, 100, 150, 200, 250, 300]) >> >>> a.dtype >> dtype('int32') >> > I'm getting dtypes of float64. When you run the snippet above or > import numpy as np > > NR = 0.25 > N = 60461826 > > initialINCIDENCE = np.array([1, 50, 100, 150, 200, 250, 300]) > initialINCIDENCE = initialINCIDENCE*N/(100000*7*NR) here, i. e. after the division? initialINCIDENCE*N should be an int32 array, but dividing by (100000*7*NR) returns an dtype=float64 array. Switching back to my modified example: >>> a/42 array([0.02380952, 1.19047619, 2.38095238, 3.57142857, 4.76190476, 5.95238095, 7.14285714]) >>> _.dtype dtype('float64') From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 24 16:23:04 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 24 Feb 2021 15:23:04 -0600 Subject: name for a mutually inclusive relationship In-Reply-To: <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> Message-ID: On 2021-02-24 at 13:05:05 -0800, Ethan Furman wrote: > entangled (none or all): > > image size override: height width IMO, that's *one* option (-s 640x480 or -s 640,480), not two. In argparse/optparse terms, a required argument with a custom type. (OTOH, in a GUI, it'd be two separate mandatory text fields, both controlled (i.e., enabled or disabled) by one checkbox.) From ethan at stoneleaf.us Wed Feb 24 16:31:42 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 24 Feb 2021 13:31:42 -0800 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> Message-ID: <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> On 2/24/21 1:23 PM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: >> entangled (none or all): >> >> image size override: height width > > IMO, that's *one* option (-s 640x480 or -s 640,480), not two. In > argparse/optparse terms, a required argument with a custom type. > > (OTOH, in a GUI, it'd be two separate mandatory text fields, both > controlled (i.e., enabled or disabled) by one checkbox.) I didn't say it was a good example. ;-) Hopefully it gets the idea across. -- ~Ethan~ From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Feb 24 16:54:44 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 24 Feb 2021 15:54:44 -0600 Subject: name for a mutually inclusive relationship In-Reply-To: <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> Message-ID: On 2021-02-24 at 13:31:42 -0800, Ethan Furman wrote: > On 2/24/21 1:23 PM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > > > > entangled (none or all): > > > > > > image size override: height width > > > > IMO, that's *one* option (-s 640x480 or -s 640,480), not two. In > > argparse/optparse terms, a required argument with a custom type. > > > > (OTOH, in a GUI, it'd be two separate mandatory text fields, both > > controlled (i.e., enabled or disabled) by one checkbox.) > > I didn't say it was a good example. ;-) Hopefully it gets the idea across. Ditto. ;-) IMO, the whole idea of "my program has two options, and the user has to specify both or neither," isn't a question of whether or not the argument parsing library supports it, but a question of whether or not it's a good API. Is the following a good API for a function? def override_image_size(image, height=0, width=0): '''specify height and width, or set both to 0''' if (height == 0 and width != 0) or (height != 0 and width == 0): raise ArgumentError('both or neither') if height != 0 and width != 0: image.height = height image.width = width Or would you more likely write something like this: def override_image_size(image, size): '''size is a (height, width) tuple''' image.height, image.width = size So why is the former a good API for a command line utility? Or maybe I don't write command line utilitis with sufficiently complex argument structures. From Bischoop at vimart.net Wed Feb 24 16:57:59 2021 From: Bischoop at vimart.net (Bischoop) Date: Wed, 24 Feb 2021 21:57:59 -0000 (UTC) Subject: Tkinter new window contentent when button is clicked. Message-ID: I'm learning Tkinter now and have upgraded few programs I've made in CLI in the past. What is bothering me now is what I should look at when I want new content in a window when button is 'Next' is clicked. In some programs we're clicking button next and new content appears in same window. I've used so far Toplevel(root) and new window was appearing on top the main one but I'd like to find out about solution without creating new windows. Is it a Canvas used for it? I'd be glad if you could direct me because I don't know even what to look for. -- Thanks From lucas at bourneuf.net Wed Feb 24 17:05:51 2021 From: lucas at bourneuf.net (lucas) Date: Wed, 24 Feb 2021 23:05:51 +0100 Subject: XML RPC changes between 3.7 and 3.9 yield 401 http error In-Reply-To: References: <11f81c52-ba66-9f2b-f1f4-3fedd0279ded@bourneuf.net> <32ee5ea5-ca33-81f4-77b2-73c17bfbeb53@bourneuf.net> <375f3055-3b46-f4b7-4a09-e8ffd40631f9@bourneuf.net> Message-ID: On 24/02/2021 20:21, Chris Angelico wrote: > On Thu, Feb 25, 2021 at 6:14 AM lucas wrote: >> I tested from the windows computer (Python 3.8, it appears, not 3.7 as i >> thought), and got the following nginx log: >> >> [LAPTOP IP] - - [24/Feb/2021:20:06:42 +0100] "POST >> /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" >> "DokuWikiXMLRPC 1.0 for testing windows" >> >> That other laptop also had an ubuntu installed, with python 3.6.9, so i >> ran the program and got the expected output, and the following nginx log: >> [LAPTOP IP] - - [24/Feb/2021:20:04:04 +0100] "POST >> /lib/exe/xmlrpc.php?u=[user]&p=[password] HTTP/1.1" 200 209 "-" >> "DokuWikiXMLRPC 1.0 for testing ubuntu" >> >> Both accessed correctly the dokuwiki version. Unless this is a platform >> specific problem, it seems to narrow it to 3.9. >> > > Curious. > > I think, at this point, we need a repeatable test case. Wonder how > hard it would be to make a single Python script that has a tiny server > and a tiny client, and tries to connect them. > > ChrisA > I will work on that tomorrow. Thanks for your guidance, i will come back with a repeatable test case. Best regards, --lucas From ethan at stoneleaf.us Wed Feb 24 17:13:40 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 24 Feb 2021 14:13:40 -0800 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> Message-ID: On 2/24/21 1:54 PM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > Ethan Furman wrote: >> I didn't say it was a good example. ;-) Hopefully it gets the idea across. > > Ditto. ;-) > > IMO, the whole idea of "my program has two options, and the user has to > specify both or neither," isn't a question of whether or not the > argument parsing library supports it, but a question of whether or not > it's a good API. Like I said, at this moment I don't have a good example, only an awareness that such a thing could exist and I don't know the name for it (if it has one). So far I have seen that there are even fewer good use-cases than I might have guessed, and that no one seems to have a name for the general idea. -- ~Ethan~ From Bischoop at vimart.net Wed Feb 24 18:08:07 2021 From: Bischoop at vimart.net (Bischoop) Date: Wed, 24 Feb 2021 23:08:07 -0000 (UTC) Subject: Tkinter new window contentent when button is clicked. References: Message-ID: On 2021-02-24, Bischoop wrote: > Just came to solution, I learnt that the combobox can be bind and call function when combobox value changes. -- Thanks From research at johnohagan.com Wed Feb 24 18:23:38 2021 From: research at johnohagan.com (John O'Hagan) Date: Thu, 25 Feb 2021 10:23:38 +1100 Subject: Tkinter long-running window freezes In-Reply-To: <9284d32a-d9a3-8335-ab54-13192a7c156f@mrabarnett.plus.com> References: <20210224220031.5ce59f6b@e7240.home> <9284d32a-d9a3-8335-ab54-13192a7c156f@mrabarnett.plus.com> Message-ID: <20210225102338.064ae456@e7240.home> On Wed, 24 Feb 2021 13:07:24 +0000 MRAB wrote: > On 2021-02-24 11:35, John O'Hagan wrote: [...] > > > > Here is some minimal, non-threaded code that reproduces the problem > > on my system (Xfce4 on Debian testing): > > > > from tkinter import * > > from random import randint > > > > root = Tk() > > > > def display(label): > > label.destroy() > > label = Label(text=randint(0, 9)) > > label.pack() > > root.after(100, display, label) > > > > display(Label()) > > mainloop() > > [...] > > This works for 3-4 hours, but eventually the window freezes. > > > > The process uses about 26 Mb of memory at first, and this gradually > > increases to around 30 or so by the time it freezes. > > > > Any ideas what could be causing this, or even how to approach > > debugging or workarounds? > > > The problem might be that you're adding the label using .pack but not > removing it with .pack_forget when you destroy it. > > Try doing both: > > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > if label is not None: > label.pack_forget() > label.destroy() > > label = Label(text=randint(0, 9)) > label.pack() > root.after(100, display, label) > > display(None) > mainloop() Thanks for the reply, I ran this overnight but unfortunately the result was the same. I'm not a tkinter expert at all, but I had gathered from the docs that calling destroy() on a widget was sufficient to cleanly remove the widget and all its children. Is that not the case? In case it's relevant, to clarify what I mean by "freeze": the window continues to display the digits indefinitely if no attempt is made to interact with the window, but after some hours have passed, if I click on the window the digits stop displaying, resizing causes fragmented images of the desktop to appear in the window, and it cannot be closed except by terminating the process (e.g, in a task manager). Thanks -- John From python.list at tim.thechases.com Wed Feb 24 17:52:33 2021 From: python.list at tim.thechases.com (Tim Chase) Date: Wed, 24 Feb 2021 16:52:33 -0600 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: <20210224165233.6fe63ba5@bigbox.attlocal.net> On 2021-02-24 08:12, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is > specified, all of them must be specified. [snip] > - ???: a group of options where, if one is specified, all must be > specified (mutually inclusive) [snip] > Is there a name out there already to describe that concept? For two items, the XNOR logical operator (effectively a "not (a xor b") has the desired truth-table. https://en.wikipedia.org/wiki/Xnor sometimes called a "logical biconditional" https://en.wikipedia.org/wiki/Logical_biconditional But in more human terms, the common phrase "all or nothing" seems to cover the concept pretty well. -tkc From research at johnohagan.com Wed Feb 24 18:53:55 2021 From: research at johnohagan.com (John O'Hagan) Date: Thu, 25 Feb 2021 10:53:55 +1100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> Message-ID: <20210225105355.2ef1d48a@e7240.home> On Wed, 24 Feb 2021 11:03:30 -0500 Terry Reedy wrote: > On 2/24/2021 6:35 AM, John O'Hagan wrote: [...] > > I am trying this out on Windows 10, with a wider label (so I can move > the window) and a button that changes when pressed, and a sequential > counter. Will report when the Window freezes, or maybe a day if not. Thank you! I've only run a few tests because of how long it takes to freeze, but so far it seems that the trigger for the window freezing is any attempt to interact with it, e.g. clicking on it, so try doing that from time to time. > > from tkinter import * > > from random import randint > > > > root = Tk() > > > > def display(label): > > label.destroy() > > label = Label(text=randint(0, 9)) > > label.pack() > > root.after(100, display, label) > > > > display(Label()) > > mainloop() > > You could try with .grid instead. I used .pack in the example for simplicity, but in the real application where I first saw the problem, I am already using .grid. > > Plus you seem to have a memory leak and may need to replicate that. Can you explain what you mean by "replicate"? Each time I run the code snippet above, I get a similar gradual increase in memory use by the process. Surely it can't be that little bit of Python code that's causing it - it must be something in tkinter? Or X11? > > This works for 3-4 hours, but eventually the window freezes. > > > > The process uses about 26 Mb of memory at first, and this gradually > > increases to around 30 or so by the time it freezes. > Thanks -- John From python at mrabarnett.plus.com Wed Feb 24 19:27:33 2021 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 25 Feb 2021 00:27:33 +0000 Subject: Tkinter long-running window freezes In-Reply-To: <20210225102338.064ae456@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> <9284d32a-d9a3-8335-ab54-13192a7c156f@mrabarnett.plus.com> <20210225102338.064ae456@e7240.home> Message-ID: <0b92823d-cfc8-2a5e-c4da-9f78d4dd06d0@mrabarnett.plus.com> On 2021-02-24 23:23, John O'Hagan wrote: > On Wed, 24 Feb 2021 13:07:24 +0000 > MRAB wrote: > >> On 2021-02-24 11:35, John O'Hagan wrote: > [...] >> > >> > Here is some minimal, non-threaded code that reproduces the problem >> > on my system (Xfce4 on Debian testing): >> > >> > from tkinter import * >> > from random import randint >> > >> > root = Tk() >> > >> > def display(label): >> > label.destroy() >> > label = Label(text=randint(0, 9)) >> > label.pack() >> > root.after(100, display, label) >> > >> > display(Label()) >> > mainloop() >> > > [...] >> > This works for 3-4 hours, but eventually the window freezes. >> > >> > The process uses about 26 Mb of memory at first, and this gradually >> > increases to around 30 or so by the time it freezes. >> > >> > Any ideas what could be causing this, or even how to approach >> > debugging or workarounds? >> > >> The problem might be that you're adding the label using .pack but not >> removing it with .pack_forget when you destroy it. >> >> Try doing both: >> >> from tkinter import * >> from random import randint >> >> root = Tk() >> >> def display(label): >> if label is not None: >> label.pack_forget() >> label.destroy() >> >> label = Label(text=randint(0, 9)) >> label.pack() >> root.after(100, display, label) >> >> display(None) >> mainloop() > > Thanks for the reply, I ran this overnight but unfortunately the result > was the same. > > I'm not a tkinter expert at all, but I had gathered from the docs that > calling destroy() on a widget was sufficient to cleanly remove the > widget and all its children. Is that not the case? > > In case it's relevant, to clarify what I mean by "freeze": the window > continues to display the digits indefinitely if no attempt is made to > interact with the window, but after some hours have passed, if I click > on the window the digits stop displaying, resizing causes fragmented > images of the desktop to appear in the window, and it cannot be closed > except by terminating the process (e.g, in a task manager). > Hmm. A memory leak perhaps? It's more noticeable if you reduce the timeout from 100 to 1. A workaround is to update the label's text instead: from tkinter import * from random import randint root = Tk() def update(): label.config(text=randint(0, 9)) root.after(1, update) label = Label() label.pack() update() mainloop() It's neater anyway. From dlevicki at gmail.com Wed Feb 24 19:42:14 2021 From: dlevicki at gmail.com (Davor Levicki) Date: Wed, 24 Feb 2021 16:42:14 -0800 (PST) Subject: comparing two lists Message-ID: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> i have two lists list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] and when I loop through the list list_difference = [] for item in list1: if item not in list2: list_difference.append(item) and I managed to get the difference, but I need time as well because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries. I tried to convert it to the dictionary, but it overwrites with last key:value {'01:15' : 'def'} From python at mrabarnett.plus.com Wed Feb 24 20:01:35 2021 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 25 Feb 2021 01:01:35 +0000 Subject: Tkinter new window contentent when button is clicked. In-Reply-To: References: Message-ID: <24b7e6ba-c886-eba9-43c5-c816e88d66db@mrabarnett.plus.com> On 2021-02-24 21:57, Bischoop wrote: > > I'm learning Tkinter now and have upgraded few programs I've made in CLI > in the past. > What is bothering me now is what I should look at when I want new > content in a window when button is 'Next' is clicked. In some programs > we're clicking button next and new content appears in same window. > I've used so far Toplevel(root) and new window was appearing on top the > main one but I'd like to find out about solution without creating new > windows. Is it a Canvas used for it? > I'd be glad if you could direct me because I don't know even what to > look for. > The trick is to put the "pages" on top of each other and then show the appropriate one, something like this: import tkinter as tk def on_next_page(): # Brings page 2 to the top. frame_2.tkraise() def on_previous_page(): # Brings page 1 to the top. frame_1.tkraise() def on_finish(): # Closes the dialog. root.destroy() root = tk.Tk() # Page 1. frame_1 = tk.Frame(root) tk.Label(frame_1, text='Page 1').pack() tk.Button(frame_1, text='Next', command=on_next_page).pack() # Page 2. frame_2 = tk.Frame() tk.Label(frame_2, text='Page 2').pack() tk.Button(frame_2, text='Previous', command=on_previous_page).pack() tk.Button(frame_2, text='Finish', command=on_finish).pack() # Put the pages on top of each other. frame_1.grid(row=0, column=0, sticky='news') frame_2.grid(row=0, column=0, sticky='news') # Bring page 1 to the top. frame_1.tkraise() tk.mainloop() From larry.martell at gmail.com Wed Feb 24 20:09:41 2021 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 24 Feb 2021 17:09:41 -0800 Subject: comparing two lists In-Reply-To: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> References: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> Message-ID: On Wed, Feb 24, 2021 at 4:45 PM Davor Levicki wrote: > > i have two lists > > list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] > list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] > > and when I loop through the list > > > list_difference = [] > for item in list1: > > if item not in list2: > list_difference.append(item) > > > and I managed to get the difference, but I need time as well > because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries. > I tried to convert it to the dictionary, but it overwrites with last key:value {'01:15' : 'def'} Instead of a list you could have a set of tuples and then just subtract them. From python at mrabarnett.plus.com Wed Feb 24 20:30:06 2021 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 25 Feb 2021 01:30:06 +0000 Subject: comparing two lists In-Reply-To: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> References: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> Message-ID: <5ed25b87-1dc9-67e8-d53f-827c7d80380e@mrabarnett.plus.com> On 2021-02-25 00:42, Davor Levicki wrote: > i have two lists > > list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] > list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] > > and when I loop through the list > > > list_difference = [] > for item in list1: > > if item not in list2: > list_difference.append(item) > > > and I managed to get the difference, but I need time as well > because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries. > I tried to convert it to the dictionary, but it overwrites with last key:value {'01:15' : 'def'} > If the items belong in pairs, try making the pairs first: >>> list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] >>> list(zip(list1[0 : : 2], list1[1 : : 2])) [('01:15', 'abc'), ('01:15', 'def'), ('01:45', 'ghi')] and then work from there. From avigross at verizon.net Thu Feb 25 00:04:51 2021 From: avigross at verizon.net (Avi Gross) Date: Thu, 25 Feb 2021 00:04:51 -0500 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> Message-ID: <0d9d01d70b33$c01072a0$403157e0$@verizon.net> Is there a more general idea here? How about asking for a control that internally manages N items and requires exactly M of them before the entry is accepted when you click? The case being discussed sort of wants N out of N, or nothing. Example, you order a family dinner from a Restaurant and are told that for a fixed price, you must order exactly 4 items from column A and another 5 from column B. Now linking the two is a bit much but if there are ten items in column A, the only valid choices might be to not order at all or pick exactly 4. Picking your first item would be easy and picking your second and third too. Once you have 4, the setup should sort of lock so you cannot add more. But if you unclick one, you should be able to select another. To get out of the setup you either stop at exactly 4 or cancel out. The problem with the N out of N case is that it is all or none. Unclicking anything in this case may not be enough and perhaps the code should clear all other items too. Clicking on any one, should mark all of them. So not really a simple subset of the cases. And what messages does a user get as they use the control? -----Original Message----- From: Python-list On Behalf Of Ethan Furman Sent: Wednesday, February 24, 2021 5:14 PM To: python-list at python.org Subject: Re: name for a mutually inclusive relationship On 2/24/21 1:54 PM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > Ethan Furman wrote: >> I didn't say it was a good example. ;-) Hopefully it gets the idea across. > > Ditto. ;-) > > IMO, the whole idea of "my program has two options, and the user has > to specify both or neither," isn't a question of whether or not the > argument parsing library supports it, but a question of whether or not > it's a good API. Like I said, at this moment I don't have a good example, only an awareness that such a thing could exist and I don't know the name for it (if it has one). So far I have seen that there are even fewer good use-cases than I might have guessed, and that no one seems to have a name for the general idea. -- ~Ethan~ -- https://mail.python.org/mailman/listinfo/python-list From frank at chagford.com Thu Feb 25 00:44:57 2021 From: frank at chagford.com (Frank Millman) Date: Thu, 25 Feb 2021 07:44:57 +0200 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: On 2021-02-24 6:12 PM, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is > specified, all of them must be specified. > > For contrast, > > - radio buttons: a group of options where only one can be specified > (mutually exclusive) > - check boxes:?? a group of options that are independent of each other > (any number of > ???????????????? them may be specified) > > - ???: a group of options where, if one is specified, all must be > specified (mutually > ?????? inclusive) > > So far, I have come up with: > > - the Three Musketeers > - clique > - club > - best friends > - tight knit > - group > > Is there a name out there already to describe that concept? > I have something vaguely similar, but my approach is different, so I don't know if this will be helpful or not. Take an example of a hospital admission form. One of the fields is 'Sex'. If the answer is Male, then certain fields are required, if the answer is Female, certain other fields are required. There can be more than one such occurrence on the same form. A field for 'Has Insurance?' could require insurance details if True, or payment method if False. I construct a dialog for each possibility, with all the fields associated with that possibility. Initially the dialogs are hidden. When the selection is made, the appropriate dialog is shown. The controlling field can have multiple options, so rather than a check-box, it is the equivalent of a radio-button. The term I use for this arrangement is 'sub-types'. Frank Millman From frank at chagford.com Thu Feb 25 00:44:57 2021 From: frank at chagford.com (Frank Millman) Date: Thu, 25 Feb 2021 07:44:57 +0200 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: On 2021-02-24 6:12 PM, Ethan Furman wrote: > I'm looking for a name for a group of options that, when one is > specified, all of them must be specified. > > For contrast, > > - radio buttons: a group of options where only one can be specified > (mutually exclusive) > - check boxes:?? a group of options that are independent of each other > (any number of > ???????????????? them may be specified) > > - ???: a group of options where, if one is specified, all must be > specified (mutually > ?????? inclusive) > > So far, I have come up with: > > - the Three Musketeers > - clique > - club > - best friends > - tight knit > - group > > Is there a name out there already to describe that concept? > I have something vaguely similar, but my approach is different, so I don't know if this will be helpful or not. Take an example of a hospital admission form. One of the fields is 'Sex'. If the answer is Male, then certain fields are required, if the answer is Female, certain other fields are required. There can be more than one such occurrence on the same form. A field for 'Has Insurance?' could require insurance details if True, or payment method if False. I construct a dialog for each possibility, with all the fields associated with that possibility. Initially the dialogs are hidden. When the selection is made, the appropriate dialog is shown. The controlling field can have multiple options, so rather than a check-box, it is the equivalent of a radio-button. The term I use for this arrangement is 'sub-types'. Frank Millman From rosuav at gmail.com Thu Feb 25 01:14:09 2021 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 25 Feb 2021 17:14:09 +1100 Subject: name for a mutually inclusive relationship In-Reply-To: <0d9d01d70b33$c01072a0$403157e0$@verizon.net> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> <0d9d01d70b33$c01072a0$403157e0$@verizon.net> Message-ID: On Thu, Feb 25, 2021 at 4:06 PM Avi Gross via Python-list wrote: > > Is there a more general idea here? How about asking for a control that > internally manages N items and requires exactly M of them before the entry > is accepted when you click? The case being discussed sort of wants N out of > N, or nothing. > YAGNI. ChrisA From research at johnohagan.com Thu Feb 25 02:20:07 2021 From: research at johnohagan.com (John O'Hagan) Date: Thu, 25 Feb 2021 18:20:07 +1100 Subject: Tkinter long-running window freezes In-Reply-To: <0b92823d-cfc8-2a5e-c4da-9f78d4dd06d0@mrabarnett.plus.com> References: <20210224220031.5ce59f6b@e7240.home> <9284d32a-d9a3-8335-ab54-13192a7c156f@mrabarnett.plus.com> <20210225102338.064ae456@e7240.home> <0b92823d-cfc8-2a5e-c4da-9f78d4dd06d0@mrabarnett.plus.com> Message-ID: <20210225182007.2f5dca1f@e7240.home> On Thu, 25 Feb 2021 00:27:33 +0000 MRAB wrote: > On 2021-02-24 23:23, John O'Hagan wrote: [...] > > In case it's relevant, to clarify what I mean by "freeze": the > > window continues to display the digits indefinitely if no attempt > > is made to interact with the window, but after some hours have > > passed, if I click on the window the digits stop displaying, > > resizing causes fragmented images of the desktop to appear in the > > window, and it cannot be closed except by terminating the process > > (e.g, in a task manager). > Hmm. A memory leak perhaps? It's more noticeable if you reduce the > timeout from 100 to 1. > A workaround is to update the label's text instead: > > from tkinter import * > from random import randint > > root = Tk() > > def update(): > label.config(text=randint(0, 9)) > root.after(1, update) > > label = Label() > label.pack() > update() > mainloop() > > It's neater anyway. That does avoid the problem in the toy example AFAICT, but as I mentioned in my OP, in the real application there are multiple streams of data which come and go, and each stream is displayed and controlled by a frame containing multiple widgets. The number of streams and therefore frames varies over time, so it seems necessary to create and destroy them. I could think about redesigning that whole approach, but it seems logical to me and it really should work! Terry Reedy also suggested a memory leak, but where? Surely not in the example code? Dare I say, maybe a bug in tkinter? Thanks for your suggestions. -- john From __peter__ at web.de Thu Feb 25 03:04:19 2021 From: __peter__ at web.de (Peter Otten) Date: Thu, 25 Feb 2021 09:04:19 +0100 Subject: comparing two lists In-Reply-To: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> References: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> Message-ID: On 25/02/2021 01:42, Davor Levicki wrote: > i have two lists > > list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] > list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] > > and when I loop through the list > > > list_difference = [] > for item in list1: > > if item not in list2: > list_difference.append(item) > > > and I managed to get the difference, but I need time as well > because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries. > I tried to convert it to the dictionary, but it overwrites with last key:value {'01:15' : 'def'} The problem is underspecified, but here's my guess: Are the even items unique? If so you can build the dicts with keys and values swapped: >>> list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] >>> list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] >>> d1 = dict(zip(list1[1::2], list1[::2])) >>> d2 = dict(zip(list2[1::2], list2[::2])) >>> d1 {'abc': '01:15', 'def': '01:15', 'ghi': '01:45'} >>> d2 {'abc': '01:15', 'uvz': '01:15', 'ghi': '01:45'} To calculate the difference: >>> d1.keys() - d2 {'def'} >>> {d1[k]: k for k in d1.keys() - d2} {'01:15': 'def'} From __peter__ at web.de Thu Feb 25 03:04:19 2021 From: __peter__ at web.de (Peter Otten) Date: Thu, 25 Feb 2021 09:04:19 +0100 Subject: comparing two lists In-Reply-To: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> References: <718c892a-ab33-4af4-98cc-94ba711886a1n@googlegroups.com> Message-ID: On 25/02/2021 01:42, Davor Levicki wrote: > i have two lists > > list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] > list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] > > and when I loop through the list > > > list_difference = [] > for item in list1: > > if item not in list2: > list_difference.append(item) > > > and I managed to get the difference, but I need time as well > because it is a separate item and 'uvz' does not mean to me anything in the list with a few thousand entries. > I tried to convert it to the dictionary, but it overwrites with last key:value {'01:15' : 'def'} The problem is underspecified, but here's my guess: Are the even items unique? If so you can build the dicts with keys and values swapped: >>> list1 = ['01:15', 'abc', '01:15', 'def', '01:45', 'ghi' ] >>> list2 = ['01:15', 'abc', '01:15', 'uvz', '01:45', 'ghi' ] >>> d1 = dict(zip(list1[1::2], list1[::2])) >>> d2 = dict(zip(list2[1::2], list2[::2])) >>> d1 {'abc': '01:15', 'def': '01:15', 'ghi': '01:45'} >>> d2 {'abc': '01:15', 'uvz': '01:15', 'ghi': '01:45'} To calculate the difference: >>> d1.keys() - d2 {'def'} >>> {d1[k]: k for k in d1.keys() - d2} {'01:15': 'def'} From tjreedy at udel.edu Thu Feb 25 09:54:15 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 25 Feb 2021 09:54:15 -0500 Subject: Tkinter long-running window freezes In-Reply-To: <20210225105355.2ef1d48a@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> <20210225105355.2ef1d48a@e7240.home> Message-ID: On 2/24/2021 6:53 PM, John O'Hagan wrote: > On Wed, 24 Feb 2021 11:03:30 -0500 > Terry Reedy wrote: > >> On 2/24/2021 6:35 AM, John O'Hagan wrote: > [...] >> >> I am trying this out on Windows 10, with a wider label (so I can move >> the window) and a button that changes when pressed, and a sequential >> counter. Will report when the Window freezes, or maybe a day if not. Counter is up to 777000 with no problem. > Thank you! I've only run a few tests because of how long it takes > to freeze, but so far it seems that the trigger for the window freezing > is any attempt to interact with it, e.g. clicking on it, so try doing > that from time to time. I clicked on Window, clicked on label, clicked on button (collectively at least 100 times), moved window all over screen, resized it multiple times, maximized it and restored it a couple of times, and no problem. I conclude for not that your issue does not occur on Windows. >> Plus you seem to have a memory leak and may need to replicate that. > > Can you explain what you mean by "replicate"? I don't remember, so forget it. -- Terry Jan Reedy From Richard at Damon-Family.org Thu Feb 25 11:06:05 2021 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 25 Feb 2021 11:06:05 -0500 Subject: Tkinter long-running window freezes In-Reply-To: <20210224220031.5ce59f6b@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> Message-ID: On 2/24/21 6:35 AM, John O'Hagan wrote: > Hi list > > I have a 3.9 tkinter interface that displays data from an arbitrary > number of threads, each of which runs for an arbitrary period of time. > A frame opens in the root window when each thread starts and closes > when it stops. Widgets in the frame and the root window control the > thread and how the data is displayed. > > This works well for several hours, but over time the root window > becomes unresponsive and eventually freezes and goes grey. No error > messages are produced in the terminal. > > Here is some minimal, non-threaded code that reproduces the problem on > my system (Xfce4 on Debian testing): > > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > label.destroy() > label = Label(text=randint(0, 9)) > label.pack() > root.after(100, display, label) > > display(Label()) > mainloop() > > This opens a tiny window that displays a random digit on a new label > every .1 second. (Obviously I could do this by updating the text rather > than recreating the label, but my real application has to destroy > widgets and create new ones). > > This works for 3-4 hours, but eventually the window freezes. > > The process uses about 26 Mb of memory at first, and this gradually > increases to around 30 or so by the time it freezes. > > Any ideas what could be causing this, or even how to approach debugging > or workarounds? > > Thanks > > -- > > John One thought is that repeatedly destroying and recreating a label might be leaking a resource. One option would be to change the code to just update the label rather than recreating it each time.? Simplest is probably to link the Label to a StringVar instead of a fixed text and updating the variable to change the text. You can also (I believe) go into the Label and change the text it has with a configuration call. -- Richard Damon From yili2005 at gmail.com Thu Feb 25 11:08:33 2021 From: yili2005 at gmail.com (Yi Li) Date: Thu, 25 Feb 2021 08:08:33 -0800 (PST) Subject: GridSearchCV generates unexpected different best parameters by only changing the parameters order in param_grid. Where did I make mistake and how to fix this unexpected results? Message-ID: I am using GridSearchCV to find the best parameter setting of my sklearn.pipeline estimator. The pipeline consists of data transformation, UMAP dimension reduction and Kmeans clustering. The final Kmeans clustering results are scored using silhouette_score. I tried to verify the whole pipeline/GridSearchCV worked correctly by only changing the parameter order in param_grid ( e.g., change 'reduce__n_neighbors': (5, 10), to 'reduce__n_neighbors': (10, 5)). I got totally different best parameters although I expect the parameter order change should not impact the best paramters determined by GridSearchCV. Where did I make mistake and how to fix this unexpected results? Below is the code. The Debug class is used to save the output from 'reduce' step. This saved output is used in cv_silhouette_scorer() to calculate silhouette_score. I suspect Debug class and cv_silhouette_scorer() did not work as I expected. I really appreciate your help. class Debug(BaseEstimator, TransformerMixin): def __init__(self): self.transX = None def transform(self, X): print(X) self.transX = X.copy() return X def fit(self, X, y=None, **fit_params): return self def cv_silhouette_scorer(estimator, X): # estimator.fit(X) sdata = estimator.named_steps['debug'].transX cluster_labels = estimator.named_steps['cluster'].labels_ num_labels = len(set(cluster_labels)) num_samples = sdata.shape[0] if num_labels == 1 or num_labels == num_samples: return -1 else: return silhouette_score(sdata, cluster_labels) ohe = OneHotEncoder(drop='if_binary', dtype=np.float32) ore = OrdinalEncoder(dtype=np.float32) ctenc = ColumnTransformer(transformers=[('ohe', ohe, nom_vars), ('ore', ore, ord_vars)], remainder='passthrough') nftr = FunctionTransformer(nominal_indicator_missing, check_inverse=False, kw_args={'feat_names': ohecols, 'orig_cols': nom_vars}) oftr = FunctionTransformer(ordinal_indicator_missing, check_inverse=False, kw_args={'miss_value': 0.}) ctmiss = ColumnTransformer(transformers=[('nftr', nftr, slice(0, 19)), ('oftr', oftr, slice(19, 20)), ('drop_cols', 'drop' , slice(32, 36) )], remainder='passthrough') mputer = IterativeImputer(random_state=RS, add_indicator=True, initial_strategy="most_frequent", skip_complete=True) # Add below keep_vars transformer to drop all demographic columns before pass to UMAP keep_cols = ColumnTransformer(transformers=[('keep_cols1', 'passthrough' , slice(17, 25) ), ('keep_cols2', 'passthrough' , slice(46, 54) )] ) scaler = StandardScaler() trans = FunctionTransformer(np.transpose, check_inverse=False) dreduce = umap.UMAP(random_state=RS) knn = KMeans(random_state=RS) pipe = Pipeline(steps=[ ('enc', ctenc) , ('functr', ctmiss) , ('mpute', mputer) , ('keep_cols', keep_cols) , ('scale', scaler) , ('trans', trans) , ('reduce', dreduce) , ("debug", Debug()) , ('cluster', knn) ] ) parameters = { 'mpute__max_iter': (15, 20), 'reduce__n_neighbors': (5, 10), 'reduce__min_dist': (0.02, 0.05), 'reduce__n_components': (2, 3), 'reduce__metric': ('euclidean', 'manhattan'), 'cluster__n_clusters': (2, 3), 'cluster__n_init': (10, 25) } # Changing parameter order above as below, GridSearchCV reports different best parameters. # parameters = { # 'mpute__max_iter': (20, 15), # 'reduce__n_neighbors': (10, 5), # 'reduce__min_dist': (0.05, 0.02), # 'reduce__n_components': (3, 2), # 'reduce__metric': ('manhattan', 'eucidean'), # 'cluster__n_clusters': (3, 2), # 'cluster__n_init': (25, 10) # } def cv_silhouette_scorer(estimator, X): # estimator.fit(X) sdata = estimator.named_steps['debug'].transX cluster_labels = estimator.named_steps['cluster'].labels_ num_labels = len(set(cluster_labels)) num_samples = sdata.shape[0] if num_labels == 1 or num_labels == num_samples: return -1 else: return silhouette_score(sdata, cluster_labels) gsearch3 = GridSearchCV(pipe, parameters, n_jobs=-1, scoring=cv_silhouette_scorer , cv=5, verbose=1) gsearch3.fit(dfnew) From yili2005 at gmail.com Thu Feb 25 11:14:23 2021 From: yili2005 at gmail.com (Yi Li) Date: Thu, 25 Feb 2021 08:14:23 -0800 (PST) Subject: GridSearchCV generates unexpected different best parameters by only changing the parameters order in param_grid. Please help! Message-ID: <5508d37f-2c27-44c4-9c48-edff1291e02en@googlegroups.com> I am using GridSearchCV to find the best parameter setting of my sklearn.pipeline estimator. The pipeline consists of data transformation, UMAP dimension reduction and Kmeans clustering. The final Kmeans clustering results are scored using silhouette_score. I tried to verify the whole pipeline/GridSearchCV worked correctly by only changing the parameter order in param_grid ( e.g., change 'reduce__n_neighbors': (5, 10), to 'reduce__n_neighbors': (10, 5)). I got totally different best parameters although I expect the parameter order change should not impact the best paramters determined by GridSearchCV. Where did I make mistake and how to fix this unexpected results? Below is the code. The Debug class is used to save the output from 'reduce' step. This saved output is used in cv_silhouette_scorer() to calculate silhouette_score. I suspect Debug class and cv_silhouette_scorer() did not work as I expected. I really appreciate your help. class Debug(BaseEstimator, TransformerMixin): def __init__(self): self.transX = None def transform(self, X): print(X) self.transX = X.copy() return X def fit(self, X, y=None, **fit_params): return self def cv_silhouette_scorer(estimator, X): # estimator.fit(X) sdata = estimator.named_steps['debug'].transX cluster_labels = estimator.named_steps['cluster'].labels_ num_labels = len(set(cluster_labels)) num_samples = sdata.shape[0] if num_labels == 1 or num_labels == num_samples: return -1 else: return silhouette_score(sdata, cluster_labels) ohe = OneHotEncoder(drop='if_binary', dtype=np.float32) ore = OrdinalEncoder(dtype=np.float32) ctenc = ColumnTransformer(transformers=[('ohe', ohe, nom_vars), ('ore', ore, ord_vars)], remainder='passthrough') nftr = FunctionTransformer(nominal_indicator_missing, check_inverse=False, kw_args={'feat_names': ohecols, 'orig_cols': nom_vars}) oftr = FunctionTransformer(ordinal_indicator_missing, check_inverse=False, kw_args={'miss_value': 0.}) ctmiss = ColumnTransformer(transformers=[('nftr', nftr, slice(0, 19)), ('oftr', oftr, slice(19, 20)), ('drop_cols', 'drop' , slice(32, 36) )], remainder='passthrough') mputer = IterativeImputer(random_state=RS, add_indicator=True, initial_strategy="most_frequent", skip_complete=True) # Add below keep_vars transformer to drop all demographic columns before pass to UMAP keep_cols = ColumnTransformer(transformers=[('keep_cols1', 'passthrough' , slice(17, 25) ), ('keep_cols2', 'passthrough' , slice(46, 54) )] ) scaler = StandardScaler() trans = FunctionTransformer(np.transpose, check_inverse=False) dreduce = umap.UMAP(random_state=RS) knn = KMeans(random_state=RS) pipe = Pipeline(steps=[ ('enc', ctenc) , ('functr', ctmiss) , ('mpute', mputer) , ('keep_cols', keep_cols) , ('scale', scaler) , ('trans', trans) , ('reduce', dreduce) , ("debug", Debug()) , ('cluster', knn) ] ) parameters = { 'mpute__max_iter': (15, 20), 'reduce__n_neighbors': (5, 10), 'reduce__min_dist': (0.02, 0.05), 'reduce__n_components': (2, 3), 'reduce__metric': ('euclidean', 'manhattan'), 'cluster__n_clusters': (2, 3), 'cluster__n_init': (10, 25) } # Changing parameter order above as below, GridSearchCV reports different best parameters. # parameters = { # 'mpute__max_iter': (20, 15), # 'reduce__n_neighbors': (10, 5), # 'reduce__min_dist': (0.05, 0.02), # 'reduce__n_components': (3, 2), # 'reduce__metric': ('manhattan', 'eucidean'), # 'cluster__n_clusters': (3, 2), # 'cluster__n_init': (25, 10) # } gsearch3 = GridSearchCV(pipe, parameters, n_jobs=-1, scoring=cv_silhouette_scorer , cv=5, verbose=1) gsearch3.fit(dfnew) From botao.liu at ucdconnect.ie Thu Feb 25 12:22:35 2021 From: botao.liu at ucdconnect.ie (Botao Liu) Date: Thu, 25 Feb 2021 17:22:35 +0000 Subject: error of opening Python Message-ID: Dear Python team, This is my first time using Python, I tried to launch Python and it showed "Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information." I don't know what this meant and how to fix this. Could you please help me? Thank you very much. Kind regards, Botao Liu From don81846 at comcast.net.invalid Thu Feb 25 14:37:08 2021 From: don81846 at comcast.net.invalid (DonK) Date: Thu, 25 Feb 2021 14:37:08 -0500 Subject: Does anyone know if there Is a 'Code Snippet' add-in for PyCharm Message-ID: <1uuf3ghpifkg7sqj7vuaeougfj5744go3r@4ax.com> Thank you Don From auriocus at gmx.de Thu Feb 25 15:57:19 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Thu, 25 Feb 2021 21:57:19 +0100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> Message-ID: Am 24.02.21 um 12:35 schrieb John O'Hagan: > Hi list > > I have a 3.9 tkinter interface that displays data from an arbitrary > number of threads, each of which runs for an arbitrary period of time. > A frame opens in the root window when each thread starts and closes > when it stops. Widgets in the frame and the root window control the > thread and how the data is displayed. > > This works well for several hours, but over time the root window > becomes unresponsive and eventually freezes and goes grey. No error > messages are produced in the terminal. > > Here is some minimal, non-threaded code that reproduces the problem on > my system (Xfce4 on Debian testing): > > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > label.destroy() > label = Label(text=randint(0, 9)) > label.pack() > root.after(100, display, label) > > display(Label()) > mainloop() > > This opens a tiny window that displays a random digit on a new label > every .1 second. (Obviously I could do this by updating the text rather > than recreating the label, but my real application has to destroy > widgets and create new ones). > > This works for 3-4 hours, but eventually the window freezes. I think it is not yet clear, if this is a bug in Tkinter or in Tcl/Tk, the underlying scripting language. It might also be platform dependent. Are you on Windows? Here is an equivalent Tcl program: ====================== package require Tk proc randint {} { expr {int(rand()*10000000)} } proc display {label} { destroy $label set id [randint] set label [label .l$id -text [randint]] pack $label after 100 [list display $label] } display [label .l] ======================== Can you run this and check that the freeze also occurs? If you can't execute the Tcl that is used by Python directly, you may also do something like root = Tk() root.eval('Here comes the Tcl code') root.mainloop() Can you also find out what version of Tcl/Tk you are using? Try root.eval('info patchlevel') Christian From mstemper at gmail.com Thu Feb 25 16:01:13 2021 From: mstemper at gmail.com (Michael F. Stemper) Date: Thu, 25 Feb 2021 15:01:13 -0600 Subject: error of opening Python In-Reply-To: References: Message-ID: On 25/02/2021 11.22, Botao Liu wrote: > Dear Python team, > > This is my first time using Python, I tried to launch Python and it showed > "Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 > bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information." I > don't know what this meant and how to fix this. Could you please help me? There isn't anything to fix. It's working just fine. -- Michael F. Stemper If you take cranberries and stew them like applesauce they taste much more like prunes than rhubarb does. From auriocus at gmx.de Thu Feb 25 17:54:44 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Thu, 25 Feb 2021 23:54:44 +0100 Subject: error of opening Python In-Reply-To: References: Message-ID: Am 25.02.21 um 18:22 schrieb Botao Liu: > Dear Python team, > > This is my first time using Python, I tried to launch Python and it showed > "Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 > bit (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information." I > don't know what this meant and how to fix this. Could you please help me? > Thank you very much. This is as it should be. What have you expected, that you think this is wrong? Maybe you are looking for an IDE like IDLE (should be installed along with Python on Windows), or something very different? Christian From research at johnohagan.com Thu Feb 25 18:32:47 2021 From: research at johnohagan.com (John O'Hagan) Date: Fri, 26 Feb 2021 10:32:47 +1100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> <20210225105355.2ef1d48a@e7240.home> Message-ID: <20210226103247.63cfcfb4@e7240.home> On Thu, 25 Feb 2021 09:54:15 -0500 Terry Reedy wrote: > On 2/24/2021 6:53 PM, John O'Hagan wrote: > > On Wed, 24 Feb 2021 11:03:30 -0500 > > Terry Reedy wrote: > > > >> On 2/24/2021 6:35 AM, John O'Hagan wrote: > > [...] > >> > >> I am trying this out on Windows 10, with a wider label (so I can > >> move the window) and a button that changes when pressed, and a > >> sequential counter. Will report when the Window freezes, or maybe > >> a day if not. > > Counter is up to 777000 with no problem. > > > Thank you! I've only run a few tests because of how long it takes > > to freeze, but so far it seems that the trigger for the window > > freezing is any attempt to interact with it, e.g. clicking on it, > > so try doing that from time to time. > > I clicked on Window, clicked on label, clicked on button > (collectively at least 100 times), moved window all over screen, > resized it multiple times, maximized it and restored it a couple of > times, and no problem. I conclude for not that your issue does not > occur on Windows. > > >> Plus you seem to have a memory leak and may need to replicate > >> that. > > > > Can you explain what you mean by "replicate"? > > I don't remember, so forget it. > Thanks for your efforts. So it seems to be something specific to my system, X11 or Tcl version, etc. From research at johnohagan.com Thu Feb 25 19:09:23 2021 From: research at johnohagan.com (John O'Hagan) Date: Fri, 26 Feb 2021 11:09:23 +1100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> Message-ID: <20210226110923.38e55db6@e7240.home> On Thu, 25 Feb 2021 11:06:05 -0500 Richard Damon wrote: > On 2/24/21 6:35 AM, John O'Hagan wrote: > > Here is some minimal, non-threaded code that reproduces the problem > > on my system (Xfce4 on Debian testing): > > > > from tkinter import * > > from random import randint > > > > root = Tk() > > > > def display(label): > > label.destroy() > > label = Label(text=randint(0, 9)) > > label.pack() > > root.after(100, display, label) > > > > display(Label()) > > mainloop() > > > > This opens a tiny window that displays a random digit on a new label > > every .1 second. (Obviously I could do this by updating the text > > rather than recreating the label, but my real application has to > > destroy widgets and create new ones). > > > > This works for 3-4 hours, but eventually the window freezes. > > > > The process uses about 26 Mb of memory at first, and this gradually > > increases to around 30 or so by the time it freezes. > > > > Any ideas what could be causing this, or even how to approach > > debugging or workarounds? > > > > Thanks > > > > -- > > > > John > > One thought is that repeatedly destroying and recreating a label might > be leaking a resource. One option would be to change the code to just > update the label rather than recreating it each time.? Simplest is > probably to link the Label to a StringVar instead of a fixed text and > updating the variable to change the text. You can also (I believe) go > into the Label and change the text it has with a configuration call. > Thanks for your reply. It's true that your suggested approach stops the leak (if that's what it is!) in the example code, but IMO there are valid use-cases where it's necessary (or at least desirable) to continually create new widgets and then destroy them in the course of running the application. In my use-case, the application reads YOLO object-recognition data from video, and displays data about each new object in a new frame. When the object ceases to be visible, the frame is destroyed. I suppose I could redesign, e.g. by withdrawing frames instead of destroying them, and keeping them in a pool to re-use later for new data streams as needed. I'll give that a try if I can't solve this issue. Thanks -- John From avigross at verizon.net Thu Feb 25 19:55:51 2021 From: avigross at verizon.net (Avi Gross) Date: Thu, 25 Feb 2021 19:55:51 -0500 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> <0d9d01d70b33$c01072a0$403157e0$@verizon.net> Message-ID: <099801d70bda$211f1460$635d3d20$@verizon.net> YAGNI? True, Chris, I never have. And if I ever did, I might not even know someone has implemented similar functionality with 86 optional function arguments that fine-tune what happens in various cases and what error messages to supply, LOL! So, I would end up re-implementing it myself. But isn't this true for so much software we discuss here. The usual mantra is that 80% of features are used maybe 20% of the time and a few are used never except maybe while testing. Realistically, it adds to bloat if a fairly well-defined object is extended to handle every possible feature that is allowed, and then some. We recently discussed the "+=" feature for an object when much of the time, it is pretty much as useful as just using the longer way of adding something to yourself. But loading a longer object description the 99% of the time when it is not used, also costs a bit. My comment was thus mostly academic and suggested realistic scenarios some people use commonly enough that might be possibly to implement to make it easier to deal with such a structure and that arguably such could also handle this edge case. No reason to think this is an important thing to add, just a category that could be doable. -----Original Message----- From: Python-list On Behalf Of Chris Angelico Sent: Thursday, February 25, 2021 1:14 AM To: Python Subject: Re: name for a mutually inclusive relationship On Thu, Feb 25, 2021 at 4:06 PM Avi Gross via Python-list wrote: > > Is there a more general idea here? How about asking for a control that > internally manages N items and requires exactly M of them before the > entry is accepted when you click? The case being discussed sort of > wants N out of N, or nothing. > YAGNI. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From alan.gauld at yahoo.co.uk Thu Feb 25 16:19:34 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Thu, 25 Feb 2021 21:19:34 +0000 Subject: error of opening Python In-Reply-To: References: Message-ID: On 25/02/2021 17:22, Botao Liu wrote: > Type "help", "copyright", "credits" or "license" for more information." Follow the instructions and type "help" at the >>> prompt. Then follow the instructions which it displays. -- 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 From randy.day at saskatel.netx Thu Feb 25 20:29:05 2021 From: randy.day at saskatel.netx (RD) Date: Thu, 25 Feb 2021 19:29:05 -0600 Subject: Where is the problem? Message-ID: Python 3.4.3 on WinXP. I create a Tk canvas and draw on it with create_text(), create_line(), and create_polygon with fill and stipple. So far, so good, looks fine on the screen. So I go to send it to a postsctript file: bmap.postscript(file="tmp.ps", colormode='color') It generates a file, no errors reported. So I open up the file in a PS viewer (2, actually), and the saved file looks like someone left a watercolor out in the rain. Artifacts everywhere, the lines are blurred, and the text is unreadable. Googling was unhelpful; did I miss something? TIA From python at mrabarnett.plus.com Thu Feb 25 21:26:39 2021 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 26 Feb 2021 02:26:39 +0000 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> Message-ID: On 2021-02-25 20:57, Christian Gollwitzer wrote: > Am 24.02.21 um 12:35 schrieb John O'Hagan: >> Hi list >> >> I have a 3.9 tkinter interface that displays data from an arbitrary >> number of threads, each of which runs for an arbitrary period of time. >> A frame opens in the root window when each thread starts and closes >> when it stops. Widgets in the frame and the root window control the >> thread and how the data is displayed. >> >> This works well for several hours, but over time the root window >> becomes unresponsive and eventually freezes and goes grey. No error >> messages are produced in the terminal. >> >> Here is some minimal, non-threaded code that reproduces the problem on >> my system (Xfce4 on Debian testing): >> >> from tkinter import * >> from random import randint >> >> root = Tk() >> >> def display(label): >> label.destroy() >> label = Label(text=randint(0, 9)) >> label.pack() >> root.after(100, display, label) >> >> display(Label()) >> mainloop() >> >> This opens a tiny window that displays a random digit on a new label >> every .1 second. (Obviously I could do this by updating the text rather >> than recreating the label, but my real application has to destroy >> widgets and create new ones). >> >> This works for 3-4 hours, but eventually the window freezes. > > > I think it is not yet clear, if this is a bug in Tkinter or in Tcl/Tk, > the underlying scripting language. It might also be platform dependent. > Are you on Windows? Here is an equivalent Tcl program: > > ====================== > package require Tk > > proc randint {} { > expr {int(rand()*10000000)} > } > > proc display {label} { > destroy $label > set id [randint] > set label [label .l$id -text [randint]] > pack $label > after 100 [list display $label] > } > > display [label .l] > ======================== > > > Can you run this and check that the freeze also occurs? If you can't > execute the Tcl that is used by Python directly, you may also do > something like > > > root = Tk() > root.eval('Here comes the Tcl code') > root.mainloop() > > Can you also find out what version of Tcl/Tk you are using? Try > > root.eval('info patchlevel') > I've just downloaded Tcl (Windows 10) and saw the same slow but steady rise in memory usage for that Tcl code (I reduced the timeout from 100 to 1 to speed it up). It looks like the leak, if that's what it is, is in Tcl. From pfeiffer at cs.nmsu.edu Thu Feb 25 22:03:52 2021 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Thu, 25 Feb 2021 20:03:52 -0700 Subject: name for a mutually inclusive relationship References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: <1bmtvrzg13.fsf@pfeifferfamily.net> Ethan Furman writes: > I'm looking for a name for a group of options that, when one is specified, all of them must be specified. I don't fully understand the question (yes, I read the part I snipped). Why is this not just a single option? Or is it hierarchical or something so option 1 implies options 2 and 3, but option 2 does not imply option 1? From pfeiffer at cs.nmsu.edu Thu Feb 25 22:06:13 2021 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Thu, 25 Feb 2021 20:06:13 -0700 Subject: name for a mutually inclusive relationship References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> Message-ID: <1bim6fzfx6.fsf@pfeifferfamily.net> Ethan Furman writes: > On 2/24/21 1:54 PM, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: >> Ethan Furman wrote: > >>> I didn't say it was a good example. ;-) Hopefully it gets the idea across. >> Ditto. ;-) >> IMO, the whole idea of "my program has two options, and the user has >> to >> specify both or neither," isn't a question of whether or not the >> argument parsing library supports it, but a question of whether or not >> it's a good API. > > Like I said, at this moment I don't have a good example, only an awareness that such a thing could exist and I don't know the name for it (if it has one). > > So far I have seen that there are even fewer good use-cases than I might have guessed, and that no one seems to have a name for the general idea. Do you have a specific problem you're trying to solve? That might help us understand the question better. From ethan at stoneleaf.us Thu Feb 25 23:30:30 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Thu, 25 Feb 2021 20:30:30 -0800 Subject: name for a mutually inclusive relationship In-Reply-To: <1bim6fzfx6.fsf@pfeifferfamily.net> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> <1bim6fzfx6.fsf@pfeifferfamily.net> Message-ID: On 2/25/21 7:06 PM, Joe Pfeiffer wrote: > Ethan Furman writes: >> Like I said, at this moment I don't have a good example, only an awareness that such a thing could exist and I don't know the name for it (if it has one). >> >> So far I have seen that there are even fewer good use-cases than I might have guessed, and that no one seems to have a name for the general idea. > > Do you have a specific problem you're trying to solve? No, I just came across the concept in my browsing and was wondering if there was a name for it. I think the most accurate name at this point is probably "pain in the butt". ;-) -- ~Ethan~ From research at johnohagan.com Fri Feb 26 00:15:06 2021 From: research at johnohagan.com (John O'Hagan) Date: Fri, 26 Feb 2021 16:15:06 +1100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> Message-ID: <20210226161506.72e9147b@e7240.home> On Thu, 25 Feb 2021 21:57:19 +0100 Christian Gollwitzer wrote: > Am 24.02.21 um 12:35 schrieb John O'Hagan: > > Hi list > > > > I have a 3.9 tkinter interface that displays data from an arbitrary > > number of threads, each of which runs for an arbitrary period of > > time. A frame opens in the root window when each thread starts and > > closes when it stops. Widgets in the frame and the root window > > control the thread and how the data is displayed. > > > > This works well for several hours, but over time the root window > > becomes unresponsive and eventually freezes and goes grey. No error > > messages are produced in the terminal. > > > > Here is some minimal, non-threaded code that reproduces the problem > > on my system (Xfce4 on Debian testing): > > > > from tkinter import * > > from random import randint > > > > root = Tk() > > > > def display(label): > > label.destroy() > > label = Label(text=randint(0, 9)) > > label.pack() > > root.after(100, display, label) > > > > display(Label()) > > mainloop() > > > > This opens a tiny window that displays a random digit on a new label > > every .1 second. (Obviously I could do this by updating the text > > rather than recreating the label, but my real application has to > > destroy widgets and create new ones). > > > > This works for 3-4 hours, but eventually the window freezes. > > > I think it is not yet clear, if this is a bug in Tkinter or in > Tcl/Tk, the underlying scripting language. It might also be platform > dependent. Are you on Windows? Here is an equivalent Tcl program: > > ====================== > package require Tk > > proc randint {} { > expr {int(rand()*10000000)} > } > > proc display {label} { > destroy $label > set id [randint] > set label [label .l$id -text [randint]] > pack $label > after 100 [list display $label] > } > > display [label .l] > ======================== > > > Can you run this and check that the freeze also occurs? If you can't > execute the Tcl that is used by Python directly, you may also do > something like > > > root = Tk() > root.eval('Here comes the Tcl code') > root.mainloop() > > Can you also find out what version of Tcl/Tk you are using? Try > > root.eval('info patchlevel') > > Christian > I've followed your suggestions as per my last post, and can confirm the same freezing behaviour when running your code directly as a tclsh script on Debian Testing, Tcl 8.6.11. I took the liberty of reducing the after delay to 10 milliseconds, which as MRAB suggests makes the issue more obvious. (If I use 1 millisecond the numbers don't display). Over the five hours or so it was running, the memory use increased from about 17 Mb to around 60. Thanks -- John From mgogala at yahoo.com Fri Feb 26 00:55:21 2021 From: mgogala at yahoo.com (Mladen Gogala) Date: Fri, 26 Feb 2021 05:55:21 +0000 (UTC) Subject: error of opening Python References: Message-ID: On Thu, 25 Feb 2021 17:22:35 +0000, Botao Liu wrote: > Dear Python team, > > This is my first time using Python, I tried to launch Python and it > showed "Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC > v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or > "license" for more information." I don't know what this meant and how to > fix this. Could you please help me? Thank you very much. > > Kind regards, > > Botao Liu Try with this first: https://python.swaroopch.com/ It gives you the details of what that means and what to do next. Also, your Python interpreter is broken it says: It should say something like this: Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC > v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or > "license" -- [mgogala at umajor ~]$ python3 Python 3.9.1 (default, Jan 20 2021, 00:00:00) [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> The problem string is "win32". You should be able to open a terminal Window and execute "uname -r". Mladen Gogala Database Consultant https://dbwhisperer.wordpress.com From rosuav at gmail.com Fri Feb 26 02:00:19 2021 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 26 Feb 2021 18:00:19 +1100 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> <1bim6fzfx6.fsf@pfeifferfamily.net> Message-ID: On Fri, Feb 26, 2021 at 3:32 PM Ethan Furman wrote: > > On 2/25/21 7:06 PM, Joe Pfeiffer wrote: > > Ethan Furman writes: > > >> Like I said, at this moment I don't have a good example, only an awareness that such a thing could exist and I don't know the name for it (if it has one). > >> > >> So far I have seen that there are even fewer good use-cases than I might have guessed, and that no one seems to have a name for the general idea. > > > > Do you have a specific problem you're trying to solve? > > No, I just came across the concept in my browsing and was wondering if there was a name for it. I think the most accurate name at this point is probably "pain in the butt". ;-) > "Design flaw" is a close second. ChrisA From auriocus at gmx.de Fri Feb 26 02:19:14 2021 From: auriocus at gmx.de (Christian Gollwitzer) Date: Fri, 26 Feb 2021 08:19:14 +0100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> Message-ID: Am 26.02.21 um 06:15 schrieb John O'Hagan: > On Thu, 25 Feb 2021 21:57:19 +0100 > Christian Gollwitzer wrote: >> I think it is not yet clear, if this is a bug in Tkinter or in >> Tcl/Tk, the underlying scripting language. It might also be platform >> dependent. Are you on Windows? Here is an equivalent Tcl program: >> >> ====================== >> package require Tk >> >> proc randint {} { >> expr {int(rand()*10000000)} >> } >> >> proc display {label} { >> destroy $label >> set id [randint] >> set label [label .l$id -text [randint]] >> pack $label >> after 100 [list display $label] >> } >> >> display [label .l] >> ======================== >> >> >> Can you run this and check that the freeze also occurs? If you can't >> execute the Tcl that is used by Python directly, you may also do >> something like >> >> >> root = Tk() >> root.eval('Here comes the Tcl code') >> root.mainloop() >> >> Can you also find out what version of Tcl/Tk you are using? Try >> >> root.eval('info patchlevel') >> >> Christian >> > > I've followed your suggestions as per my last post, and can confirm > the same freezing behaviour when running your code directly as a tclsh > script on Debian Testing, Tcl 8.6.11. You might report this as a bug to the Tcl bugtracker https://core.tcl-lang.org/tk/ticket I guess the problem is with the steady creation of widgets. Tk was not meant to be used like that. Tkinter creates new widget names for each widget with random numbers, just like the Tcl code above does, whereas in a usual Tcl/Tk program the names are given by the programmer. Can you also check this program, which reuses the same widget path name, albeit does the creation/destruction in cycles: ====================== package require Tk proc randint {} { expr {int(rand()*10000000)} } proc display {label} { destroy $label set label [label .l -text [randint]] pack $label after 100 [list display $label] } display [label .l] ======================== As mentioned by others, typically you wouldn't continuously recreate new widgets, but either update the text of the widget (label['text']="New text") or attaching a StringVar() ) or, if you must rearrange the widgets, you pack_forget() them and then repack them. Christian From antoon.pardon at vub.be Fri Feb 26 02:57:52 2021 From: antoon.pardon at vub.be (Antoon Pardon) Date: Fri, 26 Feb 2021 08:57:52 +0100 Subject: name for a mutually inclusive relationship In-Reply-To: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> Message-ID: <54d36196-09e4-39db-3dd8-1e602aa17d70@vub.be> Op 24/02/21 om 17:12 schreef Ethan Furman: > I'm looking for a name for a group of options that, when one is > specified, all of them must be specified. > It seems you are looking at an equivalence. From tjreedy at udel.edu Fri Feb 26 02:23:51 2021 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 26 Feb 2021 02:23:51 -0500 Subject: error of opening Python In-Reply-To: References: Message-ID: On 2/26/2021 12:55 AM, Mladen Gogala via Python-list wrote: > On Thu, 25 Feb 2021 17:22:35 +0000, Botao Liu wrote: > >> Dear Python team, >> >> This is my first time using Python, I tried to launch Python and it >> showed "Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC >> v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or >> "license" for more information." I don't know what this meant and how to >> fix this. Could you please help me? Thank you very much. >> >> Kind regards, >> >> Botao Liu > > Try with this first: https://python.swaroopch.com/ > It gives you the details of what that means and what to do next. Also, > your Python interpreter is broken No. it says: > > > It should say something like this: > Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC >> v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or >> "license" That is exactly what it does say, which is correct. > -- [mgogala at umajor ~]$ python3 > Python 3.9.1 (default, Jan 20 2021, 00:00:00) > [GCC 10.2.1 20201125 (Red Hat 10.2.1-9)] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> > > The problem string is "win32". No. 'win32' is a historical artifact. You should be able to open a terminal > Window and execute "uname -r". Not on Windows. Please don't spew misleading garbage that will only confuse the new user on a different operating system. -- Terry Jan Reedy From alan.gauld at yahoo.co.uk Fri Feb 26 04:57:14 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Fri, 26 Feb 2021 09:57:14 +0000 Subject: name for a mutually inclusive relationship In-Reply-To: References: <668ef473-3e9c-51c3-e272-6fd5e54a1a6b@stoneleaf.us> <29283050-5877-e6d6-c3a0-2848b358e65e@stoneleaf.us> <3c078dc6-fe3d-a195-21c2-1af65493a275@stoneleaf.us> <1bim6fzfx6.fsf@pfeifferfamily.net> Message-ID: On 26/02/2021 04:30, Ethan Furman wrote: >> Do you have a specific problem you're trying to solve? > > No, I just came across the concept in my browsing and > was wondering if there was a name for it. If we stick with boolean values (like radio buttons and checkboxes) then I think the name is "equality" A B Result -------------- 0 0 1 0 1 0 1 0 0 1 1 1 So you determine "success" by whether all inputs are equal. (Or as somebody else said "not xor") -- 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 From ethan at stoneleaf.us Fri Feb 26 09:51:02 2021 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 26 Feb 2021 06:51:02 -0800 Subject: editor recommendations? Message-ID: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> I'm looking for an editor to use for Python programming, as well as related incidentals such as markdown files, restructured text, etc. I'm currently using vim, and the primary reason I've stuck with it for so long is because I can get truly black screens with it. By which I mean that I have a colorful window title bar, a light-grey menu bar, and then a light-grey frame around the text-editing window (aka the only window), and a nice, black-background editing area. When I have occasionally tried other editors, they either don't support a black background, or the black background is only for the text-editing portion which leaves large portions of screen real-estate with a bright background, which is hard on my eyes. So, what's the state-of-the-art with regards to editors supporting dark color themes? TIA. -- ~Ethan~ From 2QdxY4RzWzUUiLuE at potatochowder.com Fri Feb 26 10:05:39 2021 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Fri, 26 Feb 2021 09:05:39 -0600 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On 2021-02-26 at 06:51:02 -0800, Ethan Furman wrote: > [...] vim [...] truly black screens with it. By which I mean that I > have a colorful window title bar, a light-grey menu bar, and then a > light-grey frame around the text-editing window (aka the only window), > and a nice, black-background editing area. That's what my emacs looks like, minus the light-grey frame (the window manager's frame and border are enough for me). Emacs has themes now, but my setup is very old; all I did was set the "base" text background and foreground colors and set a flag that says "I have a dark background rather than a light one." Did you have a Python question? ;-) From rshepard at appl-ecosys.com Fri Feb 26 11:13:05 2021 From: rshepard at appl-ecosys.com (Rich Shepard) Date: Fri, 26 Feb 2021 08:13:05 -0800 (PST) Subject: editor recommendations? In-Reply-To: References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On Fri, 26 Feb 2021, 2QdxY4RzWzUUiLuE at potatochowder.com wrote: > That's what my emacs looks like, minus the light-grey frame (the window > manager's frame and border are enough for me). Emacs has themes now, but > my setup is very old; all I did was set the "base" text background and > foreground colors and set a flag that says "I have a dark background > rather than a light one." Emacs: +1. I've been using it for more than two decades. It will provide syntax coloring (on the black background) for Python as well as other languages and file types. > Did you have a Python question? ;-) Perhaps he didn't but he should know that by opening a shell within emacs he can run his python code there. Long ago someone wrote that Emacs is an operating system that includes the kitchen sink. A friend of mine working for Sharp Electronics did all his work in Emacs, including email and web browsing (back when a text-based browser was sufficient.) Rich From drsalists at gmail.com Fri Feb 26 11:24:19 2021 From: drsalists at gmail.com (Dan Stromberg) Date: Fri, 26 Feb 2021 08:24:19 -0800 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On Fri, Feb 26, 2021 at 6:51 AM Ethan Furman wrote: > I'm looking for an editor to use for Python programming, as well as > related incidentals such as markdown files, restructured text, etc. > > I'm currently using vim, and the primary reason I've stuck with it for so > long is because I can get truly black screens with it. By which I mean > that I have a colorful window title bar, a light-grey menu bar, and then a > light-grey frame around the text-editing window (aka the only window), and > a nice, black-background editing area. > > When I have occasionally tried other editors, they either don't support a > black background, or the black background is only for the text-editing > portion which leaves large portions of screen real-estate with a bright > background, which is hard on my eyes. > > So, what's the state-of-the-art with regards to editors supporting dark > color themes? > I like vim :) I have it all set up with plugins automatically at https://stromberg.dnsalias.org/svn/vimrc/trunk/ Just cd'ing to that directory and typing "make" gives me vim with syntastic, MRU, jedi, etcetera - on Debian based Linuxes and CentOS-like Linuxes as well. From jpic at yourlabs.org Fri Feb 26 12:39:27 2021 From: jpic at yourlabs.org (J. Pic) Date: Fri, 26 Feb 2021 18:39:27 +0100 Subject: editor recommendations? In-Reply-To: References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On Fri, Feb 26, 2021 at 5:24 PM Rich Shepard wrote: > Perhaps he didn't but he should know that by opening a shell within emacs > he > can run his python code there. > :term in vim -- ? From python at mrabarnett.plus.com Fri Feb 26 12:51:50 2021 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 26 Feb 2021 17:51:50 +0000 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: <00754570-1f9e-d7cd-bcf8-6f8f2a46fbe7@mrabarnett.plus.com> On 2021-02-26 14:51, Ethan Furman wrote: > I'm looking for an editor to use for Python programming, as well as related incidentals such as markdown files, restructured text, etc. > > I'm currently using vim, and the primary reason I've stuck with it for so long is because I can get truly black screens with it. By which I mean that I have a colorful window title bar, a light-grey menu bar, and then a light-grey frame around the text-editing window (aka the only window), and a nice, black-background editing area. > > When I have occasionally tried other editors, they either don't support a black background, or the black background is only for the text-editing portion which leaves large portions of screen real-estate with a bright background, which is hard on my eyes. > > So, what's the state-of-the-art with regards to editors supporting dark color themes? > Have you looked at Visual Studio Code? From mats at wichmann.us Fri Feb 26 13:19:35 2021 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 26 Feb 2021 11:19:35 -0700 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On 2/26/21 7:51 AM, Ethan Furman wrote: > I'm looking for an editor to use for Python programming, as well as > related incidentals such as markdown files, restructured text, etc. > > I'm currently using vim, and the primary reason I've stuck with it for > so long is because I can get truly black screens with it.? By which I > mean that I have a colorful window title bar, a light-grey menu bar, and > then a light-grey frame around the text-editing window (aka the only > window), and a nice, black-background editing area. > > When I have occasionally tried other editors, they either don't support > a black background, or the black background is only for the text-editing > portion which leaves large portions of screen real-estate with a bright > background, which is hard on my eyes. > > So, what's the state-of-the-art with regards to editors supporting dark > color themes? Of course this is going to be opinionated. The editors I've tried don't do dark themes well, every theme seems to get something wrong so you're trying to squint to read something in a color that doesn't stand out sufficiently, etc., while something else is too electric I've stuck with vi/vim since it was written, but... PyCharm (I know for sure, probably others have something like this concept) has some modes to make some of the stuff you're not actually using less... cruddy - it has a "distraction-free mode" and a "zen mode". Just for fun those might be sort of what you're looking for? From tjol at tjol.eu Thu Feb 25 14:03:42 2021 From: tjol at tjol.eu (Thomas Jollans) Date: Thu, 25 Feb 2021 20:03:42 +0100 Subject: python 2.6: Need some advise for installing modules on a legacy system In-Reply-To: References: Message-ID: <4011487f-544b-c43a-2d37-c6245d49b80e@tjol.eu> On 24/02/2021 14:13, Antoon Pardon wrote: > I need to do some development on this legacy system. It only runs > python2.6 and there is little hope of installing an other version. How > can I best proceed to install modules for working with mysql and ldap? > The answer very much depends on the operating system. If it's a Linux system with a working package manager, chances are most common modules were packaged by the distribution vendor, and your best bet is probably to get the RPMs or deb packages from the corresponding package archive. There usually is one. Otherwise, as Dan suggested, find the source tar.gz (or zip, or whatever) file for the last version that supported python 2.6 on the corresponding project's website or on PyPI and install the packages (and all their dependencies) using the setup.py scripts. If you're on Windows, you'll probably need Visual Studio 2008 or at least the Visual C++ compiler version 9.0 (see ) That being said, I am curious: if you can install Python modules, why can't you install a newer Python interpreter? Are you running Windows 2000? Have fun I guess Thomas -- Dr. Thomas Jollans ? tjol at tjol.eu From cs at cskk.id.au Fri Feb 26 16:17:33 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 27 Feb 2021 08:17:33 +1100 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On 26Feb2021 06:51, Ethan Furman wrote: >I'm looking for an editor to use for Python programming, as well as related incidentals such as markdown files, restructured text, etc. > >I'm currently using vim, and the primary reason I've stuck with it for so long is because I can get truly black screens with it. By which I mean that I have a colorful window title bar, a light-grey menu bar, and then a light-grey frame around the text-editing window (aka the only window), and a nice, black-background editing area. > >When I have occasionally tried other editors, they either don't support a black background, or the black background is only for the text-editing portion which leaves large portions of screen real-estate with a bright background, which is hard on my eyes. > >So, what's the state-of-the-art with regards to editors supporting dark >color themes? I'm afraid I use vim. My colour schemes come from (a) the terminal (often my screen is 100% terminals) and (b) the vim syntax highlighting. And I've got an easy-on-the-eyes colouring for the vim pane separator characters. My fingers know vim. Some others' fingers know emacs. So I mostly get my colours from my terminal setup, which means I have a consistent dark theme for most of my activities: editing, shells and email (mutt). And I have my terminal panes which don't have the keyboard focus slightly dim themselves. Alas, this does not recommend another editor for you. Cheers, Cameron Simpson From tjol at tjol.eu Fri Feb 26 16:51:21 2021 From: tjol at tjol.eu (Thomas Jollans) Date: Fri, 26 Feb 2021 22:51:21 +0100 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: <34dbf615-4e85-0087-5694-718217b57801@tjol.eu> On 26/02/2021 15:51, Ethan Furman wrote: > > So, what's the state-of-the-art with regards to editors supporting > dark color themes? You?re in luck, ?Dark Mode? is very much en vogue these days. Most modern programmer's editors (meaning editors that think of themselves as modern) are either dark by default or at least come with a fully dark theme. I mostly use Sublime Text [???] myself. Visual Studio Code is pretty similar, but a fair bit more resource-intensive thanks to being built on Electron. They're both dark-by-default, fairly configurable and have communities obsessed with (usually dark) colour schemes. And they both have loads of plugins which can slow your editor down and give you smart completion and tooltips with docstrings if you like that sort of thing. Atom is in the same general category as VS Code. Spacemacs sounds like it could be fun. ?\_(?)_/? - Thomas From kevinmwilson1956 at yahoo.com Fri Feb 26 17:23:16 2021 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Fri, 26 Feb 2021 22:23:16 +0000 (UTC) Subject: Tkinter needed as a legacy version 2.7 imports the module... References: <99185085.877839.1614378196566.ref@mail.yahoo.com> Message-ID: <99185085.877839.1614378196566@mail.yahoo.com> Hey Community,????? ? Is there a site where I might/can download a version of Tkinter for Python 2.7? Seriously, KMW John 1:4? "In him was life; and the life was the light of men." From inhahe at gmail.com Fri Feb 26 17:29:08 2021 From: inhahe at gmail.com (inhahe) Date: Fri, 26 Feb 2021 17:29:08 -0500 Subject: editor recommendations? In-Reply-To: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: My editor of choice is Komodo IDE, which used to be commercialware but is free now. I'm pretty sure it has dark modes, but I haven't used them. I just thought I'd mention it because it's a good, solid IDE but I never see anybody mention it, e.g. in lists of Python editors and such.. On Fri, Feb 26, 2021 at 9:52 AM Ethan Furman wrote: > I'm looking for an editor to use for Python programming, as well as > related incidentals such as markdown files, restructured text, etc. > > I'm currently using vim, and the primary reason I've stuck with it for so > long is because I can get truly black screens with it. By which I mean > that I have a colorful window title bar, a light-grey menu bar, and then a > light-grey frame around the text-editing window (aka the only window), and > a nice, black-background editing area. > > When I have occasionally tried other editors, they either don't support a > black background, or the black background is only for the text-editing > portion which leaves large portions of screen real-estate with a bright > background, which is hard on my eyes. > > So, what's the state-of-the-art with regards to editors supporting dark > color themes? > > TIA. > > -- > ~Ethan~ > -- > https://mail.python.org/mailman/listinfo/python-list > From python at mrabarnett.plus.com Fri Feb 26 18:38:06 2021 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 26 Feb 2021 23:38:06 +0000 Subject: Tkinter needed as a legacy version 2.7 imports the module... In-Reply-To: <99185085.877839.1614378196566@mail.yahoo.com> References: <99185085.877839.1614378196566.ref@mail.yahoo.com> <99185085.877839.1614378196566@mail.yahoo.com> Message-ID: On 2021-02-26 22:23, Kevin M. Wilson via Python-list wrote: > Hey Community,????? ? Is there a site where I might/can download a version of Tkinter for Python 2.7? > Tkinter as already included in Python 2.7. From mgogala at yahoo.com Fri Feb 26 18:43:50 2021 From: mgogala at yahoo.com (Mladen Gogala) Date: Fri, 26 Feb 2021 23:43:50 +0000 (UTC) Subject: error of opening Python References: Message-ID: On Fri, 26 Feb 2021 02:23:51 -0500, Terry Reedy wrote: > Not on Windows. Please don't spew misleading garbage that will only > confuse the new user on a different operating system. > You are right, I apologize. I sort of like poking fun at the Winduhs users but this is not the right place. -- Mladen Gogala Database Consultant https://dbwhisperer.wordpress.com From research at johnohagan.com Fri Feb 26 18:59:24 2021 From: research at johnohagan.com (John O'Hagan) Date: Sat, 27 Feb 2021 10:59:24 +1100 Subject: Tkinter long-running window freezes In-Reply-To: References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> Message-ID: <20210227105924.34c2024a@e7240.home> On Fri, 26 Feb 2021 08:19:14 +0100 Christian Gollwitzer wrote: > Am 26.02.21 um 06:15 schrieb John O'Hagan: [...] > > > > I've followed your suggestions as per my last post, and can confirm > > the same freezing behaviour when running your code directly as a > > tclsh script on Debian Testing, Tcl 8.6.11. > > You might report this as a bug to the Tcl bugtracker > https://core.tcl-lang.org/tk/ticket > > I guess the problem is with the steady creation of widgets. Tk was > not meant to be used like that. Tkinter creates new widget names for > each widget with random numbers, just like the Tcl code above does, > whereas in a usual Tcl/Tk program the names are given by the > programmer. Thanks, I will make the bug report. However, based on your comments above, it looks similar to this one, closed as invalid 16 years ago: https://core.tcl-lang.org/tk/tktview/1173484fffffffffffff This was also related to memory "creep" caused by Tk's cache of names, which AIUI is a Tk design feature (but I don't know Tk!). > Can you also check this program, which reuses the same widget path > name, albeit does the creation/destruction in cycles: > > ====================== > package require Tk > > proc randint {} { > expr {int(rand()*10000000)} > } > > proc display {label} { > destroy $label > set label [label .l -text [randint]] > pack $label > after 100 [list display $label] > } > > display [label .l] > ======================== > I have tried this overnight and it is still running, not frozen and with no apparent increase in memory use. I guess that is likely the issue. I don't know Tcl/Tk - is there a way to emulate the above approach of re-using the widget name in tkinter? > As mentioned by others, typically you wouldn't continuously recreate > new widgets, but either update the text of the widget > (label['text']="New text") or attaching a StringVar() ) > > or, if you must rearrange the widgets, you pack_forget() them and > then repack them. > > Christian This is possible of course, but will require more than a repack. In my use case, each widget is an attribute of a Python object, intended control and display data about that object, and there is an indeterminate number of such objects at any given time. I had assumed I could just destroy the widget and let the object go out of scope to be garbage collected. I'll need to redesign this altogether if I can't rely on Tk to manage memory. IMHO it's quite surprising if .destroy doesn't free all the resources used by a widget! Thanks -- John From Marco.Sulla.Python at gmail.com Fri Feb 26 19:04:06 2021 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 27 Feb 2021 01:04:06 +0100 Subject: editor recommendations? In-Reply-To: References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: I use Sublime free for simple tasks. I like the fact it's fast and it saves to disk immediately. You don't have even to name the file. I use it also for taking notes. Probably not as powerful as Vim and it's proprietary. For development, I use PyCharm, but it's an IDE. I also used in past: gedit: slow atom: slow notepad++: windows only emacs: too much for my needs scite: too minimalist kate: not bad at all visual studio: resource intensive eclipse: slow (even if I continue to use it for non-Python coding) From python at mrabarnett.plus.com Fri Feb 26 20:06:06 2021 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 27 Feb 2021 01:06:06 +0000 Subject: Tkinter long-running window freezes In-Reply-To: <20210227105924.34c2024a@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> <20210227105924.34c2024a@e7240.home> Message-ID: <9eafbfd7-454d-df3e-0de5-6ece51e007df@mrabarnett.plus.com> On 2021-02-26 23:59, John O'Hagan wrote: > On Fri, 26 Feb 2021 08:19:14 +0100 > Christian Gollwitzer wrote: > >> Am 26.02.21 um 06:15 schrieb John O'Hagan: > [...] >> > >> > I've followed your suggestions as per my last post, and can confirm >> > the same freezing behaviour when running your code directly as a >> > tclsh script on Debian Testing, Tcl 8.6.11. >> >> You might report this as a bug to the Tcl bugtracker >> https://core.tcl-lang.org/tk/ticket >> >> I guess the problem is with the steady creation of widgets. Tk was >> not meant to be used like that. Tkinter creates new widget names for >> each widget with random numbers, just like the Tcl code above does, >> whereas in a usual Tcl/Tk program the names are given by the >> programmer. > > Thanks, I will make the bug report. However, based on your comments > above, it looks similar to this one, closed as invalid 16 years ago: > > https://core.tcl-lang.org/tk/tktview/1173484fffffffffffff > > This was also related to memory "creep" caused by Tk's cache of names, > which AIUI is a Tk design feature (but I don't know Tk!). > >> Can you also check this program, which reuses the same widget path >> name, albeit does the creation/destruction in cycles: >> >> ====================== >> package require Tk >> >> proc randint {} { >> expr {int(rand()*10000000)} >> } >> >> proc display {label} { >> destroy $label >> set label [label .l -text [randint]] >> pack $label >> after 100 [list display $label] >> } >> >> display [label .l] >> ======================== >> > > I have tried this overnight and it is still running, not frozen and with > no apparent increase in memory use. I guess that is likely the issue. I > don't know Tcl/Tk - is there a way to emulate the above approach of > re-using the widget name in tkinter? > >> As mentioned by others, typically you wouldn't continuously recreate >> new widgets, but either update the text of the widget >> (label['text']="New text") or attaching a StringVar() ) >> >> or, if you must rearrange the widgets, you pack_forget() them and >> then repack them. >> >> Christian > > This is possible of course, but will require more than a repack. In my > use case, each widget is an attribute of a Python object, intended > control and display data about that object, and there is an > indeterminate number of such objects at any given time. I had > assumed I could just destroy the widget and let the object go out of > scope to be garbage collected. I'll need to redesign this altogether if > I can't rely on Tk to manage memory. > > IMHO it's quite surprising if .destroy doesn't free all the resources > used by a widget! > I've look in Lib\tkinter\__init__.py and it appears that you can give it a name, so: from tkinter import * from random import randint root = Tk() def display(label): label.destroy() label = Label(name='my_label', text=randint(0, 9)) label.pack() root.after(1, display, label) display(Label(name='my_label')) mainloop() When I do that I'm not seeing a memory rise. From cousinstanley at gmail.com Fri Feb 26 20:12:13 2021 From: cousinstanley at gmail.com (Cousin Stanley) Date: Fri, 26 Feb 2021 18:12:13 -0700 Subject: Where is the problem? References: Message-ID: RD wrote: > Python 3.4.3 on WinXP. > > I create a Tk canvas and draw on it with create_text(), > create_line(), and create_polygon with fill and stipple. > > So far, so good, looks fine on the screen. > > So I go to send it to a postsctript file: > > bmap.postscript(file="tmp.ps", colormode='color') > > It generates a file, no errors reported. > > So I open up the file in a PS viewer (2, actually), > and the saved file looks like someone left a > watercolor out in the rain. > > Artifacts everywhere, the lines are blurred, and the > text is unreadable. > > Googling was unhelpful; did I miss something? > > TIA I have a couple of postscript saving examples that include the following geometry parameters which produce .ps files that render the same as the canvas drawings when viewed in ghostsript. retval = canvas.postscript( file = "image/ps/xyzzy.ps , height = 400 , width = 400 , pagewidth = 400 , pageheight = 400 , colormode = "color" ) Perhaps adding the geomerty parameters might help. -- Stanley C. Kitching Human Being Phoenix, Arizona From grant.b.edwards at gmail.com Fri Feb 26 13:24:47 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 26 Feb 2021 18:24:47 -0000 (UTC) Subject: editor recommendations? References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On 2021-02-26, Rich Shepard wrote: > Long ago someone wrote that Emacs is an operating system that includes the > kitchen sink. A friend of mine working for Sharp Electronics did all his > work in Emacs, including email and web browsing (back when a text-based > browser was sufficient.) Yep, I worked with somebody who did that. All his command-line shell interaction was done in emacs, as well as all his e-mail, Usenet, file-system browsing, etc. That was back before web browsing was "a thing", but I'm sure he found a way to do that inside emacs also. I pretty much only use emacs for editing text... -- Grant Edwards grant.b.edwards Yow! Hmmm ... a CRIPPLED at ACCOUNTANT with a FALAFEL gmail.com sandwich is HIT by a TROLLEY-CAR ... From bob at mellowood.ca Fri Feb 26 20:52:46 2021 From: bob at mellowood.ca (Bob van der Poel) Date: Fri, 26 Feb 2021 18:52:46 -0700 Subject: editor recommendations? In-Reply-To: References: <41697044-4479-97c6-4913-11de27f79565@stoneleaf.us> Message-ID: On Fri, Feb 26, 2021 at 11:24 AM Grant Edwards wrote: > On 2021-02-26, Rich Shepard wrote: > > > Long ago someone wrote that Emacs is an operating system that includes > the > > kitchen sink. A friend of mine working for Sharp Electronics did all his > > work in Emacs, including email and web browsing (back when a text-based > > browser was sufficient.) > > Yep, I worked with somebody who did that. All his command-line shell > interaction was done in emacs, as well as all his e-mail, Usenet, > file-system browsing, etc. That was back before web browsing was "a > thing", but I'm sure he found a way to do that inside emacs also. > Of course there is a mode for that: https://www.emacswiki.org/emacs/CategoryWebBrowser -- **** Listen to my FREE CD at http://www.mellowood.ca/music/cedars **** Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: bob at mellowood.ca WWW: http://www.mellowood.ca From research at johnohagan.com Fri Feb 26 21:38:52 2021 From: research at johnohagan.com (John O'Hagan) Date: Sat, 27 Feb 2021 13:38:52 +1100 Subject: Tkinter long-running window freezes In-Reply-To: <9eafbfd7-454d-df3e-0de5-6ece51e007df@mrabarnett.plus.com> References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> <20210227105924.34c2024a@e7240.home> <9eafbfd7-454d-df3e-0de5-6ece51e007df@mrabarnett.plus.com> Message-ID: <20210227133852.1028a4bc@e7240.home> On Sat, 27 Feb 2021 01:06:06 +0000 MRAB wrote: > On 2021-02-26 23:59, John O'Hagan wrote: > > On Fri, 26 Feb 2021 08:19:14 +0100 > > Christian Gollwitzer wrote: > > > >> Am 26.02.21 um 06:15 schrieb John O'Hagan: > > [...] > >> > > >> > I've followed your suggestions as per my last post, and can > >> > confirm the same freezing behaviour when running your code > >> > directly as a tclsh script on Debian Testing, Tcl 8.6.11. > >> > >> You might report this as a bug to the Tcl bugtracker > >> https://core.tcl-lang.org/tk/ticket > >> > >> I guess the problem is with the steady creation of widgets. Tk was > >> not meant to be used like that. Tkinter creates new widget names > >> for each widget with random numbers, just like the Tcl code above > >> does, whereas in a usual Tcl/Tk program the names are given by the > >> programmer. > > > > Thanks, I will make the bug report. However, based on your comments > > above, it looks similar to this one, closed as invalid 16 years ago: > > > > https://core.tcl-lang.org/tk/tktview/1173484fffffffffffff > > > > This was also related to memory "creep" caused by Tk's cache of > > names, which AIUI is a Tk design feature (but I don't know Tk!). > > > >> Can you also check this program, which reuses the same widget path > >> name, albeit does the creation/destruction in cycles: > >> > >> ====================== > >> package require Tk > >> > >> proc randint {} { > >> expr {int(rand()*10000000)} > >> } > >> > >> proc display {label} { > >> destroy $label > >> set label [label .l -text [randint]] > >> pack $label > >> after 100 [list display $label] > >> } > >> > >> display [label .l] > >> ======================== > >> > > > > I have tried this overnight and it is still running, not frozen and > > with no apparent increase in memory use. I guess that is likely the > > issue. I don't know Tcl/Tk - is there a way to emulate the above > > approach of re-using the widget name in tkinter? > > > >> As mentioned by others, typically you wouldn't continuously > >> recreate new widgets, but either update the text of the widget > >> (label['text']="New text") or attaching a StringVar() ) > >> > >> or, if you must rearrange the widgets, you pack_forget() them and > >> then repack them. > >> > >> Christian > > > > This is possible of course, but will require more than a repack. In > > my use case, each widget is an attribute of a Python object, > > intended control and display data about that object, and there is an > > indeterminate number of such objects at any given time. I had > > assumed I could just destroy the widget and let the object go out of > > scope to be garbage collected. I'll need to redesign this > > altogether if I can't rely on Tk to manage memory. > > > > IMHO it's quite surprising if .destroy doesn't free all the > > resources used by a widget! > > > I've look in Lib\tkinter\__init__.py and it appears that you can give > it a name, so: > > from tkinter import * > from random import randint > > root = Tk() > > def display(label): > label.destroy() > label = Label(name='my_label', text=randint(0, 9)) > label.pack() > root.after(1, display, label) > > display(Label(name='my_label')) > mainloop() > > When I do that I'm not seeing a memory rise. I just did the exact same thing, also saw no memory rise, but the window still froze after a couple of hours. Did your window freeze? Maybe the memory rise and the freeze are unrelated after all. Also, I was mistaken about Christian's second version of the Tcl code above - there is no memory rise but the window also freezes after a while. Suggests the problem is in Tcl/Tk. Thanks -- John From research at johnohagan.com Fri Feb 26 21:42:26 2021 From: research at johnohagan.com (John O'Hagan) Date: Sat, 27 Feb 2021 13:42:26 +1100 Subject: Tkinter long-running window freezes In-Reply-To: <20210227105924.34c2024a@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> <20210227105924.34c2024a@e7240.home> Message-ID: <20210227134226.54d6d48e@e7240.home> On Sat, 27 Feb 2021 10:59:24 +1100 John O'Hagan wrote: > On Fri, 26 Feb 2021 08:19:14 +0100 > Christian Gollwitzer wrote: [...] > > > Can you also check this program, which reuses the same widget path > > name, albeit does the creation/destruction in cycles: > > > > ====================== > > package require Tk > > > > proc randint {} { > > expr {int(rand()*10000000)} > > } > > > > proc display {label} { > > destroy $label > > set label [label .l -text [randint]] > > pack $label > > after 100 [list display $label] > > } > > > > display [label .l] > > ======================== > > > > I have tried this overnight and it is still running, not frozen and > with no apparent increase in memory use. [...] Correction! The window did freeze after all, and again on a second attempt. No memory rise though, so those two issues seem to be independent. Thanks -- John From python at mrabarnett.plus.com Fri Feb 26 22:02:55 2021 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 27 Feb 2021 03:02:55 +0000 Subject: Tkinter long-running window freezes In-Reply-To: <20210227133852.1028a4bc@e7240.home> References: <20210224220031.5ce59f6b@e7240.home> <20210226161506.72e9147b@e7240.home> <20210227105924.34c2024a@e7240.home> <9eafbfd7-454d-df3e-0de5-6ece51e007df@mrabarnett.plus.com> <20210227133852.1028a4bc@e7240.home> Message-ID: <63859677-e1ee-2b28-d237-d0912734868c@mrabarnett.plus.com> On 2021-02-27 02:38, John O'Hagan wrote: > On Sat, 27 Feb 2021 01:06:06 +0000 > MRAB wrote: > >> On 2021-02-26 23:59, John O'Hagan wrote: >> > On Fri, 26 Feb 2021 08:19:14 +0100 >> > Christian Gollwitzer wrote: >> > >> >> Am 26.02.21 um 06:15 schrieb John O'Hagan: >> > [...] >> >> > >> >> > I've followed your suggestions as per my last post, and can >> >> > confirm the same freezing behaviour when running your code >> >> > directly as a tclsh script on Debian Testing, Tcl 8.6.11. >> >> >> >> You might report this as a bug to the Tcl bugtracker >> >> https://core.tcl-lang.org/tk/ticket >> >> >> >> I guess the problem is with the steady creation of widgets. Tk was >> >> not meant to be used like that. Tkinter creates new widget names >> >> for each widget with random numbers, just like the Tcl code above >> >> does, whereas in a usual Tcl/Tk program the names are given by the >> >> programmer. >> > >> > Thanks, I will make the bug report. However, based on your comments >> > above, it looks similar to this one, closed as invalid 16 years ago: >> > >> > https://core.tcl-lang.org/tk/tktview/1173484fffffffffffff >> > >> > This was also related to memory "creep" caused by Tk's cache of >> > names, which AIUI is a Tk design feature (but I don't know Tk!). >> > >> >> Can you also check this program, which reuses the same widget path >> >> name, albeit does the creation/destruction in cycles: >> >> >> >> ====================== >> >> package require Tk >> >> >> >> proc randint {} { >> >> expr {int(rand()*10000000)} >> >> } >> >> >> >> proc display {label} { >> >> destroy $label >> >> set label [label .l -text [randint]] >> >> pack $label >> >> after 100 [list display $label] >> >> } >> >> >> >> display [label .l] >> >> ======================== >> >> >> > >> > I have tried this overnight and it is still running, not frozen and >> > with no apparent increase in memory use. I guess that is likely the >> > issue. I don't know Tcl/Tk - is there a way to emulate the above >> > approach of re-using the widget name in tkinter? >> > >> >> As mentioned by others, typically you wouldn't continuously >> >> recreate new widgets, but either update the text of the widget >> >> (label['text']="New text") or attaching a StringVar() ) >> >> >> >> or, if you must rearrange the widgets, you pack_forget() them and >> >> then repack them. >> >> >> >> Christian >> > >> > This is possible of course, but will require more than a repack. In >> > my use case, each widget is an attribute of a Python object, >> > intended control and display data about that object, and there is an >> > indeterminate number of such objects at any given time. I had >> > assumed I could just destroy the widget and let the object go out of >> > scope to be garbage collected. I'll need to redesign this >> > altogether if I can't rely on Tk to manage memory. >> > >> > IMHO it's quite surprising if .destroy doesn't free all the >> > resources used by a widget! >> > >> I've look in Lib\tkinter\__init__.py and it appears that you can give >> it a name, so: >> >> from tkinter import * >> from random import randint >> >> root = Tk() >> >> def display(label): >> label.destroy() >> label = Label(name='my_label', text=randint(0, 9)) >> label.pack() >> root.after(1, display, label) >> >> display(Label(name='my_label')) >> mainloop() >> >> When I do that I'm not seeing a memory rise. > > I just did the exact same thing, also saw no memory rise, but the > window still froze after a couple of hours. Did your window freeze? > Maybe the memory rise and the freeze are unrelated after all. > > Also, I was mistaken about Christian's second version of the Tcl code > above - there is no memory rise but the window also freezes after a > while. Suggests the problem is in Tcl/Tk. > I didn't run it for that long, only long enough to compare it with the previous version. (Both were started at the same time.) From phd at phdru.name Sat Feb 27 09:16:28 2021 From: phd at phdru.name (Oleg Broytman) Date: Sat, 27 Feb 2021 15:16:28 +0100 Subject: SQLObject 3.9.1 Message-ID: <20210227141628.GA14947@phdru.name> Hello! I'm pleased to announce version 3.9.1, the first minor feature release of branch 3.9 of SQLObject. What's new in SQLObject ======================= Drivers ------- * Adapt to the latest ``pg8000``. * Protect ``getuser()`` - it can raise ``ImportError`` on w32 due to absent of ``pwd`` module. Build ----- * Change URLs for ``oursql`` in ``extras_require`` in ``setup.py``. Provide separate URLs for Python 2.7 and 3.4+. * Add ``mariadb`` in ``extras_require`` in ``setup.py``. CI -- * For tests with Python 3.4 run ``tox`` under Python 3.5. Tests ----- * Refactor ``tox.ini``. For a more complete list, please see the news: http://sqlobject.org/News.html What is SQLObject ================= SQLObject is an object-relational mapper. Your database tables are described as classes, and rows are instances of those classes. SQLObject is meant to be easy to use and quick to get started with. SQLObject supports a number of backends: MySQL, PostgreSQL, SQLite; connections to other backends - Firebird, Sybase, MSSQL and MaxDB (also known as SAPDB) - are lesser debugged). Python 2.7 or 3.4+ is required. Where is SQLObject ================== Site: http://sqlobject.org Development: http://sqlobject.org/devel/ Mailing list: https://lists.sourceforge.net/mailman/listinfo/sqlobject-discuss Download: https://pypi.org/project/SQLObject/3.9.1 News and changes: http://sqlobject.org/News.html StackOverflow: https://stackoverflow.com/questions/tagged/sqlobject Example ======= Create a simple class that wraps a table:: >>> from sqlobject import * >>> >>> sqlhub.processConnection = connectionForURI('sqlite:/:memory:') >>> >>> class Person(SQLObject): ... fname = StringCol() ... mi = StringCol(length=1, default=None) ... lname = StringCol() ... >>> Person.createTable() Use the object:: >>> p = Person(fname="John", lname="Doe") >>> p >>> p.fname 'John' >>> p.mi = 'Q' >>> p2 = Person.get(1) >>> p2 >>> p is p2 True Queries:: >>> p3 = Person.selectBy(lname="Doe")[0] >>> p3 >>> pc = Person.select(Person.q.lname=="Doe").count() >>> pc 1 Oleg. -- Oleg Broytman https://phdru.name/ phd at phdru.name Programmers don't die, they just GOSUB without RETURN. From alan.gauld at yahoo.co.uk Sat Feb 27 06:41:04 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sat, 27 Feb 2021 11:41:04 +0000 Subject: Tkinter needed as a legacy version 2.7 imports the module... In-Reply-To: <99185085.877839.1614378196566@mail.yahoo.com> References: <99185085.877839.1614378196566.ref@mail.yahoo.com> <99185085.877839.1614378196566@mail.yahoo.com> Message-ID: On 26/02/2021 22:23, Kevin M. Wilson via Python-list wrote: > Hey Community,????? ? Is there a site where I might/can download a version of Tkinter for Python 2.7? Which OS? If it's Linux you may need to fetch the tkinter package for your distro. In Windoze it should come as standard In MacOS (or any other OS) ... Ask someone who knows... -- 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 From sahajverma06 at gmail.com Sat Feb 27 17:45:42 2021 From: sahajverma06 at gmail.com (Sahaj Verma) Date: Sat, 27 Feb 2021 17:45:42 -0500 Subject: Not able to use python properly Message-ID: <6E515274-3664-442B-82A3-B6E446B5093A@hxcore.ol> ? I am not able to install and use pip . I have installed python 3.9.2 version on my laptop but I am unable to use pip function. Kindly look into this matter as soon as possible. Thanking You. Sahaj Verma ? Sent from [1]Mail for Windows 10 ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986 From grant.b.edwards at gmail.com Sat Feb 27 08:04:15 2021 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sat, 27 Feb 2021 13:04:15 -0000 (UTC) Subject: Tkinter needed as a legacy version 2.7 imports the module... References: <99185085.877839.1614378196566.ref@mail.yahoo.com> <99185085.877839.1614378196566@mail.yahoo.com> Message-ID: On 2021-02-26, MRAB wrote: > On 2021-02-26 22:23, Kevin M. Wilson via Python-list wrote: > >> Is there a site where I might/can download a version of Tkinter for Python 2.7? > > Tkinter as already included in Python 2.7. Not always, it depends on how he installed Python 2.7. That said, MRAB is right that you don't install Tkinter seperately. You 1. Include it when you configure and build python 2. Install a binary Python distribution that aleady includes it. -- Grant From pkpearson at nowhere.invalid Sat Feb 27 10:59:49 2021 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 27 Feb 2021 15:59:49 GMT Subject: Not able to use python properly References: <6E515274-3664-442B-82A3-B6E446B5093A@hxcore.ol> Message-ID: On Sat, 27 Feb 2021 17:45:42 -0500, Sahaj Verma wrote: > ? > > I am not able to install and use pip . > > I have installed python 3.9.2 version on my laptop but I am unable to use > pip function. > > Kindly look into this matter as soon as possible. > > Thanking You. > > Sahaj Verma > > ? > > Sent from [1]Mail for Windows 10 > > ? > > References > > Visible links > 1. https://go.microsoft.com/fwlink/?LinkId=550986 Your chances of getting useful help will be much improved if you provide more information. "I am unable to use pip function" could result from many varied causes. Is your screen completely black? -- To email me, substitute nowhere->runbox, invalid->com. From mats at wichmann.us Sat Feb 27 11:09:35 2021 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 27 Feb 2021 09:09:35 -0700 Subject: Not able to use python properly In-Reply-To: <6E515274-3664-442B-82A3-B6E446B5093A@hxcore.ol> References: <6E515274-3664-442B-82A3-B6E446B5093A@hxcore.ol> Message-ID: On 2/27/21 3:45 PM, Sahaj Verma wrote: > > > I am not able to install and use pip . > > I have installed python 3.9.2 version on my laptop but I am unable to use > pip function. > > Kindly look into this matter as soon as possible. > > Thanking You. > > Sahaj Verma > > > > Sent from [1]Mail for Windows 10 > You're on windows. pip isn't in your path - it's in the Scripts subdirectory of the main python installation location. You can add this to the path, but it's probably more reliable to use it as a module instead. If you have the Python Launcher installed (that's recommended for the python.org installation): py -m pip list (for example - to show already-installed packages). From randy.day at saskatel.netx Sat Feb 27 11:27:36 2021 From: randy.day at saskatel.netx (RD) Date: Sat, 27 Feb 2021 10:27:36 -0600 Subject: Where is the problem? References: Message-ID: In article , cousinstanley at gmail.com says... [snip] > I have a couple of postscript saving examples > that include the following geometry parameters > which produce .ps files that render the same > as the canvas drawings when viewed in ghostsript. > retval = canvas.postscript( > file = "image/ps/xyzzy.ps , > height = 400 , > width = 400 , > pagewidth = 400 , > pageheight = 400 , > colormode = "color" ) [snip] Wow! It worked! Thankyouthankyouthankyou. RD From inhahe at gmail.com Sat Feb 27 15:05:49 2021 From: inhahe at gmail.com (inhahe) Date: Sat, 27 Feb 2021 15:05:49 -0500 Subject: Fwd: How to cycle through servers on Connection Fail in an IRC client? In-Reply-To: References: Message-ID: I'm not sure if it's okay to ask about Twisted in this mailing list, but Twisted's mailing list seems to have ignored my submission for some reason. And their mailing list seems mostly dead anyway. So here goes: I'm making an IRC client using Twisted, and I want to connect to a different server when connection fails, but I haven't been able to figure out how to do that.. Here's a more or less minimal code sample reflecting what I have now: ------------------------------------------------------------------------------------------------ from twisted.words.protocols import irc from twisted.internet import protocol from twisted.internet import reactor class ServerConnection(irc.IRCClient): def __init__(self): self.signedon = False self.nickindex = 0 def signedOn(self): print("signed on") def nickChanged(self, newnick): self.nickname = newnick class Network(object): def __init__(self, servers, mynick=None): self.servers = servers self.mynick = mynick self.serverindex = 0 class ServerFactory(protocol.ReconnectingClientFactory): def __init__(self, nickname="qttwirc", password=None, username="qttwirc", realname=None, network=None): self.network = network self.network.mynick = nickname self.nickname = nickname self.username = username self.password = password self.realname = realname protocol.ReconnectingClientFactory.initialDelay = 10 #should i leave this at 1? protocol.ReconnectingClientFactory.maxDelay = 10 #no idea what value this should be. 3.5 wasn't slow enough, i was being throttled. def buildProtocol(self, addr): p = ServerConnection() self.serverconnection = p p.server = self p.nickname = self.nickname p.username = self.username self.resetDelay() return p def clientConnectionLost(self, connector, reason): self.serverconnection = None protocol.ReconnectingClientFactory.clientConnectionLost(self, connector, reason) def clientConnectionFailed(self, connector, reason): self.serverconnection = None addr, port = self.network.servers[self.network.serverindex] self.network.serverindex = (self.network.serverindex+1) % len(self.network.servers) #todo: make it actually use these values #reactor.callLater(config.reconnectdelay, reactor.connectTCP, addr.encode("ascii"), port, self) #reactor.connectTCP(addr, port, self) #is this feasible? i don't know a better way to do this. connector.connect() apparently doesn't take server/port as arguments. protocol.ReconnectingClientFactory.clientConnectionFailed(self, connector, reason) network = Network([("hitchcock.freenode.net", 6667), ("verne.freenode.net", 6667)]) server = ServerFactory(nickname="test123", username="test123", network=network) reactor.connectTCP(*network.servers[network.serverindex], server) reactor.run() ------------------------------------------------------------------------------------------------ If I have to completely change the structure of how I connect, that's fine.. I don't understand Twisted very well, so I'm not aware of what some other options are for how to make an IRC client. (It probably doesn't matter, but in my actual program I'm using both Twisted and PyQt5 in the same run loop using qt5reactor..) Thanks. From cousinstanley at gmail.com Sat Feb 27 15:47:13 2021 From: cousinstanley at gmail.com (Cousin Stanley) Date: Sat, 27 Feb 2021 13:47:13 -0700 Subject: Where is the problem? References: Message-ID: RD wrote: > In article , cousinstanley at gmail.com says... > > [snip] > >> I have a couple of postscript saving examples >> that include the following geometry parameters >> which produce .ps files that render the same >> as the canvas drawings when viewed in ghostsript. > >> retval = canvas.postscript( >> file = "image/ps/xyzzy.ps , >> height = 400 , >> width = 400 , >> pagewidth = 400 , >> pageheight = 400 , >> colormode = "color" ) > > [snip] > > Wow! It worked! Thankyouthankyouthankyou. > > RD You're welcome .... You're Welcome .... You're Welcome .... -- Stanley C. Kitching Human Being Phoenix, Arizona From cs at cskk.id.au Sat Feb 27 19:17:32 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 28 Feb 2021 11:17:32 +1100 Subject: weirdness with list() Message-ID: I just ran into a surprising (to me) issue with list() on an iterable object. My object represents an MDAT box in an MP4 file: it is the ludicrously large data box containing the raw audiovideo data; for a TV episode it is often about 2GB and a movie is often 4GB to 6GB. For obvious reasons, I do not always want to load that into memory, or even read the data part at all when scanning an MP4 file, for example to recite its metadata. So my parser has a "skip" mode where it seeks straight past the data, but makes a note of its length in bytes. All good. That length is presented via the object's __len__ method, because I want to know that length later and this is a subclass of a suite of things which return their length in bytes this way. So, to my problem: I've got a walk method which traverses the hierarchy of boxes in the MP4 file. Until some minutes ago, it looked like this: def walk(self): subboxes = list(self) yield self, subboxes for subbox in subboxes: if isinstance(subbox, Box): yield from subbox.walk() somewhat like os.walk does for a file tree. I noticed that it was stalling, and investigation revealed it was stalling at this line: subboxes = list(self) when doing the MDAT box. That box (a) has no subboxes at all and (b) has a very large __len__ value. BUT... It also has a __iter__ value, which like any Box iterates over the subboxes. For MDAT that is implemented like this: def __iter__(self): yield from () What I was expecting was pretty much instant construction of an empty list. What I was getting was a very time consuming (10 seconds or more) construction of an empty list. I believe that this is because list() tries to preallocate storage. I _infer_ from the docs that this is done maybe using operator.length_hint, which in turn consults "the actual length of the object" (meaning __len__ for me?), then __length_hint__, then defaults to 0. I've changed my walk function like so: def walk(self): subboxes = [] for subbox in self: subboxes.append(subbox) ##subboxes = list(self) and commented out the former list(self) incantation. This is very fast, because it makes an empty list and then appends nothing to it. And for your typical movie file this is fine, because there are never _very_ many immediate subboxes anyway. But is there a cleaner way to do this? I'd like to go back to my former list(self) incantation, and modify the MDAT box class to arrange something efficient. Setting __length_hint__ didn't help: returning NotImplemeneted or 0 had no effect, because presumably __len__ was consulted first. Any suggestions? My current approach feels rather hacky. I'm already leaning towards making __len__ return the number of subboxes to match the iterator, especially as on reflection not all my subclasses are consistent about __len__ meaning the length of their binary form; I'm probably going to have to fix that - some subclasses are actually namedtuples where __len__ would be the field count. Ugh. Still, thoughts? I'm interested in any approaches that would have let me make list() fast while keeping __len__==binary_length. I'm accepting that __len__ != len(__iter__) is a bad idea now, though. Cheers, Cameron Simpson From __peter__ at web.de Sun Feb 28 04:51:56 2021 From: __peter__ at web.de (Peter Otten) Date: Sun, 28 Feb 2021 10:51:56 +0100 Subject: weirdness with list() In-Reply-To: References: Message-ID: <5471d87c-4f93-7082-91ee-eef32a7117e4@web.de> On 28/02/2021 01:17, Cameron Simpson wrote: > I just ran into a surprising (to me) issue with list() on an iterable > object. > > My object represents an MDAT box in an MP4 file: it is the ludicrously > large data box containing the raw audiovideo data; for a TV episode it > is often about 2GB and a movie is often 4GB to 6GB. For obvious reasons, > I do not always want to load that into memory, or even read the data > part at all when scanning an MP4 file, for example to recite its > metadata. > > So my parser has a "skip" mode where it seeks straight past the data, > but makes a note of its length in bytes. All good. > > That length is presented via the object's __len__ method, because I want > to know that length later and this is a subclass of a suite of things > which return their length in bytes this way. > > So, to my problem: > > I've got a walk method which traverses the hierarchy of boxes in the MP4 > file. Until some minutes ago, it looked like this: > > def walk(self): > subboxes = list(self) > yield self, subboxes > for subbox in subboxes: > if isinstance(subbox, Box): > yield from subbox.walk() > > somewhat like os.walk does for a file tree. > > I noticed that it was stalling, and investigation revealed it was > stalling at this line: > > subboxes = list(self) > > when doing the MDAT box. That box (a) has no subboxes at all and (b) has > a very large __len__ value. > > BUT... It also has a __iter__ value, which like any Box iterates over > the subboxes. For MDAT that is implemented like this: > > def __iter__(self): > yield from () > > What I was expecting was pretty much instant construction of an empty > list. What I was getting was a very time consuming (10 seconds or more) > construction of an empty list. > > I believe that this is because list() tries to preallocate storage. I > _infer_ from the docs that this is done maybe using > operator.length_hint, which in turn consults "the actual length of the > object" (meaning __len__ for me?), then __length_hint__, then defaults > to 0. > > I've changed my walk function like so: > > def walk(self): > subboxes = [] > for subbox in self: > subboxes.append(subbox) > ##subboxes = list(self) list(iter(self)) should work, too. It may be faster than the explicit loop, but also defeats the list allocation optimization. > and commented out the former list(self) incantation. This is very fast, > because it makes an empty list and then appends nothing to it. And for > your typical movie file this is fine, because there are never _very_ > many immediate subboxes anyway. > > But is there a cleaner way to do this? > > I'd like to go back to my former list(self) incantation, and modify the > MDAT box class to arrange something efficient. Setting __length_hint__ > didn't help: returning NotImplemeneted or 0 had no effect, because > presumably __len__ was consulted first. > > Any suggestions? My current approach feels rather hacky. > > I'm already leaning towards making __len__ return the number of subboxes > to match the iterator, especially as on reflection not all my subclasses > are consistent about __len__ meaning the length of their binary form; > I'm probably going to have to fix that - some subclasses are actually > namedtuples where __len__ would be the field count. Ugh. > > Still, thoughts? I'm interested in any approaches that would have let me > make list() fast while keeping __len__==binary_length. > > I'm accepting that __len__ != len(__iter__) is a bad idea now, though. Indeed. I see how that train wreck happened -- but the weirdness is not the list behavior. Maybe you can capture the intended behavior of your class with two classes, a MyIterable without length that can be converted into MyList as needed. From __peter__ at web.de Sun Feb 28 04:51:56 2021 From: __peter__ at web.de (Peter Otten) Date: Sun, 28 Feb 2021 10:51:56 +0100 Subject: weirdness with list() In-Reply-To: References: Message-ID: <5471d87c-4f93-7082-91ee-eef32a7117e4@web.de> On 28/02/2021 01:17, Cameron Simpson wrote: > I just ran into a surprising (to me) issue with list() on an iterable > object. > > My object represents an MDAT box in an MP4 file: it is the ludicrously > large data box containing the raw audiovideo data; for a TV episode it > is often about 2GB and a movie is often 4GB to 6GB. For obvious reasons, > I do not always want to load that into memory, or even read the data > part at all when scanning an MP4 file, for example to recite its > metadata. > > So my parser has a "skip" mode where it seeks straight past the data, > but makes a note of its length in bytes. All good. > > That length is presented via the object's __len__ method, because I want > to know that length later and this is a subclass of a suite of things > which return their length in bytes this way. > > So, to my problem: > > I've got a walk method which traverses the hierarchy of boxes in the MP4 > file. Until some minutes ago, it looked like this: > > def walk(self): > subboxes = list(self) > yield self, subboxes > for subbox in subboxes: > if isinstance(subbox, Box): > yield from subbox.walk() > > somewhat like os.walk does for a file tree. > > I noticed that it was stalling, and investigation revealed it was > stalling at this line: > > subboxes = list(self) > > when doing the MDAT box. That box (a) has no subboxes at all and (b) has > a very large __len__ value. > > BUT... It also has a __iter__ value, which like any Box iterates over > the subboxes. For MDAT that is implemented like this: > > def __iter__(self): > yield from () > > What I was expecting was pretty much instant construction of an empty > list. What I was getting was a very time consuming (10 seconds or more) > construction of an empty list. > > I believe that this is because list() tries to preallocate storage. I > _infer_ from the docs that this is done maybe using > operator.length_hint, which in turn consults "the actual length of the > object" (meaning __len__ for me?), then __length_hint__, then defaults > to 0. > > I've changed my walk function like so: > > def walk(self): > subboxes = [] > for subbox in self: > subboxes.append(subbox) > ##subboxes = list(self) list(iter(self)) should work, too. It may be faster than the explicit loop, but also defeats the list allocation optimization. > and commented out the former list(self) incantation. This is very fast, > because it makes an empty list and then appends nothing to it. And for > your typical movie file this is fine, because there are never _very_ > many immediate subboxes anyway. > > But is there a cleaner way to do this? > > I'd like to go back to my former list(self) incantation, and modify the > MDAT box class to arrange something efficient. Setting __length_hint__ > didn't help: returning NotImplemeneted or 0 had no effect, because > presumably __len__ was consulted first. > > Any suggestions? My current approach feels rather hacky. > > I'm already leaning towards making __len__ return the number of subboxes > to match the iterator, especially as on reflection not all my subclasses > are consistent about __len__ meaning the length of their binary form; > I'm probably going to have to fix that - some subclasses are actually > namedtuples where __len__ would be the field count. Ugh. > > Still, thoughts? I'm interested in any approaches that would have let me > make list() fast while keeping __len__==binary_length. > > I'm accepting that __len__ != len(__iter__) is a bad idea now, though. Indeed. I see how that train wreck happened -- but the weirdness is not the list behavior. Maybe you can capture the intended behavior of your class with two classes, a MyIterable without length that can be converted into MyList as needed. From Bischoop at vimart.net Sun Feb 28 06:20:59 2021 From: Bischoop at vimart.net (Bischoop) Date: Sun, 28 Feb 2021 11:20:59 -0000 (UTC) Subject: Tkinter new window contentent when button is clicked. References: <24b7e6ba-c886-eba9-43c5-c816e88d66db@mrabarnett.plus.com> Message-ID: On 2021-02-25, MRAB wrote: >> > The trick is to put the "pages" on top of each other and then show the > appropriate one, something like this: > import tkinter as tk > > def on_next_page(): > # Brings page 2 to the top. > frame_2.tkraise() > > def on_previous_page(): > # Brings page 1 to the top. > frame_1.tkraise() > > def on_finish(): > # Closes the dialog. > root.destroy() > > root = tk.Tk() > > # Page 1. > frame_1 = tk.Frame(root) > tk.Label(frame_1, text='Page 1').pack() > tk.Button(frame_1, text='Next', command=on_next_page).pack() > > # Page 2. > frame_2 = tk.Frame() > tk.Label(frame_2, text='Page 2').pack() > tk.Button(frame_2, text='Previous', command=on_previous_page).pack() > tk.Button(frame_2, text='Finish', command=on_finish).pack() > > # Put the pages on top of each other. > frame_1.grid(row=0, column=0, sticky='news') > frame_2.grid(row=0, column=0, sticky='news') > > # Bring page 1 to the top. > frame_1.tkraise() > > tk.mainloop() Great, thanks for reply, I'll look into that. -- Thanks From aotto1968 at t-online.de Sun Feb 28 12:28:25 2021 From: aotto1968 at t-online.de (aotto1968) Date: Sun, 28 Feb 2021 18:28:25 +0100 Subject: [Announce] - preview of the new python extension "pymsgque" Message-ID: Hello everybody, PYTHON has a new application server ? https://nhi1.selfhost.co/nhi1/ SOMETHING that writes code for you ? https://nhi1.selfhost.co/wiki/NHI1_-_the_POWER_of_programming have fun From Marco.Sulla.Python at gmail.com Sun Feb 28 17:33:26 2021 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 28 Feb 2021 23:33:26 +0100 Subject: weirdness with list() In-Reply-To: References: Message-ID: On Sun, 28 Feb 2021 at 01:19, Cameron Simpson wrote: > My object represents an MDAT box in an MP4 file: it is the ludicrously > large data box containing the raw audiovideo data; for a TV episode it > is often about 2GB and a movie is often 4GB to 6GB. > [...] > That length is presented via the object's __len__ method > [...] > > I noticed that it was stalling, and investigation revealed it was > stalling at this line: > > subboxes = list(self) > > when doing the MDAT box. That box (a) has no subboxes at all and (b) has > a very large __len__ value. > > BUT... It also has a __iter__ value, which like any Box iterates over > the subboxes. For MDAT that is implemented like this: > > def __iter__(self): > yield from () > > What I was expecting was pretty much instant construction of an empty > list. What I was getting was a very time consuming (10 seconds or more) > construction of an empty list. I can't reproduce, Am I missing something? marco at buzz:~$ python3 Python 3.6.9 (default, Jan 26 2021, 15:33:00) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> class A: ... def __len__(self): ... return 1024**3 ... def __iter__(self): ... yield from () ... >>> a = A() >>> len(a) 1073741824 >>> list(a) [] >>> It takes milliseconds to run list(a) From __peter__ at web.de Sun Feb 28 18:28:14 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 1 Mar 2021 00:28:14 +0100 Subject: weirdness with list() In-Reply-To: References: Message-ID: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> On 28/02/2021 23:33, Marco Sulla wrote: > On Sun, 28 Feb 2021 at 01:19, Cameron Simpson wrote: >> My object represents an MDAT box in an MP4 file: it is the ludicrously >> large data box containing the raw audiovideo data; for a TV episode it >> is often about 2GB and a movie is often 4GB to 6GB. >> [...] >> That length is presented via the object's __len__ method >> [...] >> >> I noticed that it was stalling, and investigation revealed it was >> stalling at this line: >> >> subboxes = list(self) >> >> when doing the MDAT box. That box (a) has no subboxes at all and (b) has >> a very large __len__ value. >> >> BUT... It also has a __iter__ value, which like any Box iterates over >> the subboxes. For MDAT that is implemented like this: >> >> def __iter__(self): >> yield from () >> >> What I was expecting was pretty much instant construction of an empty >> list. What I was getting was a very time consuming (10 seconds or more) >> construction of an empty list. > > I can't reproduce, Am I missing something? > > marco at buzz:~$ python3 > Python 3.6.9 (default, Jan 26 2021, 15:33:00) > [GCC 8.4.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> class A: > ... def __len__(self): > ... return 1024**3 > ... def __iter__(self): > ... yield from () > ... >>>> a = A() >>>> len(a) > 1073741824 >>>> list(a) > [] >>>> > > It takes milliseconds to run list(a) Looks like you need at least Python 3.8 to see this. Quoting https://docs.python.org/3/whatsnew/3.8.html: """ The list constructor does not overallocate the internal item buffer if the input iterable has a known length (the input implements __len__). This makes the created list 12% smaller on average. (Contributed by Raymond Hettinger and Pablo Galindo in bpo-33234.) """ From __peter__ at web.de Sun Feb 28 18:28:14 2021 From: __peter__ at web.de (Peter Otten) Date: Mon, 1 Mar 2021 00:28:14 +0100 Subject: weirdness with list() In-Reply-To: References: Message-ID: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> On 28/02/2021 23:33, Marco Sulla wrote: > On Sun, 28 Feb 2021 at 01:19, Cameron Simpson wrote: >> My object represents an MDAT box in an MP4 file: it is the ludicrously >> large data box containing the raw audiovideo data; for a TV episode it >> is often about 2GB and a movie is often 4GB to 6GB. >> [...] >> That length is presented via the object's __len__ method >> [...] >> >> I noticed that it was stalling, and investigation revealed it was >> stalling at this line: >> >> subboxes = list(self) >> >> when doing the MDAT box. That box (a) has no subboxes at all and (b) has >> a very large __len__ value. >> >> BUT... It also has a __iter__ value, which like any Box iterates over >> the subboxes. For MDAT that is implemented like this: >> >> def __iter__(self): >> yield from () >> >> What I was expecting was pretty much instant construction of an empty >> list. What I was getting was a very time consuming (10 seconds or more) >> construction of an empty list. > > I can't reproduce, Am I missing something? > > marco at buzz:~$ python3 > Python 3.6.9 (default, Jan 26 2021, 15:33:00) > [GCC 8.4.0] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> class A: > ... def __len__(self): > ... return 1024**3 > ... def __iter__(self): > ... yield from () > ... >>>> a = A() >>>> len(a) > 1073741824 >>>> list(a) > [] >>>> > > It takes milliseconds to run list(a) Looks like you need at least Python 3.8 to see this. Quoting https://docs.python.org/3/whatsnew/3.8.html: """ The list constructor does not overallocate the internal item buffer if the input iterable has a known length (the input implements __len__). This makes the created list 12% smaller on average. (Contributed by Raymond Hettinger and Pablo Galindo in bpo-33234.) """ From cs at cskk.id.au Sun Feb 28 18:50:50 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 1 Mar 2021 10:50:50 +1100 Subject: weirdness with list() In-Reply-To: <5471d87c-4f93-7082-91ee-eef32a7117e4@web.de> References: <5471d87c-4f93-7082-91ee-eef32a7117e4@web.de> Message-ID: On 28Feb2021 10:51, Peter Otten <__peter__ at web.de> wrote: >On 28/02/2021 01:17, Cameron Simpson wrote: >>I noticed that it was stalling, and investigation revealed it was >>stalling at this line: >> >> subboxes = list(self) >> >>when doing the MDAT box. That box (a) has no subboxes at all and (b) has >>a very large __len__ value. [...] > >list(iter(self)) > >should work, too. It may be faster than the explicit loop, but also >defeats the list allocation optimization. Yes, very neat. I went with [subbox for subbox in self] last night, but the above is better. [...] >>Still, thoughts? I'm interested in any approaches that would have let >>me >>make list() fast while keeping __len__==binary_length. >> >>I'm accepting that __len__ != len(__iter__) is a bad idea now, though. > >Indeed. I see how that train wreck happened -- but the weirdness is not >the list behavior. I agree. The only weirdness is that list(empty-iterable) took a very long time. Weirdness in the eye of the beholder I guess. >Maybe you can capture the intended behavior of your class with two >classes, a MyIterable without length that can be converted into MyList >as needed. Hmm. Maybe. What I've done so far is: The afore mentioned [subbox for subbox in self] which I'll replace with your nicer one today. Given my BinaryMixin a transcribed_length method which measures the length of the binary transcription. For small things that's actually fairly cheap, and totally general. By default it is aliased to __len__, which still seems a natural thing - the length of the binary object is the number of bytes required to serialise it. The alias lets me override transcribed_length() for bulky things like MDAT where (a) transcription _is_ expensive and (b) the source data may not be present anyway ("skip" mode), but the measurement of the data from the parse is recorded. And I can disassociate __len__ from transcribed_length() if need be in subclasses. I've not done that, given the iter() shuffle above. Cheers, Cameron Simpson From cs at cskk.id.au Sun Feb 28 18:54:00 2021 From: cs at cskk.id.au (Cameron Simpson) Date: Mon, 1 Mar 2021 10:54:00 +1100 Subject: weirdness with list() In-Reply-To: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> References: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> Message-ID: On 01Mar2021 00:28, Peter Otten <__peter__ at web.de> wrote: >On 28/02/2021 23:33, Marco Sulla wrote: >>I can't reproduce, Am I missing something? >> >>marco at buzz:~$ python3 >>Python 3.6.9 (default, Jan 26 2021, 15:33:00) >>[GCC 8.4.0] on linux >>Type "help", "copyright", "credits" or "license" for more information. >>>>>class A: >>... def __len__(self): >>... return 1024**3 >>... def __iter__(self): >>... yield from () >>... >>>>>a = A() >>>>>len(a) >>1073741824 >>>>>list(a) >>[] >>>>> >> >>It takes milliseconds to run list(a) > >Looks like you need at least Python 3.8 to see this. Quoting >https://docs.python.org/3/whatsnew/3.8.html: >""" >The list constructor does not overallocate the internal item buffer if >the input iterable has a known length (the input implements __len__). >This makes the created list 12% smaller on average. (Contributed by >Raymond Hettinger and Pablo Galindo in bpo-33234.) >""" That may also explain why I hadn't noticed this before, eg last year. I do kind of wish __length_hint__ overrode __len__ rather than the other way around, if it's doing what I think it's doing. Cheers, Cameron Simpson From python at mrabarnett.plus.com Sun Feb 28 19:06:31 2021 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 1 Mar 2021 00:06:31 +0000 Subject: weirdness with list() In-Reply-To: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> References: <54adaf0c-f635-8d3b-e801-caf59192b11a@web.de> Message-ID: <3a38a712-60ec-c8aa-5c85-bb8d65a047fd@mrabarnett.plus.com> On 2021-02-28 23:28, Peter Otten wrote: > On 28/02/2021 23:33, Marco Sulla wrote: >> On Sun, 28 Feb 2021 at 01:19, Cameron Simpson wrote: >>> My object represents an MDAT box in an MP4 file: it is the ludicrously >>> large data box containing the raw audiovideo data; for a TV episode it >>> is often about 2GB and a movie is often 4GB to 6GB. >>> [...] >>> That length is presented via the object's __len__ method >>> [...] >>> >>> I noticed that it was stalling, and investigation revealed it was >>> stalling at this line: >>> >>> subboxes = list(self) >>> >>> when doing the MDAT box. That box (a) has no subboxes at all and (b) has >>> a very large __len__ value. >>> >>> BUT... It also has a __iter__ value, which like any Box iterates over >>> the subboxes. For MDAT that is implemented like this: >>> >>> def __iter__(self): >>> yield from () >>> >>> What I was expecting was pretty much instant construction of an empty >>> list. What I was getting was a very time consuming (10 seconds or more) >>> construction of an empty list. >> >> I can't reproduce, Am I missing something? >> >> marco at buzz:~$ python3 >> Python 3.6.9 (default, Jan 26 2021, 15:33:00) >> [GCC 8.4.0] on linux >> Type "help", "copyright", "credits" or "license" for more information. >>>>> class A: >> ... def __len__(self): >> ... return 1024**3 >> ... def __iter__(self): >> ... yield from () >> ... >>>>> a = A() >>>>> len(a) >> 1073741824 >>>>> list(a) >> [] >>>>> >> >> It takes milliseconds to run list(a) > > Looks like you need at least Python 3.8 to see this. Quoting > https://docs.python.org/3/whatsnew/3.8.html: > > """ > The list constructor does not overallocate the internal item buffer if > the input iterable has a known length (the input implements __len__). > This makes the created list 12% smaller on average. (Contributed by > Raymond Hettinger and Pablo Galindo in bpo-33234.) > """ > I'm not seeing a huge problem here: Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import time >>> class A: ... def __len__(self): ... return 1024**3 ... def __iter__(self): ... yield from () ... >>> a = A() >>> len(a) 1073741824 >>> s = time.time() >>> list(a) [] >>> print(time.time() - s) 0.16294455528259277 From alan.gauld at yahoo.co.uk Sun Feb 28 18:47:04 2021 From: alan.gauld at yahoo.co.uk (Alan Gauld) Date: Sun, 28 Feb 2021 23:47:04 +0000 Subject: yield from () Was: Re: weirdness with list() In-Reply-To: References: Message-ID: On 28/02/2021 00:17, Cameron Simpson wrote: > BUT... It also has a __iter__ value, which like any Box iterates over > the subboxes. For MDAT that is implemented like this: > > def __iter__(self): > yield from () Sorry, a bit OT but I'm curious. I haven't seen this before: yield from () What is it doing? What do the () represent in this context? -- 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 From karamveer at btech.christuniversity.in Sun Feb 28 13:03:18 2021 From: karamveer at btech.christuniversity.in (singh.veer99999@hotmail.com) Date: Sun, 28 Feb 2021 23:33:18 +0530 Subject: is not recognized as an internal or external command, operable program or batch file. Message-ID: Dear Sir/Madam Sir I am facing the issue from 10 days. And I tried all the ways to remove this or to come out of this problem but as i try to install some PYTEST or OPENPYXL packages using pip it gives the notification that there is no writeable path present due to that I am not ?is not recognized as an internal or external command, operable program or batch file.?? I am facing problem in running the test cases in Pycharm for the PYTEST please help me pls ? ? Sent from [1]Mail for Windows 10 ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986